# 班级信息增加「所在校区」 > 日期: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 ``` 请求体: ```json { "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` - 手工:导入模板下拉可选到西溪/临安等现有校区 - 回归:原有批量毕业/暂停/解散、学院专业导入联动不受影响