编辑 | blame | 历史 | 原始文档

车辆同步部门查询修复说明

问题描述

VehicleSyncServiceImpl.findDeptByDispatchOrderClass() 方法中,虽然设置了 query.setDispatchOrderClass(dispatchOrderClass),但在 SysDeptMapper.xml 中的 selectDeptList 查询没有对应的 dispatchOrderClassserviceOrderClass 字段条件判断,导致无法正确查询到部门。

修复内容

1. 修复 SysDeptMapper.xml

文件: ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml

selectDeptList 方法中添加了 serviceOrderClassdispatchOrderClass 的查询条件:

<select id="selectDeptList" parameterType="SysDept" resultMap="SysDeptResult">
    <include refid="selectDeptVo"/>
    where d.del_flag = '0'
    <!-- ... 其他条件 ... -->
    
    <!-- ✅ 新增:服务单编码查询 -->
    <if test="serviceOrderClass != null and serviceOrderClass != ''">
        AND service_order_class = #{serviceOrderClass}
    </if>
    
    <!-- ✅ 新增:调度单编码查询 -->
    <if test="dispatchOrderClass != null and dispatchOrderClass != ''">
        AND dispatch_order_class = #{dispatchOrderClass}
    </if>
    
    <!-- 数据范围过滤 -->
    ${params.dataScope}
    order by d.parent_id, d.order_num
</select>

2. 优化 VehicleSyncServiceImpl

文件: ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleSyncServiceImpl.java

修改 parseDeptIdFromCarOrdClass() 方法,使其在找到部门后自动转换为分公司ID:

修改前
java private Long parseDeptIdFromCarOrdClass(String carOrdClass) { // ... 查找部门逻辑 ... SysDept dept = findDeptByDispatchOrderClass(code); if (dept != null) { return dept.getDeptId(); // ❌ 直接返回部门ID } }

修改后
java private Long parseDeptIdFromCarOrdClass(String carOrdClass) { // ... 查找部门逻辑 ... SysDept dept = findDeptByDispatchOrderClass(code); if (dept != null) { // ✅ 将部门ID转换为分公司ID Long branchCompanyId = sysDeptMapper.selectBranchCompanyIdByDeptId(dept.getDeptId()); if (branchCompanyId != null) { log.debug("将部门ID {} 转换为分公司ID: {}", dept.getDeptId(), branchCompanyId); return branchCompanyId; } else { log.warn("部门ID {} 无法转换为分公司ID,可能是总公司或数据异常", dept.getDeptId()); return null; } } }

修复原理

修复前的问题流程

1. VehicleSyncServiceImpl 设置查询条件
   ├─ query.setDispatchOrderClass("ZB")
   └─ sysDeptMapper.selectDeptList(query)

2. SysDeptMapper.xml 执行查询
   ├─ WHERE del_flag = '0'
   ├─ AND dept_id = ? (如果有)
   ├─ AND parent_id = ? (如果有)
   └─ ❌ 没有 dispatch_order_class 条件
   
3. 结果:查询到所有部门,不是期望的结果

修复后的正确流程

1. VehicleSyncServiceImpl 设置查询条件
   ├─ query.setDispatchOrderClass("ZB")
   └─ sysDeptMapper.selectDeptList(query)

2. SysDeptMapper.xml 执行查询
   ├─ WHERE del_flag = '0'
   ├─ ✅ AND dispatch_order_class = 'ZB'
   └─ 找到匹配的部门

3. 转换为分公司ID
   ├─ 调用 selectBranchCompanyIdByDeptId(deptId)
   ├─ 如果是分公司,直接返回
   └─ 如果是子部门,从ancestors中查找分公司ID

4. 结果:正确的分公司ID

使用场景

场景1:车辆同步时解析部门

从旧系统同步车辆数据时,根据 CarOrdClass 字段(如 "ZB", "HB.TI")查找对应的分公司:

// CarOrdClass = "ZB"
Long branchCompanyId = parseDeptIdFromCarOrdClass("ZB");

// 流程:
// 1. 拆分 "ZB" → ["ZB"]
// 2. 查询 dispatch_order_class = 'ZB' 的部门 → 找到部门201
// 3. 将部门201转换为分公司ID → 101
// 4. 返回分公司ID: 101

场景2:多段编码解析

处理包含多个编码的情况:

// CarOrdClass = "HB.TI"
Long branchCompanyId = parseDeptIdFromCarOrdClass("HB.TI");

// 流程:
// 1. 拆分 "HB.TI" → ["HB", "TI"]
// 2. 先查询 dispatch_order_class = 'HB' → 找到部门202
// 3. 将部门202转换为分公司ID → 102
// 4. 返回分公司ID: 102

数据示例

部门表数据

-- sys_dept 表数据示例
dept_id | parent_id | dept_name   | dispatch_order_class | ancestors
--------|-----------|-------------|---------------------|------------
100     | 0         | 总公司      | NULL                | 0
101     | 100       | 北京分公司   | NULL                | 0,100
102     | 100       | 上海分公司   | NULL                | 0,100
201     | 101       | 北京急救部   | ZB                  | 0,100,101
202     | 102       | 上海急救部   | HB                  | 0,100,102
203     | 102       | 上海转运部   | TI                  | 0,100,102

查询示例

示例1:查询 dispatch_order_class = 'ZB' 的部门

修复前(查询条件无效)
sql SELECT * FROM sys_dept WHERE del_flag = '0' -- 返回所有部门(错误)

修复后(正确查询)
sql SELECT * FROM sys_dept WHERE del_flag = '0' AND dispatch_order_class = 'ZB' -- 返回部门201(正确)

示例2:将部门ID转换为分公司ID

// 输入:deptId = 201 (北京急救部)
Long branchCompanyId = sysDeptMapper.selectBranchCompanyIdByDeptId(201L);
// 返回:101 (北京分公司)

// SQL执行逻辑:
// 1. 检查 dept_id=201 的 parent_id 是否为 100 → 否(parent_id=101)
// 2. 查询 ancestors="0,100,101"
// 3. 使用 FIND_IN_SET 查找 parent_id=100 的部门ID
// 4. 找到 dept_id=101,返回

测试验证

测试用例1:精确匹配单个编码

// CarOrdClass = "ZB"
Long result = parseDeptIdFromCarOrdClass("ZB");
// 预期:101 (北京分公司)

测试用例2:多段编码匹配

// CarOrdClass = "HB.TI"
Long result = parseDeptIdFromCarOrdClass("HB.TI");
// 预期:102 (上海分公司)

测试用例3:空值处理

// CarOrdClass = null
Long result = parseDeptIdFromCarOrdClass(null);
// 预期:null

测试用例4:未匹配的编码

// CarOrdClass = "UNKNOWN"
Long result = parseDeptIdFromCarOrdClass("UNKNOWN");
// 预期:null
// 日志:警告 "未找到匹配CarOrdClass='UNKNOWN' 的部门"

注意事项

1. 部门数据完整性

确保 sys_dept 表中:
- dispatch_order_class 字段已正确配置
- 分公司的 parent_id = 100
- 子部门的 ancestors 字段正确维护

2. 日志监控

方法中添加了详细的日志输出:

// 调试日志
log.debug("通过dispatch_order_class='{}' 找到部门: {} (ID={})", code, dept.getDeptName(), dept.getDeptId());
log.debug("将部门ID {} 转换为分公司ID: {}", dept.getDeptId(), branchCompanyId);

// 警告日志
log.warn("部门ID {} 无法转换为分公司ID,可能是总公司或数据异常", dept.getDeptId());
log.warn("未找到匹配CarOrdClass='{}' 的部门", carOrdClass);

建议在生产环境开启 DEBUG 级别日志,便于排查问题。

3. 性能考虑

如果车辆同步量大,建议:
- 对 dispatch_order_class 字段添加索引
- 对 service_order_class 字段添加索引

CREATE INDEX idx_dispatch_order_class ON sys_dept(dispatch_order_class);
CREATE INDEX idx_service_order_class ON sys_dept(service_order_class);

相关文件

  • /ruoyi-system/src/main/resources/mapper/system/SysDeptMapper.xml - 添加查询条件
  • /ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleSyncServiceImpl.java - 优化转换逻辑
  • /ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDeptMapper.java - 使用 selectBranchCompanyIdByDeptId 方法
  • /prd/部门分公司ID获取方法说明.md - 分公司ID转换方法文档

更新日志

  • 2025-01-25: 修复 SysDeptMapper.xml 中缺少查询条件的问题
  • 2025-01-25: 优化 parseDeptIdFromCarOrdClass 方法,自动转换为分公司ID
  • 目的: 确保车辆同步时能正确匹配部门并转换为分公司ID