library-picturebook-activity/docs/design/super-admin/registration-data-optimization.md
aid 418aa57ea8 Day4: 超管端设计优化 + UGC绘本创作社区P0实现
一、超管端设计优化
- 文档管理SOP体系建立,docs目录重组
- 统一用户管理:跨租户全局视角,合并用户管理+公众用户
- 活动监管全模块重构:全部活动(统计卡片+阶段筛选+SuperDetail详情页)、报名数据/作品数据/评审进度(两层合一扁平列表)、成果发布(去Tab+统计+隐藏写操作)
- 菜单精简:移除评委管理/评审规则/通知管理
- Bug修复:租户编辑丢失隐藏菜单、pageSize限制、主色统一

二、UGC绘本创作社区P0
- 数据库:10张新表(user_works/user_work_pages/work_tags等)
- 子女账号独立化:Child升级为独立User,家长切换+独立登录
- 用户作品库:CRUD+发布审核,8个API
- AI创作流程:提交→生成→保存到作品库,4个API
- 作品广场:首页改造为推荐流,标签+搜索+排序
- 内容审核(超管端):作品审核+作品管理+标签管理
- 活动联动:WorkSelector作品选择器
- 布局改造:底部5Tab(发现/创作/活动/作品库/我的)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:20:25 +08:00

203 lines
8.7 KiB
Markdown
Raw Permalink 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.

# 报名数据模块优化 — 设计方案
> 所属端:超管端
> 状态:已实现(待验收)
> 创建日期2026-03-27
> 最后更新2026-03-27
---
## 1. 背景与问题
超管端"报名数据"菜单目前是两层结构:第一层按活动维度展示活动列表(每行一个活动,显示报名人数),点击"报名记录"进入第二层查看某活动的具体报名记录。
### 核心问题
| 问题 | 说明 |
|------|------|
| 第一层与全部活动列表重复 | Index.vue 本质是活动列表精简版,而全部活动列表已有可点击的报名人数列,两个入口功能重叠 |
| 超管写操作未隔离 | "启动报名/关闭报名"、"通过/拒绝/删除"等写操作对超管应隐藏 |
| 缺少全局统计 | 没有报名总量、各审核状态分布等概览 |
| 无跨活动搜索 | 只能看某个活动的报名记录,不能跨活动搜索(如"某个用户报了哪些活动" |
| 样式不一致 | 主色写死 `#1890ff` |
---
## 2. 现状分析
### 2.1 第一层报名管理registrations/Index.vue
- 个人参与/团队参与 Tab 切换
- 数据来源:`contestsApi.getList()` 按活动类型过滤
- 搜索:仅活动名称
- 操作:报名记录(跳转)、启动报名、关闭报名
- **本质是活动列表的子集视图,对超管来说是冗余页面**
### 2.2 第二层报名记录registrations/Records.vue
- 数据来源:`registrationsApi.getList({ contestId })` 查某活动的报名记录
- 搜索:机构、姓名/队伍名、报名账号、审核状态、报名时间
- 功能:批量审核、导出、通过/拒绝/删除、详细信息 Drawer、团队成员弹窗
---
## 3. 设计方案
### 3.1 整体思路
**超管端将两层合并为一层**:一个扁平的报名记录列表,展示全平台所有活动的报名数据,通过筛选条件实现分活动查看。
理由:
1. 活动维度的概览已由"全部活动"列表承担(报名数字可点击跳转)
2. 超管需要的是跨活动的全局视角,快速找到某条报名记录
3. 从"全部活动"列表点击报名数字时,带 contestId 参数跳转过来,自动筛选该活动
机构端保持现有两层结构不变。
### 3.2 页面结构
```
┌─ 标题卡片 ──────────────────────────────────────────────┐
│ 报名数据 │
└─────────────────────────────────────────────────────────┘
┌─ 统计卡片 ──────────────────────────────────────────────┐
│ [全部 256] [待审核 38] [已通过 200] [已拒绝 18] │
└─────────────────────────────────────────────────────────┘
┌─ 筛选栏 ────────────────────────────────────────────────┐
│ 所属活动:[下拉搜索] 参与者:[______] 审核状态:[下拉] │
│ 参与方式:[下拉] 报名时间:[日期范围] [搜索] [重置] │
└─────────────────────────────────────────────────────────┘
┌─ 数据表格 ──────────────────────────────────────────────┐
│ 所属活动 | 参与者 | 参与方式 | 报名账号 | 主办机构 | │
│ | 审核状态 | 报名时间 | 操作 │
└─────────────────────────────────────────────────────────┘
```
### 3.3 统计卡片
4 张卡片,可点击切换筛选:
| 卡片 | 数据 | 颜色 |
|------|------|------|
| 全部 | 报名总数 | 主色 |
| 待审核 | pending 数量 | 橙色 |
| 已通过 | passed 数量 | 绿色 |
| 已拒绝 | rejected 数量 | 红色 |
数据来源:新增 `GET /api/registrations/stats` 接口。
### 3.4 筛选栏
| 筛选项 | 组件 | 说明 |
|--------|------|------|
| 所属活动 | Select远程搜索 | 按活动名称搜索下拉,选择后按 contestId 过滤 |
| 参与者 | Input | 搜索参与者姓名、手机号、子女姓名 |
| 审核状态 | Select | 待审核 / 已通过 / 已拒绝 |
| 参与方式 | Select | 本人参与 / 代子女报名 |
| 报名时间 | RangePicker | 时间范围筛选 |
**联动逻辑**:从"全部活动"列表点击报名数字跳转时URL 带 `?contestId=xx`,页面初始化时自动设置"所属活动"筛选。
### 3.5 表格列
| 列 | 宽度 | 渲染方式 |
|----|------|----------|
| 所属活动 | 180 | 活动名称,可点击跳转活动详情 |
| 参与者 | 140 | 昵称;代子女报名时附带子女姓名 |
| 参与方式 | 100 | Tag本人参与/ 代子女报名(绿) |
| 报名账号 | 120 | username |
| 主办机构 | 120 | 活动创建者所属租户名 |
| 审核状态 | 90 | Tag待审核/ 已通过(绿)/ 已拒绝(红) |
| 报名时间 | 150 | YYYY-MM-DD HH:mm |
| 操作 | 80 | 查看详情 |
超管操作列**只有"查看详情"**,不提供通过/拒绝/删除。
### 3.6 详情 Drawer
点击"查看详情"打开右侧 Drawer
```
基本信息Descriptions
├── 所属活动 / 主办机构
├── 参与者昵称 / 报名账号 / 手机号
├── 参与方式 / 子女姓名(如有)
├── 审核状态 / 审核理由(如有)
└── 报名时间
子女信息(参与方式=代子女报名时显示)
├── 姓名 / 性别 / 年龄 / 年级
├── 城市 / 学校
团队信息(团队参与时显示)
├── 队伍名称 / 队长 / 成员数
└── 成员列表表格
```
### 3.7 URL 参数支持
- `/super/contests/registrations` — 全部报名记录
- `/super/contests/registrations?contestId=3` — 筛选某个活动的报名记录(从活动列表跳转)
- `/super/contests/registrations?status=pending` — 筛选待审核记录
页面 `onMounted` 时读取 URL query 参数,自动设置对应筛选条件。
---
## 4. 后端改动
### 4.1 新增 GET /api/registrations/stats
超管调用时返回全平台报名统计:
```json
{
"total": 256,
"pending": 38,
"passed": 200,
"rejected": 18
}
```
支持可选的 `contestId` 参数,传入时只统计该活动。
### 4.2 扩展 GET /api/registrations现有接口
超管调用时:
- `contestId` 变为可选参数(当前是必填),不传时查全部活动的报名记录
- 新增 `participantType` 参数:`self` / `child`
- 新增 `keyword` 参数:搜索参与者姓名、手机号、子女姓名
- 返回数据增加活动信息:`contest: { id, contestName, creatorTenant: { name } }`
- 返回数据增加子女信息:`child: { name, gender, birthday, grade, city, schoolName }`
普通租户调用时保持现有逻辑不变。
---
## 5. 前端改动
| 文件 | 操作 | 说明 |
|------|------|------|
| `frontend/src/api/contests.ts` | 修改 | 扩展 QueryRegistrationParams新增 registrations stats 接口 |
| `frontend/src/views/contests/registrations/Index.vue` | 修改 | 超管端改为扁平报名记录列表(统计卡片+筛选+表格+Drawer机构端保持不变 |
| `backend/src/contests/registrations/registrations.service.ts` | 修改 | 扩展 findAll 支持跨活动查询,新增 getStats |
| `backend/src/contests/registrations/registrations.controller.ts` | 修改 | 新增 stats 端点findAll 增加参数 |
---
## 6. 实施记录
### 2026-03-27 — 首次实现
**后端改动3 个文件):**
- `backend/src/contests/registrations/dto/query-registration.dto.ts` — 新增 participantType、keyword 参数
- `backend/src/contests/registrations/registrations.service.ts` — 新增 getStats() 方法findAll 增加 participantType 和 keyword搜索昵称/手机/子女名)过滤
- `backend/src/contests/registrations/registrations.controller.ts` — 新增 GET /api/contests/registrations/stats 端点
**前端改动2 个文件):**
- `frontend/src/api/contests.ts` — 扩展 QueryRegistrationParamsparticipantType/keyword新增 RegistrationStats 类型和 getStats 接口
- `frontend/src/views/contests/registrations/Index.vue` — 完全重写:超管端为扁平报名记录列表(统计卡片+筛选栏+全平台表格+详情Drawer机构端保持原有两层结构支持 URL 参数联动(?contestId=xx&status=pending