Files
gongxue-base/docs/superpowers/specs/2026-07-05-gongxue-p0-design.md

12 KiB
Raw Blame History

恭学教育学生管理系统 P0 批次 — 设计规格

版本v1.0
日期2026-07-05
基于 PRD../../Downloads/PRD-恭学教育学生管理系统.mdcommit 59f75bb

目标

按 PRD 优先级分批实施,本批次覆盖 P0阻塞上线的全部 5 项 + 部分 P1上线前完成打通班级→排课→宿舍增强→操作日志→RBAC→考勤前端→数据面板的完整链路。

架构

Monorepo (Turborepo),后端 NestJS 11 + TypeORM 0.3 + SQLite/MySQL前端 React 19 + Vite + Ant Design 6 + ECharts。新增 classesschedules 两个独立 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/ 下,每个模块独立目录
  • 表名使用复数形式(与现有 studentsroomsclassroomsbills 一致)
  • 冲突检测使用数据库唯一约束 + 应用层双重保障

模块 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_idclass_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.tsx3 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_categoryVARCHAR(10)long/shortmonthly_rateDECIMAL(10,2))。

occupancies:新增 rental_typeVARCHAR(10)long/shorttenant_idFK → tenants.id

students:新增 tenant_idFK → 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 角色变更、权限变更

调用模式

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


数据库迁移

新增表

classesclass_studentclass_teacherclass_schedule — TypeORM synchronize: true 自动建表。

现有表变更

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.organizationstudents.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 完成后并行。