library-picturebook-activity/docs/design/public/ugc-development-plan.md
zhonghua 1c63cb21e5 feat: 活动提交联动作品库+多租户数据对齐
1. P0-12 活动提交联动:替换文件上传为 WorkSelector 作品选择器
   - 前端 ActivityDetail.vue 集成 WorkSelector 组件
   - 后端 submitWork 支持 userWorkId 快照复制(title/description/coverUrl/pages)
   - WorkSelector 支持 redirectUrl 创作后返回活动页

2. 多租户数据对齐:修复公众端报名/作品 tenantId 不一致
   - register() 使用活动的 contestTenants[0] 作为 tenantId
   - submitWork() 使用报名记录的 tenantId
   - 管理端报名/作品统计、列表数据一致

3. 前端报名状态区分:pending/passed/rejected 显示不同按钮
4. submitWork 报名状态检查:区分未报名/审核中/已拒绝提示
5. 活动列表添加 _count(报名数/作品数)用于已交/应交展示
6. 修复 PublicCreationService.submit() title 默认值缺失

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 14:11:59 +08:00

497 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# UGC 社区升级 — 开发计划
> 创建日期2026-03-27
> 最后更新2026-03-27
---
## 总览
```
P0最小闭环
子女账号独立化 → 作品库+创作流程 → 作品发布+审核 → 作品广场 → 活动联动
P1社区互动
点赞/收藏 → 评论+审核 → 消息通知 → 举报处理
P2进阶能力
关注/粉丝 → 分享海报 → 数据运营后台 → 推荐算法优化
```
---
## P0 — 最小闭环
目标:用户能创作绘本 → 保存到作品库 → 发布到广场 → 审核通过后公开展示 → 从作品库选作品参与活动
### 第一阶段:基础设施(子女账号独立化 + 数据库)
这是所有后续功能的基础,必须先完成。
#### P0-1. 数据库设计与迁移
**改动范围**Prisma Schema + 迁移脚本
新增表:
```
user_parent_child — 家长-子女管理关系
user_works — 用户作品主表
user_work_pages — 绘本分页内容(图片+文字+配音)
work_tags — 标签表
work_tag_relations — 作品-标签关联
content_review_logs — 审核操作日志
```
修改表:
```
users — 新增字段user_type(adult/child)、parent_control_mode
contest_works — 新增字段user_work_id关联用户作品库
```
数据迁移:
```
children 表现有数据 → 迁移为独立 User 记录
- 为每个 child 创建 User归属 public 租户user_source='child_migrated'
- 创建 user_parent_child 关联记录
- 现有 contest_registration 中 child_id 关联到新的 User
```
**依赖**:无
**产出**:数据库 Schema 变更 + 迁移脚本 + 验证通过
---
#### P0-2. 子女账号独立化(后端)
**改动范围**auth 模块 + users 模块 + public 模块
```
后端 API
├── POST /api/public/children/create-account — 家长为子女创建独立账号
├── GET /api/public/children/accounts — 家长查看已创建的子女账号列表
├── POST /api/public/auth/switch-child — 家长切换到子女身份(签发子女 JWT
├── POST /api/public/auth/login — 修改:支持子女独立登录
├── GET /api/public/mine/parent-info — 子女查看自己的家长信息
└── PUT /api/public/children/accounts/:id — 家长修改子女账号信息
```
JWT 改造:
```
现有 JWT payload{ sub, username, tenantId }
新增字段:{ userType: 'adult'|'child', parentUserId?: number }
子女登录或家长切换后,签发子女身份的 JWT
```
**依赖**P0-1
**产出**:子女可独立登录、家长可切换子女身份
---
#### P0-3. 子女账号独立化(前端)
**改动范围**:用户端 H5 页面
```
前端改动:
├── /p/login — 登录页支持子女独立登录
├── /p/mine — 个人中心增加"切换身份"入口(家长可切换到子女)
├── /p/mine/children — 改造:从"子女信息管理"变为"子女账号管理"(创建账号/设置密码/管控模式)
├── 全局状态 — authStore 支持当前身份(家长/子女)切换
└── 活动报名流程 — 改造:子女身份下直接报名(不再需要"选择参与者"步骤)
```
**依赖**P0-2
**产出**:家长可为子女创建账号、切换身份;子女可独立登录
---
### 第二阶段:创作与作品库
#### P0-4. 作品库(后端)
**改动范围**:新增 user-works 模块
```
后端 API
├── POST /api/public/works — 创建作品AI生成完毕后调用保存到作品库
├── GET /api/public/works — 我的作品列表支持状态筛选draft/published/private等
├── GET /api/public/works/:id — 作品详情(含分页内容)
├── PUT /api/public/works/:id — 更新作品信息(标题/标签/可见性)
├── DELETE /api/public/works/:id — 删除作品(软删除)
├── POST /api/public/works/:id/publish — 发布作品(进入审核队列)
├── GET /api/public/works/:id/pages — 获取绘本分页数据
└── POST /api/public/works/:id/pages — 保存绘本分页数据AI生成后写入
```
**依赖**P0-1
**产出**:作品的 CRUD + 发布接口
---
#### P0-5. AI 创作流程(后端)
**改动范围**:新增 creation 模块,对接同事的 AI 能力
```
后端 API
├── POST /api/public/creation/submit — 提交创作请求(上传画作 + 语音/文字描述)
├── GET /api/public/creation/:id/status — 查询生成进度
├── GET /api/public/creation/:id/result — 获取生成结果
└── GET /api/public/creation/history — 创作历史
```
核心流程:
```
1. 前端上传画作图片到 COS得到 imageUrl
2. 前端上传语音到 COS或直接传文字描述
3. 调用 /creation/submit 提交
4. 后端调用同事的 AI 服务,异步生成
5. 前端轮询 /creation/:id/status 等待生成完成
6. 生成完成后,后端自动创建 UserWork + UserWorkPages
7. 前端获取结果,跳转到作品详情页
```
**依赖**P0-4 + 同事 AI 接口
**产出**:创作→生成→保存到作品库的完整链路
---
#### P0-6. 创作流程 + 作品库(前端)
**改动范围**:用户端 H5 新增页面
```
新增页面:
├── /p/create — 创作入口页
├── /p/create/upload — Step 1上传画作拍照/相册)
├── /p/create/describe — Step 2语音/文字描述构思
├── /p/create/generating — Step 3生成中等待页展示进度
├── /p/create/result/:id — Step 4生成完毕预览绘本
├── /p/works — 我的作品库列表
├── /p/works/:id — 作品详情(翻页阅读绘本)
└── /p/works/:id/publish — 发布设置(标题/标签/可见性)
```
**依赖**P0-5
**产出**:用户可在 H5 上完成创作→预览→保存→发布的全流程
---
### 第三阶段:作品广场与标签
#### P0-7. 标签体系(后端)
**改动范围**:新增 tags 模块
```
后端 API
├── GET /api/public/tags — 获取标签列表(用户端选标签用)
├── GET /api/public/tags/hot — 热门标签
├── POST /api/tags — 创建标签(超管端)
├── PUT /api/tags/:id — 编辑标签(超管端)
├── DELETE /api/tags/:id — 删除标签(超管端)
└── GET /api/tags — 标签管理列表(超管端)
```
**依赖**P0-1
**产出**:标签 CRUD + 用户端标签列表
---
#### P0-8. 作品广场(后端)
**改动范围**public 模块扩展
```
后端 API
├── GET /api/public/gallery — 作品广场列表(已审核通过的公开作品,分页+筛选)
│ 参数page, pageSize, tagId, category, sortBy(latest/hot), keyword
├── GET /api/public/gallery/:id — 广场作品详情(含翻页数据,增加浏览量)
└── GET /api/public/users/:id/works — 某用户的公开作品列表(个人主页用)
```
**依赖**P0-4 + P0-7
**产出**:作品广场查询接口
---
#### P0-9. 作品广场 + 标签管理(前端)
**改动范围**:用户端 + 超管端
```
用户端新增/改造页面:
├── /p/(首页改造) — 从活动大厅改为作品推荐流(瀑布流/卡片网格)
│ ├── 搜索栏
│ ├── 热门标签横滑
│ └── 作品卡片列表(封面+标题+作者+点赞数)
├── /p/gallery/:id — 广场作品详情页(翻页阅读+作者信息)
├── /p/user/:id — 用户公开主页(头像/昵称/作品列表)
└── 底部 Tab 改造 — 从现有 3 Tab 改为 5 Tab首页/创作/活动/消息/我的)
超管端新增页面:
├── 标签管理页 — 标签列表 + 新增/编辑/删除 + 使用统计
```
**依赖**P0-6 + P0-8
**产出**:用户可浏览作品广场、查看他人作品、搜索和按标签筛选
---
### 第四阶段:内容审核 + 活动联动
#### P0-10. 内容审核(后端)
**改动范围**:新增 content-review 模块
```
后端 API
├── GET /api/content-review/works — 待审核作品队列
├── GET /api/content-review/works/stats — 审核统计
├── GET /api/content-review/works/:id — 审核详情(含绘本内容预览)
├── POST /api/content-review/works/:id/approve — 通过
├── POST /api/content-review/works/:id/reject — 拒绝(含拒绝原因)
└── GET /api/content-review/logs — 审核日志
```
**依赖**P0-4
**产出**:审核 API 完整链路
---
#### P0-11. 内容审核 + 作品管理(超管端前端)
**改动范围**:超管端新增页面
```
超管端新增页面:
├── 作品审核页 — 统计卡片 + 审核队列列表 + 审核详情 Drawer绘本翻页预览+通过/拒绝)
├── 作品管理页 — 全平台已发布作品列表 + 筛选 + 下架/置顶
└── 超管端菜单 — 新增"内容管理"一级菜单
```
**依赖**P0-10
**产出**:超管可审核作品、管理已发布作品
---
#### P0-12. 活动提交联动 ✅ 已实现 (2026-04-07)
**改动范围**:活动报名+提交流程改造
```
后端改动:
├── POST /api/public/activities/:id/submit-work — 改造:支持从作品库选择作品
│ 新增参数userWorkId用户作品ID
│ 逻辑:根据 userWorkId 从 UgcWork + UgcWorkPage 复制快照到 ContestWork
│ 校验:归属当前用户、未删除、非 rejected/taken_down 状态
└── contest_works 表 — user_work_id 字段已存在
前端改动:
├── ActivityDetail.vue — 替换文件上传弹窗为 WorkSelector 作品选择器
├── WorkSelector.vue — 已有组件,新增 redirectUrl prop 支持创作后返回活动页
└── public.ts — submitWork API 新增 userWorkId 参数
```
**快照字段映射**
| UgcWork / UgcWorkPage 字段 | ContestWork 字段 | 说明 |
|---|---|---|
| title | title | 直接复制 |
| description | description | 直接复制 |
| coverUrl | previewUrl | 封面 → 预览图 |
| aiMeta | aiModelMeta | AI 元数据 |
| (所有 page.imageUrl) | previewUrls | 所有页面图片 URL 列表 |
| (所有 page 数据) | files | 分页快照 [{pageNo, imageUrl, text, audioUrl}] |
**用户交互流程**
1. 用户在活动详情页点击"从作品库选择"
2. 弹出 WorkSelector 展示用户所有作品(排除 rejected/taken_down
3. 用户选择作品后确认提交 → 后端复制快照到 ContestWork
4. 若作品库为空,显示"去创作"按钮 → 跳转创作页 → 完成后 redirect 回活动详情页
5. 支持 resubmit 模式:可重新选择不同作品提交
**关键设计**
- 快照不可变性:提交后 ContestWork 数据与 UgcWork 解耦,后续修改/删除作品不影响活动中的作品
- 向后兼容userWorkId 为 null 时走旧逻辑(直接上传)
- 无需数据库变更t_biz_contest_work 已有所需字段
**依赖**P0-4 + P0-6 + 现有活动模块
**产出**:用户可从作品库选作品参与活动
---
## P0 任务依赖关系
```
P0-1数据库
├── P0-2子女账号后端→ P0-3子女账号前端
├── P0-4作品库后端→ P0-5AI创作后端→ P0-6创作+作品库前端)
├── P0-7标签后端
└── P0-10审核后端→ P0-11审核前端
P0-6 + P0-7 + P0-8广场后端→ P0-9广场前端
P0-4 + P0-6 → P0-12活动联动
```
可并行的工作:
- P0-2子女账号和 P0-4作品库可并行开发
- P0-7标签和 P0-5AI创作可并行
- P0-10审核后端在 P0-4 完成后即可开始,与 P0-5/P0-6 并行
---
## P1 — 社区互动
目标:用户可对作品点赞、收藏、评论;有消息通知;可举报不当内容。
#### P1-1. 点赞/收藏(后端+前端)✅ 已实现 (2026-03-31)
```
后端 API已实现
├── POST /api/public/works/:id/like — 点赞/取消点赞toggle
├── POST /api/public/works/:id/favorite — 收藏/取消收藏toggle
├── GET /api/public/works/:id/interaction — 查询交互状态
├── POST /api/public/works/batch-interaction — 批量查询交互状态
├── GET /api/public/mine/favorites — 我的收藏列表
前端改动(已实现):
├── 作品详情页 — 底部互动栏:点赞(心形)/收藏(星形)/浏览数,乐观更新+弹跳动效
├── 广场卡片 — 心形可点击点赞,已点赞显示实心粉色
├── /p/mine/favorites — 我的收藏页面(网格展示)
├── 个人中心 — 新增「我的收藏」菜单入口
```
**数据库**user_work_likes + user_work_favorites已有
**设计文档**[点赞收藏设计](../public/like-favorite.md)
---
#### P1-2. 评论(后端+前端)
```
后端 API
├── GET /api/public/works/:id/comments — 作品评论列表
├── POST /api/public/works/:id/comments — 发表评论(进入审核队列)
├── DELETE /api/public/comments/:id — 删除自己的评论
超管端 API
├── GET /api/content-review/comments — 评论审核队列
├── GET /api/content-review/comments/stats — 评论审核统计
├── POST /api/content-review/comments/:id/approve — 通过
├── POST /api/content-review/comments/:id/reject — 拒绝
前端改动:
├── 作品详情页 — 评论区(预设评语选择 + 简短文字输入)
├── 超管端 — 新增评论审核页面
```
**依赖**P0 完成
**数据库**user_work_comments
---
#### P1-3. 消息通知(后端+前端)
```
后端 API
├── GET /api/public/notifications — 通知列表(分类:互动/系统/活动)
├── POST /api/public/notifications/read — 标记已读
├── GET /api/public/notifications/unread-count — 未读数
通知触发场景:
├── 作品被点赞/收藏/评论 → 互动通知
├── 作品审核通过/拒绝 → 系统通知
├── 活动报名审核结果 → 活动通知
前端改动:
├── /p/notifications — 消息中心页面
├── 底部 Tab "消息" — 红点未读数
```
**依赖**P1-1 + P1-2
**数据库**user_notifications
---
#### P1-4. 举报处理(后端+前端)
```
后端 API
├── POST /api/public/reports — 提交举报(作品/评论/用户)
├── GET /api/content-review/reports — 举报队列(超管端)
├── GET /api/content-review/reports/stats — 举报统计
├── POST /api/content-review/reports/:id/handle — 处理举报
前端改动:
├── 作品详情页/评论 — 举报入口(举报原因选择)
├── 超管端 — 新增举报处理页面
```
**依赖**P0 完成
**数据库**user_work_reports
---
## P2 — 进阶能力
#### P2-1. 关注/粉丝体系
```
├── POST /api/public/users/:id/follow — 关注/取消关注
├── GET /api/public/mine/following — 我的关注列表
├── GET /api/public/mine/followers — 我的粉丝列表
├── GET /api/public/users/:id/followers — 某人的粉丝列表
├── 首页增加"关注"Tab — 只看关注人的作品
```
**数据库**user_follows
---
#### P2-2. 分享
```
├── POST /api/public/works/:id/share — 生成分享链接/海报
├── 作品详情页增加分享按钮 — 生成海报图 + 复制链接
├── 支持微信/朋友圈分享
```
**数据库**user_work_shares
---
#### P2-3. 数据运营后台(超管端)
```
├── 内容数据看板 — 日/周/月发布量、互动量、增长趋势
├── 用户数据看板 — 活跃用户、创作者分层、留存率
├── 推荐配置 — 精选推荐/Banner/专题管理
├── 热门榜单配置 — 配置榜单规则
```
---
#### P2-4. 创作能力增强
```
├── 绘本微调 — 生成后逐页修改文字/重新生成单页插图
├── 创作模板 — 提供主题模板(节日主题/科普主题/童话主题)
├── 多人合创 — 多个孩子协作创作一本绘本
```
---
## 交付时间线建议
| 阶段 | 内容 | 建议周期 |
|------|------|---------|
| P0 第一阶段 | 数据库 + 子女账号独立化 | 1 周 |
| P0 第二阶段 | 作品库 + AI 创作流程 | 1.5 周 |
| P0 第三阶段 | 作品广场 + 标签体系 | 1 周 |
| P0 第四阶段 | 内容审核 + 活动联动 | 1 周 |
| P0 联调测试 | 全链路联调 + Bug 修复 | 0.5 周 |
| **P0 合计** | | **5 周** |
| P1 | 点赞/收藏/评论/通知/举报 | 3 周 |
| P2 | 关注/分享/运营后台/创作增强 | 按需排期 |