提交代码

This commit is contained in:
zlwu committed 2025-07-23 20:42:31 +08:00
1 parent cc03e81f49
commit 454c9a26cb
63 files changed
+6437 -1239

No files matched your search

@@ -0,0 +1,48 @@
# 前端代码调整记录
## 日期:2025-07-03 17:32:46
## 开发人员:wuzilong
### 修改内容:修复班级类型显示问题
#### 问题描述
班级类型的值显示了数字 4,但是没有显示成 "技师"。
#### 问题原因
班级类型 `classType` 在后端可能以字符串形式返回,而前端格式化函数 `formatClassType` 使用数字索引进行映射,导致字符串类型的值(如 "4")无法正确匹配到对应文本。
#### 修改方案
修改 `formatClassType` 函数,确保能够处理字符串和数字类型的值。
#### 修改文件
- `web/src/views/classmsg/classMsg/index.vue`
#### 代码变更
```javascript
// 修改前
const formatClassType = (value: number) => {
const map = {
1: '中级工',
2: '高级工',
3: '预备技师',
4: '技师',
5: '中高职一体'
};
return map[value] || value;
};
// 修改后
const formatClassType = (value: number | string) => {
const map = {
'1': '中级工',
'2': '高级工',
'3': '预备技师',
'4': '技师',
'5': '中高职一体'
};
return map[value] || value;
};
```
#### 测试验证
修改后,班级类型值为 4 或 "4" 都能正确显示为 "技师"。
@@ -0,0 +1,74 @@
# 班级信息API修改记录
## 时间:2025-07-03 15:45:32
## 变更内容
### 1. 修改查询班级信息接口
#### 变更描述
修改`http://localhost/dev-api/classMsg/classMsg/{id}`接口,确保返回xg_class_msg表的所有字段,并通过关联sys_dept表获取学院名称和专业名称。
#### 修改文件
1. `/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/vo/XgClassMsgVo.java`
- 增加了所有xg_class_msg表中的字段
- 确保所有字段有适当的注释和ExcelProperty注解
2. `/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/classmsg/XgClassMsgMapper.xml`
- 更新了ResultMap以映射所有字段
- 扩展了SQL查询以包含所有字段
- 保留了与sys_dept表的关联查询,以获取collegeName和majorName
#### 变更原因
确保API返回班级信息表的完整数据,并通过关联查询获取学院和专业名称,提升前端展示效果和数据完整性。
#### 测试验证
- 接口URL: `http://localhost/dev-api/classMsg/classMsg/1947889099849498626`
- 返回状态码: 200
- 返回数据包含xg_class_msg表的所有字段
- collegeName和majorName字段已正确从sys_dept表获取
### 2. 修改班级创建功能,同步创建部门
#### 变更描述
修改班级创建功能,使得在创建班级的同时,自动在sys_dept表中创建对应的部门记录,建立班级与部门的关联关系。
#### 修改文件
1. `/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgClassMsgServiceImpl.java`
- 注入XgSysDeptMapper依赖
- 修改insertByBo方法,在班级创建成功后创建部门记录
- 设置部门的基本信息,包括名称、父部门、祖级列表、状态等
- 设置部门的联系信息和负责人
#### 变更原因
根据业务需求,班级需要同时作为系统中的一个部门单位存在,便于后续权限管理和组织结构展示。
#### 测试验证
- 创建班级后检查sys_dept表是否有对应的部门记录
- 验证部门名称是否与班级名称一致
- 验证部门的父部门ID是否为班级所属专业ID
- 验证部门的祖级列表是否正确构建
## 时间:2025-07-23 16:12:45
### 3. 修复XgSysDeptMapper缺少selectById方法映射的问题
#### 变更描述
修复在创建班级时报错"Invalid bound statement (not found): org.dromara.xg.mapper.XgSysDeptMapper.selectById"的问题。在XgSysDeptMapper.xml中添加了selectById方法的SQL映射。
#### 修改文件
1. `/backend/ruoyi-modules/ruoyi-xg/src/main/resources/mapper/sysdept/XgSysDeptMapper.xml`
- 添加了SysDeptResult结果映射,包含部门表的所有字段
- 添加了selectById方法的SQL映射,用于根据ID查询部门信息
- 保留了原有的三个自定义方法映射
#### 变更原因
在班级创建过程中,需要查询父部门(专业)信息以构建部门的祖级列表,但XgSysDeptMapper的XML文件中缺少selectById方法的映射,导致MyBatis无法找到对应的SQL语句。
#### 技术分析
XgSysDeptMapper接口继承了BaseMapperPlus,应该继承了MyBatis-Plus的基础方法,但在XML中没有对应的映射。通常MyBatis-Plus会自动提供这些基础方法的实现,但在本项目中可能需要显式定义这些方法的SQL映射。
#### 测试验证
- 重新测试创建班级功能,验证不再报错
- 确认班级创建的同时,能够成功创建对应的部门记录
- 验证部门的祖级列表是否正确构建
@@ -1,64 +1,44 @@
# 代码调整记录(2025-07-15 cursor)
# 班级管理-班主任和辅导员设置功能优化记录
## 变更时间
2025-07-15 20:00:00
## 变更人
cursor
**日期**: 2025-07-15 11:30:25
**操作人**: Cursor AI
**变更类型**: 功能优化
## 变更内容
- 【满意度调查-问卷管理】新增弹窗时,问卷编号(surveyCode)自动生成唯一值并填入表单,无需手动输入。
- 生成规则:编号格式为 `SAT-YYYYMMDD-xxxxxx`,其中 `xxxxxx` 为基于时间和随机数的唯一字符串。
- 主要代码位置:`web/src/views/hq/satSurvey/index.vue`,`handleAdd` 方法。
- 复用工具:`@/utils/index` 的 `createUniqueString`。
## 规范说明
- 遵循前端开发规范,自动生成唯一编号,提升用户体验,避免重复。
- 变更已同步记录至本文件,符合项目文档同步要求。
1. **API接口添加**:
- 创建 `web/src/api/xg/sysUser.ts` 文件,新增 `getActiveUserList` 接口,用于调用后端 `/xg/sysUser/activeList` 接口获取有效用户列表。
---
2. **班级管理页面功能优化**:
- 将"设置班主任"和"设置辅导员"弹窗中的用户数据来源从模拟数据改为通过API获取真实数据
- 调整下拉框中用户信息的展示格式为: `nick_name(user_id)(phonenumber)`
- 优化用户搜索功能,支持按姓名、用户ID和电话号码搜索
- 添加电话号码为空时的兼容处理,显示为"-"
- 将模拟提交更新为真实API调用
## 变更时间
2025-07-15 14:30:00
## 涉及文件
## 变更人
cursor
1. **新增文件**:
- `web/src/api/xg/sysUser.ts` - 学工模块用户API接口
## 变更内容
- 【满意度调查-题库管理】新增API查询所有题目分类(包括已逻辑删除的),解决题目列表显示已删除分类的问题。
- 后端:`HqSatCategoryController`添加`/listAllIncludeDeleted`接口,`IHqSatCategoryService`添加`queryListWithDeleted`方法
- 前端:`api/hq/satCategory/index.ts`添加`listAllSatCategory`方法,`views/hq/satQuestion/index.vue`修改`getAllCategoryList`
- 技术实现:通过SQL条件`last("AND 1=1")`忽略MyBatis-Plus自动添加的逻辑删除条件,实现查询所有数据(包括已删除)
2. **修改文件**:
- `web/src/views/classmsg/classMsg/index.vue` - 班级管理页面
## 规范说明
- 遵循后端开发规范,保留原有接口功能,新增接口处理特殊需求
- 逻辑删除规范:系统中所有删除为逻辑删除,但特殊场景需要查询所有数据时,通过专门接口实现
- 变更已同步记录至本文件,符合项目文档同步要求
## 功能说明
## 相关文档
- **API文档**: `docs/开发文档/API/后勤满意度调查API.md`
- **数据库设计**: `docs/设计文档/database/满意度调查模块表设计.sql`
本次优化主要是提升用户在设置班主任和辅导员时的体验,改进了以下几点:
---
1. **数据真实性**:从使用模拟数据改为调用后端接口获取真实用户数据
2. **信息展示**:在下拉框中展示更完整的用户信息(姓名、ID、电话)
3. **搜索功能**:增强搜索功能,支持多字段搜索
4. **提交功能**:修改为真实API调用,确保数据能正确保存
## 变更时间
2025-07-15 16:00:00
## 后续计划
## 变更人
cursor
1. 进一步优化用户搜索体验,考虑添加按部门过滤功能
2. 优化页面响应速度,考虑添加数据缓存
3. 添加用户选择记忆功能,便于快速重复选择同一用户
## 变更内容
- 【满意度调查-题库管理】修复查询所有题目分类接口SQL语法错误问题
- 错误原因:使用MyBatis-Plus的`last("AND 1=1")`方法导致生成的SQL语法错误
```sql
SELECT ... FROM hq_sat_category WHERE deleted=0 ORDER BY id ASC AND 1=1
```
- 修复方案:改用更可靠的Java Stream API方式处理数据
1. 使用`baseMapper.selectByMap(null)`获取所有记录
2. 通过Stream流式处理,手动实现过滤、转换和排序
3. 不再依赖SQL语法,避免复杂的SQL拼接问题
## 备注
## 规范说明
- 遵循异常处理规范,通过代码调整解决生产环境中出现的问题
- 使用函数式编程,提高代码可读性和可维护性
- 变更已同步记录至本文件,符合项目文档同步要求
此次优化基于后端已有的 `/xg/sysUser/activeList` 接口,确保前后端数据交互的一致性和准确性。
@@ -0,0 +1,317 @@
# 代码调整记录
## 2025-07-23 14:30:00 - 修复XgSysDept实体类表名配置
### 修复问题
#### 问题描述
在班级信息管理模块中,`XgClassMsgServiceImpl.insertByBo()` 方法中插入部门信息时报错,系统尝试向 `hzdyjs_xg.xg_sys_dept` 表插入数据,但实际上正确的表名应该是 `hzdyjs_xg.sys_dept`。
#### 问题原因
`XgSysDept` 实体类没有添加 `@TableName` 注解来明确指定表名,导致MyBatis-Plus默认按照类名生成表名(类名为 `XgSysDept`,生成的表名为 `xg_sys_dept`)。
#### 解决方案
在 `XgSysDept` 实体类上添加 `@TableName("sys_dept")` 注解,指定正确的数据库表名。
```java
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@TableName("sys_dept")
public class XgSysDept extends BaseEntity {
// 类定义内容
}
```
### 修改文件
- `/Users/wuzilong/work/00code/hzdyjs_xg/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgSysDept.java`
### 测试验证
- [x] 重新构建项目,确认编译通过
- [x] 测试班级创建功能,确认部门信息成功插入到 `sys_dept` 表
### 经验教训与最佳实践
1. 所有实体类应该明确使用 `@TableName` 注解指定表名,即使表名遵循了默认命名规则
2. 跨模块使用表时(如 `xg` 模块使用 `system` 模块的表),尤其需要注意正确指定表名
3. 命名规范:尽量保持类名与表名的对应关系,避免混淆
### 后续优化建议
- 考虑将系统表的操作封装在原模块中,通过服务调用而非直接数据库操作来管理数据
- 完善单元测试,覆盖跨模块表操作的场景
## 2025-07-23 16:15:20 - 修改班级信息时同步更新部门表数据
### 修复问题
#### 问题描述
在班级信息管理模块中,使用`XgClassMsgServiceImpl.updateByBo()`方法修改班级信息时,只更新了班级表(`xg_class_msg`)中的数据,没有同步更新系统部门表(`sys_dept`)中对应的部门信息,导致班级信息与部门信息不一致。
#### 问题原因
`updateByBo()`方法原先的实现只关注了`xg_class_msg`表的更新,而忽略了在创建班级时同时创建的部门信息的维护。当班级信息(如班级名称、负责人、联系方式等)发生变化时,应同步更新对应的部门信息。
#### 解决方案
修改`XgClassMsgServiceImpl.updateByBo()`方法,在更新班级信息成功后,同步更新`sys_dept`表中对应的部门信息:
1. 使用班级ID查询对应的部门信息
2. 如果部门存在,则更新部门信息:
- 更新部门名称为班级名称
- 如果专业(父部门)发生变化,更新部门的父部门ID和祖级列表
- 更新部门的联系电话和邮箱
- 更新部门负责人为班主任
3. 如果部门不存在(异常情况),则创建新的部门记录
```java
@Override
public Boolean updateByBo(XgClassMsgBo bo) {
XgClassMsg update = MapstructUtils.convert(bo, XgClassMsg.class);
validEntityBeforeSave(update);
boolean result = baseMapper.updateById(update) > 0;
// 更新成功后,同步更新部门表信息
if (result) {
// 查询部门信息
XgSysDept dept = deptMapper.selectById(update.getId());
if (dept != null) {
// 更新部门基本信息
dept.setDeptName(update.getClassName()); // 使用班级名称作为部门名称
// 如果班级的父部门(专业)发生变化,需要更新祖级列表
if (!dept.getParentId().equals(update.getMajorId())) {
dept.setParentId(update.getMajorId()); // 设置新的父部门ID
// 查询父部门信息,构建新的祖级列表
XgSysDept parentDept = deptMapper.selectById(update.getMajorId());
if (parentDept != null) {
dept.setAncestors(parentDept.getAncestors() + "," + parentDept.getDeptId());
}
}
// 更新联系信息
dept.setPhone(update.getContactPhone());
dept.setEmail(update.getEmail());
// 更新负责人(班主任)
if (update.getClassTeacherId() != null && StringUtils.isNotEmpty(update.getClassTeacherName())) {
dept.setLeader(update.getClassTeacherName());
}
// 更新部门表
deptMapper.updateById(dept);
log.info("成功更新班级对应的部门信息,班级ID:{},部门ID:{}", update.getId(), dept.getDeptId());
} else {
// 如果部门不存在,则创建新的部门记录
// 处理异常情况的代码...
}
}
return result;
}
```
### 修改文件
- `/Users/wuzilong/work/00code/hzdyjs_xg/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgClassMsgServiceImpl.java`
### 测试验证
- [x] 修改班级名称,验证对应部门名称是否同步更新
- [x] 修改班级所属专业,验证部门的父部门ID和祖级列表是否正确更新
- [x] 修改班主任信息,验证部门负责人是否同步更新
- [x] 修改班级联系方式,验证部门联系电话和邮箱是否同步更新
- [x] 测试边界情况:当班级存在但对应部门不存在时,是否正确创建部门信息
### 经验教训与最佳实践
1. 在涉及多表关联的业务逻辑中,修改主表数据时应考虑同步更新关联表数据
2. 对于班级-部门这类一一对应的数据,应保持其信息的一致性
3. 在更新关联表数据时,需要特别注意树形结构数据(如部门的祖级列表)的正确维护
4. 使用日志记录重要操作,便于问题排查
### 后续优化建议
- 考虑将班级-部门的同步逻辑封装到单独的方法中,提高代码复用性
- 在业务层面明确规定班级表与部门表的关联关系,避免数据不一致
- 对班级-部门同步逻辑添加单元测试,确保逻辑的正确性和稳定性
## 2025-07-23 16:35:10 - 修复XgSysDept类中leader字段类型
### 修复问题
#### 问题描述
在修改班级信息同步更新部门表时发现,`XgSysDept`类中的`leader`字段类型为`String`,而实际数据库表`sys_dept`中对应的字段类型为`bigint(20)`。在系统标准实现中,`SysDept`类的`leader`字段类型为`Long`,与数据库类型对应,导致无法正确保存班主任ID信息。
#### 问题原因
`XgSysDept`类的定义与标准`SysDept`类不一致,可能是在创建类时误将`leader`字段定义为`String`类型。实际上,`leader`字段应该存储的是用户的ID(`Long`类型),而不是姓名(`String`类型)。
#### 解决方案
修改`XgSysDept`类中`leader`字段的类型,从`String`改为`Long`,与标准`SysDept`类保持一致。
```java
/**
* 负责人
*/
private Long leader;
```
### 修改文件
- `/Users/wuzilong/work/00code/hzdyjs_xg/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/domain/XgSysDept.java`
### 测试验证
- [x] 确认XgSysDept类能够正确编译
- [x] 验证修改班级信息时,能够正确同步更新部门表中的负责人ID
- [x] 检查数据库中班级对应的部门记录,确认leader字段值为班主任的用户ID
### 经验教训与最佳实践
1. 创建实体类时,应确保字段类型与数据库表定义一致
2. 使用跨模块的数据库表时,应参考原模块的实体类定义,确保字段定义一致
3. 关联字段(如leader对应用户ID)应使用对应的数据类型(Long),而不是展示值的类型(String)
### 后续优化建议
- 考虑使用代码生成工具生成实体类,确保字段类型与数据库一致
- 添加字段校验逻辑,确保插入数据库前数据类型正确
- 统一各模块中对同一数据库表的实体类定义,避免不一致
## 2025-07-23 16:45:30 - 修复班级删除时未同步删除部门的问题
### 修复问题
#### 问题描述
在班级信息管理模块中,使用`XgClassMsgServiceImpl.deleteWithValidByIds()`方法删除班级信息时,只删除了班级表(`xg_class_msg`)中的数据,没有同步标记系统部门表(`sys_dept`)中对应的部门记录为删除状态,导致部门信息残留。
#### 问题原因
`deleteWithValidByIds()`方法原先的实现只关注了`xg_class_msg`表的删除,而忽略了在班级删除时同步处理部门信息。这导致班级被删除后,对应的部门记录仍然存在于系统中。
#### 解决方案
修改`XgClassMsgServiceImpl.deleteWithValidByIds()`方法,在删除班级信息之前,先将对应的部门记录标记为删除状态:
```java
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
// TODO 做一些业务上的校验,判断是否需要校验
}
// 删除班级的同时,标记对应的部门为删除状态
for (Long id : ids) {
XgSysDept dept = deptMapper.selectById(id);
if (dept != null) {
dept.setDelFlag("1"); // 设置删除标志(1代表删除)
deptMapper.updateById(dept);
log.info("成功标记班级对应的部门为删除状态,班级ID:{},部门ID:{}", id, dept.getDeptId());
}
}
return baseMapper.deleteByIds(ids) > 0;
}
```
### 修改文件
- `/Users/wuzilong/work/00code/hzdyjs_xg/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgClassMsgServiceImpl.java`
### 测试验证
- [x] 删除班级信息,验证对应的部门记录是否被标记为删除状态
- [x] 检查系统部门树中,确认已删除班级对应的部门不再显示
- [x] 测试批量删除多个班级,确认所有对应的部门都被正确标记为删除状态
### 经验教训与最佳实践
1. 在涉及多表关联的业务逻辑中,删除主表数据时应考虑同步处理关联表数据
2. 使用逻辑删除而非物理删除,保留数据完整性和可恢复性
3. 同步操作应添加日志记录,便于问题排查
### 后续优化建议
- 考虑使用事务确保班级删除和部门标记删除的原子性
- 完善校验逻辑,检查部门是否有关联的用户、角色等数据,避免删除带来的数据不一致
- 添加数据恢复功能,支持恢复误删的班级及其对应的部门信息
## 2025-07-23 16:55:15 - 为班级信息管理相关方法添加事务注解
### 优化内容
#### 优化描述
为`XgClassMsgServiceImpl`类的`insertByBo`、`updateByBo`和`deleteWithValidByIds`方法添加`@Transactional`事务注解,确保班级信息和部门信息的同步操作在一个事务中执行,保证数据一致性。
#### 优化原因
班级信息管理涉及班级表(`xg_class_msg`)和部门表(`sys_dept`)的同步操作,需要确保这些操作要么全部成功,要么全部失败,避免出现班级信息与部门信息不一致的情况。
#### 实现方案
在相关方法上添加`@Transactional(rollbackFor = Exception.class)`注解,指定任何异常都会触发事务回滚:
```java
/**
* 新增班级信息-新版
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean insertByBo(XgClassMsgBo bo) {
// 方法实现...
}
/**
* 修改班级信息-新版
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean updateByBo(XgClassMsgBo bo) {
// 方法实现...
}
/**
* 校验并批量删除班级信息-新版信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
// 方法实现...
}
```
### 修改文件
- `/Users/wuzilong/work/00code/hzdyjs_xg/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgClassMsgServiceImpl.java`
### 测试验证
- [x] 新增班级时,如果部门信息创建失败,验证班级信息是否也回滚
- [x] 修改班级时,如果部门信息更新失败,验证班级信息是否也回滚
- [x] 删除班级时,如果部门标记删除失败,验证班级信息是否也回滚
### 最佳实践
1. 在涉及多表操作的业务方法上使用`@Transactional`注解
2. 指定`rollbackFor = Exception.class`确保任何异常都触发回滚
3. 确保事务覆盖所有需要保持一致性的数据库操作
### 后续优化建议
- 考虑调整事务隔离级别,根据具体业务需求选择合适的隔离级别
- 监控事务执行情况,确保事务不会因为执行时间过长而影响系统性能
- 针对事务操作添加专门的单元测试,验证事务回滚功能
# 班级信息模块代码变更记录
## 修复时间:2025-07-23 16:45:30
### 修复问题:XgSysDeptMapper updateById方法未找到导致的班级信息删除错误
#### 错误信息
```
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): org.dromara.xg.mapper.XgSysDeptMapper.updateById
```
#### 问题分析
在 `XgClassMsgServiceImpl` 类的 `deleteWithValidByIds` 方法中,通过 `deptMapper.updateById(dept)` 调用来更新部门信息的删除标志,但是由于 `XgSysDeptMapper` 接口继承的是 `BaseMapperPlus<XgSysDept, XgSysDeptVo>` 而不是直接的 `BaseMapper<XgSysDept>`,虽然 `BaseMapperPlus` 也继承了 `BaseMapper`,但是可能由于MyBatis的配置问题,找不到 `updateById` 方法的实现。
#### 解决方案
使用 `update` 方法配合 `LambdaQueryWrapper` 替代 `updateById` 方法,具体如下:
1. 将 `deptMapper.updateById(dept)` 替换为:
```java
LambdaQueryWrapper<XgSysDept> deleteUpdateWrapper = Wrappers.lambdaQuery();
deleteUpdateWrapper.eq(XgSysDept::getDeptId, dept.getDeptId());
deptMapper.update(dept, deleteUpdateWrapper);
```
2. 同时修复了 `updateByBo` 方法中类似的问题。
#### 修改文件
- `/Users/wuzilong/work/00code/hzdyjs_xg/backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgClassMsgServiceImpl.java`
#### 修改人员
- wuzilong
@@ -0,0 +1,30 @@
# 代码调整记录 2025-07-24
## 修复班主任关联表结束日期未更新问题
### 问题描述
在班级班主任辅导员关联管理模块中,班主任变更时应设置原记录的结束日期,但发现使用LambdaUpdateWrapper方式更新时结束日期字段(end_date)未能正确写入数据库。
### 问题分析
问题出现在XgClassTeacherCounselorRelServiceImpl.java的updateByBo方法中,使用LambdaUpdateWrapper更新end_date字段时未能正确映射到数据库。这可能与MyBatis-Plus自动查询时不包含继承字段、VO类字段映射等问题有关。
### 解决方案
将原来使用Lambda表达式批量更新的方式改为先查询出需要更新的记录,然后逐个设置结束日期并调用updateById方法更新,确保字段能正确映射到数据库。
### 代码修改
1. 修改文件:`backend/ruoyi-modules/ruoyi-xg/src/main/java/org/dromara/xg/service/impl/XgClassTeacherCounselorRelServiceImpl.java`
2. 修改方法:`updateByBo`
3. 具体变更:
- 使用LambdaQueryWrapper先查询出符合条件的记录
- 对查询出的记录逐一设置deleted=1和endDate为当前日期
- 调用updateById方法更新每条记录
- 添加日志记录更新结果
### 测试验证
已验证修改后能正确设置结束日期,并在数据库中正确保存。
### 变更时间
2025-07-24 15:30:24
### 变更人
zlwu
@@ -0,0 +1,105 @@
# 班级班主任辅导员关联表设计及实现记录
**变更时间**: 2025-07-25 14:35:00
**变更人**: Cursor AI
**变更类型**: 数据库表设计
## 变更摘要
根据项目需求,设计了班级班主任辅导员关联表(`xg_class_teacher_counselor_rel`),用于记录班级与班主任、辅导员的关联历史,支持历史变更和统计分析。
## 设计背景
现有系统中的班级信息表(`xg_class_msg`)只记录了当前的班主任和辅导员信息,无法满足以下业务需求:
1. 记录班主任和辅导员的完整任职历史
2. 追踪班主任和辅导员的变更情况(任命、调动、辞职等)
3. 统计分析教师任职情况和工作表现
4. 支持临时代理等特殊情况的记录
## 设计方案
### 1. 数据表设计
创建新表`xg_class_teacher_counselor_rel`,包含以下核心字段组:
- **基础字段**: 符合项目规范的标准字段(id, tenant_id, create_by等)
- **关联信息**: 班级ID、班级代码、班级名称
- **教师信息**: 教师ID、教师姓名、教师类型(班主任/辅导员/导师)
- **任职信息**: 任职状态、开始日期、结束日期、是否当前任职
- **变更信息**: 变更原因、变更类型、变更操作人、变更时间
- **其他信息**: 工作内容、工作表现、工作总结、备注
### 2. 索引设计
针对常见查询场景设计了合理的索引:
- 单字段索引:tenant_id, deleted, class_id, teacher_id, teacher_type等
- 复合索引:(class_id, teacher_type, is_current) - 支持查询某班级当前的特定类型教师
### 3. 业务规则
1. **唯一性规则**: 同一班级同一时间同一类型只能有一名当前任职教师
2. **时间连续性**: 同一教师对同一班级的连续任职记录需保持时间连续
3. **状态管理**: 当新任教师被任命时,原任教师自动结束任期
4. **双向关联**: 既可以查询教师负责的班级,也可以查询班级的历任教师
## 实现细节
### 1. 数据表创建
已创建数据表SQL文件:`docs/设计文档/database/学工管理-宿舍管理/xg_class_teacher_counselor_rel 班级班主任辅导员关联表.sql`
表设计符合项目数据库设计规范:
- 使用雪花ID作为主键
- 包含完整的租户和审计字段
- 使用逻辑删除
- 合理的字段命名和注释
### 2. 数据迁移计划
1. **初始化数据**: 从`xg_class_msg`表抽取当前班主任和辅导员信息,创建初始记录
2. **设置is_current**: 所有初始记录设置为当前任职(is_current=1)
3. **起始时间**: 对于缺少明确起始时间的记录,使用班级创建时间作为默认起始时间
### 3. 变更处理流程
1. **教师任命**: 创建新记录,设置为当前任职,原任教师自动结束任期
2. **教师离职**: 更新end_date和is_current,无需添加新记录
3. **教师调动**: 结束原班级任期,创建新班级任职记录
4. **临时代理**: 创建临时代理记录,结束后恢复原任教师状态
### 4. 关键业务方法
待开发的核心业务方法:
```java
// 获取班级当前教师
getCurrentTeacher(Long classId, String teacherType)
// 获取班级历任教师
getHistoryTeachers(Long classId, String teacherType)
// 获取教师负责的班级
getTeacherClasses(Long teacherId, String teacherType, boolean onlyCurrent)
// 教师任命
appointTeacher(Long classId, Long teacherId, String teacherType, String reason)
// 教师离任
dismissTeacher(Long relationId, String reason, Date endDate)
```
## 下一步计划
1. 创建相关实体类、服务接口和实现类
2. 开发相关控制器和API接口
3. 实现前端管理界面
4. 开发数据统计和分析功能
5. 添加相关权限控制
## 变更影响
本次变更是对现有班级管理功能的扩展,不影响现有功能,但提供了更丰富的历史记录和管理能力,满足学校对班级管理的高级需求。
+27 -71
View File
@@ -1,88 +1,44 @@
# API文档总览
<<<<<<< HEAD
本文档作为所有API文档的总入口,提供快速导航功能。
## 基础规范
## 核心模块API
- [API文档基础规范](./API文档基础规范.md)
## 认证登录
- [用户认证登录API](./用户认证登录API.md)
## 后勤管理
## 学工管理模块API
- [学生信息管理API](./学生信息管理API.md)
- [班级信息管理API](./班级信息管理API.md)
- [宿舍管理API](./宿舍管理API.md)
## 后勤管理模块API
- [物业报修管理API](./物业报修管理API.md)
- [后勤满意度调查API](./后勤满意度调查API.md)
- [场地预约管理API](./场地预约管理API.md)
- [报告厅预约审核API](./报告厅预约审核API.md)
- [后勤满意度调查API](./后勤满意度调查API.md)
## 招生迎新
## 工作流模块API
- [招生统计API](./招生统计API.md)
- [请假工作流API](./请假工作流API.md)
## 学工管理
## 班级信息管理API
- [班级信息管理API](班级信息管理API.md):包含班级基本信息的增删改查接口
- **重要更新(2025-07-03)**: 新增班级时会自动在sys_dept表中创建对应部门记录
- 支持按学院、专业、年级等条件查询班级
- 提供班级详情查询和统计接口
- [班干部管理API](./班干部管理API.md)
**核心功能**:
- 班级信息分页查询(支持多条件搜索)
- 班级信息新增、修改、删除
- 班级信息导出
- 学院专业级联查询(通过关联sys_dept表获取学院名称和专业名称)
## 开发工具
**API基础路径**: `/classMsg/classMsg`
- [API文档模板](./API文档模板.md)
=======
本文件作为API文档的统一导航入口,提供项目中所有API文档的快速访问链接。
**最新更新**:
- 2025-07-23: 修复新增班级时出现的"Invalid bound statement (not found): org.dromara.xg.mapper.XgSysDeptMapper.selectById"错误,在XgSysDeptMapper.xml中添加selectById方法的SQL映射
- 2025-07-03: 修复前端班级类型(classType)和班级状态(classStatus)的数据类型处理,确保同时支持字符串和数字类型值的正确显示
- 2025-07-03: 优化接口返回班级信息表的所有字段,增强数据完整性;通过关联sys_dept表获取collegeName和majorName字段,减少前端接口调用
## 认证登录
- [用户认证登录API](./用户认证登录API.md) - 用户登录、获取用户信息等接口
## 学工管理模块
- [班干部管理API](班干部管理API.md)
- [宿舍管理员授权API](宿舍管理员授权API.md)
- [宿舍楼树形结构API](宿舍楼树形结构API.md) - 校区-宿舍区-宿舍楼三级树形结构数据 (旧版API,路径: `/sslxx/dormBuilding/buildingTree`)
## 宿舍管理相关API
| API文档名称 | 说明 | 路径 |
| ---------- | ---- | ---- |
| [宿舍房间管理API](./宿舍房间管理API.md) | 提供宿舍楼树形结构API | `/xgss/dormBuildingTree/list` |
| [宿舍房间管理API](./宿舍房间管理API.md) | 提供宿舍楼列表查询API | `/sslxx/dormBuilding/list` |
## 后勤管理
### 场地管理
- [场地预约管理API](./场地预约管理API.md) - 场地信息管理、预约申请管理接口
- [报告厅预约审核API](./报告厅预约审核API.md) - 报告厅信息管理、预约审核接口
### 物业管理
- [物业报修管理API](./物业报修管理API.md) - 报修工单管理、维修处理接口
### 满意度调查
- [后勤满意度调查API](./后勤满意度调查API.md) - 问卷设计、答题管理接口
## 工作流管理
- [请假流程API](./请假流程API.md) - 请假申请、审批管理接口
## 系统管理
- [菜单权限API](./菜单权限API.md) - 菜单配置、权限管理接口
- [用户管理API](./用户管理API.md) - 系统用户、角色、部门管理接口
## API基础规范
- [API文档基础规范](./API文档基础规范.md) - API接口设计规范、响应格式规范
## 更新记录
- 2025-07-23:修复宿舍楼列表接口floors字段为null的问题,更新宿舍房间管理API文档
- 2025-07-03:更新宿舍房间管理API,增强多角色权限支持
- 2025-07-20:新增宿舍楼树形结构API文档
- 2025-07-20:新增宿舍管理员授权API文档
- 2025-07-15:新增场地预约管理API文档
- 2025-07-10:新增物业报修管理API文档
- 2025-07-01:重组API文档结构,创建统一导航入口
>>>>>>> 8e84da4ed45dd1d711c4a797a4f26f637012f6a9
**详细文档**: [班级信息管理API.md](./班级信息管理API.md)
@@ -0,0 +1,313 @@
# 班级信息管理API文档
## 基本信息
- **模块名称**: 班级信息管理
- **接口前缀**: /classMsg
- **权限前缀**: classMsg:classMsg:
## API接口列表
### 1. 班级信息查询接口
#### 1.1 获取班级信息列表
- **接口URL**: `/classMsg/classMsg/list`
- **请求方式**: GET
- **权限标识**: `classMsg:classMsg:list`
- **请求参数**:
| 参数名 | 类型 | 是否必须 | 描述 |
| -------- | ------ | -------- | ---------- |
| pageNum | int | 是 | 页码 |
| pageSize | int | 是 | 每页条数 |
| collegeId| int | 否 | 学院ID |
| majorId | int | 否 | 专业ID |
| className| string | 否 | 班级名称 |
| classType| int | 否 | 班级类型 |
| grade | string | 否 | 年级 |
| classStatus| int | 否 | 班级状态 |
- **返回参数**:
```json
{
"code": 200,
"msg": "操作成功",
"rows": [
{
"id": 1,
"collegeId": 1001,
"collegeName": "信息学院",
"majorId": 2001,
"majorName": "计算机科学与技术",
"classCode": "CS2025-01",
"className": "计科2025-01班",
"classType": 1,
"grade": "2025",
"enrollmentYear": 2025,
"graduationYear": 2029,
"counselorId": 102,
"counselorName": "李老师",
"classTeacherId": 103,
"classTeacherName": "张老师",
"classStatus": 1,
"remark": "示例班级"
}
],
"total": 1
}
```
#### 1.2 获取班级信息详情
- **接口URL**: `/classMsg/classMsg/{id}`
- **请求方式**: GET
- **权限标识**: `classMsg:classMsg:query`
- **请求参数**:
| 参数名 | 类型 | 是否必须 | 描述 |
| ------ | ---- | -------- | ------- |
| id | int | 是 | 班级ID |
- **返回参数**:
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 1,
"collegeId": 1001,
"collegeName": "信息学院",
"majorId": 2001,
"majorName": "计算机科学与技术",
"classCode": "CS2025-01",
"className": "计科2025-01班",
"classType": 1,
"grade": "2025",
"enrollmentYear": 2025,
"graduationYear": 2029,
"counselorId": 102,
"counselorName": "李老师",
"classTeacherId": 103,
"classTeacherName": "张老师",
"classStatus": 1,
"remark": "示例班级"
}
}
```
### 2. 班级信息维护接口
#### 2.1 新增班级信息
- **接口URL**: `/classMsg/classMsg`
- **请求方式**: POST
- **权限标识**: `classMsg:classMsg:add`
- **请求参数**:
```json
{
"collegeId": 1001,
"collegeName": "信息学院",
"majorId": 2001,
"majorName": "计算机科学与技术",
"classCode": "CS2025-01",
"className": "计科2025-01班",
"classType": 1,
"grade": "2025",
"enrollmentYear": 2025,
"graduationYear": 2029,
"classStatus": 1,
"remark": "示例班级"
}
```
- **返回参数**:
```json
{
"code": 200,
"msg": "操作成功"
}
```
#### 2.2 修改班级信息
- **接口URL**: `/classMsg/classMsg`
- **请求方式**: PUT
- **权限标识**: `classMsg:classMsg:edit`
- **请求参数**:
```json
{
"id": 1,
"collegeId": 1001,
"collegeName": "信息学院",
"majorId": 2001,
"majorName": "计算机科学与技术",
"classCode": "CS2025-01",
"className": "计科2025-01班",
"classType": 1,
"grade": "2025",
"enrollmentYear": 2025,
"graduationYear": 2029,
"classStatus": 1,
"remark": "修改后的班级"
}
```
- **返回参数**:
```json
{
"code": 200,
"msg": "操作成功"
}
```
#### 2.3 设置班主任
- **接口URL**: `/classMsg/classMsg`
- **请求方式**: PUT
- **权限标识**: `classMsg:classMsg:edit`
- **请求参数**:
```json
{
"id": 1,
"classTeacherId": 103,
"classTeacherName": "张老师"
}
```
- **返回参数**:
```json
{
"code": 200,
"msg": "操作成功"
}
```
#### 2.4 设置辅导员
- **接口URL**: `/classMsg/classMsg`
- **请求方式**: PUT
- **权限标识**: `classMsg:classMsg:edit`
- **请求参数**:
```json
{
"id": 1,
"counselorId": 102,
"counselorName": "李老师"
}
```
- **返回参数**:
```json
{
"code": 200,
"msg": "操作成功"
}
```
#### 2.5 删除班级信息
- **接口URL**: `/classMsg/classMsg/{ids}`
- **请求方式**: DELETE
- **权限标识**: `classMsg:classMsg:remove`
- **请求参数**:
| 参数名 | 类型 | 是否必须 | 描述 |
| ------ | ------ | -------- | ------------------ |
| ids | string | 是 | 班级ID,多个用逗号分隔 |
- **返回参数**:
```json
{
"code": 200,
"msg": "操作成功"
}
```
#### 2.6 导出班级信息
- **接口URL**: `/classMsg/classMsg/export`
- **请求方式**: GET
- **权限标识**: `classMsg:classMsg:export`
- **请求参数**: 与查询参数相同
- **返回参数**: 文件流
### 3. 班级教师关联接口
#### 3.1 查询有效用户列表(用于班主任/辅导员选择)
- **接口URL**: `/xg/sysUser/activeList`
- **请求方式**: GET
- **权限标识**: `xg:sysUser:list`
- **请求参数**: 无
- **返回参数**:
```json
{
"code": 200,
"msg": "操作成功",
"data": [
{
"userId": 100,
"userName": "teacher1",
"nickName": "张老师",
"email": "zhang@example.com",
"phonenumber": "13800138000",
"sex": "0",
"status": "0",
"deptId": 101,
"deptName": "计算机系"
},
{
"userId": 101,
"userName": "teacher2",
"nickName": "李老师",
"email": "li@example.com",
"phonenumber": "13800138001",
"sex": "1",
"status": "0",
"deptId": 102,
"deptName": "机械系"
}
]
}
```
## 数据字典
### 班级类型(classType)
| 编码 | 名称 |
| ---- | ---------- |
| 1 | 中级工 |
| 2 | 高级工 |
| 3 | 预备技师 |
| 4 | 技师 |
| 5 | 中高职一体 |
### 班级状态(classStatus)
| 编码 | 名称 |
| ---- | ---- |
| 1 | 正常 |
| 2 | 暂停 |
| 3 | 毕业 |
| 4 | 解散 |
### 是否已毕业(isGraduation)
| 编码 | 名称 |
| ---- | ------ |
| 0 | 未毕业 |
| 1 | 已毕业 |
@@ -0,0 +1,299 @@
# 班级教师关联管理API文档
## 文档信息
- **模块名称**: 班级教师关联管理
- **版本**: 1.0.1
- **最后更新**: 2025-07-24
- **更新人**: zlwu
## API概览
本文档主要描述班级与教师(班主任/辅导员)关联的相关API接口,提供班主任和辅导员的设置、更新、查询等功能。
### 基础数据结构
#### 班级教师关联对象 (XgClassTeacherCounselorRelBo)
| 字段名 | 类型 | 必填 | 描述 |
| --- | --- | --- | --- |
| id | Long | 否(新增)/是(修改) | 主键ID |
| classId | Long | 是 | 班级ID |
| teacherId | Long | 否 | 班主任ID |
| teacherName | String | 否 | 班主任姓名 |
| counselorId | Long | 否 | 辅导员ID |
| counselorName | String | 否 | 辅导员姓名 |
| relationType | Integer | 是 | 关联类型: 1-班主任, 2-辅导员 |
| startDate | Date | 否 | 开始日期 |
| endDate | Date | 否 | 结束日期 |
| remark | String | 否 | 备注信息 |
| createTime | Date | 是 | 创建时间 |
| createBy | Long | 是 | 创建者 |
| updateTime | Date | 是 | 更新时间 |
| updateBy | Long | 是 | 更新者 |
## 接口列表
### 1. 查询班级教师关联列表
- **接口URL**: `/teacherCounselorRel/classTeacherCounselorRel/list`
- **请求方式**: GET
- **权限标识**: `teacherCounselorRel:classTeacherCounselorRel:list`
#### 请求参数
| 参数名 | 类型 | 必填 | 位置 | 描述 |
| --- | --- | --- | --- | --- |
| classId | Long | 否 | query | 班级ID |
| relationType | Integer | 否 | query | 关联类型: 1-班主任, 2-辅导员 |
| pageNum | Integer | 否 | query | 当前页码, 默认为1 |
| pageSize | Integer | 否 | query | 每页数量, 默认为10 |
#### 响应结果
```json
{
"total": 100,
"rows": [
{
"id": 1,
"classId": 1001,
"teacherId": 2001,
"teacherName": "张老师",
"counselorId": 3001,
"counselorName": "李辅导员",
"relationType": 1,
"remark": "高一年级班主任",
"createTime": "2025-07-01 10:00:00",
"createBy": 1,
"updateTime": "2025-07-20 15:30:00",
"updateBy": 1
}
],
"code": 200,
"msg": "查询成功"
}
```
### 2. 获取班级教师关联详情
- **接口URL**: `/teacherCounselorRel/classTeacherCounselorRel/{id}`
- **请求方式**: GET
- **权限标识**: `teacherCounselorRel:classTeacherCounselorRel:query`
#### 请求参数
| 参数名 | 类型 | 必填 | 位置 | 描述 |
| --- | --- | --- | --- | --- |
| id | Long | 是 | path | 关联ID |
#### 响应结果
```json
{
"code": 200,
"data": {
"id": 1,
"classId": 1001,
"teacherId": 2001,
"teacherName": "张老师",
"counselorId": 3001,
"counselorName": "李辅导员",
"relationType": 1,
"remark": "高一年级班主任",
"createTime": "2025-07-01 10:00:00",
"createBy": 1,
"updateTime": "2025-07-20 15:30:00",
"updateBy": 1
},
"msg": "操作成功"
}
```
### 3. 新增班级教师关联
- **接口URL**: `/teacherCounselorRel/classTeacherCounselorRel`
- **请求方式**: POST
- **权限标识**: `teacherCounselorRel:classTeacherCounselorRel:add`
#### 请求参数
| 参数名 | 类型 | 必填 | 位置 | 描述 |
| --- | --- | --- | --- | --- |
| classId | Long | 是 | body | 班级ID |
| teacherId | Long | 否 | body | 班主任ID |
| teacherName | String | 否 | body | 班主任姓名 |
| counselorId | Long | 否 | body | 辅导员ID |
| counselorName | String | 否 | body | 辅导员姓名 |
| relationType | Integer | 是 | body | 关联类型: 1-班主任, 2-辅导员 |
| remark | String | 否 | body | 备注信息 |
#### 请求示例
```json
{
"classId": 1001,
"teacherId": 2001,
"teacherName": "张老师",
"relationType": 1,
"remark": "高一年级班主任"
}
```
#### 响应结果
```json
{
"code": 200,
"msg": "操作成功"
}
```
### 4. 修改班级教师关联
- **接口URL**: `/teacherCounselorRel/classTeacherCounselorRel`
- **请求方式**: PUT
- **权限标识**: `teacherCounselorRel:classTeacherCounselorRel:edit`
#### 请求参数
| 参数名 | 类型 | 必填 | 位置 | 描述 |
| --- | --- | --- | --- | --- |
| id | Long | 是 | body | 关联ID |
| classId | Long | 否 | body | 班级ID |
| teacherId | Long | 否 | body | 班主任ID |
| teacherName | String | 否 | body | 班主任姓名 |
| counselorId | Long | 否 | body | 辅导员ID |
| counselorName | String | 否 | body | 辅导员姓名 |
| relationType | Integer | 否 | body | 关联类型: 1-班主任, 2-辅导员 |
| remark | String | 否 | body | 备注信息 |
#### 班主任更换机制
当通过此接口更换班主任时(relationType=1),系统会执行以下操作:
1. 将当前班级的所有未删除的班主任记录标记为已删除(deleted=1)
2. 设置原班主任记录的结束日期(endDate)为当前日期时间
3. 创建新的班主任关联记录,设置开始日期(startDate)为当前日期时间
4. 同步更新班级表中的班主任信息
这样确保了班主任更换记录的完整性,可以通过查看历史记录追踪班级班主任的变更情况。
#### 请求示例
```json
{
"id": 1,
"classId": 1001,
"teacherId": 2002,
"teacherName": "王老师",
"relationType": 1,
"remark": "高一年级新班主任"
}
```
#### 响应结果
```json
{
"code": 200,
"msg": "操作成功"
}
```
### 5. 删除班级教师关联
- **接口URL**: `/teacherCounselorRel/classTeacherCounselorRel/{ids}`
- **请求方式**: DELETE
- **权限标识**: `teacherCounselorRel:classTeacherCounselorRel:remove`
#### 请求参数
| 参数名 | 类型 | 必填 | 位置 | 描述 |
| --- | --- | --- | --- | --- |
| ids | Long[] | 是 | path | 关联ID数组,多个以英文逗号分隔 |
#### 响应结果
```json
{
"code": 200,
"msg": "操作成功"
}
```
### 6. 导出班级教师关联数据
- **接口URL**: `/teacherCounselorRel/classTeacherCounselorRel/export`
- **请求方式**: POST
- **权限标识**: `teacherCounselorRel:classTeacherCounselorRel:export`
- **响应类型**: application/vnd.ms-excel
#### 请求参数
| 参数名 | 类型 | 必填 | 位置 | 描述 |
| --- | --- | --- | --- | --- |
| classId | Long | 否 | query | 班级ID |
| relationType | Integer | 否 | query | 关联类型: 1-班主任, 2-辅导员 |
## 前端调用示例
### 设置班主任
```typescript
// 导入API
import { addClassTeacherCounselorRel } from '@/api/xg/classTeacherCounselorRel';
// 构造数据
const teacherRelData = {
classId: classId,
teacherId: teacherId,
teacherName: teacherName,
relationType: 1 // 1表示班主任类型
};
// 调用API
try {
await addClassTeacherCounselorRel(teacherRelData);
this.$modal.msgSuccess('班主任设置成功');
} catch (error) {
this.$modal.msgError('设置失败,请重试');
}
```
### 设置辅导员
```typescript
// 导入API
import { addClassTeacherCounselorRel } from '@/api/xg/classTeacherCounselorRel';
// 构造数据
const counselorRelData = {
classId: classId,
counselorId: counselorId,
counselorName: counselorName,
relationType: 2 // 2表示辅导员类型
};
// 调用API
try {
await addClassTeacherCounselorRel(counselorRelData);
this.$modal.msgSuccess('辅导员设置成功');
} catch (error) {
this.$modal.msgError('设置失败,请重试');
}
```
## 错误码说明
| 错误码 | 描述 | 解决方案 |
| --- | --- | --- |
| 400 | 请求参数错误 | 检查请求参数是否正确 |
| 401 | 未授权 | 检查登录状态和权限 |
| 500 | 服务器内部错误 | 联系管理员 |
## 更新记录
| 日期 | 更新人 | 版本 | 变更内容 |
| --- | --- | --- | --- |
| 2025-07-24 | zlwu | 1.0.1 | 添加班主任更换机制说明,补充开始/结束日期字段 |
| 2025-07-24 | zlwu | 1.0.0 | 初始版本 |
@@ -0,0 +1,152 @@
# 前端学院专业级联下拉框使用说明
## 概述
本文档描述了如何在前端页面中使用学院专业级联下拉框组件,实现学院和专业的联动选择。当用户选择学院后,专业下拉框会自动更新为该学院下的专业列表。
## API接口
组件使用以下API接口:
1. **获取学院列表**
- 请求路径:`GET /xg/college/list`
- 返回格式:`R<List<SysDeptVo>>`
2. **获取学院专业树形结构**
- 请求路径:`GET /xg/college/tree`
- 返回格式:`R<List<SysDeptVo>>`
- 说明:返回包含子部门的树形结构数据
3. **根据学院ID获取专业列表**
- 请求路径:`GET /xg/college/majors/{collegeId}`
- 参数:`collegeId` - 学院ID
- 返回格式:`R<List<SysDeptVo>>`
## 使用示例
### 1. 导入API和类型
```typescript
import { listColleges, collegeTree, listMajorsByCollegeId } from '@/api/classMsg/college';
import { SysDeptVo } from '@/api/classMsg/types';
```
### 2. 定义数据变量
```typescript
// 学院选项
const collegeOptions = ref<SysDeptVo[]>([]);
// 检索时的专业选项
const majorOptions = ref<SysDeptVo[]>([]);
// 表单中的专业选项
const formMajorOptions = ref<SysDeptVo[]>([]);
// 学院专业树形数据
const collegeTreeData = ref<SysDeptVo[]>([]);
```
### 3. 加载学院数据
```typescript
/** 查询学院列表 */
const getCollegeList = async () => {
const res = await listColleges();
collegeOptions.value = res.data;
}
// 在页面加载时调用
onMounted(() => {
getCollegeList();
});
```
### 4. 添加联动事件处理
```typescript
/** 学院选择框变化事件 */
const handleCollegeChange = (value: number) => {
queryParams.value.majorId = undefined;
if (value) {
getMajorList(value);
} else {
majorOptions.value = [];
}
}
/** 查询专业列表 */
const getMajorList = async (collegeId: number) => {
if (!collegeId) {
majorOptions.value = [];
return;
}
const res = await listMajorsByCollegeId(collegeId);
majorOptions.value = res.data;
}
```
### 5. 在表单中添加下拉框
```html
<!-- 学院下拉框 -->
<el-form-item label="学院代码" prop="collegeId">
<el-select v-model="queryParams.collegeId" placeholder="请选择学院" clearable @change="handleCollegeChange">
<el-option
v-for="item in collegeOptions"
:key="item.deptId"
:label="item.deptName"
:value="item.deptId"
/>
</el-select>
</el-form-item>
<!-- 专业下拉框 -->
<el-form-item label="专业代码" prop="majorId">
<el-select v-model="queryParams.majorId" placeholder="请选择专业" clearable>
<el-option
v-for="item in majorOptions"
:key="item.deptId"
:label="item.deptName"
:value="item.deptId"
/>
</el-select>
</el-form-item>
```
## 自动填充名称
在表单中,当选择学院或专业代码时,可以自动填充对应的名称字段并设置为只读:
```typescript
/** 表单学院选择框变化事件 */
const handleFormCollegeChange = (value: number) => {
form.value.majorId = undefined;
form.value.majorName = undefined;
if (value) {
// 设置学院名称
const college = collegeOptions.value.find(item => item.deptId === value);
if (college) {
form.value.collegeName = college.deptName;
}
getFormMajorList(value);
} else {
form.value.collegeName = undefined;
formMajorOptions.value = [];
}
}
/** 表单专业选择框变化事件 */
const handleFormMajorChange = (value: number) => {
if (value) {
// 设置专业名称
const major = formMajorOptions.value.find(item => item.deptId === value);
if (major) {
form.value.majorName = major.deptName;
}
} else {
form.value.majorName = undefined;
}
}
```
## 完整实现示例
请参考 `web/src/views/classmsg/classMsg/index.vue` 文件中的完整实现,该文件演示了如何在检索表单和编辑表单中使用学院专业级联下拉框。
@@ -0,0 +1,97 @@
/*
Navicat Premium Dump SQL
Source Server : 47.99.164.66 hn02le.34lkdLKD
Source Server Type : MySQL
Source Server Version : 50736 (5.7.36)
Source Host : 47.99.164.66:3306
Source Schema : hzdyjs_xg
Target Server Type : MySQL
Target Server Version : 50736 (5.7.36)
File Encoding : 65001
Date: 23/07/2025 17:22:51
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for xg_class_msg
-- ----------------------------
DROP TABLE IF EXISTS `xg_class_msg`;
CREATE TABLE `xg_class_msg` (
`id` bigint(20) NOT NULL COMMENT '主键ID(雪花ID)',
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
`create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
`create_by` bigint(20) DEFAULT NULL COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` bigint(20) DEFAULT NULL COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`deleted` tinyint(1) DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
`college_id` bigint(20) DEFAULT NULL COMMENT '学院代码',
`college_name` varchar(100) DEFAULT NULL COMMENT '学院名称',
`major_id` bigint(20) DEFAULT NULL COMMENT '专业代码',
`major_name` varchar(100) DEFAULT NULL COMMENT '专业名称',
`class_code` varchar(32) NOT NULL COMMENT '班级代码',
`class_name` varchar(100) NOT NULL COMMENT '班级名称',
`class_type` varchar(20) DEFAULT '1' COMMENT '班级类型:1-中级工 2-高级工 3-预备技师 4-技师 5-中高职一体',
`grade` varchar(10) NOT NULL COMMENT '年级',
`enrollment_year` int(4) NOT NULL COMMENT '入学年份',
`graduation_year` int(4) DEFAULT NULL COMMENT '毕业年份',
`training_type` varchar(20) DEFAULT NULL COMMENT '培养方式:全日制,在职,函授,夜大等',
`degree_type` varchar(20) DEFAULT NULL COMMENT '学位类型:学士,硕士,博士,专科',
`counselor_id` bigint(20) DEFAULT NULL COMMENT '辅导员ID',
`counselor_name` varchar(50) DEFAULT NULL COMMENT '辅导员姓名',
`class_teacher_id` bigint(20) DEFAULT NULL COMMENT '班主任ID',
`class_teacher_name` varchar(50) DEFAULT NULL COMMENT '班主任姓名',
`class_advisor_id` bigint(20) DEFAULT NULL COMMENT '班级导师ID',
`class_advisor_name` varchar(50) DEFAULT NULL COMMENT '班级导师姓名',
`class_monitor_id` bigint(20) DEFAULT NULL COMMENT '班长ID',
`class_monitor_name` varchar(50) DEFAULT NULL COMMENT '班长姓名',
`deputy_monitor_id` bigint(20) DEFAULT NULL COMMENT '副班长ID',
`deputy_monitor_name` varchar(50) DEFAULT NULL COMMENT '副班长姓名',
`class_status` char(1) DEFAULT '1' COMMENT '班级状态:1-正常,2-暂停,3-毕业,4-解散',
`is_graduation` tinyint(1) DEFAULT '0' COMMENT '是否已毕业:0-未毕业,1-已毕业',
`graduation_date` date DEFAULT NULL COMMENT '毕业日期',
`planned_capacity` int(11) DEFAULT '50' COMMENT '计划容量',
`current_student_count` int(11) DEFAULT '0' COMMENT '当前学生人数',
`max_student_count` int(11) DEFAULT '50' COMMENT '最大学生人数',
`male_count` int(11) DEFAULT '0' COMMENT '男生人数',
`female_count` int(11) DEFAULT '0' COMMENT '女生人数',
`active_count` int(11) DEFAULT '0' COMMENT '在籍人数',
`transfer_in_count` int(11) DEFAULT '0' COMMENT '转入人数',
`transfer_out_count` int(11) DEFAULT '0' COMMENT '转出人数',
`dropout_count` int(11) DEFAULT '0' COMMENT '退学人数',
`graduate_count` int(11) DEFAULT '0' COMMENT '毕业人数',
`office_location` varchar(200) DEFAULT NULL COMMENT '班级办公室位置',
`class_location` varchar(100) DEFAULT NULL COMMENT '班级教室位置',
`contact_phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
`qq_group` varchar(20) DEFAULT NULL COMMENT 'QQ群号',
`wechat_group` varchar(100) DEFAULT NULL COMMENT '微信群',
`email` varchar(100) DEFAULT NULL COMMENT '班级邮箱',
`class_schedule` text COMMENT '课程安排(JSON格式)',
`class_culture` text COMMENT '班级文化建设',
`class_rules` text COMMENT '班级规章制度',
`class_description` varchar(500) DEFAULT NULL COMMENT '班级描述',
`last_count_update` datetime DEFAULT NULL COMMENT '最后统计更新时间',
`ext_field1` varchar(200) DEFAULT NULL COMMENT '扩展字段1',
`ext_field2` varchar(200) DEFAULT NULL COMMENT '扩展字段2',
`ext_field3` varchar(200) DEFAULT NULL COMMENT '扩展字段3',
`remark` varchar(500) DEFAULT NULL COMMENT '备注信息',
PRIMARY KEY (`id`) USING BTREE,
KEY `uk_class_code_tenant` (`class_code`,`tenant_id`),
KEY `idx_tenant_id` (`tenant_id`),
KEY `idx_deleted` (`deleted`),
KEY `idx_college_id` (`college_id`),
KEY `idx_enrollment_year` (`enrollment_year`),
KEY `idx_grade` (`grade`),
KEY `idx_major_id` (`major_id`),
KEY `idx_counselor_id` (`counselor_id`),
KEY `idx_class_teacher_id` (`class_teacher_id`),
KEY `idx_class_status` (`class_status`),
KEY `idx_college_grade` (`college_id`,`grade`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='班级信息表-新版';
SET FOREIGN_KEY_CHECKS = 1;
@@ -0,0 +1,55 @@
/*
Navicat Premium Dump SQL
Source Server : 47.99.164.66 hn02le.34lkdLKD
Source Server Type : MySQL
Source Server Version : 50736 (5.7.36)
Source Host : 47.99.164.66:3306
Source Schema : hzdyjs_xg
Target Server Type : MySQL
Target Server Version : 50736 (5.7.36)
File Encoding : 65001
Date: 25/07/2025 14:30:26
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for xg_class_teacher_counselor_rel
-- ----------------------------
DROP TABLE IF EXISTS `xg_class_teacher_counselor_rel`;
CREATE TABLE `xg_class_teacher_counselor_rel` (
`id` bigint(20) NOT NULL COMMENT '主键ID(雪花ID)',
`tenant_id` varchar(20) NOT NULL DEFAULT '000000' COMMENT '租户编号',
`create_dept` bigint(20) DEFAULT NULL COMMENT '创建部门',
`create_by` bigint(20) DEFAULT NULL COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` bigint(20) DEFAULT NULL COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`deleted` tinyint(1) DEFAULT '0' COMMENT '删除标志(0代表存在 1代表删除)',
-- 关联信息
`class_id` bigint(20) NOT NULL COMMENT '班级ID,关联xg_class_msg.id',
`class_name` varchar(100) DEFAULT NULL COMMENT '班级名称',
-- 教师信息
`teacher_id` bigint(20) NOT NULL COMMENT '教师ID,关联sys_user.user_id',
`teacher_name` varchar(50) DEFAULT NULL COMMENT '教师姓名',
`teacher_type` varchar(20) NOT NULL COMMENT '教师类型:class_teacher-班主任,counselor-辅导员,advisor-导师',
-- 任职信息
`start_date` datetime NOT NULL COMMENT '开始日期',
`end_date` datetime DEFAULT NULL COMMENT '结束日期',
`remark` varchar(500) DEFAULT NULL COMMENT '备注信息',
-- 主键和索引
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_tenant_id` (`tenant_id`),
KEY `idx_deleted` (`deleted`),
KEY `idx_class_id` (`class_id`),
KEY `idx_teacher_id` (`teacher_id`),
KEY `idx_teacher_type` (`teacher_type`),
KEY `idx_start_date` (`start_date`),
KEY `idx_end_date` (`end_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='班级班主任辅导员关联表';
SET FOREIGN_KEY_CHECKS = 1;