docs: add P0 design spec and project APPEND_SYSTEM.md

This commit is contained in:
2026-07-05 18:34:42 +08:00
parent b4c1d11cf2
commit ebacf8601f
2 changed files with 349 additions and 0 deletions

47
.omp/APPEND_SYSTEM.md Normal file
View File

@@ -0,0 +1,47 @@
# 恭学教育学生管理系统 — 项目约束
完整 PRD 文档:`../../Downloads/PRD-恭学教育学生管理系统.md`(相对项目根目录)
## 技术栈
| 层级 | 技术 |
|------|------|
| 架构 | Monorepo (Turborepo) |
| 前端 | React 19 + Vite + Ant Design 6 + ECharts |
| 后端 | NestJS 11 + TypeORM 0.3 + JWT + Passport |
| 数据库 | 开发 SQLite / 生产 MySQL 8 |
| 部署 | Docker Compose (MySQL + NestJS + Nginx) |
## 核心用户角色
- 超级管理员:系统配置、账号管理、全部数据
- 教职工(宿管+财务):宿舍管理、费用录入、账单生成、指定部门
- 班主任:本班学生信息、档案、费用、考勤
- 学生:仅本人数据
## 业务域
- 学员管理域:学生管理、学生档案、考勤管理
- 教务管理域:班级管理(新)、排课管理(新)、教师管理、教室管理
- 住宿管理域:宿舍管理、入住管理
- 财务运营域:费用管理、账单管理、押金管理、租赁方管理、数据面板
## 横切关注点
- RBAC 权限控制
- 操作日志(所有关键写操作)
- 钉钉/企业微信集成
- 报表导出、批量导入
## 上线优先级
**P0阻塞上线**:班级管理、排课管理、宿舍管理增强、账单管理(长租)、操作日志
**P1上线前完成**考勤管理前端、数据面板、RBAC 扩展、教室管理增强、organization→tenant_id
**P2可迭代**:报表导出、教师档案增强、多班型对比、押金分期、第三方集成
## 编码规范
- 所有涉及大量数据的列表/表单页面必须有详细的筛选方案
- 敏感信息(手机号、身份证)需脱敏展示,查看时二次确认+记录日志
- 遵循现有 NestJS 模块结构:每个业务模块独立目录,含 entity/dto/service/controller
- 前端页面放在 `apps/admin/src/pages/` 下,每个模块独立目录

View File

@@ -0,0 +1,302 @@
# 恭学教育学生管理系统 P0 批次 — 设计规格
> 版本v1.0
> 日期2026-07-05
> 基于 PRD`../../Downloads/PRD-恭学教育学生管理系统.md`commit `59f75bb`
## 目标
按 PRD 优先级分批实施,本批次覆盖 P0阻塞上线的全部 5 项 + 部分 P1上线前完成打通班级→排课→宿舍增强→操作日志→RBAC→考勤前端→数据面板的完整链路。
## 架构
Monorepo (Turborepo),后端 NestJS 11 + TypeORM 0.3 + SQLite/MySQL前端 React 19 + Vite + Ant Design 6 + ECharts。新增 `classes``schedules` 两个独立 NestJS 模块,在现有 `rooms`/`occupancies`/`bills` 模块上增量增强,考勤前端新建页面。遵循现有模块结构:每个业务模块独立目录,含 `entity`/`dto`/`service`/`controller`/`module`
## 技术栈
| 层级 | 技术 |
|------|------|
| 架构 | Monorepo (Turborepo) |
| 前端 | React 19 + Vite + Ant Design 6 + ECharts |
| 后端 | NestJS 11 + TypeORM 0.3 + JWT + Passport |
| 数据库 | 开发 SQLite / 生产 MySQL 8 |
| 测试 | Jest (后端) + Playwright (前端 E2E) |
## 全局约束
- 所有涉及大量数据的列表/表单页面必须有详细的筛选方案
- 敏感信息(手机号、身份证)需脱敏展示,查看时二次确认+记录操作日志
- 遵循现有 NestJS 模块结构,每个业务模块独立目录
- 前端页面放在 `apps/admin/src/pages/` 下,每个模块独立目录
- 表名使用复数形式(与现有 `students``rooms``classrooms``bills` 一致)
- 冲突检测使用数据库唯一约束 + 应用层双重保障
---
## 模块 1班级管理Class
### 实体
**`classes`**:班级主表,含 name/code/class_type/status/日期/教师/人数上限,通过 `department_id` 关联校区。
**`class_student`**:班级-学员关联,`UNIQUE(class_id, student_id)`,含 enroll_id/join_date/leave_date/status。
**`class_teacher`**:班级-教师关联,`UNIQUE(class_id, user_id, role_type)`,含 role_type任课老师/班主任/生活老师/学服老师)+ subject。
Class 自身的 `head_teacher_id`/`life_teacher_id`/`academic_teacher_id``class_teacher` 表保持同步——创建/编辑班级时,若传了 head_teacher_id 等字段,同时写入 class_teacher 表对应记录。
### API
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/classes` | 班级列表筛选department_id/status/class_type/keyword |
| POST | `/classes` | 创建班级(含初始教师/学员分配) |
| GET | `/classes/:id` | 班级详情(教师列表+学员统计) |
| PUT | `/classes/:id` | 编辑班级 |
| DELETE | `/classes/:id` | 删除班级CASCADE 删除关联) |
| GET | `/classes/:id/students` | 班级学员列表 |
| POST | `/classes/:id/students` | 批量添加学员 `{ studentIds: number[] }` |
| DELETE | `/classes/:id/students/:studentId` | 移除学员 |
| GET | `/classes/:id/teachers` | 班级教师列表 |
| POST | `/classes/:id/teachers` | 添加教师 `{ userId, roleType, subject? }` |
| DELETE | `/classes/:id/teachers/:userId` | 移除教师 |
### 前端
**列表页 `Classes/index.tsx`**:筛选栏(校区下拉/班型下拉/状态下拉/搜索输入)+ 表格(名称/编码/校区/班型/日期/学员数/班主任/状态Tag/操作)+ 分页。
**详情页 `Classes/Detail.tsx`**3 Tab — 基本信息(可编辑表单)、花名册(学员表格+批量添加/移除)、教师(教师表格+添加/移除)。
---
## 模块 2排课管理ClassSchedule
### 实体
**`class_schedule`**:排课记录,含 class_id/classroom_id/week_day/start_time/end_time/start_date/end_date/subject/teacher_id/schedule_typeINTERNAL/RENTAL/rental_id/status。
唯一约束:同教室 + 同 week_day + 时间段重叠 + status=active 拒绝写入(应用层检测 + 数据库层面依赖应用层保证SQLite 不支持排他约束)。
### 核心规则
1. INTERNAL 排课:按班级维度,展示科目+教师,关联 class_id
2. RENTAL 排课:仅标记教室占用,关联 rental_idclassroom_rentals
3. 冲突检测:新增/编辑时检查同教室同星期同时段是否已有 active 排课
4. 时段定义:预设 PRD 作息表(早自习 7:30-8:40、上午 9:00-12:00、下午 14:00-17:00、晚自习 18:30-21:00管理员可在系统设置中调整
### API
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/class-schedules` | 排课列表筛选classroom_id/class_id/week_day/date_range |
| POST | `/class-schedules` | 创建排课(含冲突检测) |
| PUT | `/class-schedules/:id` | 编辑排课(含冲突检测) |
| DELETE | `/class-schedules/:id` | 删除排课 |
| GET | `/class-schedules/weekly` | 周视图数据(按教室+week_day聚合 |
| GET | `/class-schedules/classroom/:id/occupancy` | 教室占用时间线(合并内部+外部) |
### 前端
**周视图 `Schedules/index.tsx`**:顶部周切换 + 教室/班级筛选,主体 7列×N行矩阵列=周一~周日,行=教室),每格显示科目/教师/时间。点击格子弹出排课表单 Modal班级/科目/教师/教室/星期/时段/日期范围)。冲突时 Modal 内红色提示。
---
## 模块 3宿舍/入住/账单增强
### 数据变更
**rooms**:新增 `rental_category`VARCHAR(10)long/short`monthly_rate`DECIMAL(10,2))。
**occupancies**:新增 `rental_type`VARCHAR(10)long/short`tenant_id`FK → tenants.id
**students**:新增 `tenant_id`FK → tenants.id替代原 `organization` 文本字段。迁移时根据 `organization` 匹配 `tenants.name`
### 账单逻辑
`POST /bills/generate` 内部:遍历宿舍的 occupancy 记录,`rental_type === 'long'` 的长租学生走固定月费独立生成(不参与分摊),`short` 学生走原人天数加权分摊。
### 前端
Rooms 表单增加 `rental_category` Select + `monthly_rate` InputNumber。Occupancies 表单增加 `rental_type` Select + `tenant_id` Select。
---
## 模块 4操作日志全量接入
### 覆盖范围
在以下 controller 的每个写操作中统一调用 `OperationLogsService.log()`
| 模块 | 审计操作 |
|------|---------|
| Classes | 创建/编辑/删除班级、添加/移除学员、添加/移除教师 |
| ClassSchedules | 创建/编辑/删除排课 |
| Students | 新增/编辑/删除学生、导入/导出、查看敏感信息 |
| Occupancies | 新增/编辑/退住 |
| Expenses | 新增/编辑/删除费用 |
| Bills | 生成账单、确认账单、标记已付、导出 |
| Deposits | 收取/退还押金 |
| Attendance | 补录/编辑考勤、匹配钉钉数据 |
| RBAC | 角色变更、权限变更 |
### 调用模式
```typescript
this.operationLogsService.log({
userId: req.user.id,
username: req.user.username,
module: 'CLASS',
action: 'CREATE',
targetId: result.id,
targetType: 'class',
detail: { name: result.name },
ipAddress: req.ip,
status: 'success',
});
```
---
## 模块 5RBAC 权限扩展
`permission.json` 新增以下节点:
| 权限节点 | super_admin | staff | class_teacher | student |
|----------|:---:|:---:|:---:|:---:|
| CLASS:READ | ✅ | ✅ | ✅ | - |
| CLASS:ADD | ✅ | ✅ | - | - |
| CLASS:UPDATE | ✅ | ✅ | - | - |
| CLASS:DELETE | ✅ | - | - | - |
| SCHEDULE:READ | ✅ | ✅ | ✅ | - |
| SCHEDULE:ADD | ✅ | ✅ | - | - |
| SCHEDULE:UPDATE | ✅ | ✅ | - | - |
| SCHEDULE:DELETE | ✅ | - | - | - |
| ATTENDANCE:READ | ✅ | ✅ | ✅ | ✅ |
| ATTENDANCE:ADD | ✅ | ✅ | - | - |
| ATTENDANCE:UPDATE | ✅ | ✅ | - | - |
---
## 模块 6考勤管理前端
### 页面
**列表页 `Attendance/index.tsx`**:筛选栏(班级/日期范围/时段/状态/来源)+ 表格(姓名/班级/日期/时段/状态Tag/来源/打卡时间/备注/操作)+ 批量补录按钮 + 切换到日历视图按钮。
**日历视图**:切换模式,行=学生、列=日期+时段,格=状态色块(绿=出勤、黄=迟到、红=缺勤、蓝=请假)。
### API
增强现有 `/attendance-records` 筛选参数,新增:
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/attendance-records/batch` | 批量补录 |
| GET | `/attendance-records/summary` | 考勤汇总统计(按班级/日期范围) |
| GET | `/attendance-records/calendar` | 日历视图数据 |
| GET | `/ding-attendance-raw` | 钉钉原始数据列表筛选match_status |
| POST | `/ding-attendance-raw/:id/match` | 手动匹配钉钉数据到学生 |
---
## 模块 7数据面板增强
在现有 Dashboard 的基础上:
- **第二行指标卡**:教室总数/占用率、今日出勤率、本月收入总额、教室占用率
- **新增图表**考勤趋势折线图近30天、近6月收入趋势图
- **权限控制**:不同角色看到不同指标——班主任只看本班考勤,超管看全局
### API
`GET /dashboard` 返回数据增加字段:`classroomCount`/`classroomOccupancyRate`/`todayAttendanceRate`/`monthlyIncome`/`attendanceTrend`/`incomeTrend`
---
## 数据库迁移
### 新增表
`classes``class_student``class_teacher``class_schedule` — TypeORM `synchronize: true` 自动建表。
### 现有表变更
```sql
ALTER TABLE rooms ADD COLUMN rental_category VARCHAR(10) DEFAULT 'short';
ALTER TABLE rooms ADD COLUMN monthly_rate DECIMAL(10,2) DEFAULT 0;
ALTER TABLE occupancies ADD COLUMN rental_type VARCHAR(10) DEFAULT 'short';
ALTER TABLE occupancies ADD COLUMN tenant_id INTEGER REFERENCES tenants(id);
ALTER TABLE students ADD COLUMN tenant_id INTEGER REFERENCES tenants(id);
```
### 数据迁移
`students.organization``students.tenant_id`:遍历 students 表,根据 `organization` 文本匹配 `tenants.name`,匹配到的写入 tenant_id未匹配的置 NULL。原 `organization` 列保留不删,待后续迭代清理。
---
## 文件结构
```
apps/server/src/
├── entities/
│ ├── class.entity.ts 🆕
│ ├── class-student.entity.ts 🆕
│ ├── class-teacher.entity.ts 🆕
│ ├── class-schedule.entity.ts 🆕
│ ├── room.entity.ts ✏️
│ ├── occupancy.entity.ts ✏️
│ ├── student.entity.ts ✏️
│ └── index.ts ✏️
├── classes/ 🆕
│ ├── classes.module.ts
│ ├── classes.controller.ts
│ ├── classes.service.ts
│ └── dto/
├── schedules/ 🆕
│ ├── schedules.module.ts
│ ├── schedules.controller.ts
│ ├── schedules.service.ts
│ └── dto/
├── rooms/ ✏️ dto
├── occupancies/ ✏️ dto + service
├── bills/ ✏️ service
├── operation-logs/ ✏️ 注入各模块
├── rbac/ ✏️ permission.json
├── dashboard/ ✏️ service + controller
└── app.module.ts ✏️ 注册新模块
apps/admin/src/pages/
├── Classes/ 🆕
│ ├── index.tsx
│ └── Detail.tsx
├── Schedules/ 🆕
│ └── index.tsx
├── Attendance/ 🆕
│ └── index.tsx
├── Dashboard/ ✏️ index.tsx
├── Rooms/ ✏️ index.tsx
└── Occupancies/ ✏️ index.tsx
```
---
## 开发顺序
```
Phase 1 班级管理(无上游依赖)
Phase 2 排课管理(依赖班级+教室)
Phase 3 宿舍/入住/账单增强独立可与1/2并行
Phase 4 操作日志全量接入依赖1/2/3的controller就绪
Phase 5 RBAC权限扩展依赖1/2模块存在
Phase 6 考勤管理前端后端API已有独立开发
Phase 7 数据面板增强(依赖各方面数据)
```
Phase 1-3 可部分并行Phase 4-5 需等 1-3 完成Phase 6-7 可在 1-5 完成后并行。