library-picturebook-activity/docs/project/02-architecture.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

287 lines
13 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.

# 系统架构设计
## 1. 整体架构
```
┌─────────────────────────────────────────────────────────────┐
│ 用户访问层 │
│ ┌─────────────┐ ┌──────────────┐ ┌────────────────────┐ │
│ │ 公众端(H5) │ │ 管理后台(Web) │ │ 微信内置浏览器(H5) │ │
│ │ /p/... │ │ /:tenant/... │ │ /p/... │ │
│ └──────┬──────┘ └──────┬───────┘ └─────────┬──────────┘ │
└─────────┼────────────────┼────────────────────┼─────────────┘
│ │ │
┌─────────▼────────────────▼────────────────────▼─────────────┐
│ Vue3 前端应用 │
│ ┌─────────────────┐ ┌──────────────────────────────────┐ │
│ │ 公众端模块 │ │ 管理端模块 │ │
│ │ - 活动大厅 │ │ - 机构管理端(图书馆/学校/... │ │
│ │ - 活动详情 │ │ - 评审端 │ │
│ │ - 报名/提交作品 │ │ - 平台管理端(超管) │ │
│ │ - 个人中心 │ │ - 现有功能保持不变 │ │
│ │ - 子女管理 │ │ │ │
│ └─────────────────┘ └──────────────────────────────────┘ │
└────────────────────────────┬─────────────────────────────────┘
│ HTTP API
┌────────────────────────────▼─────────────────────────────────┐
│ NestJS 后端 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────────┐ │
│ │ Auth模块 │ │ 用户模块 │ │ 活动模块 │ │ 公众API模块 │ │
│ │(多种登录) │ │(子女管理) │ │(现有改造) │ │ (公众端专用) │ │
│ └──────────┘ └──────────┘ └──────────┘ └────────────────┘ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────────────┐ │
│ │ 租户模块 │ │ 评审模块 │ │ 作品模块 │ │ 其他现有模块 │ │
│ │(类型扩展) │ │(现有) │ │(现有改造) │ │ (保持不变) │ │
│ └──────────┘ └──────────┘ └──────────┘ └────────────────┘ │
└────────────────────────────┬─────────────────────────────────┘
│ Prisma ORM
┌────────────────────────────▼─────────────────────────────────┐
│ MySQL 数据库 │
│ users / children / tenants / contests / registrations / ... │
└──────────────────────────────────────────────────────────────┘
```
---
## 2. 租户模型设计
### 2.1 租户类型
| 类型标识 | 名称 | 说明 | 举例 |
|---------|------|------|------|
| `platform` | 平台租户 | 系统运营方,全局唯一 | 乐绘世界 |
| `library` | 图书馆 | 公共图书馆机构 | 广东省立中山图书馆 |
| `kindergarten` | 幼儿园 | 幼儿教育机构 | XX幼儿园 |
| `school` | 学校 | 中小学校 | XX小学 |
| `institution` | 社会机构 | 美术培训、文化机构等 | XX美术中心 |
| `other` | 其他 | 未分类的机构 | - |
### 2.2 租户与用户的关系
```
租户(机构)
├── 拥有机构用户:管理员、工作人员、评委
│ └── 通过 tenant_id 关联
公众用户
├── 不隶属任何租户
├── 通过自主注册创建
├── 可以查看所有"公开"活动并报名
身份重叠场景(二期实现)
├── 一个手机号 = 一个账号
├── 同一账号可以同时拥有:公众用户身份 + 机构用户身份
└── 通过"身份切换"在不同工作台之间切换
```
### 2.3 活动可见范围
```
活动创建时设置 visibility 字段:
├── public — 公开(所有注册用户可见,广东省图本次使用)
├── designated — 指定机构(选择哪些租户可见,现有逻辑)
└── internal — 仅内部(仅本机构内部可见)
```
---
## 3. 用户体系设计
### 3.1 核心原则:一号多身份
**一个手机号/账号 = 一个用户**,用户可以拥有多个身份角色。
一期先实现账号密码登录,二期补充手机号和微信登录。一期阶段公众用户通过"用户名+密码"自主注册。
### 3.2 用户来源
| 来源 | 标识 | 说明 |
|------|------|------|
| 管理员创建 | `admin_created` | 现有方式,管理员在后台创建用户 |
| 自主注册 | `self_registered` | 新增,用户通过公众端注册页面自行注册 |
### 3.3 用户参与模型
```
注册用户User
├── 可以以"自己"的身份报名活动(所有用户默认能力)
├── 可以添加子女,以"子女"的身份代为报名(可选能力)
├── 我自己报名的活动participant_type = 'self'
│ └── 适用场景:有手机号的青少年自己注册参与
└── 我为子女报名的活动participant_type = 'child'
├── child_id 指向具体哪个子女
└── 适用场景:家长为年幼子女代报名
```
### 3.4 报名流程
```
用户点击"报名活动"
├── 检查是否已登录 → 未登录则跳转登录/注册页
├── 已登录 → 检查是否有关联子女
├── 无子女 → 直接以自己身份报名
│ → 填写报名补充信息 → 提交
└── 有子女 → 弹出"选择参与者"
┌─────────────────────────┐
│ 请选择参与者: │
│ ○ 我自己 │
│ ○ 子女小明8岁
│ ○ 子女小红5岁
添加新的子女 │
└─────────────────────────┘
→ 选择后填写报名信息 → 提交
```
---
## 4. 前端架构
### 4.1 路由设计
```
前端路由结构:
├── /p/ # 公众端H5 + Web 响应式)
│ ├── /p/login # 公众端登录
│ ├── /p/register # 公众端注册
│ ├── /p/activities # 活动大厅(活动列表)
│ ├── /p/activities/:id # 活动详情
│ ├── /p/activities/:id/register # 报名页面
│ ├── /p/activities/:id/submit # 提交作品
│ ├── /p/mine # 个人中心
│ ├── /p/mine/children # 子女管理
│ ├── /p/mine/registrations # 我的报名
│ └── /p/mine/works # 我的作品
├── /:tenantCode/ # 管理端(现有,保持不变)
│ ├── /:tenantCode/login # 机构登录
│ ├── /:tenantCode/contests # 活动管理
│ ├── /:tenantCode/system # 系统管理
│ └── ...
└── / # 根路径重定向
```
### 4.2 公众端布局
```
┌────────────────────────────────────────┐ Web 端
│ 顶部导航栏 │
│ [Logo 乐绘世界] [活动大厅] [个人中心] │
├────────────────────────────────────────┤
│ │
│ 页面内容区 │
│ │
└────────────────────────────────────────┘
┌──────────────┐ H5 移动端
│ 顶部标题栏 │
├──────────────┤
│ │
│ 页面内容区 │
│ │
├──────────────┤
│ 底部Tab导航 │
│ [首页][我的] │
└──────────────┘
```
### 4.3 响应式适配策略
```
一套 Vue 代码,通过 CSS 媒体查询和 Tailwind 断点适配:
├── sm (< 640px) → H5 移动端布局(底部 Tab 导航)
├── md (640-1024px) → 平板端布局
└── lg (> 1024px) → Web 端布局(顶部导航栏)
```
---
## 5. 后端 API 设计
### 5.1 新增公众端 API 模块
```
/api/public/ # 公众端 API无需租户上下文
├── POST /auth/register # 公众注册
├── POST /auth/login # 公众登录
├── GET /activities # 获取公开活动列表
├── GET /activities/:id # 获取活动详情
├── POST /activities/:id/register # 报名活动
├── POST /activities/:id/submit # 提交作品
├── GET /mine/profile # 获取个人信息
├── PUT /mine/profile # 更新个人信息
├── GET /mine/children # 获取子女列表
├── POST /mine/children # 添加子女
├── PUT /mine/children/:id # 编辑子女
├── DELETE /mine/children/:id # 删除子女
├── GET /mine/registrations # 我的报名列表
└── GET /mine/works # 我的作品列表
```
### 5.2 现有 API 改造
```
活动相关 API 变更:
├── 创建活动:新增 visibility 字段public/designated/internal
├── 获取活动列表:支持按 visibility 过滤
├── 报名接口:新增 participant_type 和 child_id 字段
└── 报名记录查询:支持按 participant_type 筛选
```
---
## 6. 多机构联合举办(二期)
### 6.1 主办-协办模型
```
活动表新增:
├── organizer_tenant_id — 主办机构 ID
└── co_organizer_ids — 协办机构 ID 列表JSON 数组)
权限分配:
├── 主办方:完整管理权限(创建、编辑、审核、发布成果)
└── 协办方:有限权限(查看报名数据、推荐评委、查看成果)
```
### 6.2 活动页面展示
```
活动详情页展示:
├── 主办单位:广东省立中山图书馆
└── 协办单位:北京国家图书馆、上海图书馆
```
---
## 7. 一号多身份(二期)
### 7.1 身份切换机制
```
用户登录后:
├── 默认进入公众端(活动大厅)
├── 如果用户同时是某机构的管理员/工作人员
│ └── 显示"切换到管理端"入口
├── 切换身份 = 切换工作台视角
└── 不需要重新登录JWT token 中包含所有身份信息
```
### 7.2 身份绑定
```
用户身份表user_identities
├── user_id — 用户 ID
├── identity_type — 身份类型public / tenant_admin / judge / staff
├── tenant_id — 关联租户(公众身份为 NULL
├── role_id — 关联角色
└── status — 状态active / inactive
```