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

旧系统车辆同步功能说明

一、功能概述

从SQL Server旧系统的CarData表同步车辆数据到MySQL的tb_vehicle_info表,实现车辆信息的自动同步和部门关联。

核心功能

  1. 从SQL Server的CarData表查询正常状态的车辆(CarState=1)
  2. 提取车牌号并匹配tb_vehicle_info中的记录(支持模糊匹配)
  3. 解析CarOrdClass字段,通过dispatch_order_class匹配部门
  4. 同步CarID和dept_id到tb_vehicle_info表

二、数据映射关系

2.1 SQL Server → MySQL 字段映射

SQL Server (CarData) MySQL (tb_vehicle_info) 说明
CarId car_id 旧系统车辆ID
CarLicense vehicle_no 车牌号(去除括号内容)
CarOrdClass dept_id 通过匹配dispatch_order_class转换为部门ID

2.2 CarOrdClass 解析规则

格式示例
- ZB → 单个编码
- HB.TI → 多个编码用.分隔
- HB,TI → 多个编码用,分隔

解析流程
1. 按分隔符(., ,, 空格)拆分CarOrdClass
2. 遍历每个编码,在sys_dept表中查询dispatch_order_class字段
3. 返回第一个匹配的部门ID

2.3 车牌号匹配规则

场景1:精确匹配
SQL Server: 浙A12345 MySQL: 浙A12345 → 精确匹配成功

场景2:带品牌信息
SQL Server: 浙A12345(奔驰) MySQL: 浙A12345 → 提取括号前部分匹配

场景3:模糊匹配
SQL Server: 浙A12345 MySQL: 浙A12345(奔驰GLE) → 包含关系匹配成功

三、数据库变更

3.1 表结构变更

-- 在tb_vehicle_info表中添加car_id字段
ALTER TABLE tb_vehicle_info 
ADD COLUMN car_id INT NULL COMMENT '旧系统车辆ID(SQL Server CarID)' AFTER vehicle_id;

-- 添加索引
ALTER TABLE tb_vehicle_info ADD INDEX idx_car_id (car_id);

3.2 定时任务配置

INSERT INTO sys_job (
    job_name, 
    job_group, 
    invoke_target, 
    cron_expression, 
    misfire_policy, 
    concurrent, 
    status, 
    create_by, 
    create_time, 
    remark
) VALUES (
    '旧系统车辆同步',
    'DEFAULT',
    'legacyVehicleSyncTask.syncVehicles()',
    '0 0 2 * * ?',  -- 每天凌晨2点执行
    '3',
    '1',
    '0',
    'admin',
    sysdate(),
    '从SQL Server的CarData表同步车辆数据到MySQL'
);

四、技术实现

4.1 核心类说明

1. VehicleSyncDTO

路径: ruoyi-system/src/main/java/com/ruoyi/system/domain/VehicleSyncDTO.java

作用: 封装从SQL Server查询的车辆数据

字段:
- carId: 车辆ID
- carLicense: 车牌号
- carOrdClass: 单据类型编码

2. VehicleSyncMapper

路径: ruoyi-system/src/main/java/com/ruoyi/system/mapper/VehicleSyncMapper.java

作用: SQL Server数据源查询接口

注解: @DataSource(DataSourceType.SQLSERVER)

SQL:
sql SELECT CarId, CarLicense, CarOrdClass FROM CarData WHERE CarState = 1 ORDER BY CarId

3. VehicleSyncDataServiceImpl

路径: ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleSyncDataServiceImpl.java

职责: 专门负责从SQL Server查询车辆数据

数据流向: SQL Server → 返回DTO列表

4. VehicleSyncServiceImpl

路径: ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleSyncServiceImpl.java

职责: 将查询到的数据同步到MySQL

核心方法:
- syncVehicles(): 同步车辆数据
- extractPlateNumber(): 提取车牌号
- parseDeptIdFromCarOrdClass(): 解析部门ID
- findVehicleByPlateNumber(): 查找车辆(支持模糊匹配)

5. LegacyVehicleSyncTask

路径: ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/LegacyVehicleSyncTask.java

作用: 定时任务执行类

调用目标: legacyVehicleSyncTask.syncVehicles()

4.2 同步流程

graph TD
    A[定时任务触发] --> B[查询SQL Server CarData表]
    B --> C[遍历车辆数据]
    C --> D[提取车牌号]
    D --> E{车辆是否存在?}
    E -->|存在| F[更新车辆信息]
    E -->|不存在| G[新增车辆]
    F --> H[解析CarOrdClass]
    G --> H
    H --> I[匹配部门dispatch_order_class]
    I --> J[更新dept_id]
    J --> K[保存CarID到car_id字段]
    K --> L[记录同步结果]

4.3 错误处理

级别1:记录级错误
- 单条车辆同步失败不影响其他车辆
- 错误信息记录到结果中
- 继续处理下一条记录

级别2:整体错误
- 查询SQL Server失败:直接返回错误
- 事务回滚:确保数据一致性

五、API接口

5.1 手动同步接口

接口地址: POST /system/vehicle/sync/legacy

权限标识: system:vehicle:sync

请求参数: 无

响应示例:
json { "code": 200, "msg": "车辆同步完成 - 新增: 5, 更新: 10, 跳过: 2, 失败: 0", "data": { "insertCount": 5, "updateCount": 10, "skipCount": 2, "errorCount": 0, "errors": {} } }

六、使用说明

6.1 定时任务配置

  1. 登录若依后台管理系统
  2. 进入「系统监控」→「定时任务」
  3. 找到「旧系统车辆同步」任务
  4. 可以执行以下操作:
  • 启动/停止: 控制任务是否定时执行
  • 立即执行: 手动触发一次同步
  • 修改: 调整执行时间(cron表达式)

6.2 手动同步

通过API接口手动触发同步:

curl -X POST http://localhost:8080/system/vehicle/sync/legacy \
  -H "Authorization: Bearer YOUR_TOKEN"

6.3 查看同步日志

方式1:系统日志
bash tail -f logs/sys-info.log | grep "车辆同步"

方式2:定时任务日志
1. 进入「系统监控」→「定时任务」
2. 点击「旧系统车辆同步」的「日志」按钮
3. 查看执行历史和结果

七、测试验证

7.1 测试前准备

  1. 确保SQL Server数据源配置正确
  2. 确保CarData表有测试数据
  3. 确保sys_dept表中有对应的dispatch_order_class数据

7.2 测试步骤

步骤1:准备测试数据
```sql
-- SQL Server 中准备测试数据
INSERT INTO CarData (CarLicense, CarOrdClass, CarState)
VALUES
('浙A12345', 'HB', 1),
('浙B67890(奔驰)', 'TI.ZB', 1);

-- MySQL 中准备部门数据
UPDATE sys_dept SET dispatch_order_class = 'HB' WHERE dept_name = '转运队';
UPDATE sys_dept SET dispatch_order_class = 'TI' WHERE dept_name = '调度中心';
```

步骤2:执行同步
- 方式1:通过定时任务「立即执行」
- 方式2:调用API接口

步骤3:验证结果
```sql
-- 查询同步结果
SELECT vehicle_id, car_id, vehicle_no, dept_id, platform_code, remark
FROM tb_vehicle_info
WHERE platform_code = 'LEGACY';

-- 验证部门关联
SELECT v.vehicle_no, v.car_id, d.dept_name, d.dispatch_order_class
FROM tb_vehicle_info v
LEFT JOIN sys_dept d ON v.dept_id = d.dept_id
WHERE v.platform_code = 'LEGACY';
```

7.3 预期结果

测试场景 输入 预期输出
新车辆同步 CarLicense='浙A12345', CarOrdClass='HB' 新增记录,dept_id匹配到'转运队'
更新车辆 车牌已存在,CarOrdClass变更 更新dept_id
多编码解析 CarOrdClass='TI.ZB' 匹配第一个编码TI对应的部门
车牌提取 CarLicense='浙B67890(奔驰)' vehicle_no='浙B67890'

八、注意事项

8.1 数据一致性

  1. CarID唯一性: car_id字段记录SQL Server的原始ID,便于追溯
  2. 车牌匹配: 支持模糊匹配,但优先精确匹配
  3. 部门关联: 如果CarOrdClass无法匹配部门,dept_id为NULL

8.2 性能优化

  1. 批量查询: 一次性查询所有车辆,避免多次数据库连接
  2. 索引优化: car_id字段已建立索引
  3. 事务控制: 整体事务,确保数据一致性

8.3 错误排查

问题1:车辆未同步
- 检查CarState是否为1
- 检查车牌号是否为空
- 查看错误日志

问题2:部门未关联
- 检查sys_dept表中是否有对应的dispatch_order_class
- 检查CarOrdClass格式是否正确
- 查看日志中的解析过程

问题3:数据源连接失败
- 检查application-dev.yml中的SQL Server配置
- 验证网络连接和权限

九、后续优化建议

  1. 增量同步: 添加同步时间字段,只同步变更的数据
  2. 冲突处理: 当car_id重复时的处理策略
  3. 数据校验: 同步前后的数据一致性校验
  4. 同步报告: 生成详细的同步报告并发送通知

十、相关文件清单

后端文件

  • VehicleSyncDTO.java - 数据传输对象
  • VehicleSyncMapper.java - 数据查询Mapper
  • VehicleSyncMapper.xml - SQL映射文件
  • IVehicleSyncDataService.java - 数据查询服务接口
  • VehicleSyncDataServiceImpl.java - 数据查询服务实现
  • IVehicleSyncService.java - 同步服务接口
  • VehicleSyncServiceImpl.java - 同步服务实现
  • LegacyVehicleSyncTask.java - 定时任务
  • VehicleSyncController.java - 控制器
  • VehicleInfo.java - 车辆实体(新增car_id字段)
  • VehicleInfoMapper.xml - 车辆Mapper(新增car_id映射)

SQL文件

  • legacy_vehicle_sync.sql - 数据库变更和任务配置

文档

  • 本文档:旧系统车辆同步功能说明.md