# 学校管理与比赛管理模块 - 产品功能说明、实现思路与开发计划

## 📋 目录

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 的细粒度权限控制

建议按照开发计划逐步实施，每个阶段完成后进行充分测试，确保系统稳定可靠。
