6.5 KiB
6.5 KiB
📌 修复总结 - 审批记录显示问题
📋 问题描述
模块:出国行程变更审批 → 审批记录选项卡
现象:列表不显示数据
错误:浏览器 F12 显示 500 错误
错误信息:
Error querying database. Cause: java.lang.IllegalArgumentException:
Unable to convert type java.lang.Character of , to type of java.lang.CharSequence
🔍 问题诊断
错误原因
MyBatis Mapper.xml 语法错误:
<!-- ❌ 错误代码 -->
<when test="status.contains(',')">
AND c.status IN
<foreach collection="status.split(',')" item="item" ...>
#{item}
</foreach>
</when>
问题分析:
- MyBatis 不支持
status.contains(',')方法调用 - MyBatis 不支持
status.split(',')字符串拆分 - 导致类型转换错误:
Character→CharSequence
✅ 修复方案
修改文件
文件路径:
backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/RsOverseasItineraryChangeMapper.xml
修改位置:第 126-138 行
修改内容
修改前(错误):
<if test="status != null and status != ''">
<choose>
<!-- ❌ 不支持的语法 -->
<when test="status.contains(',')">
AND c.status IN
<foreach collection="status.split(',')" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</when>
<otherwise>
AND c.status = #{status}
</otherwise>
</choose>
</if>
修改后(正确):
<if test="status != null and status != ''">
<!-- 支持逗号分隔的多状态查询,如 '1,2',使用 FIND_IN_SET 函数 -->
<choose>
<!-- ✅ 判断是否包含逗号 -->
<when test='status.indexOf(",") > 0'>
AND FIND_IN_SET(c.status, #{status})
</when>
<!-- 单个状态精确匹配 -->
<otherwise>
AND c.status = #{status}
</otherwise>
</choose>
</if>
🛠️ 修复步骤
执行过程
-
✅ 修改 Mapper.xml
- 替换错误的 MyBatis 语法
- 使用
indexOf()+FIND_IN_SET()
-
✅ 删除冲突的 target 目录
rm -rf backend/ruoyi-modules/ruoyi-hq/target rm -rf backend/target -
✅ 重新编译项目
cd backend && mvn clean install -DskipTests -T 4- 编译结果:BUILD SUCCESS
- 编译耗时:01:09 min
-
⏳ 重启后端服务(待执行)
- 在 IDEA 中启动 RuoYiApplication
- 等待启动成功
-
⏳ 测试验证(待执行)
- 打开审批记录页面
- 刷新页面验证数据显示
🎯 技术要点
FIND_IN_SET 函数
MySQL 内置函数:
FIND_IN_SET(str, strlist)
功能:查找 str 是否在逗号分隔的 strlist 中
返回值:
- 找到:返回位置(1, 2, 3...)
- 未找到:返回 0
示例:
-- 找到,返回1
SELECT FIND_IN_SET('1', '1,2'); -- 结果:1
-- 找到,返回2
SELECT FIND_IN_SET('2', '1,2'); -- 结果:2
-- 未找到,返回0
SELECT FIND_IN_SET('3', '1,2'); -- 结果:0
应用场景:
-- 前端传参:status=1,2(表示查询 "已通过" 和 "已拒绝")
-- SQL查询:
WHERE FIND_IN_SET(c.status, '1,2')
-- 等价于:
WHERE c.status IN ('1', '2')
适用情况
单个状态:
前端传参:status=0
SQL执行:WHERE c.status = '0'
多个状态:
前端传参:status=1,2
SQL执行:WHERE FIND_IN_SET(c.status, '1,2')
不传状态(查询全部):
前端传参:不传 status
SQL执行:不添加 status 条件
📊 状态值对照
| 状态值 | 状态名称 | 字典类型 | 备注 |
|---|---|---|---|
| 0 | 待审批 | rs_itinerary_change_status | 审批中选项卡 |
| 1 | 已通过 | rs_itinerary_change_status | 审批记录选项卡 |
| 2 | 已拒绝 | rs_itinerary_change_status | 审批记录选项卡 |
| 3 | 已撤回 | rs_itinerary_change_status | - |
审批记录选项卡查询:
前端传参:status=1,2
含义:查询 "已通过" 和 "已拒绝" 的记录
📁 修复文件清单
修改的文件
- RsOverseasItineraryChangeMapper.xml
- 路径:
backend/ruoyi-modules/ruoyi-rs/src/main/resources/mapper/rs/ - 修改行:126-138
- 修改内容:替换 MyBatis 查询条件
- 路径:
创建的文档
-
🔥立即执行-重启后端测试.md
- 详细的重启和测试指南
- 包含预期结果和故障排查
-
📊验证FIND_IN_SET修复.sql
- 数据库验证脚本
- 包含测试数据插入语句
-
✅编译成功-立即重启后端.md
- 编译成功后的操作指南
- 包含测试数据创建脚本
-
📌修复总结-审批记录显示问题.md(本文件)
- 完整的修复总结文档
🚀 下一步操作
立即执行
查看文件:✅编译成功-立即重启后端.md
操作步骤:
1️⃣ 打开 IDEA
2️⃣ 启动后端服务(▶️)
- 点击绿色运行按钮
- 等待看到
Started RuoYiApplication
3️⃣ 打开浏览器测试
- 访问:http://localhost
- 进入:人事管理 → 出国行程变更审批
- 点击:审批记录选项卡
- 刷新:Cmd+Shift+R
4️⃣ 验证结果
- ✅ 显示数据:问题解决!
- ❌ 无数据:执行 SQL 插入测试数据
💡 知识总结
MyBatis 动态 SQL 注意事项
不支持的语法:
<!-- ❌ 错误:不能调用 Java 字符串方法 -->
<when test="str.contains('x')">...</when>
<when test="str.split(',')">...</when>
<when test="str.substring(0, 1)">...</when>
支持的语法:
<!-- ✅ 正确:可以使用的方法 -->
<when test='str.indexOf(",") > 0'>...</when>
<when test="str != null and str != ''">...</when>
<when test="list != null and list.size() > 0">...</when>
推荐做法:
- 使用
indexOf()判断字符串包含 - 使用数据库函数(如
FIND_IN_SET) - 在 Service 层处理复杂逻辑,传递简单参数给 Mapper
✅ 完成标志
- 问题诊断
- 修复方案确定
- 代码修改完成
- 编译成功
- 后端重启(待执行)
- 功能测试(待执行)
- 问题关闭
修复完成时间:2025-10-14 00:43
修复耗时:约10分钟(诊断 + 修复 + 编译)
下一步:重启后端服务并测试
🔥 立即操作:打开 ✅编译成功-立即重启后端.md 继续执行! 🚀