- 完成学生信息管理核心功能开发 - 新增学生信息采集批次管理功能 - 完成班干部管理模块开发 - 修复物业报修模块附件上传逻辑 - 完善数据库表结构和权限配置 - 更新API文档和变更记录 - 优化前端页面交互体验 详细变更记录见: - docs/变更管理/code-adjust-record-2025-01-13-wuzhen.md - docs/变更管理/code-adjust-record-2025-07-11-wuzilong.md - docs/变更管理/code-adjust-record-2025-07-12-wuzhen.md
9.5 KiB
9.5 KiB
代码调整记录 - 2025-07-12 - wuzhen
📋 变更概述
变更日期: 2025-07-12 14:52:00
变更人员: wuzhen
变更类型: 功能修复
变更模块: 班级干部管理模块
🎯 变更目标
- 解决"职务级别不能为空"的验证错误
- 修复"cannot find converter from XgClassCadreBo to XgClassCadre"的转换器错误
🔍 问题分析
问题1: 职务级别必填验证错误
- 错误现象: 前台提示"职务级别不能为空",但界面没有该字段输入框
- 根本原因: 后端
positionLevel字段被标记为必填(@NotNull),但前端未提供输入 - 设计缺陷: 职务级别应该根据职务编码自动确定,不需要用户手动输入
问题2: MapStruct转换器缺失
- 错误现象: 添加班干部时报错"cannot find converter from XgClassCadreBo to XgClassCadre"
- 根本原因:
XgClassCadreBo类缺少@AutoMapper注解配置 - 技术问题: MapStruct无法自动生成转换器代码
🛠️ 解决方案
解决方案1: 取消职务级别必填验证 + 自动设置逻辑
-
移除必填验证注解
// 移除 @NotNull 注解 @Min(value = 1, message = "职务级别最小值为1") @Max(value = 9, message = "职务级别最大值为9") private Integer positionLevel; -
添加自动设置逻辑
// 在 validEntityBeforeSave 方法中添加 if (StringUtils.isNotBlank(entity.getPositionCode()) && entity.getPositionLevel() == null) { entity.setPositionLevel(determinePositionLevel(entity.getPositionCode())); } -
职务级别映射规则
- 班长类职务 (monitor, class_monitor) → 级别1
- 副班长类职务 (deputy, deputy_monitor) → 级别2
- 委员类职务 (secretary, study_secretary等) → 级别3
- 其他职务 → 级别9
解决方案2: 添加MapStruct转换器配置
@AutoMapper(target = XgClassCadre.class, reverseConvertGenerate = false)
public class XgClassCadreBo extends BaseEntity {
📝 具体修改内容
1. 修改实体类验证规则
- 文件:
backend/ruoyi-modules/ruoyi-xg-xx/src/main/java/org/dromara/xg/domain/XgClassCadre.java - 修改: 移除
positionLevel字段的@NotNull验证注解
2. 修改业务对象验证规则
- 文件:
backend/ruoyi-modules/ruoyi-xg-xx/src/main/java/org/dromara/xg/domain/bo/XgClassCadreBo.java - 修改: 移除
positionLevel字段的@NotNull验证注解 - 新增: 添加
@AutoMapper注解配置转换器
3. 修改业务逻辑
- 文件:
backend/ruoyi-modules/ruoyi-xg-xx/src/main/java/org/dromara/xg/service/impl/XgClassCadreServiceImpl.java - 新增:
determinePositionLevel()方法,根据职务编码自动确定职务级别 - 修改:
validEntityBeforeSave()方法,添加自动设置职务级别的逻辑
✅ 验证结果
- 编译成功: Maven编译通过,无语法错误
- 转换器生成: MapStruct自动生成
XgClassCadreBo到XgClassCadre的转换器 - 验证逻辑优化: 职务级别不再是必填字段,系统自动设置
🔄 影响范围
- 前端: 不需要修改,职务级别字段自动处理
- 后端: 班级干部管理相关功能
- 数据库: 无影响,字段保持不变
- API: 接口行为保持一致,但验证规则更宽松
📋 测试建议
- 功能测试: 验证添加班级干部功能正常
- 数据验证: 确认职务级别自动设置正确
- 边界测试: 测试各种职务编码的级别映射
- 兼容性测试: 确认现有数据不受影响
📝 备注
- 此次修改提升了用户体验,减少了手动输入错误
- 职务级别的自动设置逻辑可根据实际需求调整
- 建议在生产环境部署前进行充分测试
📋 变更概述
变更日期: 2025-07-12 16:33:00
变更人员: wuzhen
变更类型: 功能修复
变更模块: 班级干部管理模块
🎯 变更目标
修复"cannot find converter from XgClassCadre to XgClassCadreVo"的转换器错误
🔍 问题分析
问题现象
- 添加班干部成功,但列表页面不显示数据
- 刷新页面后报错"cannot find converter from XgClassCadre to XgClassCadreVo"
- 查询列表时无法将实体对象转换为视图对象
根本原因
XgClassCadreVo类缺少@AutoMapper注解配置- MapStruct无法自动生成从
XgClassCadre到XgClassCadreVo的转换器 - 列表查询时需要将实体对象转换为视图对象用于前端展示
🛠️ 解决方案
添加MapStruct转换器配置
@AutoMapper(target = XgClassCadre.class, reverseConvertGenerate = false)
public class XgClassCadreVo extends XgClassCadre {
📝 具体修改内容
修改视图对象配置
- 文件:
backend/ruoyi-modules/ruoyi-xg-xx/src/main/java/org/dromara/xg/domain/vo/XgClassCadreVo.java - 新增: 添加
@AutoMapper注解和相应的import语句 - 目的: 启用自动转换器生成,支持实体对象到视图对象的转换
✅ 验证结果
- 编译成功: Maven编译通过,转换器自动生成
- 转换器生成: MapStruct自动生成
XgClassCadre到XgClassCadreVo的转换器 - 功能完整: 添加班干部后列表页面可以正常显示数据
🔄 影响范围
- 列表查询: 班级干部列表页面可以正常显示数据
- 数据转换: 实体对象与视图对象之间的转换正常
- 前端展示: 解决了数据不显示的问题
📋 测试验证
- 添加功能: 验证添加班级干部功能正常
- 列表显示: 确认添加后列表页面立即显示新数据
- 页面刷新: 验证刷新页面后不再报转换器错误
- 数据完整性: 确认显示的数据字段完整正确
📝 备注
- 此次修复解决了数据显示问题,完善了班级干部管理功能
- 转换器配置是RuoYi框架的标准做法,确保了代码的一致性
- 建议在创建新的VO类时,及时添加转换器配置
📋 变更概述
变更日期: 2025-07-12 13:52:00
变更人员: wuzhen
变更类型: 功能优化
变更模块: 学生信息管理模块
🎯 变更目标
解决学生信息查询功能中的参数传递和字段匹配问题,优化用户搜索体验。
🔍 问题分析
原始问题
- 前端传递的参数格式错误:
{"name":["王"],"studentNo":["王"]}(数组格式) - 后端查询条件过于严格:同时使用学号精确匹配和姓名模糊匹配(AND条件)
- 用户输入"王"无法查询到相关学生信息
根本原因
- 参数格式不匹配: 前端传递数组,后端期望字符串
- 查询逻辑不合理: 用户输入关键字时,应该支持同时搜索学号和姓名
- 用户体验差: 查询条件过于严格,难以找到想要的结果
🛠️ 解决方案
采用方案3:添加通用搜索字段的方式来优化查询功能。
具体实现
-
在
XgStudentInfoBo中添加通用搜索字段/** * 通用搜索关键字(同时搜索学号和姓名) */ private String keyword; -
修改
XgStudentInfoServiceImpl查询逻辑// 通用搜索关键字:同时搜索学号和姓名(OR条件) if (StringUtils.isNotBlank(bo.getKeyword())) { lqw.and(wrapper -> wrapper .like(XgStudentInfo::getStudentNo, bo.getKeyword()) .or() .like(XgStudentInfo::getName, bo.getKeyword()) ); } else { // 兼容原有的分别搜索逻辑 if (StringUtils.isNotBlank(bo.getStudentNo()) && StringUtils.isNotBlank(bo.getName())) { lqw.and(wrapper -> wrapper .like(XgStudentInfo::getStudentNo, bo.getStudentNo()) .or() .like(XgStudentInfo::getName, bo.getName()) ); } else { lqw.like(StringUtils.isNotBlank(bo.getStudentNo()), XgStudentInfo::getStudentNo, bo.getStudentNo()); lqw.like(StringUtils.isNotBlank(bo.getName()), XgStudentInfo::getName, bo.getName()); } }
📝 具体修改内容
1. 业务对象字段扩展
- 文件:
backend/ruoyi-modules/ruoyi-xg-xx/src/main/java/org/dromara/xg/domain/bo/XgStudentInfoBo.java - 新增:
keyword字段用于通用搜索
2. 查询逻辑优化
- 文件:
backend/ruoyi-modules/ruoyi-xg-xx/src/main/java/org/dromara/xg/service/impl/XgStudentInfoServiceImpl.java - 修改:
buildQueryWrapper()方法,支持通用搜索和兼容原有逻辑
✅ 验证结果
- 编译成功: Maven编译通过,无语法错误
- 查询优化: 支持OR条件查询,提升搜索命中率
- 向下兼容: 原有的分别搜索逻辑仍然有效
🔄 优化效果对比
优化前:
- 用户输入"王"
- 查询条件:
student_no = '王' AND name LIKE '%王%' - 结果:0条记录(因为没有学号为"王"的学生)
优化后:
- 用户输入"王"
- 查询条件:
student_no LIKE '%王%' OR name LIKE '%王%' - 结果:返回所有学号或姓名包含"王"的学生
📋 使用方式
前端现在可以通过以下方式调用:
// 方式1:使用新的keyword参数(推荐)
GET /xg/studentInfo/list?keyword=王&pageSize=20
// 方式2:继续使用原有参数(兼容)
GET /xg/studentInfo/list?name=王&pageSize=20
📝 备注
- 新增的通用搜索功能提升了用户体验
- 保持了向下兼容,不影响现有功能
- 建议前端逐步迁移到使用
keyword参数进行搜索