6.2 KiB
6.2 KiB
勤工俭学申请详情页面问题修复记录
问题描述
- 时间: 2025-01-03
- 现象: 点击勤工俭学申请列表页面的"查看详情"按钮,页面弹出错误信息"申请信息不存在或已被删除,请刷新页面重试",并且详情页面的所有字段都不显示任何值。
问题分析
1. 前端调用链
// 列表页面调用详情
function handleDetail(row) {
proxy.$refs['applicationDetailRef']?.handleDetail(row.id)
}
// 详情组件中的处理
function handleDetail(id) {
getWorkStudyApplication(id).then(response => {
// 数据处理...
})
}
2. 后端API调用链
// Controller
@GetMapping("/{id}")
public R<JcbtWorkStudyApplicationVo> getInfo(@PathVariable Long id) {
return R.ok(workStudyApplicationService.queryById(id));
}
// Service
public JcbtWorkStudyApplicationVo queryById(Long id) {
JcbtWorkStudyApplicationVo applicationVo = baseMapper.selectVoById(id);
return applicationVo; // 返回 null
}
3. 根本原因
经过调试发现:
baseMapper.selectById(id)能够成功查询到Entity对象baseMapper.selectVoById(id)返回null
问题出现在 BaseMapperPlus 的 selectVoById 实现中:
// BaseMapperPlus.java 第144-150行
default <C> C selectVoById(Serializable id, Class<C> voClass) {
T obj = this.selectById(id); // Entity查询成功
if (ObjectUtil.isNull(obj)) {
return null;
}
return MapstructUtils.convert(obj, voClass); // MapStruct转换失败
}
核心问题: MapstructUtils.convert() 转换从 Entity 到 VO 时失败,导致返回 null。
解决方案
方案1: 添加自定义selectVoById方法 ✅ 已实施
在 JcbtWorkStudyApplicationMapper.xml 中添加自定义的 selectVoById 方法,直接使用SQL查询和ResultMap映射,避免MapStruct转换:
<!-- 根据ID查询VO对象 - 自定义实现 -->
<select id="selectVoById" parameterType="java.io.Serializable" resultMap="JcbtWorkStudyApplicationResult">
<include refid="selectJcbtWorkStudyApplicationVo"/>
WHERE id = #{id}
AND deleted = 0
</select>
方案2: 完善VO类基础字段 ✅ 已验证
确保VO类包含所有必要的基础字段,避免字段缺失导致的映射问题:
// JcbtWorkStudyApplicationVo.java 必须包含的基础字段
private Long createBy; // 创建者
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime; // 创建时间
private Long updateBy; // 更新者
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime; // 更新时间
技术细节
BaseMapperPlus工作原理
- 继承关系:
JcbtWorkStudyApplicationMapper extends BaseMapperPlus<Entity, VO> - 默认selectVoById: 先查Entity,再用MapStruct转换为VO
- 自定义selectVoById: 直接SQL查询映射为VO,绕过MapStruct转换
MapStruct转换失败的可能原因
- 字段映射不匹配: Entity字段与VO字段名称或类型不对应
- 注解配置问题:
@AutoMapper(target = JcbtWorkStudyApplication.class)配置有误 - 编译时生成问题: MapStruct生成的转换器代码有问题
ResultMap映射
<resultMap type="org.dromara.jcbt.domain.vo.JcbtWorkStudyApplicationVo" id="JcbtWorkStudyApplicationResult">
<result property="id" column="id"/>
<result property="studentName" column="student_name"/>
<result property="positionName" column="position_name"/>
<!-- ... 其他字段映射 ... -->
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
</resultMap>
修复文件清单
1. 修改的文件
backend/ruoyi-modules/ruoyi-jcbt/src/main/resources/mapper/jcbt/JcbtWorkStudyApplicationMapper.xml
2. 添加的内容
- 自定义
selectVoById方法 - 使用现有的 ResultMap 和 SQL 模板
- 添加逻辑删除和条件查询
3. 调试日志增强
在 JcbtWorkStudyApplicationServiceImpl.java 中添加了详细的调试日志:
@Override
public JcbtWorkStudyApplicationVo queryById(Long id) {
log.info("查询勤工俭学申请信息,ID: {}", id);
JcbtWorkStudyApplicationVo applicationVo = baseMapper.selectVoById(id);
log.info("查询结果: {}", applicationVo != null ? "找到记录" : "未找到记录");
if (applicationVo == null) {
// 调试:尝试直接查询Entity
JcbtWorkStudyApplication entity = baseMapper.selectById(id);
log.info("直接查询Entity结果: {}", entity != null ? "找到记录" : "未找到记录");
return null;
}
// ... 其他逻辑 ...
}
验证方法
1. 后端API测试
# 使用Python脚本测试
python3 test_api.py
# 或者使用curl测试
curl -X GET "http://localhost:8080/jcbt/workStudyApplication/1" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json"
2. 前端功能测试
- 打开勤工俭学申请列表页面
- 点击任意记录的"查看详情"按钮
- 验证详情弹窗正常显示所有字段信息
3. 日志验证
查看后端日志中的调试信息:
tail -f backend/logs/admin.log | grep "查询勤工俭学申请信息"
预防措施
1. VO类规范
- 所有VO类必须包含统一的基础字段(createBy, createTime, updateBy, updateTime)
- 使用
@JsonFormat注解格式化时间字段 - 确保
@AutoMapper注解正确配置
2. Mapper接口规范
- 对于复杂的查询逻辑,优先使用自定义SQL而非依赖MapStruct转换
- 在Mapper.xml中提供完整的ResultMap映射
- 添加适当的WHERE条件(如逻辑删除、租户隔离)
3. 测试规范
- 新增API接口必须编写对应的测试脚本
- 包含正常情况和异常情况的测试用例
- 验证前后端集成的完整流程
相关链接
- RuoYi-Cloud文档: BaseMapperPlus使用说明
- MapStruct官方文档: https://mapstruct.org/
- 项目规范:
.cursor/cursorrules-backend.md→ "VO类基础字段规范"
修复人员: AI Assistant
修复时间: 2025-01-03
修复状态: ✅ 已完成,待验证