2026-09-01-class-msg-campus-design.md 7.1 KB

班级信息增加「所在校区」

日期:2026-09-01
状态:已实现(待库表执行 SQL 后验收)
方案:A — 班级表直接挂 campus_id + campus_name
范围:Web 班级信息模块 + 后端 classMsg + 导入模板/导入;不改移动端


1. 背景与目标

1.1 问题

班级信息(xg_class_msg)目前无校区属性。业务需要标识班级所属校区,数据来源于【校区信息】(xg_dorm_campus),并支持历史数据逐步补齐。

1.2 目标

  1. 班级增加「所在校区」(选填)
  2. 列表可按校区筛选;表格展示校区名称
  3. 新增/修改可选择校区
  4. 列表多选后「批量设置校区」
  5. 导入模板与导入支持校区(下拉 + 按名称解析)

1.3 已确认产品决策

项 决策
必填性 选填,允许为空
存储方案 A:campus_id + campus_name 冗余(对齐学院/专业)
批量设置 列表多选 → 按钮 → 弹窗选一个校区统一写入
导入识别 模板下拉填校区名称;导入按名称解析为 ID
列表筛选 搜索区增加校区下拉
历史补齐 主要靠批量设置;导入仅服务新建班级

2. 数据模型

表 xg_class_msg 新增:

字段 类型 可空 说明
campus_id bigint(20) YES 关联 xg_dorm_campus.id
campus_name varchar(100) YES 冗余校区名称
  • 索引:KEY idx_campus_id (campus_id)
  • 不建数据库外键(与学院/专业一致)
  • 校区改名/删除:本期不做级联同步;班级保留已写入值;筛选仍按 campus_id

同步改动的类型:

  • 后端:XgClassMsg、XgClassMsgBo、XgClassMsgVo、XgClassMsgImportVo
  • 前端:ClassMsgVO / ClassMsgForm / ClassMsgQuery(web/src/api/xg/xsjcxx/classMsg/...)

增量 SQL 放入 docs/数据库脚本/(文件名建议 2026-09-01-xg_class_msg-add-campus.sql),实现时同步更新 docs/设计文档/database/ 中班级表说明(若有)。


3. 接口设计

3.1 扩展现有接口

方法 路径 变化
GET /classMsg/classMsg/list Query 支持 campusId;行数据含 campusId/campusName
GET /classMsg/classMsg/{id} 详情含校区字段
POST /classMsg/classMsg Body 可选 campusId;服务端校验存在后回填 campusName
PUT /classMsg/classMsg 同上;允许将校区改为空(清空)
POST /classMsg/classMsg/export 导出列增加「所在校区」(campusName)
POST /classMsg/classMsg/importTemplate 模板增加「所在校区」下拉
POST /classMsg/classMsg/importData 解析并写入校区

单条增改校区规则:

  • campusId 为空:campus_id、campus_name 置空
  • campusId 有值:必须在 xg_dorm_campus 且未删除;用该记录的 campus_name 覆盖冗余字段(不信任前端传的 name)

3.2 新增批量接口

PUT /classMsg/classMsg/campus/batch

请求体:

{
  "ids": [1, 2, 3],
  "campusId": 1946815553291304962
}
字段 校验
ids 非空
campusId 非空;必须存在于 xg_dorm_campus(未删除)

行为:将选中班级的 campus_id、campus_name 统一更新为该校区。
权限:classMsg:classMsg:edit(与现有批量状态一致,当前控制器上部分权限注解可能被注释,实现时保持与同模块其他写接口同一风格)。
日志:@Log 业务类型 UPDATE,标题「班级信息-新版」。

BO 建议:XgClassCampusBatchBo(对齐 XgClassStatusBatchBo)。

校区选项:前端继续使用 GET /xqxx/dormCampus/list,不新增选项 API。


4. 前端设计

页面:web/src/views/xg/xsjcxx/classmsg/classMsg/index.vue

区域 改动
搜索区 「所在校区」el-select,选项来自 listDormCampus,queryParams.campusId
工具栏 「批量设置校区」按钮;未勾选行时禁用(与毕业/暂停同用 :disabled="multiple");v-hasPermi="['classMsg:classMsg:edit']"
表格 列「所在校区」→ campusName
新增/修改弹窗 「所在校区」下拉,选填;变更时同步 form.campusId / form.campusName
批量弹窗 仅校区下拉(必选)+ 确认;调用 updateClassCampusBatch

API 封装:在 classMsg/index.ts 增加 updateClassCampusBatch,指向 /classMsg/classMsg/campus/batch。

交互:成功后提示并 getList(),对齐批量毕业/暂停。


5. 导入 / 模板规则

5.1 模板

  • XgClassMsgImportVo 增加字段「所在校区」(选填,无 @NotBlank)
  • 列顺序:插在「班级教室位置」之后;其后「班级状态 / 班主任 / 班级描述 / 备注」index 依次 +1
  • buildImportDropDownOptions:加载全部有效校区名称,注册为该列下拉
  • 示例行可不填校区;若填写须为真实可解析的校区名

5.2 导入解析(XgClassMsgImportListener)

情况 行为
单元格为空 不设置校区,班级仍可导入成功
名称唯一匹配到未删除校区 写入 campusId + campusName
名称不存在 / 已删除 该行失败,提示「校区不存在:xxx」
重名校区(极端) 该行失败,提示「校区名称不唯一:xxx」

说明:现有导入为仅新增;班级名重复则失败。历史班级补校区依赖批量设置,本期不做导入更新已有班级。


6. 主要改动文件(预估)

数据库

  • 增量 SQL:xg_class_msg 加列 + 索引

后端

  • XgClassMsg.java / XgClassMsgBo / XgClassMsgVo / XgClassMsgImportVo
  • XgClassCampusBatchBo(新建)
  • XgClassMsgController:list/export/importTemplate/importData + /campus/batch
  • IXgClassMsgService / XgClassMsgServiceImpl:查询条件、回填名称、批量更新
  • XgClassMsgImportListener:校区解析
  • XgClassMsgMapper.xml:若自定义列清单需补字段

前端

  • api/.../classMsg/types.ts、classMsg/index.ts
  • views/.../classMsg/index.vue

文档

  • 本 spec;实现后按项目规范同步 API/业务模块文档(若有班级信息专档)

7. 不在本期

  • 批量清空校区
  • 校区改名/删除后同步班级冗余名
  • 导入更新已有班级
  • 移动端班级相关页面
  • 数据库物理外键

8. 验收要点

  1. 新增班级可不选校区;可选校区后列表显示名称
  2. 搜索按校区过滤正确(含「空校区」班级不被误筛入有校区条件)
  3. 多选批量设置后,选中行 campusId/campusName 一致更新
  4. 下载模板「所在校区」为下拉;导入空校区成功;错误校区名行失败且有明确提示
  5. 导出含所在校区列
  6. 修改班级时可更换或清空校区

9. 测试建议

  • 单测/手工:批量接口非法 campusId、空 ids
  • 手工:导入模板下拉可选到西溪/临安等现有校区
  • 回归:原有批量毕业/暂停/解散、学院专业导入联动不受影响