2026-06-28-template-edit-page-basic-info-design.md 7.4 KB

模板编辑页与任务完成入口调整设计

1. 背景

当前模板模块存在两个问题:

  1. 模板制作任务完成后,TemplateMakeTaskPage 提供的是“查看模板详情”入口,但用户当前真实后续动作是补充和确认模板基本信息。
  2. 现有 TemplateDetailPage 同时承担了详情展示和信息编辑职责,页面边界不清晰,不符合“新加一个编辑页面,并且只能编辑模板基本信息”的目标。

本次设计将模板详情与模板编辑拆分:

  • 保留现有模板详情页作为展示页。
  • 新增独立模板编辑页,只允许编辑模板基本信息。
  • 模板制作任务完成后的主按钮改为“编辑模板信息”,引导用户进入新编辑页。

2. 目标

本次改动完成后,应满足以下目标:

  1. 模板制作任务成功后,用户可直接进入独立的“编辑模板信息”页面。
  2. 模板详情页继续保留为展示用途,不再承担任务完成后的主编辑入口。
  3. 编辑页只能修改模板基本信息,不允许修改素材、封面、模板包和任务相关数据。
  4. 前后端都要建立独立的“读取模板基本信息 / 更新模板基本信息”链路。

3. 非目标

以下内容不在本次范围内:

  1. 不重做模板详情页整体视觉结构。
  2. 不允许在编辑页重新上传或替换参考图、AI 模特、服装、背景。
  3. 不允许在编辑页修改模板封面图或模板包 URL。
  4. 不处理模板重新生成、任务重试、任务取消等能力。
  5. 不改造模板列表的整体交互模式,列表仍然以详情页为主要查看入口。

4. 目标交互

4.1 任务页

当模板制作任务状态为 STEP2_SUCCESS 时:

  • 当前按钮文案从“查看模板详情”改为“编辑模板信息”。
  • 跳转目标从模板详情页改为模板编辑页。

任务页中的“返回模板列表”按钮保持不变。

4.2 模板详情页

模板详情页继续保留,作为展示页存在:

  • 模板列表点击卡片仍然进入详情页。
  • 详情页展示模板封面、生成状态、统计信息、使用结果等现有内容。
  • 本次不要求将详情页完全去编辑化,但任务完成态不再把它作为首要后续入口。

4.3 模板编辑页

新增独立模板编辑页,路径与职责如下:

  • 路由:/:locale/templates/:templateId/edit
  • 职责:仅编辑模板基本信息

允许编辑的字段:

  1. 模板名 templateName
  2. 状态 status
  3. 分类 category
  4. 标签 tags
  5. 描述 description

不允许编辑的字段:

  1. 封面图 coverUrl
  2. 模板包 templateUrl
  3. 参考图 refHairUrl
  4. 模特图 modelUrl
  5. 服装图 clothesUrl
  6. 背景图 backgroundUrl
  7. 任意任务状态与任务资源字段

页面布局采用现有工作台编辑页骨架:

  • 顶部使用统一的 stylist-workbench-top ipad-top-space-margin mb-2
  • 提供返回、取消、保存按钮
  • 主体使用标准表单布局

5. 路由与页面结构

5.1 前端路由

新增路由:

templateEdit: '/:locale/templates/:templateId/edit'

路由注册到 App.tsx,使用登录保护,与其他工作台页面一致。

5.2 页面职责划分

  • TemplateMakeTaskPage
    • 任务状态轮询
    • 成功后引导进入编辑页
  • TemplateDetailPage
    • 模板展示页
  • TemplateEditPage
    • 模板基本信息编辑页

6. 前端数据流

6.1 任务成功后的跳转

  1. 用户在 TemplateMakeTaskPage 轮询到 STEP2_SUCCESS
  2. 页面显示“编辑模板信息”按钮
  3. 点击后跳转到 /:locale/templates/:templateId/edit

6.2 编辑页加载

  1. 页面根据 templateId 请求模板基本信息
  2. 请求成功后回填表单
  3. 请求失败则显示错误或未找到状态

6.3 编辑页保存

  1. 用户修改模板基本信息
  2. 点击保存按钮
  3. 前端调用更新接口
  4. 更新成功后保留在当前页,并提示保存成功
  5. 更新失败时显示错误提示,不清空现有表单内容

7. 后端接口设计

7.1 获取模板基本信息

新增接口:

GET /api/v1/templates/:templateId

职责:

  • 按模板 ID 返回模板基本信息
  • 校验模板存在
  • 校验模板属于当前登录发型师

返回字段最少包含:

{
  "id": "43",
  "templateName": "柔和层次长发",
  "status": "DRAFT",
  "category": "LONG",
  "tags": ["层次", "首次建议"],
  "description": "适合轻盈感修饰",
  "coverUrl": "https://example.com/cover.jpg",
  "templateUrl": "https://example.com/template.zip"
}

说明:

  • 编辑页虽然不允许修改 coverUrl / templateUrl,但允许后端返回,以便页面按需展示只读信息。

7.2 更新模板基本信息

新增接口:

PATCH /api/v1/templates/:templateId

仅允许更新以下字段:

{
  "templateName": "空气感中长发",
  "status": "PUBLIC",
  "category": "MEDIUM",
  "tags": ["空气感", "层次"],
  "description": "适合脸部轮廓柔化"
}

后端必须保证:

  1. 只能更新允许字段
  2. 不得覆盖模板封面、模板包 URL、素材 URL、任务状态等字段
  3. 模板不存在时返回未找到错误
  4. 模板不属于当前发型师时返回未找到或无权限错误

8. 后端服务设计

模板模块新增两类能力:

  1. getById(stylistId, templateId)
  2. updateBasicInfo(stylistId, templateId, dto)

实现原则:

  • 以 hair_template 为唯一事实来源
  • 查询和更新都按 hairstylist_id + id + is_deleted = 0 做范围限制
  • tags 在数据库中仍按现有约定以逗号串存储,接口层负责数组与字符串之间的转换

9. 数据边界

9.1 可写字段边界

本次编辑页只能修改:

  • template_name
  • status
  • category
  • tags
  • description

9.2 不可写字段边界

以下字段必须保持只读:

  • cover_url
  • template_url
  • ref_hair_url
  • model_url
  • clothes_url
  • background_url
  • is_system_template
  • 任务表 hair_template_make_task 的全部字段

10. 错误处理

10.1 前端

  • 加载失败:显示加载失败提示
  • 未找到:显示模板不存在提示
  • 保存失败:显示后端返回错误,不清空表单
  • 保存中:按钮禁用,避免重复提交

10.2 后端

  • 模板不存在:返回 404
  • 越权访问:返回 404 或统一业务未找到错误
  • DTO 校验失败:返回 400

11. 测试策略

11.1 前端

至少覆盖以下场景:

  1. 任务页成功按钮文案变为“编辑模板信息”
  2. 任务页成功按钮跳转到 /templates/:templateId/edit
  3. 编辑页路由可访问
  4. 编辑页可加载模板基本信息并完成回填
  5. 编辑页保存时只提交允许字段

11.2 后端

至少覆盖以下场景:

  1. GET /templates/:templateId 成功返回模板基本信息
  2. GET /templates/:templateId 对不存在模板返回 404
  3. PATCH /templates/:templateId 可更新基本信息字段
  4. PATCH /templates/:templateId 不会改动非允许字段
  5. 越权访问返回未找到或拒绝访问

12. 验收标准

满足以下条件即视为本次需求完成:

  1. 模板制作任务完成页主按钮改为“编辑模板信息”
  2. 点击后进入新建的模板编辑页
  3. 编辑页只允许修改模板名、状态、分类、标签、描述
  4. 后端存在对应的读取与更新接口
  5. 模板详情页仍然保留为展示入口
  6. 前后端相关测试通过