|
|
|
|
@ -0,0 +1,210 @@
|
|
|
|
|
# 学校组织模式与可选行政班设计
|
|
|
|
|
|
|
|
|
|
## 背景与结论
|
|
|
|
|
|
|
|
|
|
产品需要同时服务两类学校:
|
|
|
|
|
|
|
|
|
|
- 标准学校:学生属于行政班,教师从行政班组建教学班;
|
|
|
|
|
- 珠江学校:不使用行政班,由教师直接维护教学班学生名单。
|
|
|
|
|
|
|
|
|
|
两类需求共用同一个产品、同一套代码库和同一套数据库。行政班不是系统的必备实体,而是某些学校启用的学生归属方式;教学班始终是实训、任务、成绩和学习进度的业务主体。
|
|
|
|
|
|
|
|
|
|
不建立长期客户分支,也不重建项目。短期交付若必须使用分支,分支中的差异必须回收为学校级配置或明确的扩展点。
|
|
|
|
|
|
|
|
|
|
## 目标与非目标
|
|
|
|
|
|
|
|
|
|
### 目标
|
|
|
|
|
|
|
|
|
|
1. 让每所学校独立选择是否启用行政班。
|
|
|
|
|
2. 珠江学校由教师创建教学班、添加和维护教学班学生。
|
|
|
|
|
3. 标准学校保持现有行政班和教学班逻辑,避免数据或操作回归。
|
|
|
|
|
4. 学生可以加入多个教学班;任务、成绩和进度只以教学班为准。
|
|
|
|
|
5. 复用现有 `school_class.class_type`、`created_by` 与 `teaching_class_student` 数据模型。
|
|
|
|
|
|
|
|
|
|
### 非目标
|
|
|
|
|
|
|
|
|
|
- 本期不拆分为两套部署或两套数据库结构。
|
|
|
|
|
- 本期不将学校管理员的全校学生管理能力开放给珠江学校。
|
|
|
|
|
- 本期不引入通用流程引擎或任意层级组织树。
|
|
|
|
|
- 本期不改变外部教务系统同步的既有语义;后续可将其作为第三种名单来源扩展。
|
|
|
|
|
|
|
|
|
|
## 方案选择
|
|
|
|
|
|
|
|
|
|
| 方案 | 结论 | 原因 |
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
| 客户长期分支 | 不采用 | 版本升级、缺陷修复和安全补丁都需要反复合并,维护成本随客户数增长。 |
|
|
|
|
|
| 独立项目 | 不采用 | 当前差异集中在组织结构与名单维护,不足以证明业务核心已经分化。 |
|
|
|
|
|
| 学校级组织模式配置 | 采用 | 差异可被稳定规则表达,公共任务、成绩、实训等能力继续复用。 |
|
|
|
|
|
|
|
|
|
|
## 核心模型
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
学校
|
|
|
|
|
├─ 学生身份(必属学校,以“学校 + 学号”去重)
|
|
|
|
|
├─ 行政班(可选,仅 ADMIN_CLASS_ENABLED 学校)
|
|
|
|
|
└─ 教学班(实训业务主体)
|
|
|
|
|
└─ 教学班学生成员(学生可加入多个教学班)
|
|
|
|
|
└─ 实训任务、提交、成绩、学习进度
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 学校组织配置
|
|
|
|
|
|
|
|
|
|
新增一张一对一配置表 `school_product_config`,避免以后不断向 `school` 表加入互不相关的定制字段。
|
|
|
|
|
|
|
|
|
|
| 字段 | 类型 | 说明 |
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
| `school_id` | VARCHAR(64), PK | 对应 `school.school_id` |
|
|
|
|
|
| `organization_mode` | VARCHAR(32) | `ADMIN_CLASS_ENABLED` 或 `TEACHING_CLASS_ONLY` |
|
|
|
|
|
| `student_roster_owner` | VARCHAR(32) | `SCHOOL_ADMIN`、`TEACHER`;预留 `EXTERNAL_SYNC` |
|
|
|
|
|
| `create_time` / `update_time` | DATETIME | 审计时间 |
|
|
|
|
|
|
|
|
|
|
配置必须由平台超管维护,学校管理员和教师只读取当前学校配置。创建新学校时必须创建配置记录,默认值为:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
organization_mode = ADMIN_CLASS_ENABLED
|
|
|
|
|
student_roster_owner = SCHOOL_ADMIN
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
珠江学校配置为:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
organization_mode = TEACHING_CLASS_ONLY
|
|
|
|
|
student_roster_owner = TEACHER
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
不允许在学校已存在行政班或学生数据时直接切换组织模式;应先完成数据核查/迁移,或新建学校租户。
|
|
|
|
|
|
|
|
|
|
### 珠江学校的数据规则
|
|
|
|
|
|
|
|
|
|
| 对象 | 规则 |
|
|
|
|
|
| --- | --- |
|
|
|
|
|
| 学生 `Userinfo` | `school_id` 必填;`school_class_id` 可为空;院系、专业在珠江模式下可为空。 |
|
|
|
|
|
| 行政班 `SchoolClass` | 不允许创建 `class_type=ADMIN`;行政班列表、导入入口和相关菜单不展示。 |
|
|
|
|
|
| 教学班 `SchoolClass` | 必须为 `class_type=TEACHING`,`created_by` 必填且等于创建教师。`school_major_id` 允许为空。 |
|
|
|
|
|
| 教学班成员 `TeachingClassStudent` | `teaching_class_id`、`student_user_id` 必填;`admin_class_id` 改为可为空。保留 `(teaching_class_id, student_user_id)` 唯一约束。 |
|
|
|
|
|
| 学生身份去重 | 导入及新增均以 `school_id + student_number`(现有学号/账号字段的业务含义需统一)查重,不能仅按姓名查重。 |
|
|
|
|
|
|
|
|
|
|
`school_class_id` 只能继续作为历史兼容字段或行政班归属,不能再作为“学生当前教学班”的唯一来源。所有实训上下文应通过 `teaching_class_student` 查询教学班成员关系。
|
|
|
|
|
|
|
|
|
|
## 业务流程
|
|
|
|
|
|
|
|
|
|
### 珠江:教师维护名单
|
|
|
|
|
|
|
|
|
|
1. 教师进入“我的教学班”,创建教学班;系统写入 `class_type=TEACHING`、`created_by=当前教师`。
|
|
|
|
|
2. 教师在教学班内选择“添加学生”:单个新增、批量导入,或搜索并加入本校已有学生。
|
|
|
|
|
3. 系统用学校和学号查找学生:
|
|
|
|
|
- 找到已有学生:仅新增当前教学班成员关系;
|
|
|
|
|
- 未找到学生:创建本校学生身份后新增成员关系;
|
|
|
|
|
- 已在当前教学班:返回重复明细,不创建重复记录。
|
|
|
|
|
4. 教师可编辑自己教学班成员的基本资料,并移出该教学班。
|
|
|
|
|
5. 移出教学班仅删除/失效成员关系,绝不删除 `Userinfo`、提交、成绩或其他教学班成员关系。
|
|
|
|
|
|
|
|
|
|
学生首次被任何教师导入后成为学校范围的学生身份。后续教师只能把已有学生加入自己的教学班;如允许编辑共享身份资料,必须记录操作者和修改时间,并以学号唯一性校验为准。
|
|
|
|
|
|
|
|
|
|
### 标准学校:保持既有逻辑
|
|
|
|
|
|
|
|
|
|
1. 学校管理员维护学生及行政班。
|
|
|
|
|
2. 教师可从一个或多个行政班生成教学班,或导入名单。
|
|
|
|
|
3. 导入教学班时保留现有“学生属于指定行政班/专业范围”的校验。
|
|
|
|
|
4. `TeachingClassStudent.admin_class_id` 记录学生行政班快照。
|
|
|
|
|
|
|
|
|
|
所有涉及“行政班存在”或“成员必须来自行政班”的规则,都以当前学校的 `organization_mode` 为前提。不得让珠江模式经过标准模式的行政班校验。
|
|
|
|
|
|
|
|
|
|
## 权限与界面
|
|
|
|
|
|
|
|
|
|
### 珠江学校
|
|
|
|
|
|
|
|
|
|
| 角色 | 可见模块 | 关键限制 |
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
| 平台超管 | 学校与学校配置 | 可查看学校数据;配置变更须通过平台端。 |
|
|
|
|
|
| 学校管理员 | 学校基础信息、教师管理 | 不显示院系、专业、行政班和全校学生管理。 |
|
|
|
|
|
| 教师 | 我的教学班、教学班学生、任务和成绩 | 只可操作 `created_by=本人` 的教学班及其成员。 |
|
|
|
|
|
| 学生 | 已加入教学班的实训内容 | 仅访问自己有效教学班中的任务、进度和成绩。 |
|
|
|
|
|
|
|
|
|
|
### 前端行为
|
|
|
|
|
|
|
|
|
|
- 登录后返回或单独读取学校产品配置,并存入用户会话状态。
|
|
|
|
|
- 菜单、路由守卫、页面操作按钮均按角色和学校配置判断;隐藏菜单不是权限控制,后端必须执行相同校验。
|
|
|
|
|
- 珠江教师创建教学班页不展示“从行政班组建”,只提供“空教学班后添加学生”及“按学生名单创建教学班”。
|
|
|
|
|
- 珠江导入模板只包含学生必要身份字段,不包含院系、专业、行政班列。
|
|
|
|
|
- 标准学校继续使用现有模板与页面流程。
|
|
|
|
|
|
|
|
|
|
## 后端改造边界
|
|
|
|
|
|
|
|
|
|
现有代码已具备 `SchoolClass.classType`、`SchoolClass.createdBy`、`TeachingClassStudent` 和教师教学班成员导入入口。改造应优先在既有服务/控制器上补充配置判断,而不是复制一套珠江控制器。
|
|
|
|
|
|
|
|
|
|
### 配置读取
|
|
|
|
|
|
|
|
|
|
新增 `SchoolProductConfig`、Mapper 与 `SchoolProductConfigService`,对外提供:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
getRequiredConfig(schoolId)
|
|
|
|
|
requiresAdminClass(schoolId)
|
|
|
|
|
isTeacherRosterManaged(schoolId)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
服务层必须获取登录用户所属学校后自行读取配置;不能信任前端传入的组织模式。
|
|
|
|
|
|
|
|
|
|
### 教师教学班接口
|
|
|
|
|
|
|
|
|
|
可沿用现有教学班与成员导入接口,但应收敛为以下语义:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
POST /api/.../teaching-classes
|
|
|
|
|
GET /api/.../teaching-classes/mine
|
|
|
|
|
GET /api/.../teaching-classes/{id}/students
|
|
|
|
|
POST /api/.../teaching-classes/{id}/students
|
|
|
|
|
POST /api/.../teaching-classes/{id}/students/import
|
|
|
|
|
PATCH /api/.../teaching-classes/{id}/students/{studentId}
|
|
|
|
|
DELETE /api/.../teaching-classes/{id}/students/{studentId}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
每个教学班接口先验证:班级存在、`class_type=TEACHING`、归属学校等于操作者学校、`created_by` 等于操作者。名单接口在珠江模式下不得调用行政班、专业或院系的必填校验。
|
|
|
|
|
|
|
|
|
|
### 需要重点检查的现有逻辑
|
|
|
|
|
|
|
|
|
|
- 教学班成员导入与“按学生名单创建教学班”当前会调用行政班/专业范围校验;应按组织模式分支为标准校验与珠江校验。
|
|
|
|
|
- 教学班成员写入当前会传入学生的 `schoolClassId`;珠江模式传入 `NULL`。
|
|
|
|
|
- 学生任务、成绩、AI 评价和学习进度的“当前教学班”解析必须优先使用 `TeachingClassStudent`;若学生可并行处于多个教学班,调用方必须显式传入 `teachingClassId` 或让学生选择上下文,禁止任取第一条成员记录。
|
|
|
|
|
- 删除学生的接口必须在教学班上下文中仅移除成员关系;任何全局删除学生账号的行为不应向教师开放。
|
|
|
|
|
|
|
|
|
|
## 数据迁移与上线
|
|
|
|
|
|
|
|
|
|
1. 新增 `school_product_config`,为所有已有学校写入标准学校默认配置。
|
|
|
|
|
2. 将 `teaching_class_student.admin_class_id` 改为可空;保留已有数据。
|
|
|
|
|
3. 确认 `school_class.school_major_id`、学生的院系/专业字段在数据库层允许为空;若不允许,仅为珠江场景放宽为空。
|
|
|
|
|
4. 为珠江创建配置,发布后先由一名教师做小范围名单导入验收。
|
|
|
|
|
5. 不删除行政班、专业、院系或历史 `school_class_id` 数据,不对标准学校做批量数据重写。
|
|
|
|
|
6. 配置切换设置为受控操作:出现行政班、学生归属或任务数据时,后端拒绝直接切换并返回可操作的迁移提示。
|
|
|
|
|
|
|
|
|
|
## 审计与错误处理
|
|
|
|
|
|
|
|
|
|
记录教学班创建、学生身份创建、成员加入、成员移出和成员资料变更,至少包含学校、教学班、学生、操作者、时间、来源(手工/导入)。
|
|
|
|
|
|
|
|
|
|
典型错误:
|
|
|
|
|
|
|
|
|
|
- 教师操作非本人教学班:403。
|
|
|
|
|
- 非珠江学校以珠江模板导入:返回“当前学校启用了行政班,请使用标准导入方式”。
|
|
|
|
|
- 珠江学校请求创建行政班:返回“当前学校未启用行政班”。
|
|
|
|
|
- 学号已存在但姓名冲突:返回冲突行,不自动覆盖既有学生身份。
|
|
|
|
|
- 学生已在当前教学班:返回重复明细,整批导入的处理策略统一为“重复行跳过并回显”;其他校验错误则整批拒绝。
|
|
|
|
|
|
|
|
|
|
## 验收标准
|
|
|
|
|
|
|
|
|
|
1. 珠江教师可创建教学班、导入新学生、将已有学生加入另一教学班,且成员 `admin_class_id` 为空。
|
|
|
|
|
2. 珠江教师不需要创建或选择行政班、院系、专业即可完成名单维护。
|
|
|
|
|
3. 珠江学校管理员看不到且无法调用行政班、院系、专业、全校学生管理功能。
|
|
|
|
|
4. 珠江教师不能操作其他教师教学班或其成员。
|
|
|
|
|
5. 标准学校仍需经行政班规则组建教学班,原有行政班成员导入与任务分配测试通过。
|
|
|
|
|
6. 学生在多个教学班时,任务、成绩、AI 评价与学习进度都按明确的 `teachingClassId` 隔离。
|
|
|
|
|
7. 移出教学班不会删除学生身份、历史任务提交或其他教学班的成员资格。
|
|
|
|
|
8. 非法切换学校组织模式被后端拒绝;前端隐藏入口不能绕过后端授权。
|
|
|
|
|
|
|
|
|
|
## 实施顺序
|
|
|
|
|
|
|
|
|
|
1. 编写数据库迁移与配置实体/服务单元测试。
|
|
|
|
|
2. 完成学校创建、查询与平台配置管理接口。
|
|
|
|
|
3. 调整教学班创建、学生新增、名单导入、成员移出服务的配置分支。
|
|
|
|
|
4. 调整学生当前教学班解析,使多教学班上下文明确。
|
|
|
|
|
5. 修改前端会话配置、菜单与教学班名单页面/导入模板。
|
|
|
|
|
6. 覆盖珠江模式、标准模式、跨教师越权、多教学班和历史回归测试。
|