一、超管端设计优化 - 文档管理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>
750 lines
24 KiB
Markdown
750 lines
24 KiB
Markdown
# 赛事管理模块产品方案与实现计划
|
||
|
||
## 📋 目录
|
||
1. [产品交互方案](#产品交互方案)
|
||
2. [数据库设计分析](#数据库设计分析)
|
||
3. [功能模块划分](#功能模块划分)
|
||
4. [实现计划](#实现计划)
|
||
5. [技术实现要点](#技术实现要点)
|
||
|
||
---
|
||
|
||
## 产品交互方案
|
||
|
||
### 1. 赛事创建
|
||
|
||
#### 1.1 功能概述
|
||
管理员创建赛事,填写赛事基本信息、时间安排、参赛范围等。
|
||
|
||
#### 1.2 交互流程
|
||
```
|
||
管理员进入"赛事管理" → 点击"创建赛事" → 填写表单 → 保存草稿/提交审核
|
||
```
|
||
|
||
#### 1.3 表单字段(基于 t_contest 表)
|
||
- **基本信息**
|
||
- 赛事名称(必填,唯一性校验)
|
||
- 赛事类型(字典:individual/team)
|
||
- 赛事状态(默认:unpublished)
|
||
- 封面图(上传)
|
||
- 海报图(上传)
|
||
- 赛事详情(富文本编辑器)
|
||
|
||
- **时间安排**
|
||
- 赛事开始时间
|
||
- 赛事结束时间
|
||
- 报名开始时间
|
||
- 报名结束时间
|
||
- 作品提交开始时间
|
||
- 作品提交结束时间
|
||
- 评审开始时间
|
||
- 评审结束时间
|
||
- 结果发布时间(可选)
|
||
|
||
- **参赛范围**
|
||
- 授权租户(多选,支持租户列表选择)
|
||
- 提交规则(once/resubmit)
|
||
|
||
- **联系信息**
|
||
- 联系人姓名
|
||
- 联系电话
|
||
- 联系人二维码(上传)
|
||
|
||
- **组织信息**
|
||
- 主办单位(数组)
|
||
- 协办单位(数组)
|
||
- 赞助单位(数组)
|
||
|
||
- **线下信息**
|
||
- 线下地址(可选)
|
||
|
||
- **评审规则**
|
||
- 评审规则ID(关联评审规则配置)
|
||
|
||
#### 1.4 业务规则
|
||
- 时间顺序校验:报名开始 < 报名结束 < 提交开始 < 提交结束 < 评审开始 < 评审结束 < 结果发布
|
||
- 赛事名称在系统内唯一
|
||
- 创建后状态为 `unpublished`,需要发布后才能被租户看到
|
||
- 支持保存草稿(可多次编辑)
|
||
|
||
---
|
||
|
||
### 2. 赛事发布
|
||
|
||
#### 2.1 功能概述
|
||
管理员将已创建的赛事发布,使其对授权租户可见。
|
||
|
||
#### 2.2 交互流程
|
||
```
|
||
赛事列表 → 选择赛事 → 点击"发布" → 确认发布 → 更新状态为 published
|
||
```
|
||
|
||
#### 2.3 业务规则
|
||
- 只有状态为 `unpublished` 的赛事可以发布
|
||
- 发布前校验必填字段完整性
|
||
- 发布后,授权租户可以看到该赛事
|
||
- 已发布的赛事可以撤回(状态改回 `unpublished`),但需要检查是否有报名记录
|
||
|
||
---
|
||
|
||
### 3. 赛事公告
|
||
|
||
#### 3.1 功能概述
|
||
管理员发布赛事相关公告,通知参赛者重要信息。
|
||
|
||
#### 3.2 交互流程
|
||
```
|
||
赛事详情页 → "公告管理" → 创建公告 → 编辑内容 → 发布公告
|
||
```
|
||
|
||
#### 3.3 功能设计
|
||
**注意**:当前 SQL 中没有公告表,需要新增:
|
||
- `t_contest_notice` 表
|
||
- id, contest_id, title, content, notice_type, priority, publish_time, creator, create_time, modify_time, valid_state
|
||
|
||
#### 3.4 公告类型
|
||
- 系统公告(系统自动生成)
|
||
- 人工公告(管理员发布)
|
||
- 紧急通知(高优先级)
|
||
|
||
---
|
||
|
||
### 4. 赛事报名
|
||
|
||
#### 4.1 功能概述
|
||
授权租户的用户(学生/老师)报名参加赛事,支持个人赛和团队赛。
|
||
|
||
#### 4.2 交互流程
|
||
|
||
**个人赛报名:**
|
||
```
|
||
租户用户登录 → 浏览已发布赛事 → 选择赛事 → 点击"立即报名" → 填写信息 → 提交报名
|
||
```
|
||
|
||
**团队赛报名:**
|
||
```
|
||
队长创建团队 → 邀请成员 → 成员确认加入 → 队长提交团队报名 → 等待审核
|
||
```
|
||
|
||
#### 4.3 报名流程详细设计
|
||
|
||
**4.3.1 个人赛报名**
|
||
1. 用户选择赛事
|
||
2. 检查报名时间是否在有效期内
|
||
3. 检查用户是否已报名(防止重复报名)
|
||
4. 填写报名信息(账号信息自动填充)
|
||
5. 提交报名(状态:pending)
|
||
6. 管理员审核(可选,根据赛事配置)
|
||
7. 审核通过(状态:passed)或拒绝(状态:rejected)
|
||
|
||
**4.3.2 团队赛报名**
|
||
1. 队长创建团队
|
||
- 填写团队名称(租户内唯一)
|
||
- 设置最大成员数
|
||
- 邀请成员(通过账号搜索)
|
||
2. 成员确认加入
|
||
- 收到邀请通知
|
||
- 确认/拒绝加入
|
||
3. 队长提交团队报名
|
||
- 检查团队成员数量是否符合要求
|
||
- 提交报名(所有成员状态:pending)
|
||
4. 管理员审核团队报名
|
||
- 审核通过:所有成员状态改为 passed
|
||
- 审核拒绝:所有成员状态改为 rejected
|
||
|
||
#### 4.4 数据表关系
|
||
- `t_contest_registration`:报名记录表
|
||
- 个人赛:registration_type = 'individual',team_id = null
|
||
- 团队赛:registration_type = 'team',team_id 关联 t_contest_team
|
||
- `t_contest_team`:团队表
|
||
- `t_contest_team_member`:团队成员表
|
||
|
||
#### 4.5 业务规则
|
||
- 报名时间限制:必须在 `register_start_time` 和 `register_end_time` 之间
|
||
- 报名状态流转:pending → passed/rejected/withdrawn
|
||
- 已通过的报名可以撤回(withdrawn),但需要检查是否已提交作品
|
||
- 团队名称在同一赛事、同一租户内唯一
|
||
- 团队成员角色:leader(队长)、member(队员)、mentor(指导教师)
|
||
|
||
---
|
||
|
||
### 5. 赛事作品提交
|
||
|
||
#### 5.1 功能概述
|
||
已报名的用户提交参赛作品,支持单次提交和多次提交(根据赛事配置)。
|
||
|
||
#### 5.2 交互流程
|
||
```
|
||
已报名用户 → 进入"我的赛事" → 选择赛事 → 点击"提交作品" → 上传作品文件 → 填写作品信息 → 提交
|
||
```
|
||
|
||
#### 5.3 作品提交表单
|
||
- 作品标题(必填)
|
||
- 作品说明(可选)
|
||
- 作品文件(支持多文件上传)
|
||
- 图片、视频、3D模型等
|
||
- 文件类型和大小限制
|
||
- 作品预览URL(可选,用于3D/视频预览)
|
||
- AI建模元数据(可选,JSON格式)
|
||
|
||
#### 5.4 提交规则
|
||
|
||
**单次提交(submit_rule = 'once'):**
|
||
- 只能提交一次作品
|
||
- 提交后状态为 `submitted`,不可修改
|
||
|
||
**多次提交(submit_rule = 'resubmit'):**
|
||
- 可以多次提交作品
|
||
- 每次提交创建新版本(version 递增)
|
||
- 旧版本 `is_latest = 0`,新版本 `is_latest = 1`
|
||
- 只有最新版本参与评审
|
||
|
||
#### 5.5 数据表关系
|
||
- `t_contest_work`:作品主表
|
||
- entry_id 关联 t_contest_registration.id
|
||
- files 字段存储简易文件列表(JSON)
|
||
- `t_contest_work_attachment`:作品附件表(详细文件信息)
|
||
|
||
#### 5.6 业务规则
|
||
- 提交时间限制:必须在 `submit_start_time` 和 `submit_end_time` 之间
|
||
- 必须已通过报名审核(registration_state = 'passed')
|
||
- 作品编号(work_no)自动生成,格式:CONTEST-{contest_id}-{序号}
|
||
- 作品状态流转:
|
||
- submitted(已提交)
|
||
- locked(已锁定,不可修改)
|
||
- reviewing(评审中)
|
||
- rejected(已拒绝)
|
||
- accepted(已接受)
|
||
|
||
---
|
||
|
||
### 6. 赛事作品评审
|
||
|
||
#### 6.1 功能概述
|
||
评委对提交的作品进行评分,支持多维度评分和评语。
|
||
|
||
#### 6.2 交互流程
|
||
```
|
||
评委登录 → 进入"评审管理" → 选择赛事 → 查看分配的作品列表 → 点击作品 → 查看作品详情 → 评分 → 提交评分
|
||
```
|
||
|
||
#### 6.3 评审流程设计
|
||
|
||
**6.3.1 作品分配**
|
||
- 需要新增表:`t_contest_work_judge_assignment`(作品分配表)
|
||
- id, contest_id, work_id, judge_id, assignment_time, status
|
||
- 管理员或系统自动分配作品给评委
|
||
- 支持手动分配和自动分配(轮询、随机等)
|
||
|
||
**6.3.2 评分界面**
|
||
- 显示作品信息(标题、说明、文件、预览等)
|
||
- 显示评审规则(review_rule_id 关联的评审规则)
|
||
- 多维度评分表单
|
||
- 根据评审规则动态生成评分维度
|
||
- 每个维度设置分数范围
|
||
- 总分自动计算(根据评审规则配置的权重)
|
||
- 评语输入框
|
||
- 提交评分按钮
|
||
|
||
**6.3.3 评分数据**
|
||
- `t_contest_work_score`:评分表
|
||
- dimension_scores:JSON格式,存储各维度分数
|
||
- total_score:总分(根据规则计算)
|
||
- comments:评语
|
||
|
||
#### 6.4 评审规则设计
|
||
需要新增表:`t_contest_review_rule`(评审规则表)
|
||
- id, contest_id, rule_name, dimensions(JSON,存储评分维度配置)
|
||
- 示例维度配置:
|
||
```json
|
||
{
|
||
"dimension1": {
|
||
"name": "创意性",
|
||
"weight": 0.3,
|
||
"maxScore": 100
|
||
},
|
||
"dimension2": {
|
||
"name": "技术性",
|
||
"weight": 0.4,
|
||
"maxScore": 100
|
||
},
|
||
"dimension3": {
|
||
"name": "完成度",
|
||
"weight": 0.3,
|
||
"maxScore": 100
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 6.5 业务规则
|
||
- 评审时间限制:必须在 `review_start_time` 和 `review_end_time` 之间
|
||
- 作品状态更新:评审开始时,作品状态改为 `reviewing`
|
||
- 每个作品可以被多个评委评审
|
||
- 最终得分计算:取所有评委的平均分,或根据评审规则计算
|
||
- 评审完成后,作品状态改为 `accepted` 或 `rejected`
|
||
|
||
---
|
||
|
||
### 7. 赛事结果公布
|
||
|
||
#### 7.1 功能概述
|
||
管理员公布赛事评审结果,包括获奖名单、排名等。
|
||
|
||
#### 7.2 交互流程
|
||
```
|
||
管理员 → 进入"赛事管理" → 选择赛事 → 点击"公布结果" → 确认公布 → 结果发布
|
||
```
|
||
|
||
#### 7.3 结果公布内容
|
||
- 获奖名单(按奖项分类)
|
||
- 作品排名(按总分排序)
|
||
- 各维度平均分统计
|
||
- 评审统计信息(参与评审人数、作品数量等)
|
||
|
||
#### 7.4 业务规则
|
||
- 只有评审已完成的赛事可以公布结果
|
||
- 公布后,`result_publish_time` 设置为当前时间
|
||
- 结果公布后,所有用户可以看到排名和获奖信息
|
||
- 支持导出结果(Excel/PDF)
|
||
|
||
---
|
||
|
||
## 数据库设计分析
|
||
|
||
### 现有表结构
|
||
|
||
#### 1. t_contest(赛事表)
|
||
✅ **优点:**
|
||
- 字段设计完整,覆盖赛事全生命周期
|
||
- 支持多租户(contest_tenant 字段)
|
||
- 时间字段齐全
|
||
|
||
⚠️ **注意事项:**
|
||
- `contest_tenant` 使用 text 类型存储租户列表,建议考虑 JSON 类型或关联表
|
||
- `organizers`、`co_organizers`、`sponsors` 使用 text 存储数组,建议使用 JSON
|
||
|
||
#### 2. t_contest_attachment(赛事附件表)
|
||
✅ 设计合理,支持多种文件类型
|
||
|
||
#### 3. t_contest_work(作品表)
|
||
✅ **优点:**
|
||
- 支持版本控制(version、is_latest)
|
||
- 支持多种提交来源(teacher/student/team_leader)
|
||
- 支持 AI 建模元数据
|
||
|
||
⚠️ **问题:**
|
||
- 索引 `idx_submit_filter` 引用了不存在的字段 `review_status`,应删除或修正
|
||
|
||
#### 4. t_contest_work_attachment(作品附件表)
|
||
⚠️ **问题:**
|
||
- 第102行末尾有多余的逗号,需要删除
|
||
|
||
#### 5. t_contest_work_score(评分表)
|
||
⚠️ **问题:**
|
||
- 表定义重复(104-123行和125-144行),需要删除重复定义
|
||
|
||
#### 6. t_contest_registration(报名表)
|
||
✅ 设计合理,支持个人和团队报名
|
||
|
||
#### 7. t_contest_team(团队表)
|
||
⚠️ **问题:**
|
||
- 唯一索引 `uk_team_name` 引用了不存在的字段 `name`,应改为 `team_name`
|
||
|
||
#### 8. t_contest_team_member(团队成员表)
|
||
✅ 设计合理
|
||
|
||
### 缺失的表结构
|
||
|
||
#### 1. t_contest_notice(赛事公告表)
|
||
```sql
|
||
CREATE TABLE `t_contest_notice` (
|
||
`id` varchar(63) NOT NULL COMMENT '主键id',
|
||
`contest_id` varchar(63) NOT NULL COMMENT '赛事id',
|
||
`title` varchar(255) NOT NULL COMMENT '公告标题',
|
||
`content` text NOT NULL COMMENT '公告内容',
|
||
`notice_type` varchar(31) NOT NULL DEFAULT 'manual' COMMENT '公告类型:system/manual/urgent',
|
||
`priority` int DEFAULT 0 COMMENT '优先级(数字越大优先级越高)',
|
||
`publish_time` datetime DEFAULT NULL COMMENT '发布时间',
|
||
`creator` varchar(63) NOT NULL DEFAULT '' COMMENT '创建人',
|
||
`modifier` varchar(63) NOT NULL DEFAULT '' COMMENT '修改人',
|
||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
`modify_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||
`valid_state` varchar(1) NOT NULL DEFAULT '1' COMMENT '有效状态(1-有效,2-失效)',
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_contest` (`contest_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='赛事公告表';
|
||
```
|
||
|
||
#### 2. t_contest_review_rule(评审规则表)
|
||
```sql
|
||
CREATE TABLE `t_contest_review_rule` (
|
||
`id` varchar(63) NOT NULL COMMENT '主键id',
|
||
`contest_id` varchar(63) NOT NULL COMMENT '赛事id',
|
||
`rule_name` varchar(127) NOT NULL COMMENT '规则名称',
|
||
`dimensions` json NOT NULL COMMENT '评分维度配置JSON',
|
||
`calculation_rule` varchar(31) DEFAULT 'average' COMMENT '计算规则:average/max/min/weighted',
|
||
`creator` varchar(63) NOT NULL DEFAULT '' COMMENT '创建人',
|
||
`modifier` varchar(63) NOT NULL DEFAULT '' COMMENT '修改人',
|
||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
`modify_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||
`valid_state` varchar(1) NOT NULL DEFAULT '1' COMMENT '有效状态(1-有效,2-失效)',
|
||
PRIMARY KEY (`id`),
|
||
KEY `idx_contest` (`contest_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='评审规则表';
|
||
```
|
||
|
||
#### 3. t_contest_work_judge_assignment(作品分配表)
|
||
```sql
|
||
CREATE TABLE `t_contest_work_judge_assignment` (
|
||
`id` varchar(63) NOT NULL COMMENT '主键id',
|
||
`contest_id` varchar(63) NOT NULL COMMENT '赛事id',
|
||
`work_id` varchar(63) NOT NULL COMMENT '作品id',
|
||
`judge_id` varchar(63) NOT NULL COMMENT '评委用户id',
|
||
`assignment_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '分配时间',
|
||
`status` varchar(31) NOT NULL DEFAULT 'assigned' COMMENT '分配状态:assigned/reviewing/completed',
|
||
`creator` varchar(63) NOT NULL DEFAULT '' COMMENT '创建人',
|
||
`modifier` varchar(63) NOT NULL DEFAULT '' COMMENT '修改人',
|
||
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||
`modify_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_work_judge` (`work_id`, `judge_id`),
|
||
KEY `idx_contest_judge` (`contest_id`, `judge_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='作品分配表';
|
||
```
|
||
|
||
---
|
||
|
||
## 功能模块划分
|
||
|
||
### 后端模块结构
|
||
|
||
```
|
||
backend/src/contests/
|
||
├── contests.module.ts # 赛事主模块
|
||
├── contests.controller.ts # 赛事控制器
|
||
├── contests.service.ts # 赛事服务
|
||
├── dto/
|
||
│ ├── create-contest.dto.ts
|
||
│ ├── update-contest.dto.ts
|
||
│ ├── query-contest.dto.ts
|
||
│ └── publish-contest.dto.ts
|
||
├── works/
|
||
│ ├── works.module.ts
|
||
│ ├── works.controller.ts
|
||
│ ├── works.service.ts
|
||
│ └── dto/
|
||
│ ├── create-work.dto.ts
|
||
│ ├── update-work.dto.ts
|
||
│ └── submit-work.dto.ts
|
||
├── registrations/
|
||
│ ├── registrations.module.ts
|
||
│ ├── registrations.controller.ts
|
||
│ ├── registrations.service.ts
|
||
│ └── dto/
|
||
│ ├── create-registration.dto.ts
|
||
│ ├── review-registration.dto.ts
|
||
│ └── create-team.dto.ts
|
||
├── teams/
|
||
│ ├── teams.module.ts
|
||
│ ├── teams.controller.ts
|
||
│ ├── teams.service.ts
|
||
│ └── dto/
|
||
│ ├── create-team.dto.ts
|
||
│ └── invite-member.dto.ts
|
||
├── reviews/
|
||
│ ├── reviews.module.ts
|
||
│ ├── reviews.controller.ts
|
||
│ ├── reviews.service.ts
|
||
│ └── dto/
|
||
│ ├── create-score.dto.ts
|
||
│ ├── assign-work.dto.ts
|
||
│ └── create-review-rule.dto.ts
|
||
└── notices/
|
||
├── notices.module.ts
|
||
├── notices.controller.ts
|
||
├── notices.service.ts
|
||
└── dto/
|
||
├── create-notice.dto.ts
|
||
└── update-notice.dto.ts
|
||
```
|
||
|
||
### 前端模块结构
|
||
|
||
```
|
||
frontend/src/views/contests/
|
||
├── Index.vue # 赛事列表页
|
||
├── Create.vue # 创建赛事页
|
||
├── Detail.vue # 赛事详情页
|
||
├── Edit.vue # 编辑赛事页
|
||
├── works/
|
||
│ ├── Index.vue # 作品列表页
|
||
│ ├── Submit.vue # 提交作品页
|
||
│ └── Detail.vue # 作品详情页
|
||
├── registrations/
|
||
│ ├── Index.vue # 报名列表页
|
||
│ ├── Register.vue # 报名页
|
||
│ └── Review.vue # 审核报名页
|
||
├── teams/
|
||
│ ├── Index.vue # 团队列表页
|
||
│ ├── Create.vue # 创建团队页
|
||
│ └── Detail.vue # 团队详情页
|
||
├── reviews/
|
||
│ ├── Index.vue # 评审列表页
|
||
│ ├── Score.vue # 评分页
|
||
│ └── Results.vue # 结果公布页
|
||
└── notices/
|
||
├── Index.vue # 公告列表页
|
||
└── Create.vue # 创建公告页
|
||
```
|
||
|
||
---
|
||
|
||
## 实现计划
|
||
|
||
### 阶段一:基础功能(2-3周)
|
||
|
||
#### 1.1 数据库迁移
|
||
- [ ] 修复 SQL 文件中的错误
|
||
- 删除 `t_contest_work_score` 重复定义
|
||
- 修复 `t_contest_work_attachment` 的逗号错误
|
||
- 修复 `t_contest_team` 索引字段名错误
|
||
- 修复 `t_contest_work` 索引字段错误
|
||
- [ ] 创建缺失的表(公告表、评审规则表、作品分配表)
|
||
- [ ] 更新 Prisma schema
|
||
- [ ] 执行数据库迁移
|
||
|
||
#### 1.2 后端基础模块
|
||
- [ ] 创建 contests 模块(Controller、Service、DTO)
|
||
- [ ] 实现赛事 CRUD 接口
|
||
- [ ] 实现赛事发布/撤回接口
|
||
- [ ] 实现租户权限控制
|
||
- [ ] 编写单元测试
|
||
|
||
#### 1.3 前端基础页面
|
||
- [ ] 创建赛事列表页
|
||
- [ ] 创建赛事创建/编辑页
|
||
- [ ] 创建赛事详情页
|
||
- [ ] 集成权限控制
|
||
- [ ] 实现路由配置
|
||
|
||
### 阶段二:报名功能(2周)
|
||
|
||
#### 2.1 后端实现
|
||
- [ ] 创建 registrations 模块
|
||
- [ ] 实现个人报名接口
|
||
- [ ] 实现团队报名接口
|
||
- [ ] 实现报名审核接口
|
||
- [ ] 实现报名状态流转逻辑
|
||
|
||
#### 2.2 前端实现
|
||
- [ ] 创建报名页面
|
||
- [ ] 创建团队管理页面
|
||
- [ ] 创建报名审核页面
|
||
- [ ] 实现报名状态展示
|
||
|
||
### 阶段三:作品提交功能(2周)
|
||
|
||
#### 3.1 后端实现
|
||
- [ ] 创建 works 模块
|
||
- [ ] 实现作品提交接口
|
||
- [ ] 实现文件上传功能
|
||
- [ ] 实现作品版本控制逻辑
|
||
- [ ] 实现作品状态管理
|
||
|
||
#### 3.2 前端实现
|
||
- [ ] 创建作品提交页面
|
||
- [ ] 实现文件上传组件
|
||
- [ ] 创建作品列表页
|
||
- [ ] 创建作品详情页
|
||
|
||
### 阶段四:评审功能(2-3周)
|
||
|
||
#### 4.1 后端实现
|
||
- [ ] 创建 reviews 模块
|
||
- [ ] 实现评审规则管理接口
|
||
- [ ] 实现作品分配接口
|
||
- [ ] 实现评分接口
|
||
- [ ] 实现评分计算逻辑
|
||
|
||
#### 4.2 前端实现
|
||
- [ ] 创建评审规则配置页
|
||
- [ ] 创建作品分配页
|
||
- [ ] 创建评分页面
|
||
- [ ] 实现多维度评分表单
|
||
|
||
### 阶段五:结果公布与公告(1周)
|
||
|
||
#### 5.1 后端实现
|
||
- [ ] 创建 notices 模块
|
||
- [ ] 实现公告 CRUD 接口
|
||
- [ ] 实现结果公布接口
|
||
- [ ] 实现结果统计接口
|
||
|
||
#### 5.2 前端实现
|
||
- [ ] 创建公告管理页面
|
||
- [ ] 创建结果公布页面
|
||
- [ ] 实现结果展示页面
|
||
|
||
### 阶段六:优化与测试(1-2周)
|
||
|
||
#### 6.1 功能优化
|
||
- [ ] 性能优化(数据库查询优化、缓存)
|
||
- [ ] 用户体验优化
|
||
- [ ] 错误处理完善
|
||
|
||
#### 6.2 测试
|
||
- [ ] 单元测试
|
||
- [ ] 集成测试
|
||
- [ ] 端到端测试
|
||
- [ ] 压力测试
|
||
|
||
---
|
||
|
||
## 技术实现要点
|
||
|
||
### 1. 权限设计
|
||
|
||
#### 1.1 权限编码规划
|
||
```
|
||
contest:create # 创建赛事
|
||
contest:read # 查看赛事
|
||
contest:update # 更新赛事
|
||
contest:delete # 删除赛事
|
||
contest:publish # 发布赛事
|
||
contest:register # 报名赛事
|
||
work:submit # 提交作品
|
||
work:read # 查看作品
|
||
work:update # 更新作品
|
||
review:assign # 分配作品
|
||
review:score # 评分
|
||
review:read # 查看评审
|
||
result:publish # 公布结果
|
||
notice:create # 创建公告
|
||
notice:read # 查看公告
|
||
```
|
||
|
||
#### 1.2 角色规划
|
||
- **超级管理员**:所有权限
|
||
- **赛事管理员**:contest:*、notice:*、result:publish
|
||
- **评委**:review:assign、review:score、review:read、work:read
|
||
- **参赛者**:contest:read、contest:register、work:submit、work:read
|
||
|
||
### 2. 租户隔离
|
||
|
||
#### 2.1 数据隔离策略
|
||
- 赛事创建:超级租户创建,通过 `contest_tenant` 字段控制可见范围
|
||
- 报名数据:通过 `tenant_key` 字段隔离
|
||
- 作品数据:通过 `tenant_key` 字段隔离
|
||
- 评审数据:通过 `tenant_key` 字段隔离
|
||
|
||
#### 2.2 接口权限控制
|
||
- 使用 `@TenantId()` 装饰器获取租户信息
|
||
- Service 层自动过滤租户数据
|
||
- Controller 层验证租户权限
|
||
|
||
### 3. 时间状态管理
|
||
|
||
#### 3.1 赛事状态机
|
||
```
|
||
unpublished → published → (可撤回) → unpublished
|
||
```
|
||
|
||
#### 3.2 报名状态机
|
||
```
|
||
pending → passed/rejected/withdrawn
|
||
```
|
||
|
||
#### 3.3 作品状态机
|
||
```
|
||
submitted → locked → reviewing → accepted/rejected
|
||
```
|
||
|
||
#### 3.4 定时任务
|
||
- 自动更新报名状态(根据时间)
|
||
- 自动更新作品提交状态
|
||
- 自动更新评审状态
|
||
- 自动发送通知(可选)
|
||
|
||
### 4. 文件上传
|
||
|
||
#### 4.1 文件存储
|
||
- 使用对象存储(OSS/S3)或本地存储
|
||
- 文件类型限制:图片、视频、3D模型、文档等
|
||
- 文件大小限制:根据文件类型设置
|
||
|
||
#### 4.2 文件管理
|
||
- 文件上传接口
|
||
- 文件删除接口
|
||
- 文件预览接口
|
||
- 文件下载接口
|
||
|
||
### 5. 通知系统
|
||
|
||
#### 5.1 通知类型
|
||
- 报名成功通知
|
||
- 报名审核结果通知
|
||
- 作品提交成功通知
|
||
- 评审结果通知
|
||
- 结果公布通知
|
||
|
||
#### 5.2 通知方式(可选)
|
||
- 站内消息
|
||
- 邮件通知
|
||
- 短信通知(可选)
|
||
|
||
### 6. 数据统计
|
||
|
||
#### 6.1 赛事统计
|
||
- 报名人数统计
|
||
- 作品提交数量统计
|
||
- 评审进度统计
|
||
- 结果统计
|
||
|
||
#### 6.2 报表导出
|
||
- 报名名单导出(Excel)
|
||
- 作品列表导出(Excel)
|
||
- 评审结果导出(Excel)
|
||
- 结果报告导出(PDF)
|
||
|
||
---
|
||
|
||
## 注意事项
|
||
|
||
### 1. SQL 文件问题修复
|
||
在开始开发前,必须先修复 SQL 文件中的错误:
|
||
- 删除重复的 `t_contest_work_score` 表定义
|
||
- 修复 `t_contest_work_attachment` 表的语法错误
|
||
- 修复 `t_contest_team` 表的索引错误
|
||
- 修复 `t_contest_work` 表的索引错误
|
||
|
||
### 2. 数据一致性
|
||
- 报名和作品的关系:一个报名可以对应多个作品版本
|
||
- 团队和报名的关系:一个团队对应多个报名记录(每个成员一条)
|
||
- 作品和评分的关系:一个作品可以有多条评分记录(多个评委)
|
||
|
||
### 3. 性能考虑
|
||
- 赛事列表查询需要分页
|
||
- 作品列表查询需要分页和筛选
|
||
- 评分计算需要缓存
|
||
- 文件上传需要异步处理
|
||
|
||
### 4. 安全性
|
||
- 文件上传需要验证文件类型和大小
|
||
- 接口需要权限验证
|
||
- 敏感操作需要日志记录
|
||
- 防止 SQL 注入和 XSS 攻击
|
||
|
||
---
|
||
|
||
## 总结
|
||
|
||
本方案基于现有的多租户 RBAC 系统架构,设计了完整的赛事管理功能模块。主要特点:
|
||
|
||
1. **完整的生命周期管理**:从赛事创建到结果公布的全流程
|
||
2. **灵活的参赛方式**:支持个人赛和团队赛
|
||
3. **强大的评审系统**:支持多维度评分和自定义评审规则
|
||
4. **良好的扩展性**:模块化设计,易于扩展新功能
|
||
|
||
建议按照阶段逐步实现,每个阶段完成后进行测试和优化,确保系统稳定可靠。
|
||
|