feat(console): 附件全链路接线(预览/下载/删除 + 已建任务交互)

- app/src/api.js: 新增 attachmentUrl(inline/下载 URL 构造)与 deleteAttachment 封装
- app/src/app.jsx: taskOps 增 delAttachment(删除→toast→局部刷新)
- design/ui_kits/console/TaskTree.jsx: TaskDetail 附件区从纯文本升级为画廊
  (图片缩略图点击新标签预览 + 下载按钮 + 确认删除),URL 内联零依赖、删除走 taskOps
- design/ui_kits/console/i18n.js: 新增 attSection/attDownload/attDeleteConfirm/
  attDeleted/attDeleteFailed(zh/en/es/ja/fr 五语齐全)

tsk_dbtI_ffTJll9

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
wangjia
2026-06-30 01:49:17 +08:00
parent b51163ceed
commit 00e6bc72e7
4 changed files with 60 additions and 1 deletions
+7
View File
@@ -52,6 +52,13 @@ export const api = {
}
return res.json();
},
// 附件预览/下载 URL:默认 inline(图片可 <img src> 预览),download=true 触发下载。
// name = basename(att.path)(磁盘安全名,非展示名)。纯字符串构造,GET 走 <img>/<a> 由浏览器处理。
attachmentUrl: (taskId, name, opts = {}) =>
`/api/tasks/${taskId}/attachments/${encodeURIComponent(name)}${opts.download ? '?download=1' : ''}`,
// 删除单个附件(按磁盘文件名)。返回 { attachments } 最新列表。
deleteAttachment: (taskId, name) =>
http('DELETE', `/api/tasks/${taskId}/attachments/${encodeURIComponent(name)}`),
};
// WS 单向订阅:连上后服务端推送 events 表记录。断线自动重连(指数退避,封顶 10s)。
+5
View File
@@ -387,6 +387,11 @@ export function App() {
try { await api.deleteTask(taskId); toast('warn', '已删除'); loadProject(currentId); loadGlobal(); }
catch (e) { toast('warn', '删除失败:' + e.message); }
},
// 删除已建任务的单个附件(name = 磁盘文件名 basename(att.path)),成功后局部刷新
delAttachment: async (taskId, name) => {
try { await api.deleteAttachment(taskId, name); toast('warn', t.attDeleted); loadProject(currentId); }
catch (e) { toast('warn', t.attDeleteFailed + e.message); }
},
};
const [showNewProject, setShowNewProject] = React.useState(false);
const createProject = async (body) => {