You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

11 KiB

学校组织模式与可选行政班设计

背景与结论

产品需要同时服务两类学校:

  • 标准学校:学生属于行政班,教师从行政班组建教学班;
  • 珠江学校:不使用行政班,由教师直接维护教学班学生名单。

两类需求共用同一个产品、同一套代码库和同一套数据库。行政班不是系统的必备实体,而是某些学校启用的学生归属方式;教学班始终是实训、任务、成绩和学习进度的业务主体。

不建立长期客户分支,也不重建项目。短期交付若必须使用分支,分支中的差异必须回收为学校级配置或明确的扩展点。

目标与非目标

目标

  1. 让每所学校独立选择是否启用行政班。
  2. 珠江学校由教师创建教学班、添加和维护教学班学生。
  3. 标准学校保持现有行政班和教学班逻辑,避免数据或操作回归。
  4. 学生可以加入多个教学班;任务、成绩和进度只以教学班为准。
  5. 复用现有 school_class.class_typecreated_byteaching_class_student 数据模型。

非目标

  • 本期不拆分为两套部署或两套数据库结构。
  • 本期不将学校管理员的全校学生管理能力开放给珠江学校。
  • 本期不引入通用流程引擎或任意层级组织树。
  • 本期不改变外部教务系统同步的既有语义;后续可将其作为第三种名单来源扩展。

方案选择

方案 结论 原因
客户长期分支 不采用 版本升级、缺陷修复和安全补丁都需要反复合并,维护成本随客户数增长。
独立项目 不采用 当前差异集中在组织结构与名单维护,不足以证明业务核心已经分化。
学校级组织模式配置 采用 差异可被稳定规则表达,公共任务、成绩、实训等能力继续复用。

核心模型

学校
 ├─ 学生身份(必属学校,以“学校 + 学号”去重)
 ├─ 行政班(可选,仅 ADMIN_CLASS_ENABLED 学校)
 └─ 教学班(实训业务主体)
      └─ 教学班学生成员(学生可加入多个教学班)
           └─ 实训任务、提交、成绩、学习进度

学校组织配置

新增一张一对一配置表 school_product_config,避免以后不断向 school 表加入互不相关的定制字段。

字段 类型 说明
school_id VARCHAR(64), PK 对应 school.school_id
organization_mode VARCHAR(32) ADMIN_CLASS_ENABLEDTEACHING_CLASS_ONLY
student_roster_owner VARCHAR(32) SCHOOL_ADMINTEACHER;预留 EXTERNAL_SYNC
create_time / update_time DATETIME 审计时间

配置必须由平台超管维护,学校管理员和教师只读取当前学校配置。创建新学校时必须创建配置记录,默认值为:

organization_mode = ADMIN_CLASS_ENABLED
student_roster_owner = SCHOOL_ADMIN

珠江学校配置为:

organization_mode = TEACHING_CLASS_ONLY
student_roster_owner = TEACHER

不允许在学校已存在行政班或学生数据时直接切换组织模式;应先完成数据核查/迁移,或新建学校租户。

珠江学校的数据规则

对象 规则
学生 Userinfo school_id 必填;school_class_id 可为空;院系、专业在珠江模式下可为空。
行政班 SchoolClass 不允许创建 class_type=ADMIN;行政班列表、导入入口和相关菜单不展示。
教学班 SchoolClass 必须为 class_type=TEACHINGcreated_by 必填且等于创建教师。school_major_id 允许为空。
教学班成员 TeachingClassStudent teaching_class_idstudent_user_id 必填;admin_class_id 改为可为空。保留 (teaching_class_id, student_user_id) 唯一约束。
学生身份去重 导入及新增均以 school_id + student_number(现有学号/账号字段的业务含义需统一)查重,不能仅按姓名查重。

school_class_id 只能继续作为历史兼容字段或行政班归属,不能再作为“学生当前教学班”的唯一来源。所有实训上下文应通过 teaching_class_student 查询教学班成员关系。

业务流程

珠江:教师维护名单

  1. 教师进入“我的教学班”,创建教学班;系统写入 class_type=TEACHINGcreated_by=当前教师
  2. 教师在教学班内选择“添加学生”:单个新增、批量导入,或搜索并加入本校已有学生。
  3. 系统用学校和学号查找学生:
    • 找到已有学生:仅新增当前教学班成员关系;
    • 未找到学生:创建本校学生身份后新增成员关系;
    • 已在当前教学班:返回重复明细,不创建重复记录。
  4. 教师可编辑自己教学班成员的基本资料,并移出该教学班。
  5. 移出教学班仅删除/失效成员关系,绝不删除 Userinfo、提交、成绩或其他教学班成员关系。

学生首次被任何教师导入后成为学校范围的学生身份。后续教师只能把已有学生加入自己的教学班;如允许编辑共享身份资料,必须记录操作者和修改时间,并以学号唯一性校验为准。

标准学校:保持既有逻辑

  1. 学校管理员维护学生及行政班。
  2. 教师可从一个或多个行政班生成教学班,或导入名单。
  3. 导入教学班时保留现有“学生属于指定行政班/专业范围”的校验。
  4. TeachingClassStudent.admin_class_id 记录学生行政班快照。

所有涉及“行政班存在”或“成员必须来自行政班”的规则,都以当前学校的 organization_mode 为前提。不得让珠江模式经过标准模式的行政班校验。

权限与界面

珠江学校

角色 可见模块 关键限制
平台超管 学校与学校配置 可查看学校数据;配置变更须通过平台端。
学校管理员 学校基础信息、教师管理 不显示院系、专业、行政班和全校学生管理。
教师 我的教学班、教学班学生、任务和成绩 只可操作 created_by=本人 的教学班及其成员。
学生 已加入教学班的实训内容 仅访问自己有效教学班中的任务、进度和成绩。

前端行为

  • 登录后返回或单独读取学校产品配置,并存入用户会话状态。
  • 菜单、路由守卫、页面操作按钮均按角色和学校配置判断;隐藏菜单不是权限控制,后端必须执行相同校验。
  • 珠江教师创建教学班页不展示“从行政班组建”,只提供“空教学班后添加学生”及“按学生名单创建教学班”。
  • 珠江导入模板只包含学生必要身份字段,不包含院系、专业、行政班列。
  • 标准学校继续使用现有模板与页面流程。

后端改造边界

现有代码已具备 SchoolClass.classTypeSchoolClass.createdByTeachingClassStudent 和教师教学班成员导入入口。改造应优先在既有服务/控制器上补充配置判断,而不是复制一套珠江控制器。

配置读取

新增 SchoolProductConfig、Mapper 与 SchoolProductConfigService,对外提供:

getRequiredConfig(schoolId)
requiresAdminClass(schoolId)
isTeacherRosterManaged(schoolId)

服务层必须获取登录用户所属学校后自行读取配置;不能信任前端传入的组织模式。

教师教学班接口

可沿用现有教学班与成员导入接口,但应收敛为以下语义:

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. 覆盖珠江模式、标准模式、跨教师越权、多教学班和历史回归测试。