# 学校模块数据库设计文档

## 概述

本文档描述了学校管理系统的数据库表设计，包括学校信息、年级、班级、部门、教师和学生等核心实体。

## 设计原则

1. **租户隔离**：所有表都通过 `tenantId` 关联到 `Tenant` 表，实现多租户数据隔离
2. **用户统一**：教师和学生都基于 `User` 表，通过一对一关系扩展特定信息
3. **数据完整性**：使用外键约束和级联删除保证数据一致性
4. **审计追踪**：所有表都包含创建人、修改人、创建时间、修改时间字段

## 表结构设计

### 1. 学校信息表 (School)

**说明**：扩展租户信息，存储学校的详细资料。与 `Tenant` 表一对一关系。

**字段说明**：
- `id`: 主键
- `tenantId`: 租户ID（唯一，一对一关联Tenant）
- `address`: 学校地址
- `phone`: 联系电话
- `principal`: 校长姓名
- `established`: 建校时间
- `description`: 学校描述
- `logo`: 学校Logo URL
- `website`: 学校网站
- `creator/modifier`: 创建人/修改人ID
- `createTime/modifyTime`: 创建/修改时间

**关系**：
- 一对一关联 `Tenant`
- 多对一关联 `User` (创建人/修改人)

---

### 2. 年级表 (Grade)

**说明**：管理学校的年级信息，如一年级、二年级等。

**字段说明**：
- `id`: 主键
- `tenantId`: 租户ID
- `name`: 年级名称（如：一年级、二年级）
- `code`: 年级编码（在租户内唯一，如：grade_1, grade_2）
- `level`: 年级级别（用于排序，如：1, 2, 3）
- `description`: 年级描述
- `validState`: 有效状态（1-有效，2-失效）
- `creator/modifier`: 创建人/修改人ID
- `createTime/modifyTime`: 创建/修改时间

**唯一约束**：
- `[tenantId, code]`: 租户内年级编码唯一
- `[tenantId, level]`: 租户内年级级别唯一

**关系**：
- 多对一关联 `Tenant`
- 一对多关联 `Class` (班级)
- 多对一关联 `User` (创建人/修改人)

---

### 3. 部门表 (Department)

**说明**：管理学校的部门信息，支持树形结构（如：教务处 > 语文组）。

**字段说明**：
- `id`: 主键
- `tenantId`: 租户ID
- `name`: 部门名称
- `code`: 部门编码（在租户内唯一）
- `parentId`: 父部门ID（支持树形结构）
- `description`: 部门描述
- `sort`: 排序
- `validState`: 有效状态（1-有效，2-失效）
- `creator/modifier`: 创建人/修改人ID
- `createTime/modifyTime`: 创建/修改时间

**唯一约束**：
- `[tenantId, code]`: 租户内部门编码唯一

**关系**：
- 多对一关联 `Tenant`
- 自关联（树形结构）：`parent` 和 `children`
- 一对多关联 `Teacher` (教师)
- 多对一关联 `User` (创建人/修改人)

---

### 4. 班级表 (Class)

**说明**：管理班级信息，支持行政班级（教学班级）和兴趣班两种类型。

**字段说明**：
- `id`: 主键
- `tenantId`: 租户ID
- `gradeId`: 年级ID
- `name`: 班级名称（如：一年级1班、二年级2班）
- `code`: 班级编码（在租户内唯一）
- `type`: 班级类型（1-行政班级/教学班级，2-兴趣班）
- `capacity`: 班级容量（可选）
- `description`: 班级描述
- `validState`: 有效状态（1-有效，2-失效）
- `creator/modifier`: 创建人/修改人ID
- `createTime/modifyTime`: 创建/修改时间

**唯一约束**：
- `[tenantId, code]`: 租户内班级编码唯一

**关系**：
- 多对一关联 `Tenant`
- 多对一关联 `Grade` (年级)
- 一对多关联 `Student` (学生，仅行政班级)
- 一对多关联 `StudentInterestClass` (学生兴趣班关联)
- 多对一关联 `User` (创建人/修改人)

**注意事项**：
- `students` 关系仅用于行政班级（type=1），需要在应用层验证
- 兴趣班通过 `StudentInterestClass` 表关联学生

---

### 5. 教师表 (Teacher)

**说明**：存储教师的详细信息，与 `User` 表一对一关系。

**字段说明**：
- `id`: 主键
- `userId`: 用户ID（唯一，一对一关联User）
- `tenantId`: 租户ID
- `departmentId`: 部门ID
- `employeeNo`: 工号（在租户内唯一）
- `phone`: 联系电话
- `idCard`: 身份证号
- `gender`: 性别（1-男，2-女）
- `birthDate`: 出生日期
- `hireDate`: 入职日期
- `subject`: 任教科目（可选，如：语文、数学）
- `title`: 职称（可选，如：高级教师、一级教师）
- `description`: 教师描述
- `validState`: 有效状态（1-有效，2-失效）
- `creator/modifier`: 创建人/修改人ID
- `createTime/modifyTime`: 创建/修改时间

**唯一约束**：
- `userId`: 用户ID唯一（一对一）
- `[tenantId, employeeNo]`: 租户内工号唯一

**关系**：
- 一对一关联 `User`
- 多对一关联 `Tenant`
- 多对一关联 `Department` (部门)
- 多对一关联 `User` (创建人/修改人)

---

### 6. 学生表 (Student)

**说明**：存储学生的详细信息，与 `User` 表一对一关系。

**字段说明**：
- `id`: 主键
- `userId`: 用户ID（唯一，一对一关联User）
- `tenantId`: 租户ID
- `classId`: 行政班级ID
- `studentNo`: 学号（在租户内唯一）
- `phone`: 联系电话
- `idCard`: 身份证号
- `gender`: 性别（1-男，2-女）
- `birthDate`: 出生日期
- `enrollmentDate`: 入学日期
- `parentName`: 家长姓名
- `parentPhone`: 家长电话
- `address`: 家庭地址
- `description`: 学生描述
- `validState`: 有效状态（1-有效，2-失效）
- `creator/modifier`: 创建人/修改人ID
- `createTime/modifyTime`: 创建/修改时间

**唯一约束**：
- `userId`: 用户ID唯一（一对一）
- `[tenantId, studentNo]`: 租户内学号唯一

**关系**：
- 一对一关联 `User`
- 多对一关联 `Tenant`
- 多对一关联 `Class` (行政班级)
- 一对多关联 `StudentInterestClass` (兴趣班关联)
- 多对一关联 `User` (创建人/修改人)

**注意事项**：
- `classId` 必须关联行政班级（type=1），需要在应用层验证
- 兴趣班通过 `StudentInterestClass` 表关联

---

### 7. 学生兴趣班关联表 (StudentInterestClass)

**说明**：学生和兴趣班的多对多关联表。

**字段说明**：
- `id`: 主键
- `studentId`: 学生ID
- `classId`: 兴趣班ID（type=2的Class）

**唯一约束**：
- `[studentId, classId]`: 学生和兴趣班组合唯一

**关系**：
- 多对一关联 `Student`
- 多对一关联 `Class` (兴趣班)

**注意事项**：
- `classId` 必须关联兴趣班（type=2），需要在应用层验证

---

## 数据关系图

```
Tenant (租户/学校)
├── School (学校信息) [1:1]
├── Grade (年级) [1:N]
│   └── Class (班级) [1:N]
│       ├── Student (学生) [1:N, 仅行政班级]
│       └── StudentInterestClass [N:M, 仅兴趣班]
├── Department (部门) [1:N, 树形结构]
│   └── Teacher (教师) [1:N]
└── User (用户) [1:N]
    ├── Teacher [1:1]
    └── Student [1:1]
```

## 业务规则

1. **学校与租户**：每个租户对应一个学校，通过 `School` 表扩展学校信息
2. **年级管理**：年级按 `level` 排序，每个租户内级别唯一
3. **班级类型**：
   - 行政班级（type=1）：学生必须属于一个行政班级
   - 兴趣班（type=2）：学生可以加入多个兴趣班
4. **部门树形结构**：部门支持多级嵌套，通过 `parentId` 实现
5. **教师归属**：教师必须归属于一个部门
6. **学生归属**：学生必须属于一个行政班级，可以加入多个兴趣班

## 数据完整性约束

1. **级联删除**：
   - 删除租户时，级联删除所有相关数据
   - 删除年级时，级联删除所有班级
   - 删除用户时，级联删除教师/学生信息
   - 删除班级时，级联删除学生兴趣班关联

2. **限制删除**：
   - 删除部门时，如果存在教师，不允许删除（Restrict）
   - 删除班级时，如果存在学生，不允许删除（Restrict）

3. **唯一性约束**：
   - 租户内年级编码唯一
   - 租户内年级级别唯一
   - 租户内部门编码唯一
   - 租户内班级编码唯一
   - 租户内教师工号唯一
   - 租户内学生学号唯一

## 应用层验证建议

1. **班级类型验证**：
   - 创建学生时，`classId` 必须关联 `type=1` 的班级
   - 创建学生兴趣班关联时，`classId` 必须关联 `type=2` 的班级

2. **数据一致性**：
   - 教师/学生的 `tenantId` 必须与关联的 `User.tenantId` 一致
   - 班级的 `tenantId` 必须与关联的 `Grade.tenantId` 一致

3. **业务逻辑**：
   - 删除部门前，需要先转移或删除该部门下的所有教师
   - 删除班级前，需要先转移或删除该班级下的所有学生

## 迁移建议

1. 运行 Prisma 迁移生成 SQL：
   ```bash
   npx prisma migrate dev --name add_school_module
   ```

2. 数据初始化：
   - 为现有租户创建对应的 `School` 记录
   - 根据业务需求初始化年级数据

3. 数据迁移（如需要）：
   - 如果已有教师/学生数据，需要创建对应的 `User` 记录并关联

## 后续扩展建议

1. **课程管理**：可以添加课程表、课程安排等
2. **成绩管理**：可以添加成绩表、考试表等
3. **考勤管理**：可以添加考勤记录表
4. **通知公告**：可以添加通知表、公告表等

