# 恭学教育学生管理系统 — 产品需求文档 (PRD) > 版本:v1.0 > 日期:2026-07-03 > 状态:待评审 > 基于代码审查 commit:`59f75bb` --- ## 目录 1. [系统概述](#1-系统概述) 2. [域模型全景图](#2-域模型全景图) 3. [模块 1:学生管理](#3-模块-1学生管理) 4. [模块 2:学生档案](#4-模块-2学生档案) 5. [模块 3:班级管理](#5-模块-3班级管理-新模块) 6. [模块 4:排课管理](#6-模块-4排课管理-新模块) 7. [模块 5:教师管理](#7-模块-5教师管理) 8. [模块 6:教室管理](#8-模块-6教室管理) 9. [模块 7:宿舍管理](#9-模块-7宿舍管理) 10. [模块 8:入住管理](#10-模块-8入住管理) 11. [模块 9:费用管理](#11-模块-9费用管理) 12. [模块 10:账单管理](#12-模块-10账单管理) 13. [模块 11:押金管理](#13-模块-11押金管理) 14. [模块 12:租赁方管理](#14-模块-12租赁方管理) 15. [模块 13:考勤管理](#15-模块-13考勤管理) 16. [模块 14:数据面板](#16-模块-14数据面板) 17. [横切关注点:RBAC 权限](#17-横切关注点rbac-权限) 18. [横切关注点:操作日志](#18-横切关注点操作日志) 19. [横切关注点:第三方集成](#19-横切关注点第三方集成) 20. [横切关注点:报表导出](#20-横切关注点报表导出) 21. [现有代码 vs 目标状态 差距总览](#21-现有代码-vs-目标状态-差距总览) 22. [上线优先级排序](#22-上线优先级排序) 23. [待澄清问题](#23-待澄清问题) --- ## 1. 系统概述 ### 1.1 项目定位 恭学教育学生管理系统是一个面向教培集训基地的综合管理平台,覆盖**学员管理、教务排课、住宿运营、财务计费**四大业务域,支撑从学员入学、分班、排课、考勤、住宿、计费到结课归档的全生命周期管理。 ### 1.2 核心用户角色 | 角色 | 职责 | 数据范围 | |------|------|----------| | 超级管理员 | 系统配置、账号管理、角色分配 | 全部数据 | | 教职工(宿管+财务) | 宿舍管理、费用录入、账单生成、押金管理 | 指定部门 + 子部门 | | 班主任 | 查看本班学生信息、档案、费用、考勤 | 本班及下级班级 | | 学生 | 查看个人信息、账单、押金 | 仅本人 | 默认导入的用户都是学生权限,需要更高权限往往是由超管去为该角色分配。权限的配置很灵活,因为涉及多种老师,生活老师(宿管)、班主任(可看考勤和管理自己班级的学生) ### 1.3 技术栈 | 层级 | 技术 | |------|------| | 架构 | Monorepo (Turborepo) | | 前端 | React 19 + Vite + Ant Design 6 + ECharts | | 后端 | NestJS 11 + TypeORM 0.3 + JWT + Passport | | 数据库 | 开发 SQLite / 生产 MySQL 8 | | 集成 | 钉钉开放平台 API + 企业微信 API | | 部署 | Docker Compose (MySQL + NestJS + Nginx) | | 测试 | Jest (后端) + Playwright (前端 E2E) | --- ## 2. 域模型全景图 ``` ┌──────────────────────────────────────────────────────────────────────┐ │ 恭学教育学生管理系统 │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │ │ │ 学员管理域 │ │ 教务管理域 │ │ 住宿管理域 │ │ 财务运营域│ │ │ │ │ │ │ │ │ │ │ │ │ │ 1.学生管理 │ │ 3.班级管理 🆕 │ │ 7.宿舍管理 │ │ 9.费用管理│ │ │ │ 2.学生档案 │ │ 4.排课管理 🆕 │ │ 8.入住管理 │ │ 10.账单管理│ │ │ │ 13.考勤管理 │ │ 5.教师管理 │ │ │ │ 11.押金管理│ │ │ │ │ │ 6.教室管理 │ │ │ │ 12.租赁方 │ │ │ │ │ │ │ │ │ │ 14.数据面板│ │ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────────┐ │ │ │ 横切:RBAC权限 · 操作日志 · 钉钉/企微集成 · 报表/导出· 导入模板│ │ │ └───────────────────────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────────────────────────┘ ``` ### 核心实体关系 ``` User ──┬── Student ──┬── StudentProfile (1:1) │ ├── StudentEnrollment (1:N) ── 关联 Class │ ├── ExamScore (1:N) │ ├── AttendanceRecord (1:N) ←── DingAttendanceRaw │ ├── LearningRecord (1:N) │ ├── ResultArchive (1:N) │ ├── ArchiveAttachment (1:N) │ ├── StudentReport (1:N) │ ├── Occupancy (1:N) ── Room │ ├── PersonalExpense (1:N) │ └── Bill (1:N) ── BillItem (1:N) │ ├── Department ──┬── DepartmentCommander (用户-部门负责人) │ └── DepartmentSubstitute (教师代管) │ └── Role ── RolePermission ── Menu Class (🆕) ──┬── ClassStudent ── Student ├── ClassTeacher ── User └── ClassSchedule (🆕) ── Classroom Room ──┬── Occupancy ── Student ├── RoomExpense └── (rental_category: long/short) Classroom ──┬── ClassroomRental ── Tenant └── ClassSchedule (🆕) ── Class Tenant ──┬── ClassroomRental └── Occupancy.tenant_id (🆕) ``` --- ## 3. 模块 1:学生管理 ### 3.1 概述 管理所有学员的基本信息,是系统最核心的基础数据。学生与 `User`(登录账号)通过 `user_id` 一对一关联,与钉钉/企微用户通过 `resource_user_id` 关联。 ### 3.2 现有实现 | 项目 | 状态 | |------|:---:| | 数据模型 `students` | ✅ | | 后端 CRUD API | ✅ | | Excel 批量导入/导出 | ✅ | | 前端列表/搜索/筛选 | ✅ | | 与 User 关联 (userId) | ✅ | | 与钉钉/企微关联 (resourceUserId) | ✅ | ### 3.3 数据模型 ``` students ├── id (PK) ├── user_id FK → users.id (UNIQUE) ├── name, phone, id_card (INDEX), student_no (INDEX) ├── gender, ethnicity ├── emergency_contact, emergency_phone ├── status (active/inactive/graduated) ├── organization → 🆕 改为 tenant_id FK → tenants.id ├── supervisor (负责人) ├── resource_user_id (钉钉/企微 userid) ├── department_id FK → sys_department.id ├── created_at, updated_at ``` ### 3.4 待实现 | 编号 | 需求 | 优先级 | 说明 | |:---:|------|:---:|------| | 1.1 | `organization` 改为 `tenant_id` 外键 | P1 | 当前是纯文本,无法关联 Tenant 表做筛选统计 | | 1.2 | 按机构维度筛选学生 | P1 | 依赖 1.1 | | 1.3 | 敏感信息查看需二次确认 + 日志 | P1 | phone/idCard 脱敏展示,点击查看需确认弹窗 + 记录操作日志 | 各种涉及表单或者列表或是大量数据的页面都需要有非常详细的筛选方案,方便我们快速筛查检索需要的信息,或批量进行控制。 ### 3.5 用户故事 - 教务老师通过 Excel 模板批量导入 200 名历史学员 - 从钉钉同步后,自动创建 Student 档案并关联 User - 在学员列表按"合作机构 A"筛选,导出该机构所有在读学员 ### 3.6 状态说明 ``` active — 在读 inactive — 已离校 graduated — 已毕业/结课 ``` --- ## 4. 模块 2:学生档案 ### 4.1 概述 学生档案是学员全生命周期数据的聚合视图,包含报读信息、考试成绩、出勤记录、学情记录、最终录取结果、附件、报告版本。 ### 4.2 现有实现 | 项目 | 状态 | |------|:---:| | 8 张档案子表 CRUD | ✅ | | 档案聚合查询 API | ✅ | | PDF 报表生成(Chrome headless) | ✅ | | HTML 报表预览 | ✅ | | Excel 模板导入(预览→确认两步) | ✅ | | 敏感信息脱敏(身份证/电话) | ✅ | | 出勤汇总 + 考试汇总 | ✅ | ### 4.3 数据模型(全部已实现) ``` student_profiles — 扩展档案(院校/专业/科类/年级/校区/建档日期) student_enrollments — 报读记录(课程类别/班型/班级/班主任/任课老师/开结课日期) exam_scores — 考试成绩(类型/名称/科目/分数/班级平均/排名) attendance_records — 出勤记录(日期/时段/状态/来源/备注) learning_records — 学情记录(日期/类型/内容/跟进方式/下一步) result_archives — 录取归档(文化课/专业课最终成绩/录取状态/院校/专业) archive_attachments — 附件(成绩截图/录取截图/协议等) student_reports — 报告版本(快照数据/PDF/HTML/生成时间) ``` ### 4.4 待优化 | 编号 | 需求 | 优先级 | 说明 | |:---:|------|:---:|------| | 2.1 | 多班型(3+ enrollment)档案封面展示不完整 | P2 | 当前只展示前 2 个 enrollment 的卡片 | | 2.2 | 报表支持"多班型对比视图" | P2 | 同一学生文化课 vs 专业课独立对比报表 | ### 4.5 报表内容(多页 A4) 1. **封面**:学员姓名、身份证号、科类方向、报考院校/专业、班主任、建档日期 2. **基础信息**:个人信息 + 升学意向 + 文化课报读 + 专业课报读 3. **入学测评与阶段概览**:入学测试总分、阶段最高分、总分提升、趋势 SVG 图 4. **出勤记录与过程跟踪**:出勤率、请假/缺勤统计、出勤明细矩阵、出勤记录需要覆盖整个学习周期 5. **文化课测评成绩**:周测/月测/模考总分表、冲刺分科进度条、分科观察 6. **专业课测评与阶段记录**:模考总分、分项提升柱状图、学情记录、待补充归档清单 --- ## 5. 模块 3:班级管理 🆕 新模块 ### 5.1 概述 班级是排课、考勤、教师分配的核心组织单元。当前系统用 `Department`(type="class")间接承载班级概念,需独立建模。 ### 5.2 现有实现 | 项目 | 状态 | |------|:---:| | Department.type = "class" 表示班级 | ⚠️ 间接实现 | | DepartmentCommander 记录班级负责人 | ⚠️ 间接实现 | | StudentEnrollment 包含 classType/className | ⚠️ 文本字段 | ### 5.3 需要新增的数据模型 ``` class(班级,表名待定避免关键字冲突,如 classes / sys_class) ├── id (PK) ├── name — 班级名称,如 "2026届文化课冲刺1班" ├── code — 班级编码(唯一) ├── department_id FK — 所属校区/部门 ├── class_type — 班型:文化课 / 专业课 / 集训营 / 冲刺营 ├── start_date — 开班日期 ├── end_date — 结课日期 ├── status — 招生中 / 在读 / 结课 / 停课 ├── head_teacher_id FK → users (班主任) ├── life_teacher_id FK → users (生活老师) ├── academic_teacher_id FK → users (学服老师) ├── max_students — 班级人数上限 ├── notes ├── created_at, updated_at class_student(班级学员关联) ├── id (PK) ├── class_id FK ├── student_id FK ├── enrollment_id FK — 关联 student_enrollments ├── join_date, leave_date ├── status (active/left) ├── created_at class_teacher(班级教师关联) ├── id (PK) ├── class_id FK ├── user_id FK ├── role_type — 任课老师 / 班主任 / 生活老师 / 学服老师 ├── subject — 任教科目(任课老师时必填) ├── created_at ``` ### 5.4 用户故事 | 编号 | 故事 | |:---:|------| | 3.1 | 教务老师创建"2026届文化课冲刺1班",指定班主任张三、生活老师李四、学服老师王五 | | 3.2 | 为该班级批量添加 35 名学员 | | 3.3 | 为该班级分配任课教师:语文-赵老师、数学-钱老师、英语-孙老师 | | 3.4 | 查看班级花名册(学员列表 + 教师列表) | | 3.5 | 查看班级出勤汇总(出勤率/缺勤率/迟到率) | ### 5.5 API 设计 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/classes` | 班级列表(支持按 department_id/status/class_type 筛选) | | POST | `/classes` | 创建班级 | | GET | `/classes/:id` | 班级详情(含教师列表、学员统计) | | PUT | `/classes/:id` | 编辑班级 | | DELETE | `/classes/:id` | 删除班级 | | GET | `/classes/:id/students` | 班级学员列表 | | POST | `/classes/:id/students` | 添加学员到班级 | | DELETE | `/classes/:id/students/:studentId` | 移除学员 | | GET | `/classes/:id/teachers` | 班级教师列表 | | POST | `/classes/:id/teachers` | 添加教师到班级 | | DELETE | `/classes/:id/teachers/:userId` | 移除教师 | | GET | `/classes/:id/schedule` | 班级课表 | | GET | `/classes/:id/attendance-summary` | 班级出勤汇总 | --- ## 6. 模块 4:排课管理 🆕 新模块 ### 6.1 概述 管理内部班级在教室中的排课安排。与外部租赁不同:外部租赁只需知道"哪个教室被哪个租赁方占用",内部排课需要知道"哪个班级、什么科目、哪位教师、在哪个教室、什么时段"。 ### 6.2 现有实现 | 项目 | 状态 | |------|:---:| | 排课实体/API/页面 | ❌ 完全缺失 | | StudentEnrollment.scheduleType | ⚠️ 仅为文本字段 | ### 6.3 需要新增的数据模型 ``` class_schedule(排课记录) ├── id (PK) ├── class_id FK — 关联班级 ├── classroom_id FK — 关联教室 ├── week_day — 星期几 (1=周一 ~ 7=周日) ├── start_time — 开始时间 (HH:mm) ├── end_time — 结束时间 (HH:mm) ├── start_date — 排课生效开始日期 ├── end_date — 排课生效结束日期 ├── subject — 科目 ├── teacher_id FK → users — 任课教师 ├── schedule_type — INTERNAL(内部排课)/ RENTAL(外部租赁,关联 ClassroomRental) ├── rental_id FK — 当 schedule_type=RENTAL 时关联 classroom_rentals.id ├── status — active / cancelled ├── notes ├── created_at, updated_at ``` **唯一约束:** 同一教室 + 同一 week_day + 时间段重叠 + status=active 不能有两条记录(排课冲突检测)。 ### 6.4 核心规则 1. **冲突检测**:新增排课时检查同一教室同一时间段是否已被占用 2. **INTERNAL vs RENTAL**: - 内部排课:按班级维度管理,展示科目+教师 - 外部租赁:仅标记教室占用,不涉及班级/教师信息 3. **排课视图**: - 周视图(7 天 × 时间段 矩阵,每个格子显示科目+教师) - 月视图(日历形式,点击日期展开当日排课) ### 6.5 用户故事 | 编号 | 故事 | |:---:|------| | 4.1 | 教务老师为"冲刺1班"在 301 教室安排「周一至周五 8:00-12:00 语文课」,教师赵老师 | | 4.2 | 系统检测到 301 教室周一 8:00-10:00 已被"基础班"占用,提示冲突 | | 4.3 | 班主任打开本班课表,看到一周的课程安排 | | 4.4 | 管理员打开教室占用视图,看到每个教室各时段的使用情况(内部排课 + 外部租赁) | ### 6.6 API 设计 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/class-schedules` | 排课列表(支持 classroom_id/class_id/week_day/date 筛选) | | POST | `/class-schedules` | 创建排课(含冲突检测) | | PUT | `/class-schedules/:id` | 编辑排课 | | DELETE | `/class-schedules/:id` | 删除排课 | | GET | `/class-schedules/weekly` | 周视图数据(按教室+星期几聚合) | | GET | `/class-schedules/classroom/:id/occupancy` | 某教室的占用时间线 | --- ## 7. 模块 5:教师管理 ### 7.1 概述 教师是 User 的一种角色,需要管理其与班级的关联、任教学科信息。 ### 7.2 现有实现 | 项目 | 状态 | |------|:---:| | User 表 + 角色(class_teacher/staff) | ✅ | | DepartmentCommander(部门-用户负责人) | ✅ | | DepartmentSubstitute(教师代管) | ✅ | | 教师档案(学科/资质) | ❌ | | 教师-班级显式关联 | ❌ | ### 7.3 待增强 | 编号 | 需求 | 优先级 | 说明 | |:---:|------|:---:|------| | 5.1 | `user_extend` 增加教师档案字段 | P2 | 任教学科、入职日期、资质等(JSON 扩展或独立字段) | | 5.2 | 班级模块中的 `class_teacher` 建立显式关联 | P0 | 依赖班级模块 | | 5.3 | 教师工作台视图 | P2 | 查看自己所带班级课表、学员列表、出勤统计 | ### 7.4 教师角色的业务含义 | 角色类型 | 职责 | |----------|------| | 任课老师 | 负责特定科目的教学,关联到班级+科目 | | 班主任 (head_teacher) | 班级主要负责人,关注学员全面情况 | | 生活老师 | 负责学员日常起居管理 | | 学服老师 | 学习服务跟进,学情记录 | --- ## 8. 模块 6:教室管理 ### 8.1 概述 管理教室资源,区分内部使用和外部租赁两种场景。 ### 8.2 现有实现 | 项目 | 状态 | |------|:---:| | classrooms 表 + CRUD | ✅ | | 教室列表/筛选 | ✅ | | 教室租赁排期可视化 (ClassroomSchedule) | ✅ | ### 8.3 数据模型(现有) ``` classrooms ├── id (PK) ├── name, building, floor, capacity ├── room_type (大/次大/小) ├── course_type, supervisor ├── status (available/in_use/maintenance) ├── notes, created_at ``` ### 8.4 待增强 | 编号 | 需求 | 优先级 | 说明 | |:---:|------|:---:|------| | 6.1 | 教室占用状态整合排课数据 | P1 | 当前只看外部租赁,需合并内部排课计算综合占用率 | | 6.2 | ClassroomSchedule 区分内部排课 vs 外部租赁 | P1 | 颜色/标签区分两种使用类型 | | 6.3 | 教室利用率统计 | P2 | 内部 + 外部的综合指标 | --- ## 9. 模块 7:宿舍管理 ### 9.1 概述 管理宿舍房间资源,支持长租和短租两种模式,支持合作机构标记。 ### 9.2 现有实现 | 项目 | 状态 | |------|:---:| | rooms 表 + CRUD | ✅ | | 宿舍总览可视化 (RoomVisual) | ✅ | | 长租/短租区分 | ❌ | | 合作机构标记 | ❌ | ### 9.3 数据模型变更 ``` rooms (现有字段 + 新增) ├── room_number, building, floor, capacity, status, gender ├── room_type (现有,文本) ├── 🆕 rental_category — long / short (长租/短租) ├── 🆕 monthly_rate — 月租金(长租时使用,decimal) ├── created_at occupancies (现有字段 + 新增) ├── student_id, room_id ├── check_in_date, check_out_date ├── billing_start_date, billing_end_date ├── check_out_reason, notes ├── 🆕 rental_type — long / short (继承自 Room 或独立设置) ├── 🆕 tenant_id FK → tenants.id (合作机构) ├── created_at ``` ### 9.4 业务规则 | 场景 | 规则 | |------|------| | 长租 | 按月固定费用计费,不参与人天数分摊,独立生成月度账单 | | 短租 | 按天计费,参与人天数加权分摊 | | 混合宿舍 | 同一宿舍可能有长租+短租学生,分摊时分别处理 | ### 9.5 待实现 | 编号 | 需求 | 优先级 | 说明 | |:---:|------|:---:|------| | 7.1 | Room 增加 rental_category + monthly_rate | P0 | 数据模型变更 + 迁移脚本 | | 7.2 | Occupancy 增加 rental_type + tenant_id | P0 | 数据模型变更 | | 7.3 | 宿舍总览页增加机构颜色标记 | P1 | 按 tenant.color 着色 | | 7.4 | 长租独立账单生成逻辑 | P0 | 账单生成时区分 rental_type | ### 9.6 用户故事 - 宿管老师将 401 设为"长租宿舍",月费 800 元/人,402 为"短租宿舍" - 学生 A(来自机构 X)入住 401 长租,学生 B(来自机构 Y)入住 402 短租 - 宿舍总览页以机构颜色区分显示 - 生成账单时,401 长租学生生成「月固定费用」账单,402 短租学生参与人天数分摊 --- ## 10. 模块 8:入住管理 ### 10.1 现有实现 | 项目 | 状态 | |------|:---:| | occupancies 表 + CRUD | ✅ | | 入住/退住日期管理 | ✅ | | 计费起止日期独立管理 | ✅ | ### 10.2 待优化 | 编号 | 需求 | 优先级 | |:---:|------|:---:| | 8.1 | 入住时自动拉取学生当前 enrollment 信息 | P2 | | 8.2 | 批量退住操作 | P2 | | 8.3 | 入住历史时间线视图 | P2 | --- ## 11. 模块 9:费用管理 ### 11.1 现有实现 | 项目 | 状态 | |------|:---:| | room_expenses(宿舍公摊费) | ✅ | | personal_expenses(个人附加费) | ✅ | ### 11.2 费用类型(当前支持) ``` water — 水费 electricity — 电费 cleaning — 保洁费 damage — 损坏赔偿 penalty — 罚款 key — 钥匙费 remote — 空调遥控器 deposit_deduction — 押金扣除 other — 其他 ``` ### 11.3 待优化 | 编号 | 需求 | 优先级 | 说明 | |:---:|------|:---:|------| | 9.1 | 费用类型可配置化 | P2 | 当前硬编码,支持管理员自定义费用类型 | --- ## 12. 模块 10:账单管理 ### 12.1 核心计费算法 **人天数加权分摊:** 1. 取某宿舍在计费周期内的所有入住记录 2. 计算每个学生的计费天数(billingStartDate ~ billingEndDate 与 周期 overlap) 3. 每项房间费用按「该学生人天数 / 总人天数」比例分摊 4. 加上学生的个人附加费 → 账单总额 ### 12.2 现有实现 | 项目 | 状态 | |------|:---:| | 人天数加权分摊引擎 | ✅ | | 押金联动(自动计算押金抵扣) | ✅ | | 账单状态管理(draft/confirmed/paid) | ✅ | | Excel 导出 | ✅ | ### 12.3 待实现 | 编号 | 需求 | 优先级 | 说明 | |:---:|------|:---:|------| | 10.1 | 长租模式账单生成 | P0 | 按月固定费直接生成,不参与分摊 | | 10.2 | 账单通知推送 | P2 | 钉钉/企微通知学生账单已生成 | --- ## 13. 模块 11:押金管理 ### 13.1 现有实现 | 项目 | 状态 | |------|:---:| | deposits 表 + CRUD | ✅ | | 押金-账单联动 | ✅ | ### 13.2 待优化 | 编号 | 需求 | 优先级 | 说明 | |:---:|------|:---:|------| | 11.1 | 押金分期管理 | P2 | 多次入住/退住场景的押金历史追溯 | | 11.2 | 押金退还审批流 | P2 | 多级确认 | --- ## 14. 模块 12:租赁方管理 ### 14.1 现有实现 | 项目 | 状态 | |------|:---:| | tenants 表 + CRUD | ✅ | | 颜色标记(可视化) | ✅ | ### 14.2 数据模型(现有) ``` tenants ├── id (PK) ├── name, contact, phone ├── color (可视化颜色 hex) ├── notes, status (active/archived) ├── created_at, updated_at ``` --- ## 15. 模块 13:考勤管理 ### 15.1 概述 考勤数据有两个来源: 1. **钉钉打卡机自动同步**:Stream 事件 → ding_attendance_raw → 匹配 Student → attendance_records 2. **人工补录**:通过系统手动添加考勤记录 ### 15.2 现有实现 | 项目 | 状态 | |------|:---:| | 钉钉 Stream 打卡事件处理 | ✅ | | 原始数据落库 ding_attendance_raw | ✅ | | Student 匹配(resourceUserId) | ✅ | | 出勤记录写入 attendance_records | ✅ | | 人工补录 API(StudentArchives 子模块) | ✅ | | **前端考勤管理页面** | ❌ | | 考勤统计 | ⚠️ 仅个人档案中有汇总 | ### 15.3 数据模型(全部已实现) ``` attendance_records ├── student_id, attendance_date, session (早自习/上午/下午/晚自习/晚寝) ├── course_name, expected_time, actual_time ├── status (出勤/迟到/早退/事假/病假/缺勤/未填) ├── leave_type, late_minutes ├── source (钉钉/人工点名/Excel导入/系统补录) ├── source_record_id, confirmed_by, remark ├── created_at, updated_at ding_attendance_raw ├── ding_user_id, phone, source_record_id ├── check_time, raw_status ├── match_status (未处理/已匹配/待匹配) ├── raw_json (完整钉钉推送数据) ├── created_at ``` ### 15.4 待实现 | 编号 | 需求 | 优先级 | 说明 | |:---:|------|:---:|------| | 13.1 | **前端考勤管理页面** | P1 | 按日期/班级/状态筛选、批量补录、查看原始钉钉数据 | | 13.2 | 考勤日历视图 | P1 | 类似 ClassroomSchedule 的矩阵布局,行=学生,列=日期+时段 | | 13.3 | 班级考勤总览 | P1 | 按班级统计出勤率/缺勤率/迟到率,支持导出 | | 13.4 | 异常考勤预警 | P2 | 连续缺勤/迟到超过阈值自动标记 | | 13.5 | 未匹配钉钉数据处理 | P1 | 展示 match_status=待匹配 的数据,手动关联到 Student | | 13.6 | 考勤数据纳入 Dashboard | P1 | 全局出勤率、缺勤趋势 | ### 15.5 前端页面设计 **考勤管理页:** - 顶部筛选栏:班级、日期范围、时段、状态、来源 - 数据表格:姓名、班级、日期、时段、状态、来源、打卡时间、备注 - 批量操作:批量标记出勤/请假 - 切换到日历视图按钮 **考勤日历视图:** ``` 周一 周二 周三 周四 周五 张三 到 到 假 到 到 李四 到 到 到 迟 到 王五 缺 到 到 到 到 ``` ### 15.6 API 设计 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/attendance-records` | 考勤列表(已有,需增强筛选参数) | | POST | `/attendance-records` | 新增考勤记录(已有) | | PUT | `/attendance-records/:id` | 编辑考勤记录(已有) | | DELETE | `/attendance-records/:id` | 删除考勤记录(已有) | | POST | `/attendance-records/batch` | 🆕 批量补录 | | GET | `/attendance-records/summary` | 🆕 考勤汇总统计 | | GET | `/attendance-records/calendar` | 🆕 日历视图数据 | | GET | `/ding-attendance-raw` | 🆕 钉钉原始数据列表 | | POST | `/ding-attendance-raw/:id/match` | 🆕 手动匹配钉钉数据到学生 | --- ## 16. 模块 14:数据面板 ### 16.1 概述 系统总览仪表盘,用可视化图表展示各业务域关键指标。 ### 16.2 现有实现 | 项目 | 状态 | |------|:---:| | 4 个宿舍指标卡 | ✅ | | 宿舍入住甘特图 | ✅ | | 费用类型饼图 | ✅ | | 宿舍费用排行 | ✅ | | 教室/考勤/收入指标 | ❌ | ### 16.3 待实现 | 编号 | 需求 | 优先级 | 说明 | |:---:|------|:---:|------| | 14.1 | 第二行指标卡 | P1 | 教室总数/占用率、本月出勤率、本月收入总额 | | 14.2 | 教室排期热力图 | P2 | 各教室本月占用率颜色热力 | | 14.3 | 考勤趋势线 | P1 | 近 30 天全局出勤率变化 | | 14.4 | 收入趋势图 | P1 | 近 6 个月账单收入趋势(宿舍+教室租赁) | | 14.5 | 班级出勤率排行 | P2 | TOP/BOTTOM 班级出勤率 | ### 16.4 目标布局 ``` ┌──────────────┬──────────────┬──────────────┬──────────────┐ │ 宿舍总数 │ 在读学员 │ 当前在住 │ 入住率 │ │ 120 │ 856 │ 342 / 480 │ 71.3% │ ├──────────────┼──────────────┼──────────────┼──────────────┤ │ 教室总数 │ 今日出勤率 │ 出勤学生 │ 教室占用率 │ │ 28 │ 92.5% │ 666 人 │ 64.8% │ └──────────────┴──────────────┴──────────────┴──────────────┘ ┌─────────────────────────┐ ┌─────────────────────────┐ │ 入住时间线(甘特图) │ │ 考勤趋势(折线图) │ └─────────────────────────┘ └─────────────────────────┘ ┌─────────────────────────┐ ┌─────────────────────────┐ │ 费用类型分布(饼图) │ │ 教室占用趋势(柱状图) │ └─────────────────────────┘ └─────────────────────────┘ ``` --- ## 17. 横切关注点:RBAC 权限 ### 17.1 现有实现 | 项目 | 状态 | |------|:---:| | roles / role_permissions / menus 表 | ✅ | | permission.json(7 个模块) | ✅ | | JWT Guard + API Key Guard + Permissions Guard | ✅ | | DataScope Interceptor(数据范围控制) | ✅ | | 4 个预置角色 | ✅ | ### 17.2 权限矩阵(当前) | 权限节点 | super_admin | staff | class_teacher | student | |----------|:---:|:---:|:---:|:---:| | STUDENT:READ | ✅ | ✅ | ✅ | - | | STUDENT:ADD/UPDATE | ✅ | ✅ | - | - | | STUDENT:DELETE | ✅ | ❌ | - | - | | STUDENT:IMPORT/EXPORT | ✅ | ✅ | ✅ | - | | DORMITORY:* | ✅ | ✅ | - | - | | CHECKIN:* | ✅ | ✅ | - | - | | FEE:READ | ✅ | ✅ | ✅ | - | | FEE:ADD/UPDATE/DELETE | ✅ | ✅ | - | - | | BILL:GENERATE | ✅ | ✅ | - | - | | BILL:CONFIRM/MARK_PAID | ✅ | ✅ | - | - | | BILL:READ | ✅ | ✅ | ✅ | ✅ | | BILL:EXPORT | ✅ | ✅ | ✅ | ✅ | | CLASSROOM:* | ✅ | ✅ | - | - | | DEPOSIT:COLLECT/REFUND | ✅ | ✅ | - | - | | DEPOSIT:READ | ✅ | ✅ | ✅ | ✅ | | ARCHIVE:READ | ✅ | ✅ | ✅ | ✅ | | ARCHIVE:IMPORT | ✅ | ✅ | - | - | | ARCHIVE:EXPORT | ✅ | ✅ | - | - | | REPORT:GENERATE | ✅ | ✅ | - | - | | OPERATION_LOG:READ | ✅ | ✅ | - | - | | DASHBOARD:READ | ✅ | ✅ | ✅ | ✅ | ### 17.3 待补全 | 编号 | 需求 | 优先级 | 说明 | |:---:|------|:---:|------| | RBAC.1 | 新增 CLASS:* 权限节点 | P1 | 班级管理模块 | | RBAC.2 | 新增 SCHEDULE:* 权限节点 | P1 | 排课管理模块 | | RBAC.3 | 新增 ATTENDANCE:* 权限节点 | P1 | 考勤管理(当前隐含在 ARCHIVE 中) | | RBAC.4 | 新增 LEARNING:* 权限节点 | P2 | 学情记录管理 | | RBAC.5 | 新增 EXAM:* 权限节点 | P2 | 考试成绩管理 | | RBAC.6 | 新增 INTEGRATION:* 权限节点 | P2 | 第三方集成配置 | | RBAC.7 | staff 角色细化拆分为多角色 | P2 | 财务、宿管、教务分离 | --- ## 18. 横切关注点:操作日志 ### 18.1 现有实现 | 项目 | 状态 | |------|:---:| | operation_logs 表 | ✅ | | OperationLogsService.log() | ✅ | | 教室租赁模块全操作覆盖 | ✅ | | 其他模块覆盖 | ❌ | ### 18.2 操作日志字段 ``` operation_logs ├── user_id, username ├── module (模块名) ├── action (动作) ├── target_id, target_type ├── detail (JSON/文本) ├── ip_address, user_agent ├── status (success/failure) ├── created_at ``` ### 18.3 待覆盖 | 模块 | 需审计操作 | |------|-----------| | 学生管理 | 新增/编辑/删除学生、导入/导出 | | 学生档案 | 查看敏感信息(phone/idCard)、生成报告 | | 账单管理 | 生成账单、确认账单、标记已付、导出 | | 押金管理 | 收取/退还押金 | | 费用管理 | 新增/编辑/删除费用 | | 入住管理 | 新增/编辑/退住 | | 班级管理 🆕 | 创建/编辑/删除班级、添加/移除学员 | | 排课管理 🆕 | 创建/编辑/删除排课 | | 考勤管理 | 补录/编辑考勤、匹配钉钉数据 | | 权限管理 | 角色变更、权限变更 | --- ## 19. 横切关注点:第三方集成 ### 19.1 钉钉集成 | 能力 | 状态 | |------|:---:| | 获取 access_token(带缓存) | ✅ | | 组织架构拉取(部门+用户) | ✅ | | 打卡记录 Stream 订阅 | ✅ | | 工作通知发送 | ✅ | | 限流控制 | ✅ | ### 19.2 企业微信集成 | 能力 | 状态 | |------|:---:| | 获取 access_token(带缓存) | ✅ | | 组织架构拉取(部门+用户) | ✅ | | OAuth2 登录 | ✅ | | 应用消息推送 | ✅ | | 应用可用性检测 | ✅ | ### 19.3 待增强 | 编号 | 需求 | 优先级 | 说明 | |:---:|------|:---:|------| | INT.1 | 定时自动同步 | P2 | 当前为手动触发,增加 Cron 定时任务 | | INT.2 | 同步日志/历史 | P2 | 记录每次同步的时间/结果/数量 | | INT.3 | 增量同步优化 | P2 | 当前全量拉取,优化为增量 | --- ## 20. 横切关注点:报表导出 ### 20.1 现有实现 | 能力 | 状态 | |------|:---:| | 学员个人档案 PDF | ✅ | | 账单 Excel 导出 | ✅ | | 学员 Excel 导入/导出 | ✅ | | 学员档案 Excel 模板导入 | ✅ | ### 20.2 待实现 | 编号 | 需求 | 优先级 | 说明 | |:---:|------|:---:|------| | RPT.1 | 班级花名册导出 | P1 | 班级学员名单 + 教师信息 Excel | | RPT.2 | 考勤统计报表 | P1 | 班级/全局出勤率 Excel | | RPT.3 | 教室使用报表 | P2 | 教室利用率统计 | --- ## 21. 现有代码 vs 目标状态 差距总览 | 模块 | 后端模型 | 后端 API | 前端页面 | 操作日志 | 权限定义 | 上线就绪 | |------|:---:|:---:|:---:|:---:|:---:|:---:| | 1. 学生管理 | ✅ | ✅ | ✅ | ❌ | ✅ | ⚠️ | | 2. 学生档案 | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | | 3. 班级管理 🆕 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | 4. 排课管理 🆕 | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | 5. 教师管理 | ⚠️ | ⚠️ | ❌ | ❌ | ⚠️ | ❌ | | 6. 教室管理 | ✅ | ✅ | ✅ | ❌ | ✅ | ⚠️ | | 7. 宿舍管理 | ⚠️ | ⚠️ | ⚠️ | ❌ | ✅ | ❌ | | 8. 入住管理 | ✅ | ✅ | ✅ | ❌ | ✅ | ⚠️ | | 9. 费用管理 | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | | 10. 账单管理 | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | | 11. 押金管理 | ✅ | ✅ | ✅ | ❌ | ✅ | ⚠️ | | 12. 租赁方管理 | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | | 13. 考勤管理 | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | | 14. 数据面板 | ⚠️ | ⚠️ | ⚠️ | - | ✅ | ❌ | | RBAC 权限 | ✅ | ✅ | - | - | ⚠️ | ⚠️ | | 操作日志 | ✅ | ⚠️ | - | - | - | ❌ | | 第三方集成 | ✅ | ✅ | ✅ | ❌ | - | ⚠️ | | 报表导出 | ✅ | ✅ | ✅ | - | - | ⚠️ | > ✅ 完成 ⚠️ 部分完成/需增强 ❌ 缺失 `-` 不适用 前端tab也需要进行优化,有些tab应该是子项。 --- ## 22. 上线优先级排序 ### P0 — 阻塞上线,必须完成 | 序号 | 模块 | 任务 | 工作量 | |:---:|------|------|:---:| | 1 | 班级管理 | 新建 Class / ClassStudent / ClassTeacher 实体 + CRUD API + 前端页面 | **大** | | 2 | 排课管理 | 新建 ClassSchedule 实体 + 冲突检测 + API + 前端周视图 | **大** | | 3 | 宿舍管理 | Room 增加 rental_category/monthly_rate;Occupancy 增加 rental_type/tenant_id | **中** | | 4 | 账单管理 | 长租模式独立账单生成逻辑 | **中** | | 5 | 操作日志 | 全部关键写操作接入 OperationLogsService | **中** | ### P1 — 上线前应完成 | 序号 | 模块 | 任务 | 工作量 | |:---:|------|------|:---:| | 6 | 考勤管理 | 前端考勤管理页面 + 考勤日历 + 班级考勤汇总 | **中** | | 7 | 数据面板 | 新增教室/考勤/收入指标卡 + 趋势图 | **中** | | 8 | RBAC | 新增 CLASS/SCHEDULE/ATTENDANCE 权限节点 | **小** | | 9 | 教室管理 | 占用状态整合排课数据 | **中** | | 10 | 学生管理 | organization → tenant_id 外键 | **小** | 筛选功能、检索功能,每个涉及大量数据的页面都需要有筛选分类功能,方便我们根据情况快速筛选出需要的信息范围。 ### P2 — 上线后可迭代 | 序号 | 模块 | 任务 | |:---:|------|------| | 11 | 报表 | 班级花名册导出、考勤统计报表 | | 12 | 教师管理 | 教师档案增强、教师工作台 | | 13 | 学生档案 | 多班型对比视图 | | 14 | 押金管理 | 分期管理、退还审批流 | | 15 | 第三方集成 | 定时同步、增量同步 | --- ## 23. 待澄清问题 > ⚠️ 以下问题需要你来确认/补充,我标注了待定项。 ### 23.1 宿舍长租/短租 - [ ] 长租的计费方式:是**按月固定费用**独立生成账单,还是也参与某些分摊? 长租和短租是因为我们本身这个线下的基地就是租用别的人的宿舍,有些属于我们长期租的宿舍房间,有的房间属于临时租的短期宿舍房间。 由于长短涉及到计费不同,所以才需要标记长期短期的问题,本质上是方便我们快速检索相关的宿舍分类,而不只是以楼为单位,宿舍带有的筛选方式有很多。 - [ ] 是否存在"混合宿舍"(同一宿舍部分学生长租、部分短租)? 目前不存在,因为长短是指一个房间,不是按人员的租赁时常。这是我们分类的一种方式。 ### 23.2 排课管理 - [ ] 排课的时间粒度:每天分几个时段?(如 8:00-10:00, 10:00-12:00, 14:00-16:00 ...) 排课时间可以灵活定义全局的,当然我们也有个大致的范围,可以作为预设,但是本身时间都是可调整的。 时间安排 7:30-8:40早自习: 9:00-10:30课程学习 10:30-10:45课间休息 课程学习10:45-12:00 12:00-14:00午餐&午休 14:00-15:30课程学习 15:30-15:45课间休息 15:45-17:00课程学习 17:00-18:30 晚餐 18:30-21:00晚自习 22:30熄灯 - [ ] 排课是否需要支持"单双周"模式? 支持常见的排课方式。 - [ ] 排课冲突检测:同一教室同一时段完全重叠才算冲突,还是部分重叠也算? 同一教室同一时段完全重叠才算冲突 ### 23.3 考勤管理 - [ ] 考勤时段与排课时段的对应关系?排了课的时间段是否自动生成考勤节点? 要根据学生所处的班级和班型情况,不一定每个学生每天都是满课状态,要按分配的班级和班级绑定的课程时段来看。 - [ ] 钉钉打卡数据匹配:完全依赖 resourceUserId 匹配,是否需要手机号兜底匹配? 需要手机号、身份证号都能作为兜底匹配的方案。 - [ ] 请假审批流程:系统内提交请假 → 班主任审批 → 自动更新考勤状态?还是线下审批后手动补录? 学生端未来才开放,目前缺勤的话老师会自己看到,目前是手动改,后续支持学生通过学生的前端发起请假。 ### 23.4 教师角色 - [ ] 任课老师/生活老师/学服老师这三种角色是否对应不同的 RBAC 角色?还是都在 class_teacher 下用 class_teacher.role_type 区分? - [ ] 一个教师可否同时承担多个角色(如既是班主任又是某科目的任课老师)? 这个属于灵活配置,完全可以在用户管理里面设置其权限,而不用单独在创建一个自定义的权限,而且默认预设的权限也比较灵活。 ### 23.5 教室管理 - [ ] 教室 status 枚举是否需要扩展?(当前:available/in_use/maintenance,是否需增加 reserved 预留状态?) - [ ] 教室租赁合同是否需要到期提醒? ### 23.6 数据面板 - [ ] 除了上述指标,还有哪些你特别关注的 KPI 需要在首页看到? 你看下作为一个学生管理系统的使用者,你需要在面板中看到什么信息。 当然你还需要注意一个问题,就是不同权限的人能看到的面板信息是不一样的,比如自己管自己班的那么看考勤信息应该是自己能看的比较合适的。 唯有超管才能看到各项指标。 ### 23.7 其他 - [ ] 系统是否需要消息通知中心(站内信)? 需要。 - [ ] 是否需要多校区切换/隔离?(当前数据层面已在 Department.type=campus 中预留) --- > 📝 **请在此文档基础上补充你的需求细节,特别是「23. 待澄清问题」部分。** > 补充完成后我们进入详细的设计和开发排期阶段。