library-picturebook-activity/docs/legacy/CONTEST_MODULES.md

884 lines
21 KiB
Markdown
Raw Permalink Normal View History

# 学校管理与比赛管理模块 - 产品功能说明、实现思路与开发计划
## 📋 目录
1. [概述](#概述)
2. [学校管理模块](#学校管理模块)
3. [比赛管理模块](#比赛管理模块)
4. [技术架构](#技术架构)
5. [实现思路](#实现思路)
6. [开发计划](#开发计划)
7. [权限设计](#权限设计)
8. [数据流转](#数据流转)
---
## 概述
### 系统定位
本系统是一个**多租户的学校管理与比赛管理平台**,支持:
- **多租户架构**:每个学校作为一个租户,数据完全隔离
- **统一用户体系**:教师和学生基于统一的 User 表,通过扩展表存储特定信息
- **完整的比赛流程**:从比赛创建、报名、作品提交到评审、结果公布的完整生命周期
- **灵活的权限控制**:基于 RBAC 的权限管理,支持细粒度的功能权限控制
### 核心价值
1. **学校管理数字化**:实现学校组织架构、人员管理的数字化
2. **比赛管理规范化**:规范比赛流程,提高管理效率
3. **数据安全隔离**:多租户架构确保各学校数据安全隔离
4. **灵活扩展**:模块化设计,易于扩展新功能
---
## 比赛管理模块
### 1. 功能概述
比赛管理模块提供完整的比赛生命周期管理,从比赛创建、发布、报名、作品提交、评审到结果公布的完整流程。
### 2. 核心功能
#### 2.1 比赛管理
**功能描述**
- 创建比赛(基本信息、时间安排、参赛范围等)
- 编辑比赛信息
- 发布/撤回比赛
- 查看比赛列表和详情
**用户角色**
- 超级管理员:创建和管理所有比赛
- 比赛管理员:管理指定比赛
**业务规则**
- 比赛名称在系统内唯一
- 时间顺序校验:报名开始 < 报名结束 < 提交开始 < 提交结束 < 评审开始 < 评审结束 < 结果发布
- 只有发布的比赛才能被租户看到
- 已发布的比赛可以撤回,但需检查是否有报名记录
#### 2.2 比赛报名
**功能描述**
- **个人赛报名**:学生或教师个人报名
- **团队赛报名**:创建团队、邀请成员、提交团队报名
- 报名审核(可选)
- 查看报名状态
**用户角色**
- 学生:个人报名、创建/加入团队
- 教师:个人报名、代学生报名、创建/管理团队
- 比赛管理员:审核报名
**业务规则**
- 报名时间限制:必须在报名时间窗口内
- 个人赛:一个用户在一个比赛中只能报名一次
- 团队赛:
- 团队名称在同一比赛、同一租户内唯一
- 团队成员角色leader队长、member队员、mentor指导教师
- 团队报名时,所有成员状态同步更新
#### 2.3 作品提交
**功能描述**
- 提交参赛作品(标题、说明、文件等)
- 支持单次提交和多次提交(根据比赛配置)
- 作品版本管理
- 查看作品列表和详情
**用户角色**
- 学生:提交作品
- 教师:代学生提交作品
- 团队队长:提交团队作品
**业务规则**
- 提交时间限制:必须在提交时间窗口内
- 必须已通过报名审核
- **单次提交submit_rule = 'once'**:只能提交一次
- **多次提交submit_rule = 'resubmit'**
- 可以多次提交,每次创建新版本
- 只有最新版本参与评审
- 旧版本保留历史记录
#### 2.4 作品评审
**功能描述**
- 配置评审规则(评分维度、权重等)
- 分配作品给评委
- 评委评分(多维度评分、评语)
- 查看评审进度和结果
**用户角色**
- 比赛管理员:配置评审规则、分配作品
- 评委:查看分配的作品、进行评分
**业务规则**
- 评审时间限制:必须在评审时间窗口内
- 每个作品可以被多个评委评审
- 最终得分计算:根据评审规则计算(平均分、加权平均等)
- 评审完成后,作品状态更新为 accepted 或 rejected
#### 2.5 结果公布
**功能描述**
- 公布比赛结果(获奖名单、排名等)
- 查看比赛结果统计
- 导出结果Excel/PDF
**用户角色**
- 比赛管理员:公布结果
- 所有用户:查看结果
**业务规则**
- 只有评审已完成的比赛可以公布结果
- 结果公布后,所有用户可以看到排名和获奖信息
#### 2.6 比赛公告
**功能描述**
- 发布比赛公告
- 管理公告(编辑、删除、置顶)
- 查看公告列表
**用户角色**
- 比赛管理员:发布和管理公告
- 所有用户:查看公告
**业务规则**
- 支持公告类型:系统公告、人工公告、紧急通知
- 支持优先级设置
### 3. 数据模型
```
Contest (比赛)
├── ContestAttachment (比赛附件) [1:N]
├── ContestReviewRule (评审规则) [1:1]
├── ContestTeam (团队) [1:N]
│ └── ContestTeamMember (团队成员) [1:N]
├── ContestRegistration (报名记录) [1:N]
│ └── ContestWork (作品) [1:N]
│ ├── ContestWorkAttachment (作品附件) [1:N]
│ ├── ContestWorkJudgeAssignment (作品分配) [1:N]
│ └── ContestWorkScore (作品评分) [1:N]
└── ContestNotice (比赛公告) [1:N]
```
### 4. 关键业务规则
1. **租户隔离**:比赛通过 `contest_tenants` 字段控制可见范围
2. **时间管理**:严格的时间顺序校验和状态流转
3. **版本控制**:作品支持版本管理,保留历史记录
4. **评审灵活**:支持多维度评分和自定义评审规则
---
## 技术架构
### 1. 后端架构
```
backend/
├── src/
│ ├── school/ # 学校管理模块
│ │ ├── schools/
│ │ ├── grades/
│ │ ├── classes/
│ │ ├── departments/
│ │ ├── teachers/
│ │ └── students/
│ ├── contests/ # 比赛管理模块
│ │ ├── contests/
│ │ ├── registrations/
│ │ ├── teams/
│ │ ├── works/
│ │ ├── reviews/
│ │ └── notices/
│ ├── auth/ # 认证授权
│ ├── tenants/ # 租户管理
│ └── common/ # 公共模块
```
**技术栈**
- **框架**NestJS
- **ORM**Prisma
- **数据库**MySQL
- **认证**JWT
- **权限**RBAC
### 2. 前端架构
```
frontend/
├── src/
│ ├── views/
│ │ ├── school/ # 学校管理页面
│ │ │ ├── schools/
│ │ │ ├── grades/
│ │ │ ├── classes/
│ │ │ ├── departments/
│ │ │ ├── teachers/
│ │ │ └── students/
│ │ └── contests/ # 比赛管理页面
│ │ ├── Index.vue
│ │ ├── Create.vue
│ │ ├── works/
│ │ ├── registrations/
│ │ └── reviews/
│ ├── api/ # API 接口
│ ├── stores/ # 状态管理
│ └── utils/ # 工具函数
```
**技术栈**
- **框架**Vue 3 + TypeScript
- **路由**Vue Router
- **状态管理**Pinia
- **UI 框架**Element Plus / Ant Design Vue
- **构建工具**Vite
### 3. 数据库设计
**设计原则**
1. **多租户隔离**:所有业务表都包含 `tenantId` 字段
2. **统一用户体系**:教师和学生基于 User 表
3. **数据完整性**:使用外键约束和级联删除
4. **审计追踪**:所有表包含创建人、修改人、时间字段
**核心表**
- 学校管理:`schools`, `grades`, `classes`, `departments`, `teachers`, `students`
- 比赛管理:`t_contest`, `t_contest_registration`, `t_contest_work`, `t_contest_work_score`
---
## 实现思路
### 1. 多租户数据隔离
#### 1.1 租户识别
**实现方式**
1. **请求头方式**(推荐):
- `X-Tenant-Code`: 租户编码
- `X-Tenant-Id`: 租户ID
2. **JWT Token 方式**
- Token 中包含 `tenantId` 字段
- 登录时自动关联租户
3. **子域名方式**
-`Host` 请求头提取子域名
- 匹配租户的 `code``domain` 字段
#### 1.2 数据过滤
**实现方式**
```typescript
// Service 层自动过滤租户数据
async findAll(tenantId: number) {
return this.prisma.model.findMany({
where: { tenantId }
});
}
// Controller 层获取租户信息
@Get()
findAll(@Request() req) {
const tenantId = req.tenantId || req.user?.tenantId;
return this.service.findAll(tenantId);
}
```
### 2. 统一用户体系
#### 2.1 用户创建流程
**教师创建**
```
1. 创建 User 记录username, password, tenantId
2. 创建 Teacher 记录(关联 User.id
3. 分配角色和权限
```
**学生创建**
```
1. 创建 User 记录username, password, tenantId
2. 创建 Student 记录(关联 User.id
3. 分配角色和权限
```
#### 2.2 用户扩展信息
**实现方式**
- 使用 Prisma 的一对一关系
- 通过 `include` 查询关联数据
- 通过事务保证数据一致性
### 3. 比赛流程管理
#### 3.1 状态机设计
**比赛状态**
```
unpublished → published → (可撤回) → unpublished
```
**报名状态**
```
pending → passed/rejected/withdrawn
```
**作品状态**
```
submitted → locked → reviewing → accepted/rejected
```
#### 3.2 时间校验
**实现方式**
```typescript
// DTO 验证
@IsDate()
@Validate(TimeOrderValidator)
registerStartTime: Date;
// 自定义验证器
class TimeOrderValidator implements ValidatorConstraintInterface {
validate(value: any, args: ValidationArguments) {
const dto = args.object as CreateContestDto;
return dto.registerStartTime < dto.registerEndTime <
dto.submitStartTime < dto.submitEndTime <
dto.reviewStartTime < dto.reviewEndTime;
}
}
```
### 4. 文件上传
#### 4.1 文件存储
**实现方式**
- 使用对象存储OSS/S3或本地存储
- 文件上传接口返回文件 URL
- 文件信息存储到数据库
#### 4.2 文件管理
**实现方式**
```typescript
// 文件上传
@Post('upload')
@UseInterceptors(FileInterceptor('file'))
async uploadFile(@UploadedFile() file: Express.Multer.File) {
// 验证文件类型和大小
// 上传到存储
// 返回文件 URL
}
// 文件删除
@Delete('files/:id')
async deleteFile(@Param('id') id: string) {
// 删除文件
// 更新数据库记录
}
```
### 5. 权限控制
#### 5.1 权限编码
**命名规则**`资源:操作`
**示例**
```
school:create # 创建学校
school:read # 查看学校
teacher:create # 创建教师
student:read # 查看学生
contest:create # 创建比赛
contest:publish # 发布比赛
work:submit # 提交作品
review:score # 评分
```
#### 5.2 权限验证
**实现方式**
```typescript
// 使用装饰器
@RequirePermission('contest:create')
@Post()
create(@Body() dto: CreateContestDto) {
// ...
}
// Guard 自动验证权限
@Injectable()
export class PermissionsGuard implements CanActivate {
async canActivate(context: ExecutionContext) {
const requiredPermission = this.reflector.get(PERMISSION_KEY);
const userPermissions = await this.getUserPermissions();
return userPermissions.includes(requiredPermission);
}
}
```
---
## 开发计划
### 阶段一基础架构与学校管理3-4周
#### 1.1 数据库迁移1周
**任务**
- [ ] 执行学校管理模块数据库迁移
- [ ] 执行比赛管理模块数据库迁移
- [ ] 验证数据表结构
- [ ] 创建初始化数据脚本
**交付物**
- 数据库迁移文件
- 初始化数据脚本
- 数据库设计文档
#### 1.2 学校管理后端2周
**任务**
- [ ] 创建 school 模块Controller、Service、DTO
- [ ] 实现学校信息 CRUD
- [ ] 实现年级管理 CRUD
- [ ] 实现班级管理 CRUD支持行政班级和兴趣班
- [ ] 实现部门管理 CRUD支持树形结构
- [ ] 实现教师管理 CRUD自动创建 User
- [ ] 实现学生管理 CRUD自动创建 User
- [ ] 实现学生兴趣班关联管理
- [ ] 实现租户权限控制
- [ ] 编写单元测试
**交付物**
- 学校管理后端 API
- API 文档
- 单元测试
#### 1.3 学校管理前端1-2周
**任务**
- [ ] 创建学校管理页面结构
- [ ] 实现学校信息管理页面
- [ ] 实现年级管理页面
- [ ] 实现班级管理页面(支持类型切换)
- [ ] 实现部门管理页面(树形结构)
- [ ] 实现教师管理页面(列表、创建、编辑)
- [ ] 实现学生管理页面(列表、创建、编辑)
- [ ] 实现学生兴趣班管理页面
- [ ] 集成权限控制
- [ ] 实现路由配置
**交付物**
- 学校管理前端页面
- 路由配置
- 权限控制
### 阶段二比赛管理基础功能3-4周
#### 2.1 比赛管理后端2周
**任务**
- [ ] 创建 contests 模块Controller、Service、DTO
- [ ] 实现比赛 CRUD 接口
- [ ] 实现比赛发布/撤回接口
- [ ] 实现比赛附件管理接口
- [ ] 实现评审规则管理接口
- [ ] 实现租户权限控制
- [ ] 实现时间校验逻辑
- [ ] 编写单元测试
**交付物**
- 比赛管理后端 API
- API 文档
- 单元测试
#### 2.2 比赛管理前端1-2周
**任务**
- [ ] 创建比赛管理页面结构
- [ ] 实现比赛列表页面
- [ ] 实现比赛创建/编辑页面
- [ ] 实现比赛详情页面
- [ ] 实现比赛发布功能
- [ ] 集成权限控制
- [ ] 实现路由配置
**交付物**
- 比赛管理前端页面
- 路由配置
### 阶段三报名功能2-3周
#### 3.1 报名后端1.5周)
**任务**
- [ ] 创建 registrations 模块
- [ ] 实现个人报名接口
- [ ] 创建 teams 模块
- [ ] 实现团队创建/管理接口
- [ ] 实现团队报名接口
- [ ] 实现报名审核接口
- [ ] 实现报名状态流转逻辑
- [ ] 编写单元测试
**交付物**
- 报名管理后端 API
- API 文档
#### 3.2 报名前端1-1.5周)
**任务**
- [ ] 实现比赛报名页面
- [ ] 实现团队管理页面
- [ ] 实现报名审核页面
- [ ] 实现报名状态展示
- [ ] 实现团队邀请功能
**交付物**
- 报名管理前端页面
### 阶段四作品提交功能2-3周
#### 4.1 作品提交后端1.5周)
**任务**
- [ ] 创建 works 模块
- [ ] 实现作品提交接口
- [ ] 实现文件上传功能
- [ ] 实现作品版本控制逻辑
- [ ] 实现作品状态管理
- [ ] 实现作品列表查询(支持筛选)
- [ ] 编写单元测试
**交付物**
- 作品管理后端 API
- 文件上传功能
#### 4.2 作品提交前端1-1.5周)
**任务**
- [ ] 实现作品提交页面
- [ ] 实现文件上传组件
- [ ] 实现作品列表页面
- [ ] 实现作品详情页面
- [ ] 实现作品版本管理
**交付物**
- 作品管理前端页面
### 阶段五评审功能3-4周
#### 5.1 评审后端2周
**任务**
- [ ] 创建 reviews 模块
- [ ] 实现评审规则管理接口
- [ ] 实现作品分配接口(手动/自动)
- [ ] 实现评分接口
- [ ] 实现评分计算逻辑
- [ ] 实现评审进度统计
- [ ] 编写单元测试
**交付物**
- 评审管理后端 API
- 评分计算逻辑
#### 5.2 评审前端1-2周
**任务**
- [ ] 实现评审规则配置页面
- [ ] 实现作品分配页面
- [ ] 实现评分页面(多维度评分表单)
- [ ] 实现评审进度页面
- [ ] 实现评审结果统计
**交付物**
- 评审管理前端页面
### 阶段六结果公布与公告1-2周
#### 6.1 结果公布后端1周
**任务**
- [ ] 创建 notices 模块
- [ ] 实现公告 CRUD 接口
- [ ] 实现结果公布接口
- [ ] 实现结果统计接口
- [ ] 实现结果导出接口Excel/PDF
**交付物**
- 公告和结果管理后端 API
#### 6.2 结果公布前端1周
**任务**
- [ ] 实现公告管理页面
- [ ] 实现结果公布页面
- [ ] 实现结果展示页面(排名、获奖名单)
- [ ] 实现结果导出功能
**交付物**
- 公告和结果管理前端页面
### 阶段七优化与测试2-3周
#### 7.1 功能优化1-2周
**任务**
- [ ] 性能优化(数据库查询优化、缓存)
- [ ] 用户体验优化
- [ ] 错误处理完善
- [ ] 日志记录完善
#### 7.2 测试1周
**任务**
- [ ] 单元测试补充
- [ ] 集成测试
- [ ] 端到端测试
- [ ] 压力测试
- [ ] 安全测试
**交付物**
- 测试报告
- 性能报告
---
## 权限设计
### 1. 角色规划
#### 1.1 系统角色
**超级管理员super_admin**
- 所有权限
- 创建和管理租户
- 创建和管理比赛
**学校管理员school_admin**
- 学校管理school:\*
- 年级管理grade:\*
- 班级管理class:\*
- 部门管理department:\*
- 教师管理teacher:\*
- 学生管理student:\*
**比赛管理员contest_admin**
- 比赛管理contest:\*
- 公告管理notice:\*
- 结果公布result:publish
**评委judge**
- 作品查看work:read
- 评审分配review:assign
- 评分review:score
- 评审查看review:read
**教师teacher**
- 比赛查看contest:read
- 比赛报名contest:register
- 作品提交work:submit
- 作品查看work:read
- 学生管理student:read本班级
**学生student**
- 比赛查看contest:read
- 比赛报名contest:register
- 作品提交work:submit
- 作品查看work:read自己的作品
- 结果查看result:read
### 2. 权限编码
#### 2.2 比赛管理权限
```
contest:create # 创建比赛
contest:read # 查看比赛
contest:update # 更新比赛
contest:delete # 删除比赛
contest:publish # 发布比赛
contest:register # 报名比赛
team:create # 创建团队
team:read # 查看团队
team:update # 更新团队
team:delete # 删除团队
work:submit # 提交作品
work:read # 查看作品
work:update # 更新作品
review:assign # 分配作品
review:score # 评分
review:read # 查看评审
result:publish # 公布结果
result:read # 查看结果
notice:create # 创建公告
notice:read # 查看公告
notice:update # 更新公告
notice:delete # 删除公告
```
---
## 数据流转
### 1. 学校管理数据流
```
创建租户
创建学校信息
创建年级
创建班级(行政班级/兴趣班)
创建部门
创建教师账号User + Teacher
创建学生账号User + Student
学生加入兴趣班StudentInterestClass
```
### 2. 比赛管理数据流
```
创建比赛(超级管理员)
配置评审规则
发布比赛
学生/教师报名(个人/团队)
报名审核(可选)
提交作品
分配作品给评委
评委评分
计算最终得分
公布结果
```
### 3. 关键数据关联
**用户与学校**
- User.tenantId → Tenant.id
- Teacher.userId → User.id
- Student.userId → User.id
**用户与比赛**
- ContestRegistration.userId → User.id
- ContestWork.submitterUserId → User.id
- ContestWorkScore.judgeId → User.id
**比赛与租户**
- Contest.contestTenants (JSON) → Tenant.id[]
- ContestRegistration.tenantId → Tenant.id
- ContestWork.tenantId → Tenant.id
---
## 总结
本文档详细描述了学校管理和比赛管理两个核心模块的产品功能、实现思路和开发计划。主要特点:
1. **完整的业务流程**:覆盖从学校管理到比赛全生命周期的所有环节
2. **清晰的架构设计**:多租户、统一用户体系、模块化设计
3. **详细的开发计划**:分阶段实施,每个阶段都有明确的交付物
4. **完善的权限体系**:基于 RBAC 的细粒度权限控制
建议按照开发计划逐步实施,每个阶段完成后进行充分测试,确保系统稳定可靠。