# 专业信息管理 API 接口文档 ### 模块概述 **模块名称**:majormsg / 专业信息管理 **基础路径**:`/system/dept` **版本**:v1.0 **负责人**:Cursor AI **更新时间**:2025-12-26 ### 模块功能 专业信息管理模块主要用于管理学校的专业组织信息,通过sys_dept表存储专业基本信息,包括专业名称、所属学院、类别编码等。支持专业信息的增删改查操作,为学校专业架构管理提供基础数据支撑。 专业信息通过 `dept_category` 字段以 "zy-" 开头进行标识,属于二级学院的下级组织。 ### 权限说明 - **权限前缀**:`majormsg:` - **权限列表**: - `majormsg:major:list` - 查询权限 - `majormsg:major:add` - 新增权限 - `majormsg:major:edit` - 编辑权限 - `majormsg:major:remove` - 删除权限 --- ## 📊 接口概览 ### 接口分类 #### 基础 CRUD 接口 | 接口名称 | HTTP 方法 | 路径 | 权限要求 | 功能描述 | | -------------- | --------- | --------------------- | ---------------------- | ---------------------- | | 查询专业列表 | GET | `/system/dept/list` | `majormsg:major:list` | 分页查询专业列表 | | 查询专业详情 | GET | `/system/dept/{deptId}` | `majormsg:major:list` | 根据 ID 查询专业详情 | | 新增专业 | POST | `/system/dept` | `majormsg:major:add` | 创建新的专业 | | 修改专业 | PUT | `/system/dept` | `majormsg:major:edit` | 更新专业信息 | | 删除专业 | DELETE | `/system/dept/{deptId}` | `majormsg:major:remove` | 删除专业 | #### 业务逻辑接口 | 接口名称 | HTTP 方法 | 路径 | 权限要求 | 功能描述 | | ---------------- | --------- | ------------------- | --------------------- | ---------------- | | 获取学院树结构 | GET | `/system/dept/list` | `majormsg:major:list` | 获取二级学院树结构 | | 专业合并预览 | POST | `/xg/major/merge/preview` | `majormsg:major:merge` | 预览合并影响范围 | | 执行专业合并 | POST | `/xg/major/merge` | `majormsg:major:merge` | 执行专业合并(含行级快照) | ### 通用响应格式 #### 成功响应 ```json { "code": 200, "msg": "操作成功", "data": { // 响应数据 } } ``` #### 分页响应 ```json { "code": 200, "msg": "查询成功", "rows": [ // 数据列表 ], "total": 100 } ``` #### 错误响应 ```json { "code": 400001, "msg": "参数错误", "data": null } ``` --- ## 🔍 接口详细说明 ### 1. 查询专业列表 #### 接口信息 **接口地址**: `GET /system/dept/list` **接口描述**: 分页查询专业列表,支持多条件筛选,固定查询dept_category以"zy-"开头的数据 **权限要求**: `majormsg:major:list` #### 请求参数 | 参数名 | 类型 | 必填 | 说明 | 示例值 | | --------------- | ------- | ---- | ------------------------ | ------------ | | pageNum | Integer | N | 页码,默认 1 | 1 | | pageSize | Integer | N | 每页大小,默认 10 | 10 | | deptName | String | N | 专业名称 | "计算机科学" | | deptCategory | String | N | 部门类别编码 | "zy-001" | | deptCategoryLike| String | Y | 部门类别模糊匹配(zy-) | "zy-" | | parentId | Integer | N | 所属学院ID | 102 | | status | String | N | 状态:0 正常,1 停用 | "0" | #### 请求示例 ```bash curl -X GET "http://localhost:8080/system/dept/list?pageNum=1&pageSize=10&deptCategoryLike=zy-" \ -H "Authorization: Bearer {token}" \ -H "Content-Type: application/json" ``` #### 响应示例 ```json { "code": 200, "msg": "查询成功", "rows": [ { "deptId": 201, "parentId": 102, "parentName": "计算机学院", "deptName": "计算机科学与技术", "deptCategory": "zy-001", "orderNum": 1, "status": "0", "delFlag": "0", "createBy": 1, "createTime": "2025-12-26 10:00:00", "updateBy": 1, "updateTime": "2025-12-26 10:00:00" } ], "total": 1 } ``` #### 错误码 | 错误码 | 说明 | 解决方案 | | ------ | -------- | -------------------- | | 401001 | 未登录 | 请先登录获取 token | | 403001 | 无权限 | 请联系管理员分配权限 | | 400001 | 参数错误 | 检查请求参数格式 | --- ### 2. 查询专业详情 #### 接口信息 **接口地址**: `GET /system/dept/{deptId}` **接口描述**: 根据部门ID查询专业的详细信息 **权限要求**: `majormsg:major:list` #### 路径参数 | 参数名 | 类型 | 必填 | 说明 | 示例值 | | ------ | ---- | ---- | ------ | ------ | | deptId | Long | Y | 部门ID | 201 | #### 请求示例 ```bash curl -X GET "http://localhost:8080/system/dept/201" \ -H "Authorization: Bearer {token}" \ -H "Content-Type: application/json" ``` #### 响应示例 ```json { "code": 200, "msg": "查询成功", "data": { "deptId": 201, "parentId": 102, "parentName": "计算机学院", "deptName": "计算机科学与技术", "deptCategory": "zy-001", "orderNum": 1, "status": "0", "delFlag": "0", "createBy": 1, "createTime": "2025-12-26 10:00:00", "updateBy": 1, "updateTime": "2025-12-26 10:00:00" } } ``` #### 错误码 | 错误码 | 说明 | 解决方案 | | ------ | ---------- | -------------------- | | 404001 | 数据不存在 | 检查 ID 是否正确 | | 401001 | 未登录 | 请先登录获取 token | | 403001 | 无权限 | 请联系管理员分配权限 | --- ### 3. 新增专业 #### 接口信息 **接口地址**: `POST /system/dept` **接口描述**: 创建新的专业记录,dept_category必须以"zy-"开头 **权限要求**: `majormsg:major:add` #### 请求参数 | 参数名 | 类型 | 必填 | 说明 | 示例值 | | ----------- | ------- | ---- | ---------------------------- | ------------------- | | parentId | Integer | Y | 所属学院ID | 102 | | deptName | String | Y | 专业名称 | "计算机科学与技术" | | deptCategory| String | Y | 部门类别编码(必须以zy-开头)| "zy-001" | | orderNum | Integer | Y | 显示顺序 | 1 | | status | String | Y | 状态:0 正常,1 停用 | "0" | #### 请求体 ```json { "parentId": 102, "deptName": "计算机科学与技术", "deptCategory": "zy-001", "orderNum": 1, "status": "0" } ``` #### 请求示例 ```bash curl -X POST "http://localhost:8080/system/dept" \ -H "Authorization: Bearer {token}" \ -H "Content-Type: application/json" \ -d '{ "parentId": 102, "deptName": "计算机科学与技术", "deptCategory": "zy-001", "orderNum": 1, "status": "0" }' ``` #### 响应示例 ```json { "code": 200, "msg": "新增成功", "data": { "deptId": 201 } } ``` #### 错误码 | 错误码 | 说明 | 解决方案 | | ------ | ---------- | -------------------- | | 400001 | 参数错误 | 检查必填参数是否缺失 | | 400002 | 数据已存在 | 检查专业名称是否重复 | | 401001 | 未登录 | 请先登录获取 token | | 403001 | 无权限 | 请联系管理员分配权限 | #### 参数验证规则 - `parentId`: 必须是有效的二级学院ID - `deptName`: 长度 2-50 字符,不能为空 - `deptCategory`: 必须以 "zy-" 开头,长度 4-30 字符,不能为空 - `orderNum`: 必须为正整数 - `status`: 只能为 "0" 或 "1" --- ### 4. 修改专业 #### 接口信息 **接口地址**: `PUT /system/dept` **接口描述**: 更新专业信息 **权限要求**: `majormsg:major:edit` #### 请求参数 | 参数名 | 类型 | 必填 | 说明 | 示例值 | | ----------- | ------- | ---- | ---------------------------- | ------------------- | | deptId | Integer | Y | 专业ID | 201 | | parentId | Integer | Y | 所属学院ID | 102 | | deptName | String | Y | 专业名称 | "计算机科学与技术" | | deptCategory| String | Y | 部门类别编码(必须以zy-开头)| "zy-001" | | orderNum | Integer | Y | 显示顺序 | 1 | | status | String | Y | 状态:0 正常,1 停用 | "0" | #### 请求体 ```json { "deptId": 201, "parentId": 102, "deptName": "计算机科学与技术(本)", "deptCategory": "zy-001", "orderNum": 1, "status": "0" } ``` #### 请求示例 ```bash curl -X PUT "http://localhost:8080/system/dept" \ -H "Authorization: Bearer {token}" \ -H "Content-Type: application/json" \ -d '{ "deptId": 201, "parentId": 102, "deptName": "计算机科学与技术(本)", "deptCategory": "zy-001", "orderNum": 1, "status": "0" }' ``` #### 响应示例 ```json { "code": 200, "msg": "修改成功", "data": null } ``` #### 错误码 | 错误码 | 说明 | 解决方案 | | ------ | ---------- | -------------------- | | 404001 | 数据不存在 | 检查 ID 是否正确 | | 400001 | 参数错误 | 检查参数格式是否正确 | | 401001 | 未登录 | 请先登录获取 token | | 403001 | 无权限 | 请联系管理员分配权限 | --- ### 5. 删除专业 #### 接口信息 **接口地址**: `DELETE /system/dept/{deptId}` **接口描述**: 删除专业,支持逻辑删除 **权限要求**: `majormsg:major:remove` #### 路径参数 | 参数名 | 类型 | 必填 | 说明 | 示例值 | | ------ | ---- | ---- | -------- | ------ | | deptId | Long | Y | 专业ID | 201 | #### 请求示例 ```bash curl -X DELETE "http://localhost:8080/system/dept/201" \ -H "Authorization: Bearer {token}" \ -H "Content-Type: application/json" ``` #### 响应示例 ```json { "code": 200, "msg": "删除成功", "data": null } ``` #### 错误码 | 错误码 | 说明 | 解决方案 | | ------ | ---------- | -------------------- | | 400001 | 参数错误 | 检查 ID 格式是否正确 | | 400003 | 数据被引用 | 请先删除关联数据 | | 401001 | 未登录 | 请先登录获取 token | | 403001 | 无权限 | 请联系管理员分配权限 | --- ### 6. 获取学院树结构 #### 接口信息 **接口地址**: `GET /system/dept/list` **接口描述**: 获取二级学院的树形结构,用于左侧导航菜单 **权限要求**: `majormsg:major:list` #### 请求参数 | 参数名 | 类型 | 必填 | 说明 | 示例值 | | -------- | ------- | ---- | ---------------- | ------ | | parentId | Integer | Y | 父节点ID(固定为101) | 101 | #### 请求示例 ```bash curl -X GET "http://localhost:8080/system/dept/list?parentId=101" \ -H "Authorization: Bearer {token}" \ -H "Content-Type: application/json" ``` #### 响应示例 ```json { "code": 200, "msg": "查询成功", "data": [ { "deptId": 102, "parentId": 101, "deptName": "计算机学院", "deptCategory": "xy-19", "orderNum": 1, "status": "0" }, { "deptId": 103, "parentId": 101, "deptName": "人文学院", "deptCategory": "xy-19", "orderNum": 2, "status": "0" } ] } ``` --- ## 🔀 专业合并接口 > 权限:`majormsg:major:merge` > 说明:仅允许同一学院下专业合并;班级 ID 不变只改归属;`major_id` 与 `major_name`(及 code)同改;源专业停用;改前写入行级快照。 ### 1. 合并影响预览 **接口地址**: `POST /xg/major/merge/preview` #### 请求体 ```json { "targetMajorId": 20251223133304109, "selectedMajorIds": [20251223133304109, 20251223133304116] } ``` | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | targetMajorId | Long | Y | 目标专业 ID(必须在 selectedMajorIds 中) | | selectedMajorIds | Long[] | Y | 已选专业(含目标,至少 2 个) | #### 响应 data 要点 - `sources[]`:每个源专业的班级数、学生数 - `tableHits[]`:各业务表预计影响行数 - `warnings[]`:提示信息 - `totalClassCount` / `totalStudentCount` ### 2. 执行合并 **接口地址**: `POST /xg/major/merge` 请求体同预览。成功返回: ```json { "code": 200, "msg": "操作成功", "data": { "success": true, "mergeBatchId": 2090, "targetMajorId": 20251223133304109, "targetMajorName": "中药", "movedClassCount": 1, "updatedStudentCount": 50, "disabledMajorCount": 1, "snapshotRowCount": 120, "tableUpdateSummary": [{ "table": "xg_class_msg", "updated": 1 }] } } ``` ### 3. 相关 SQL - 表结构:`docs/设计文档/database/专业信息管理/专业合并快照表结构.sql` - 按钮权限:`docs/设计文档/database/专业信息管理/专业合并菜单权限.sql` - 实施计划:`docs/业务模块/专业信息管理/专业合并功能实施计划.md` ### 4. 手工回滚说明(P0) 合并成功后若需恢复,可按 `mergeBatchId` 查询: ```sql SELECT table_name, row_pk, row_json FROM xg_major_merge_row_snapshot WHERE merge_batch_id = ? AND deleted = 0; ``` 按 `table_name` 将 `row_json` 中的专业相关字段回写原表(注意:回滚会覆盖合并后的再次手工修改)。一键回滚 API 列入 P1。 --- ## 📋 数据字典 ### 专业状态枚举 | 值 | 名称 | 说明 | | --- | ---- | -------- | | 0 | 正常 | 专业正常运行 | | 1 | 停用 | 专业已停用 | ### 专业类别编码规范 | 前缀 | 说明 | 示例 | | ---- | ---- | ---- | | zy- | 专业标识前缀 | zy-001(计算机科学与技术)
zy-002(软件工程) | --- ## 🔧 SDK 使用示例 ### JavaScript SDK ```javascript // 查询专业列表 const queryParams = { pageNum: 1, pageSize: 10, deptCategoryLike: 'zy-', parentId: 102 }; const listResult = await listMajor(queryParams); // 新增专业 const majorData = { parentId: 102, deptName: "计算机科学与技术", deptCategory: "zy-001", orderNum: 1, status: "0" }; const addResult = await addMajor(majorData); // 修改专业 majorData.deptId = 201; majorData.deptName = "计算机科学与技术(本)"; const updateResult = await updateMajor(majorData); // 删除专业 const deleteResult = await delMajor(201); // 获取学院树 const collegeTree = await getCollegeTree(); ``` --- ## 🧪 测试用例 ### 接口测试 ```javascript // Jest 测试示例 describe('专业信息管理 API Tests', () => { test('查询专业列表接口', async () => { const response = await request(app) .get('/system/dept/list?deptCategoryLike=zy-') .set('Authorization', `Bearer ${token}`) .expect(200); expect(response.body.code).toBe(200); expect(response.body.data).toBeDefined(); }); test('新增专业接口', async () => { const majorData = { parentId: 102, deptName: "测试专业", deptCategory: "zy-test", orderNum: 1, status: "0" }; const response = await request(app) .post('/system/dept') .set('Authorization', `Bearer ${token}`) .send(majorData) .expect(200); expect(response.body.code).toBe(200); expect(response.body.data.deptId).toBeDefined(); }); }); ``` --- ## 🔄 版本历史 ### v1.1.0 - 2026-08-18 - ✅ 新增专业合并预览 / 执行接口(`/xg/major/merge`) - ✅ 同学院多选合并;班级改挂;专业 ID 与名称同改;源专业停用 - ✅ 合并前行级快照(`xg_major_merge_batch` / `xg_major_merge_row_snapshot`) - ✅ 前端专业信息页增加【专业合并】按钮与弹窗 ### v1.0.0 - 2025-12-26 - ✅ 初始版本发布 - ✅ 完成基础 CRUD 接口 - ✅ 实现学院树形菜单和专业列表联动 - ✅ 支持专业的增删改查功能 --- ## 📖 相关文档 - **数据库设计**:[数据库设计文档](../设计文档/database/) - **业务需求**:[业务需求文档](../需求文档/) - **二级学院管理**:[二级学院管理API](./二级学院管理API.md) - **技术架构**:[技术架构文档](./技术架构/) - **开发规范**:[开发规范文档](./开发规范/) --- ## 📞 联系方式 **开发团队**:Cursor AI **负责人**:Cursor AI **邮箱**:无 **文档维护**:实时更新,如有问题请及时反馈 --- **📌 重要提醒**: 1. 所有接口都需要先登录获取 token 2. 请求头必须包含 `Authorization: Bearer {token}` 3. 专业类别编码必须以 "zy-" 开头 4. 新增专业时必须选择所属的二级学院 5. 删除操作会进行关联数据检查 6. 左侧学院树点击后,右侧列表会筛选对应学院的专业 7. 生产环境请使用 HTTPS 协议