forked from wangziqi/gongxue-base
docs: add P0 design spec and project APPEND_SYSTEM.md
This commit is contained in:
47
.omp/APPEND_SYSTEM.md
Normal file
47
.omp/APPEND_SYSTEM.md
Normal 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/` 下,每个模块独立目录
|
||||
302
docs/superpowers/specs/2026-07-05-gongxue-p0-design.md
Normal file
302
docs/superpowers/specs/2026-07-05-gongxue-p0-design.md
Normal 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_type(INTERNAL/RENTAL)/rental_id/status。
|
||||
|
||||
唯一约束:同教室 + 同 week_day + 时间段重叠 + status=active 拒绝写入(应用层检测 + 数据库层面依赖应用层保证,SQLite 不支持排他约束)。
|
||||
|
||||
### 核心规则
|
||||
|
||||
1. INTERNAL 排课:按班级维度,展示科目+教师,关联 class_id
|
||||
2. RENTAL 排课:仅标记教室占用,关联 rental_id(classroom_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',
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 模块 5:RBAC 权限扩展
|
||||
|
||||
`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 完成后并行。
|
||||
Reference in New Issue
Block a user