324 lines
10 KiB
Markdown
324 lines
10 KiB
Markdown
|
|
# 功能模块设计
|
|||
|
|
|
|||
|
|
## 1. 模块总览
|
|||
|
|
|
|||
|
|
### 一期功能(三周内完成)
|
|||
|
|
|
|||
|
|
| 模块 | 优先级 | 说明 |
|
|||
|
|
|------|--------|------|
|
|||
|
|
| 公众端注册/登录 | P0 | 用户名+密码方式自主注册和登录 |
|
|||
|
|
| 公众端活动大厅 | P0 | 浏览公开活动列表,查看活动详情 |
|
|||
|
|
| 子女管理 | P0 | 添加/编辑/删除子女信息 |
|
|||
|
|
| 活动报名 | P0 | 选择参与者(自己/子女)并报名 |
|
|||
|
|
| 作品提交 | P0 | 上传绘本作品(图片/PDF) |
|
|||
|
|
| 个人中心 | P0 | 个人信息、报名记录、作品列表 |
|
|||
|
|
| 租户类型字段 | P0 | 租户新增类型分类 |
|
|||
|
|
| 活动可见范围 | P0 | 新增"公开"选项 |
|
|||
|
|
| 管理端适配 | P0 | 报名记录展示参与者类型和子女信息 |
|
|||
|
|
|
|||
|
|
### 二期功能
|
|||
|
|
|
|||
|
|
| 模块 | 说明 |
|
|||
|
|
|------|------|
|
|||
|
|
| 手机号验证码登录 | 短信服务集成 |
|
|||
|
|
| 微信扫码登录 | 微信开放平台 OAuth |
|
|||
|
|
| 一号多身份切换 | 同一账号在公众端和管理端切换 |
|
|||
|
|
| 多机构联合举办 | 主办+协办模式 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. 公众端注册与登录
|
|||
|
|
|
|||
|
|
> **实现说明**:登录与注册合并为同一页面 `/p/login`,通过 `isRegister` 标志切换表单。公众用户归属公众租户(code='public', tenantId=8),而非 tenant_id 为 NULL。
|
|||
|
|
|
|||
|
|
### 2.1 登录/注册页面(合一)
|
|||
|
|
|
|||
|
|
**路由**:`/p/login`
|
|||
|
|
|
|||
|
|
**注册表单字段**:
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| 用户名 | 文本输入 | 是 | 4-20位字母数字下划线 |
|
|||
|
|
| 密码 | 密码输入 | 是 | 6-20位,至少包含字母和数字 |
|
|||
|
|
| 确认密码 | 密码输入 | 是 | 与密码一致 |
|
|||
|
|
| 昵称 | 文本输入 | 是 | 2-20位,显示在界面上的名字 |
|
|||
|
|
| 手机号 | 文本输入 | 否 | 预留字段,二期用于验证码登录 |
|
|||
|
|
| 所在城市 | 文本输入 | 否 | 便于活动统计 |
|
|||
|
|
|
|||
|
|
**登录表单字段**:
|
|||
|
|
- 用户名 / 手机号
|
|||
|
|
- 密码
|
|||
|
|
|
|||
|
|
**交互逻辑**:
|
|||
|
|
1. 页面底部有"切换到注册/切换到登录"链接,通过 `isRegister` 标志切换
|
|||
|
|
2. 注册:前端校验 → 提交注册 → 后端创建用户(user_source = 'self_registered', 归属 public 租户)→ 自动登录 → 跳转活动大厅
|
|||
|
|
3. 登录:公众用户登录不需要填写租户编码 → 后端在公众租户中查找匹配用户 → 登录成功 → 跳转活动大厅
|
|||
|
|
|
|||
|
|
### 2.3 与现有登录的关系
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
登录入口:
|
|||
|
|
├── /p/login → 公众端登录(无需租户编码)
|
|||
|
|
└── /:tenantCode/login → 管理端登录(现有,需要租户编码)
|
|||
|
|
|
|||
|
|
两套登录页面独立,共用同一个 Auth API(后端区分来源)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. 公众端活动大厅
|
|||
|
|
|
|||
|
|
### 3.1 活动列表页
|
|||
|
|
|
|||
|
|
**路由**:`/p/activities`
|
|||
|
|
|
|||
|
|
**页面元素**:
|
|||
|
|
- 顶部:搜索框(按活动名称搜索)
|
|||
|
|
- 筛选:活动状态(报名中/进行中/已结束)
|
|||
|
|
- 列表:活动卡片网格展示
|
|||
|
|
|
|||
|
|
**活动卡片信息**:
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────┐
|
|||
|
|
│ [活动封面图] │
|
|||
|
|
│ ┌─报名中─┐ ┌个人参与┐ │
|
|||
|
|
├─────────────────────────┤
|
|||
|
|
│ 活动名称 │
|
|||
|
|
│ 主办:广东省立中山图书馆 │
|
|||
|
|
│ 报名时间:xx - xx │
|
|||
|
|
│ [查看详情] │
|
|||
|
|
└─────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**数据来源**:
|
|||
|
|
- 调用 `/api/public/activities` 接口
|
|||
|
|
- 仅返回 `visibility = 'public'` 且 `contest_state = 'published'` 的活动
|
|||
|
|
- 未登录用户也能浏览列表,但报名需要登录
|
|||
|
|
|
|||
|
|
### 3.2 活动详情页
|
|||
|
|
|
|||
|
|
**路由**:`/p/activities/:id`
|
|||
|
|
|
|||
|
|
**页面结构**:
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────┐
|
|||
|
|
│ 活动封面/海报 │
|
|||
|
|
├─────────────────────────────────┤
|
|||
|
|
│ 活动名称 │
|
|||
|
|
│ 主办单位 | 活动类型 | 状态 │
|
|||
|
|
├─────────────────────────────────┤
|
|||
|
|
│ Tab: [活动详情] [活动公告] [成果] │
|
|||
|
|
├─────────────────────────────────┤
|
|||
|
|
│ 活动详情内容(富文本) │
|
|||
|
|
│ 附件下载 │
|
|||
|
|
├─────────────────────────────────┤
|
|||
|
|
│ [立即报名] / [提交作品] 按钮 │
|
|||
|
|
│ (根据活动阶段动态显示) │
|
|||
|
|
└─────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**按钮状态逻辑**:
|
|||
|
|
|
|||
|
|
| 活动阶段 | 未登录 | 已登录未报名 | 已登录已报名 |
|
|||
|
|
|---------|--------|------------|------------|
|
|||
|
|
| 报名阶段 | 登录后报名 | 立即报名 | 已报名 |
|
|||
|
|
| 提交阶段 | 登录查看 | - | 提交作品 |
|
|||
|
|
| 评审阶段 | - | - | 评审中 |
|
|||
|
|
| 已结束 | 查看成果 | 查看成果 | 查看成果 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. 子女管理
|
|||
|
|
|
|||
|
|
### 4.1 子女列表页
|
|||
|
|
|
|||
|
|
**路由**:`/p/mine/children`
|
|||
|
|
|
|||
|
|
**页面元素**:
|
|||
|
|
- 子女卡片列表
|
|||
|
|
- "添加子女"按钮
|
|||
|
|
|
|||
|
|
**子女卡片**:
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────┐
|
|||
|
|
│ [头像] 小明 │
|
|||
|
|
│ 8岁 | 三年级 | 广州 │
|
|||
|
|
│ XX小学 │
|
|||
|
|
│ [编辑] [删除] │
|
|||
|
|
└─────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.2 添加/编辑子女
|
|||
|
|
|
|||
|
|
**弹窗表单字段**:
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| 姓名 | 文本 | 是 | 子女真实姓名 |
|
|||
|
|
| 性别 | 选择 | 否 | 男/女 |
|
|||
|
|
| 出生日期 | 日期选择 | 否 | 用于自动计算年龄 |
|
|||
|
|
| 年级 | 文本/选择 | 否 | 如:大班、一年级 |
|
|||
|
|
| 所在城市 | 文本 | 否 | |
|
|||
|
|
| 学校/幼儿园 | 文本 | 否 | 手动填写 |
|
|||
|
|
|
|||
|
|
### 4.3 删除保护
|
|||
|
|
|
|||
|
|
- 如果子女有关联的报名记录,提示"该子女有 N 个活动报名记录,删除后历史数据中将显示为'已删除子女'"
|
|||
|
|
- 使用软删除(is_deleted = 1),不物理删除
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. 活动报名
|
|||
|
|
|
|||
|
|
### 5.1 报名流程
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
步骤1:选择参与者
|
|||
|
|
├── 系统检测用户是否有子女
|
|||
|
|
├── 无子女 → 跳过此步,以自己身份报名
|
|||
|
|
└── 有子女 → 显示参与者选择页面
|
|||
|
|
○ 我自己
|
|||
|
|
○ 子女A(姓名,年龄)
|
|||
|
|
○ 子女B(姓名,年龄)
|
|||
|
|
+ 添加新的子女
|
|||
|
|
|
|||
|
|
步骤2:填写报名信息
|
|||
|
|
├── 参与者基本信息(自动带入,可编辑)
|
|||
|
|
│ ├── 自己报名:显示用户昵称、城市
|
|||
|
|
│ └── 子女报名:显示子女姓名、年龄、学校
|
|||
|
|
├── 活动要求的附加信息(由活动定义,如:创作主题选择)
|
|||
|
|
└── 指导老师信息(可选)
|
|||
|
|
|
|||
|
|
步骤3:确认提交
|
|||
|
|
├── 确认报名信息
|
|||
|
|
└── 提交 → 等待审核(如果活动开启了审核)/ 直接通过
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.2 报名数据存储
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
registrations 表记录:
|
|||
|
|
├── user_id = 操作人(家长或独立参与者)
|
|||
|
|
├── contest_id = 活动 ID
|
|||
|
|
├── participant_type = 'self' 或 'child'
|
|||
|
|
├── child_id = 子女 ID(仅 child 类型)
|
|||
|
|
├── status = 审核状态
|
|||
|
|
└── 其他现有字段不变
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.3 重复报名检测
|
|||
|
|
|
|||
|
|
- 同一用户不能以"自己"身份重复报名同一活动
|
|||
|
|
- 同一子女不能被重复报名同一活动(通过 child_id 去重)
|
|||
|
|
- 不同子女可以分别报名同一活动
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6. 作品提交
|
|||
|
|
|
|||
|
|
### 6.1 提交页面
|
|||
|
|
|
|||
|
|
**路由**:`/p/activities/:id/submit`
|
|||
|
|
|
|||
|
|
**前置条件**:
|
|||
|
|
- 用户已登录
|
|||
|
|
- 用户/子女已报名该活动且报名状态为"通过"
|
|||
|
|
- 活动处于"提交阶段"
|
|||
|
|
|
|||
|
|
**表单字段**:
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 必填 | 说明 |
|
|||
|
|
|------|------|------|------|
|
|||
|
|
| 作品名称 | 文本 | 是 | 绘本作品标题 |
|
|||
|
|
| 作品描述 | 多行文本 | 否 | 创作说明 |
|
|||
|
|
| 作品文件 | 文件上传 | 是 | 支持图片(JPG/PNG)和 PDF |
|
|||
|
|
| 封面图 | 图片上传 | 否 | 作品封面,用于列表展示 |
|
|||
|
|
|
|||
|
|
### 6.2 与现有作品模块的关系
|
|||
|
|
|
|||
|
|
复用现有 works 表和上传逻辑,新增关联:
|
|||
|
|
- 如果是子女报名,作品记录关联 child_id(通过 registration 关联)
|
|||
|
|
- 管理端查看作品时,能看到实际创作者(子女)的信息
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 7. 个人中心
|
|||
|
|
|
|||
|
|
### 7.1 个人中心首页
|
|||
|
|
|
|||
|
|
**路由**:`/p/mine`
|
|||
|
|
|
|||
|
|
**页面结构**:
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────┐
|
|||
|
|
│ [头像] 昵称 │
|
|||
|
|
│ 手机号 | 城市 │
|
|||
|
|
│ [编辑个人信息] │
|
|||
|
|
├─────────────────────────┤
|
|||
|
|
│ 📋 我的报名(N) │
|
|||
|
|
│ 🎨 我的作品(N) │
|
|||
|
|
│ 👶 子女管理(N) │
|
|||
|
|
└─────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 7.2 我的报名
|
|||
|
|
|
|||
|
|
**路由**:`/p/mine/registrations`
|
|||
|
|
|
|||
|
|
**列表项信息**:
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────┐
|
|||
|
|
│ [活动封面] │
|
|||
|
|
│ 活动名称 │
|
|||
|
|
│ 参与者:我自己 / 子女:小明 │
|
|||
|
|
│ 报名时间:2026-04-01 │
|
|||
|
|
│ 状态:待审核 / 已通过 / 已拒绝 │
|
|||
|
|
│ [查看详情] [提交作品] │
|
|||
|
|
└─────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 7.3 我的作品
|
|||
|
|
|
|||
|
|
**路由**:`/p/mine/works`
|
|||
|
|
|
|||
|
|
展示该用户提交的所有作品(包括代子女提交的)。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 8. 管理端适配
|
|||
|
|
|
|||
|
|
### 8.1 活动创建改造
|
|||
|
|
|
|||
|
|
**活动创建表单新增字段**:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
活动可见范围:
|
|||
|
|
○ 公开(所有注册用户可见)
|
|||
|
|
○ 指定机构(选择机构列表)
|
|||
|
|
○ 仅内部
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
当选择"公开"时,`contest_tenants` 字段不需要填写。
|
|||
|
|
|
|||
|
|
### 8.2 报名管理改造
|
|||
|
|
|
|||
|
|
**报名记录表格新增列**:
|
|||
|
|
|
|||
|
|
| 列名 | 说明 |
|
|||
|
|
|------|------|
|
|||
|
|
| 报名人 | user.nickname(操作人) |
|
|||
|
|
| 参与者 | 自己报名显示用户名;子女报名显示"子女:小明" |
|
|||
|
|
| 参与方式 | 自己 / 代子女报名 |
|
|||
|
|
|
|||
|
|
**筛选条件新增**:
|
|||
|
|
- 参与方式:全部 / 自己报名 / 代子女报名
|
|||
|
|
|
|||
|
|
### 8.3 租户管理改造
|
|||
|
|
|
|||
|
|
**租户列表新增列**:
|
|||
|
|
- 租户类型:图书馆 / 幼儿园 / 学校 / 社会机构 / 其他
|
|||
|
|
|
|||
|
|
**租户创建表单新增字段**:
|
|||
|
|
- 租户类型(下拉选择)
|