feat(restore): 恢复到指定目录(文件类型本机恢复 + 确认弹窗输入) (#86)

* feat(restore): 支持恢复到指定目录(文件类型本机恢复)

恢复此前只能覆盖原始源路径。新增「恢复到指定目录」:把文件备份还原到任意目录,
用于测试恢复、迁移、并排恢复而不覆盖现网数据。

- backup.TaskSpec +RestoreTargetPath;FileRunner.Restore 非空时把归档解压到该目录。
- model.RestoreRecord +TargetPath(持久化/审计)。
- RestoreService.Start 增加 targetPath 参数与校验:仅文件类型、需绝对路径、
  远程节点暂不支持(清晰报错);executeLocally 透传到 spec。
- 恢复触发端点接受可选请求体 {targetPath}(无 body 时恢复到原始路径)。
- 测试:恢复到指定目录后文件落在该目录;相对路径被拒。

* feat(restore): 恢复确认弹窗支持指定恢复目录

文件类型 + 本机恢复时,恢复确认弹窗新增「恢复到指定目录」输入(可选、绝对路径、
留空=原位置),并实时反映在「恢复目标」摘要中;经 startRestoreFromBackup 透传 targetPath。
This commit is contained in:
Wu Qing
2026-06-01 00:39:17 +08:00
committed by GitHub
parent f7599dd9bd
commit 50ce6587d8
9 changed files with 155 additions and 33 deletions
@@ -151,11 +151,14 @@ func (h *BackupRecordHandler) Restore(c *gin.Context) {
if subject, exists := c.Get(contextUserSubjectKey); exists {
triggeredBy = strings.TrimSpace(fmt.Sprintf("%v", subject))
}
// 可选请求体:selectedPaths 按需(选择性)恢复;targetPath 恢复到指定目录(仅文件类型本机恢复)。
// 无 body 时为整体恢复到原始路径。
var body struct {
SelectedPaths []string `json:"selectedPaths"`
TargetPath string `json:"targetPath"`
}
_ = c.ShouldBindJSON(&body) // body 可选:无 body 为整体恢复,含 selectedPaths 为按需恢复
detail, err := h.restoreService.StartSelective(c.Request.Context(), id, body.SelectedPaths, triggeredBy)
_ = c.ShouldBindJSON(&body)
detail, err := h.restoreService.StartSelective(c.Request.Context(), id, body.SelectedPaths, strings.TrimSpace(body.TargetPath), triggeredBy)
if err != nil {
response.Error(c, err)
return