当前“我的发型模板”页面已经具备模板列表卡片和顶部 4 个统计卡片的 UI 骨架,但这部分数据还不是真实业务数据:
GET /api/v1/templates 当前返回的 usedCount 仍是固定值 0。TemplateListPage 中顶部统计使用的是本地默认值,且请求的 /api/v1/stylist/dashboard/template-summary 在后端并没有真实实现。本轮目标是在尽量不改动现有模板列表 UI 结构的前提下,把模板使用量和顶部统计接成真实、可持续维护的数据链路。
本轮交付后,需要满足以下目标:
hair_template 表新增累计使用量字段。usedCount 返回真实值,卡片展示“使用 x 次”。以下内容不在本次范围内:
做法:
hair_template 增加累计字段。优点:
缺点:
做法:
hair_template 落累计字段。ai_hair_simulation_task。优点:
缺点:
做法:
hair_template 增加 used_count,保存累计使用量。used_count + 1。ai_hair_simulation_task 统计本周成功任务数。优点:
缺点:
采用 方案 C:模板表存累计使用量,顶部“本周使用”从任务表做周增量统计。
hair_template.used_countai_hair_simulation_tasktask_status = 'SUCCESSES'task_finish_time 落在当前自然周范围内is_deleted = 0template_id 能关联到当前美发师自己的 hair_template说明:
继续沿用当前页面已有的 4 个统计项,不改 UI 结构:
total
published
status = 'PUBLIC' 的未删除模板数weeklyUsed
draft
status = 'DRAFT' 的未删除模板数在 hair_template 新增字段:
used_count int unsigned not null default 0 comment '模板累计使用次数'
要求:
0在 HairTemplate 模型新增:
usedCount Int @default(0) @map("used_count") @db.UnsignedInt
used_count = 0。继续使用现有接口:
GET /api/v1/templates
返回结构保持不变,但 usedCount 改为真实映射:
{
items: Array<{
id: string
name: string
category: 'LONG' | 'MEDIUM' | 'SHORT' | 'DYE'
status: 'DRAFT' | 'PUBLIC'
description: string
tags: string[]
image: string
makeTaskId?: string
makeTaskStatus?: string
usedCount: number
}>
total: number
page: number
pageSize: number
}
实现要求:
usedCount 直接来自 hair_template.used_count0新增模板模块内的真实统计接口:
GET /api/v1/templates/summary
返回结构:
{
"total": 24,
"published": 18,
"weeklyUsed": 6,
"draft": 4
}
说明:
/api/v1/stylist/dashboard/template-summaryTemplatesService 新增 getSummary(stylistId) 方法,返回:
totalpublishedweeklyUseddraft建议实现方式:
total
hair_template.counthairstylist_id = 当前美发师,is_deleted = 0published
hair_template.countstatus = 'PUBLIC'draft
hair_template.countstatus = 'DRAFT'weeklyUsed
ai_hair_simulation_task 中本周成功任务数weeklyUsed 的推荐查询思路:
ai_hair_simulation_task 中筛选:
taskStatus = 'SUCCESSES'taskFinishTime 在本周范围内isDeleted = 0templateId 关联 hair_templatehair_template.hairstylist_id = 当前美发师hair_template.is_deleted = 0如果 Prisma 直接跨表过滤不够顺手,可以采用两段式最小实现:
累计值的更新触发点放在“AI 发型模拟任务成功”的链路里。
当前系统已经存在 ai_hair_simulation_task 的状态刷新和结果落库逻辑,因此本轮在任务状态首次转为 SUCCESSES 时,补充:
hair_template.used_count += 1
要求:
SUCCESSES 时递增一次推荐做法:
SUCCESSESSUCCESSES
时,才对对应模板执行一次递增说明:
SimulationsService 中任务刷新成功的逻辑,而不是放在列表查询时临时聚合。TemplateListPage 保持现有布局与交互,数据层做以下调整:
template.usedCount前端 getTemplateDashboardSummary() 当前请求:
/stylist/dashboard/template-summary
本轮改为请求:
/templates/summary
当前前端存在默认假数据:
{
total: 24,
published: 18,
weeklyUsed: 6,
draft: 4,
}
本轮改为:
00原因:
更新 templates.service.spec.ts,至少覆盖:
usedCountgetSummary() 返回:
totalpublishedweeklyUseddraftused_count + 1更新 templates.e2e-spec.ts,至少覆盖:
GET /api/v1/templates 返回真实 usedCountGET /api/v1/templates/summary 返回 4 个真实统计字段如现有 E2E 框架不便直接覆盖“模拟任务成功触发模板使用量递增”,可优先用单测锁住该业务规则。
更新 TemplateListPage.test.tsx,至少覆盖:
0weeklyUsed 依赖 task_finish_time,因此只有成功完成并记录完成时间的任务才会被统计。template_id 在 ai_hair_simulation_task 中是字符串,需要在统计时注意与 hair_template.id 的类型转换。本轮完成后,系统应具备以下结果:
used_count 字段