From c47eb46d77a907c04351cc6841de35de1326c2e4 Mon Sep 17 00:00:00 2001 From: CI Bot Date: Fri, 25 Sep 2026 21:57:53 +0800 Subject: [PATCH] =?UTF-8?q?fix(cover):=20=E4=BF=AE=E5=A4=8DAI=E6=95=B0?= =?UTF-8?q?=E5=AD=97=E4=BA=BA=E9=A1=B5=E9=9D=A2=E7=B3=BB=E7=BB=9F=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E7=BC=96=E8=BE=91=E8=BF=94=E5=9B=9E403=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因: - 后端 PUT /cover-templates/{id} 对 is_system=true 的模板返回 403「系统模板不可修改」是正确的权限控制 - 前端 CoverSettingsModal 对系统模板(默认模板/大胆红/优雅黑等)也渲染「编辑」按钮 - useSharedCover/useStep6Cover 的 handleSaveTemplate 只要 tpl.id 存在就走 update 分支,对系统模板调用 PUT → 403 - 用户在 AI 数字人页面(无 project/task 上下文)点击系统模板编辑/保存时复现 403 修复: 1. CoverSettingsModal: 系统模板按钮文字从「编辑」改为「复制」,语义明确为另存为 2. useSharedCover.handleEditTemplate: 系统模板点击时创建新模板草稿(清空id, 名称加「副本」, is_system=false) 3. useSharedCover.handleSaveTemplate: 增加 isSystem 判断,系统模板或无id都走 create 分支 4. useStep6Cover 同步上述修复,保持 generate 页面行为一致 5. 保存成功后清空 editingTemplate,避免后续打开残留状态 --- .../src/components/cover/useSharedCover.ts | 30 +++++++++++++---- .../cover-settings/CoverSettingsModal.tsx | 2 +- .../src/pages/generate/hooks/useStep6Cover.ts | 32 ++++++++++++++----- 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/apps/web/src/components/cover/useSharedCover.ts b/apps/web/src/components/cover/useSharedCover.ts index 29a174c15..eac74e189 100644 --- a/apps/web/src/components/cover/useSharedCover.ts +++ b/apps/web/src/components/cover/useSharedCover.ts @@ -104,7 +104,18 @@ export function useSharedCover(opts: UseSharedCoverOptions): UseSharedCoverRetur }, []) const handleEditTemplate = useCallback((tpl: CoverTemplate) => { - setEditingTemplate(tpl) + // 系统模板不可修改:复制为新模板草稿,走另存为流程 + if (tpl.is_system) { + setEditingTemplate({ + ...tpl, + id: "", + name: tpl.name + " 副本", + is_system: false, + created_at: "", + }) + } else { + setEditingTemplate(tpl) + } setShowCoverEditor(true) }, []) @@ -116,15 +127,22 @@ export function useSharedCover(opts: UseSharedCoverOptions): UseSharedCoverRetur const handleSaveTemplate = useCallback( async (tpl: CoverTemplate) => { try { - if (tpl.id && templates.some((t) => t.id === tpl.id)) { - const updated = await updateCoverTemplate(tpl.id, { name: tpl.name, config: tpl.config }) - setTemplates((prev) => prev.map((t) => (t.id === tpl.id ? { ...t, ...updated } : t))) - } else { - const created = await createCoverTemplate({ name: tpl.name, config: tpl.config }) + // 系统模板或无 id(新建/副本)→ 走创建分支;否则走更新 + const isSystem = templates.find((t) => t.id === tpl.id)?.is_system === true + const shouldCreate = !tpl.id || isSystem + if (shouldCreate) { + const created = await createCoverTemplate({ + name: tpl.name || "我的封面模板", + config: tpl.config, + }) setTemplates((prev) => [...prev, created]) setSelectedTemplateId(created.id || tpl.id) + } else { + const updated = await updateCoverTemplate(tpl.id, { name: tpl.name, config: tpl.config }) + setTemplates((prev) => prev.map((t) => (t.id === tpl.id ? { ...t, ...updated } : t))) } setShowCoverEditor(false) + setEditingTemplate(null) } catch (err) { console.error("[SharedCover] 保存模板失败:", err) message.error("保存模板失败,请稍后重试") diff --git a/apps/web/src/pages/generate/components/cover-settings/CoverSettingsModal.tsx b/apps/web/src/pages/generate/components/cover-settings/CoverSettingsModal.tsx index c4e4423bf..9877c909e 100644 --- a/apps/web/src/pages/generate/components/cover-settings/CoverSettingsModal.tsx +++ b/apps/web/src/pages/generate/components/cover-settings/CoverSettingsModal.tsx @@ -111,7 +111,7 @@ const CoverSettingsModal: React.FC = ({
e.stopPropagation()}> {!tpl.is_system && (