|
|
@@ -0,0 +1,135 @@
|
|
|
+# 批量学生换班级 — 设计说明
|
|
|
+
|
|
|
+**日期**: 2026-09-15
|
|
|
+**状态**: 已确认
|
|
|
+**范围**: 学生信息页「换班级」支持多人批量提交
|
|
|
+**方案**: A — 前端循环调用现有单条接口
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 1. 背景与目标
|
|
|
+
|
|
|
+### 现状
|
|
|
+
|
|
|
+- 页面:`web` → `/student/studentmsg/studentMsg`(学生信息)
|
|
|
+- 「换班级」按钮当前仅支持选中 **1** 名学生(`ids.length !== 1` 时拦截)
|
|
|
+- 提交后调用 `POST /studentMsg/studentClassChange`,写入一条 `xg_student_class_change` 记录,`status='0'`
|
|
|
+- **无审批流程**;后台脚本 `学生换班级/process_student_class_change_fixed.sh` 扫描未处理记录,更新学生班级并将 `status` 置为 `'1'`
|
|
|
+
|
|
|
+### 目标
|
|
|
+
|
|
|
+- 支持勾选多名学生,一次操作换到 **同一目标班级**
|
|
|
+- 每人一条异动记录,走与单人完全相同的后续处理链路
|
|
|
+- 不改后端接口、表结构、后台处理脚本
|
|
|
+
|
|
|
+### 非目标
|
|
|
+
|
|
|
+- 不引入 Warm-Flow / 审批
|
|
|
+- 不新增批量 API
|
|
|
+- 不在前端/接口层立即更新 `xg_student_msg` 班级字段(仍由后台脚本执行)
|
|
|
+- 不做「每人不同目标班级」
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 2. 需求确认摘要
|
|
|
+
|
|
|
+| 项 | 结论 |
|
|
|
+|----|------|
|
|
|
+| 目标班级 | 多人共用同一套:新学院 / 新专业 / 新班级 / 生效时间 / 原因 |
|
|
|
+| 原班级约束 | 不限制,任意原班级可一起选 |
|
|
|
+| 生效方式 | 与现在一致:只写 `status=0` 记录,由后台脚本处理 |
|
|
|
+| 实现方式 | 前端串行循环现有单条接口 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 3. 整体流程
|
|
|
+
|
|
|
+```
|
|
|
+勾选 N 名学生 → 点击「换班级」
|
|
|
+ → 弹窗:学生列表 + 共用目标班级表单
|
|
|
+ → 确定后,对每人依次 POST /studentMsg/studentClassChange
|
|
|
+ → 提示成功/失败汇总
|
|
|
+ → 现有后台脚本照常处理 status=0 记录
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 4. UI 与交互
|
|
|
+
|
|
|
+### 4.1 按钮
|
|
|
+
|
|
|
+- 权限:`studentMsg:class:change`(不变)
|
|
|
+- 启用条件:至少勾选 1 人(去掉「只能选 1 人」限制)
|
|
|
+
|
|
|
+### 4.2 弹窗
|
|
|
+
|
|
|
+- 标题:
|
|
|
+ - 1 人:`换班级申请`
|
|
|
+ - 多人:`批量换班级(N 人)`
|
|
|
+- **上半区**:学生表格(学号、姓名、原学院、原专业、原班级),可滚动
|
|
|
+- **下半区**:共用目标表单(新学院 / 新专业 / 新班级 / 生效时间 / 换班级原因),字段与校验与现单人一致
|
|
|
+
|
|
|
+### 4.3 提交反馈
|
|
|
+
|
|
|
+- 提交中禁用「确定」,可显示进度(如 `3/10`)
|
|
|
+- 结束后汇总:`成功 X 人`;失败则列出学号 + 原因
|
|
|
+- **全部成功**:关闭弹窗并刷新列表
|
|
|
+- **存在失败**:保留弹窗并展示失败明细
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 5. 校验与错误处理
|
|
|
+
|
|
|
+### 5.1 提交前
|
|
|
+
|
|
|
+- 表单必填:新学院、新专业、新班级、生效时间、原因
|
|
|
+- 若某人当前 `classId` 已等于目标 `newClassId`:该人跳过,记入失败明细「已在目标班级」,其余人继续
|
|
|
+- 不校验「是否已有未处理换班级申请」(与现单人行为一致)
|
|
|
+
|
|
|
+### 5.2 提交中
|
|
|
+
|
|
|
+- 串行调用现有接口(避免并发压力)
|
|
|
+- 每人 payload:该生原学院/专业/班级信息 + 共用新班级信息;`changeType='1'`,`status='0'`
|
|
|
+- 单人接口失败不中断整批;记录后继续下一人
|
|
|
+- 不回滚已成功写入的记录(方案 A 无服务端事务)
|
|
|
+
|
|
|
+### 5.3 边界
|
|
|
+
|
|
|
+- 暂不设人数硬上限(后续如需可加,例如 100)
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 6. 改动范围
|
|
|
+
|
|
|
+### 改
|
|
|
+
|
|
|
+| 位置 | 内容 |
|
|
|
+|------|------|
|
|
|
+| `web/src/views/xg/xsjcxx/studentMsg/studentMsg/index.vue` | 按钮禁用逻辑、`openChangeClassModal`、弹窗结构、`submitChangeClass` 批量循环与结果汇总 |
|
|
|
+
|
|
|
+### 不改
|
|
|
+
|
|
|
+- 后端 `XgStudentClassChangeController` / Service / 表结构
|
|
|
+- `学生换班级/process_student_class_change_fixed.sh`
|
|
|
+- `web/src/views/xg/xsjcxx/studentClassChange/index.vue`(记录列表页)
|
|
|
+
|
|
|
+### 文档同步
|
|
|
+
|
|
|
+- 在 `docs/开发文档/API/学生学籍异动与换班级API.md`(或业务模块文档)补充说明:学生信息页支持批量换班级,前端循环写入多条记录,处理链路不变
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 7. 测试要点
|
|
|
+
|
|
|
+1. 选 1 人:与现行为一致,写出 1 条 `status=0`
|
|
|
+2. 选多人、不同原班级:写出 N 条,目标班级字段相同
|
|
|
+3. 含「已在目标班」的学生:该人跳过,其他人成功
|
|
|
+4. 模拟单人接口失败:其余仍提交,弹窗保留并显示失败明细
|
|
|
+5. 后台脚本执行后:成功记录变 `status=1`,对应学生班级信息更新
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 8. 风险与说明
|
|
|
+
|
|
|
+- **部分成功**:方案 A 无整批事务;失败明细需清晰展示,由操作人决定是否对失败学生重试
|
|
|
+- **与「审批」的关系**:设计文档中曾有「未处理/已处理」状态字段,实际无人工审批;「处理」指后台脚本执行。本需求不改变该模型
|