|
|
|
@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
# 学校默认实训任务配置设计
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 目标
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
让每所学校拥有可独立维护的一套默认实训任务。仅本校的管理员教师可以在教师端维护该配置;新建学校后异步从平台基线复制默认任务,学校创建接口不等待复制完成。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 范围与不变量
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 保留现有教学班任务分配与权限:只有教学班创建教师可以编辑该教学班的任务。
|
|
|
|
|
|
|
|
- 教学班已有任务配置时,继续优先使用教学班配置。
|
|
|
|
|
|
|
|
- 教学班没有配置时,优先使用本校默认配置;本校默认未就绪时,临时回退平台基线,避免学生端任务为空。
|
|
|
|
|
|
|
|
- 已有学生成绩、排名和教学班任务配置均不迁移、不删除、不重算。
|
|
|
|
|
|
|
|
- 默认任务开关沿用 `task_allocation.module`、`disabled_status` 和 `sort` 的现有语义。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 数据模型
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`task_allocation` 保持现有表结构,通过固定的 `class_id` 区分三层任务配置:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 层级 | class_id | school_id | 用途 |
|
|
|
|
|
|
|
|
| --- | --- | --- | --- |
|
|
|
|
|
|
|
|
| 平台基线 | `999999999` | `999999999` | 新学校复制源与学校初始化期间的只读回退 |
|
|
|
|
|
|
|
|
| 学校默认 | `SCHOOL_DEFAULT:{schoolId}` | 实际学校 ID | 本校管理员教师维护的默认任务 |
|
|
|
|
|
|
|
|
| 教学班 | 实际教学班 ID | 实际学校 ID | 任课教师维护的班级覆盖配置 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
学校默认记录由服务端构造固定 class ID,前端不得传入该 ID 作为授权依据。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
新增 `school_default_task_initialization` 状态表,每校一行,字段为 `school_id`、`status`(`PENDING`、`RUNNING`、`READY`、`FAILED`)、`last_error`、`attempt_count`、`create_time`、`update_time`。该表只跟踪异步复制,不参与学生任务读取。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 异步初始化
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. 平台超管成功插入学校及学校产品配置后,提交一个学校默认任务初始化任务。
|
|
|
|
|
|
|
|
2. 创建学校接口立即返回成功,不等待复制。
|
|
|
|
|
|
|
|
3. 异步任务读取平台基线记录,复制为该校的学校默认记录。
|
|
|
|
|
|
|
|
4. 初始化必须幂等:目标学校已有任意学校默认记录时不覆盖,重复任务只在目标记录为空时执行复制。
|
|
|
|
|
|
|
|
5. 异步任务开始时将状态置为 `RUNNING`;成功后置为 `READY`;失败时记录错误摘要并置为 `FAILED`。管理员教师可调用受限的重试接口重新投递任务。
|
|
|
|
|
|
|
|
6. 任务尚未执行、执行中或失败时,默认任务查询返回状态及平台基线任务,供只读展示与学生端回退使用。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
初始化状态以状态表为准;兼容已存在学校时,若学校默认记录已存在但状态行缺失,则读取时补为 `READY`。创建学校提交异步任务前先落一条 `PENDING` 状态,确保管理员页面能明确区分“正在初始化”和“初始化失败”。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 查询优先级
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
学生通过当前有效教学班查询任务时:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. 查询教学班配置;存在则返回。
|
|
|
|
|
|
|
|
2. 否则查询该教学班所属学校的学校默认配置;存在则返回。
|
|
|
|
|
|
|
|
3. 否则返回平台基线配置。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
教师的教学班任务分配页使用同一查询优先级,但当教师首次保存时,仍将完整任务清单写为教学班配置,形成覆盖层。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 权限与接口
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
新增学校默认任务的查询、保存和重试接口。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 查询:必须为本校教师;普通教师只允许读取学校默认的只读结果,以支撑教学班未覆盖时的展示,管理员教师可获得初始化状态和重试能力。
|
|
|
|
|
|
|
|
- 保存与重试:仅允许当前登录用户对应的 `userinfo` 记录满足 `role=3`、`teacher_admin=true`,且 `school_id` 与目标学校一致。
|
|
|
|
|
|
|
|
- 令牌仅用于获取当前登录 `userId`;所有权限判断均回查 `userinfo`,移除默认任务写操作对请求参数 `userId` 的信任。
|
|
|
|
|
|
|
|
- 平台基线记录不可经学校默认接口编辑。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 教师端体验
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 在教师端增加“默认实训任务配置”菜单;仅 `teacherAdmin=true` 时显示,并在路由守卫层同步限制直接访问。
|
|
|
|
|
|
|
|
- 页面复用现有任务分配的任务开关与排序展示,不提供教学班选择器。
|
|
|
|
|
|
|
|
- `READY` 时允许保存开关;`INITIALIZING` 时展示平台基线任务、禁用编辑,显示“正在初始化,稍后刷新”,并提供“立即重试”;重试成功投递后维持等待提示。
|
|
|
|
|
|
|
|
- 普通教师完全不显示该菜单;直接访问时显示无权限,不泄露其他学校的任务。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 错误处理
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 平台基线为空:初始化任务记录错误并使学校默认页显示“初始化失败,请联系平台管理员”;重试不产生空配置。
|
|
|
|
|
|
|
|
- 学校不存在、操作者不是本校管理员教师、尝试编辑平台基线:返回 403/400,且不写数据。
|
|
|
|
|
|
|
|
- 异步复制发生重复投递:只保留第一份成功复制结果,后续任务不覆盖学校管理员修改。
|
|
|
|
|
|
|
|
- 教学班已经有任务:学校默认配置改动不影响该教学班。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 验收与测试
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- 新建学校接口可立即成功返回,初始化逻辑在独立执行器中运行。
|
|
|
|
|
|
|
|
- 初始任务复制平台基线为学校默认配置;重复初始化不覆盖已修改配置。
|
|
|
|
|
|
|
|
- 学生和教学班查询按“教学班 → 学校默认 → 平台基线”回退。
|
|
|
|
|
|
|
|
- 管理员教师可查询、保存、重试本校默认任务;普通教师及跨校教师均被后端拒绝。
|
|
|
|
|
|
|
|
- 前端仅管理员教师可见菜单;初始化中页面不可保存但可重试。
|
|
|
|
|
|
|
|
- 现有教学班创建者权限测试继续通过。
|