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

转运任务状态变更记录同步到旧系统功能说明

一、功能概述

本功能实现了在转运任务状态发生变更时,自动将状态变更记录同步到SQL Server旧系统的 DispatchOrd_Running 表中。该功能通过Spring事件监听机制实现,确保状态变更的完整记录和追踪。

二、核心组件

1. 数据库表结构

旧系统表:DispatchOrd_Running(SQL Server)

create table DispatchOrd_Running(
    id int comment "自增主键",
    DispatchOrdIDDt bigint comment '调度单ID',
    DispatchOrdState int comment '状态',
    DispatchOrdStartDate datetime comment '状态时间',
    DispatchOrdStartOA int comment '操作状态的OA用户ID',
    OA_latitude float comment '更新状态时的纬度',
    OA_longitude float comment '更新状态时的经度',
    OA_address nvarchar(400) comment '更新状态时的地址'
)

2. Mapper接口

LegacyTransferSyncMapper.java

新增方法:
java /** * 插入调度单状态变更记录到 DispatchOrd_Running 表 * * @param dispatchOrdID 调度单ID * @param dispatchOrdState 状态码 * @param dispatchOrdStartDate 状态时间 * @param dispatchOrdStartOA 操作状态的OA用户ID * @param oaLatitude 更新状态时的纬度 * @param oaLongitude 更新状态时的经度 * @param oaAddress 更新状态时的地址 * @return 影响行数 */ int insertDispatchOrdRunning( @Param("dispatchOrdID") Long dispatchOrdID, @Param("dispatchOrdState") Integer dispatchOrdState, @Param("dispatchOrdStartDate") java.util.Date dispatchOrdStartDate, @Param("dispatchOrdStartOA") Long dispatchOrdStartOA, @Param("oaLatitude") Double oaLatitude, @Param("oaLongitude") Double oaLongitude, @Param("oaAddress") String oaAddress );

3. Mapper XML配置

LegacyTransferSyncMapper.xml

<!-- 插入调度单状态变更记录到 DispatchOrd_Running 表 -->
<insert id="insertDispatchOrdRunning">
    INSERT INTO DispatchOrd_Running (
        DispatchOrdIDDt,
        DispatchOrdState,
        DispatchOrdStartDate,
        DispatchOrdStartOA,
        OA_latitude,
        OA_longitude,
        OA_address
    ) VALUES (
        #{dispatchOrdID},
        #{dispatchOrdState},
        #{dispatchOrdStartDate},
        #{dispatchOrdStartOA},
        #{oaLatitude},
        #{oaLongitude},
        #{oaAddress}
    )
</insert>

4. 事件监听器

DispatchOrdRunningListener.java

  • 位置: ruoyi-system/src/main/java/com/ruoyi/system/listener/
  • 功能: 监听任务状态变更事件(TaskStatusChangedEvent),自动同步状态变更记录到旧系统
  • 特性:
  • 异步处理: 使用 @Async 注解,不阻塞主业务流程
  • 事件监听: 使用 @EventListener 注解监听状态变更事件
  • 智能过滤: 只处理急救转运任务且已同步到旧系统的任务
  • 状态转换: 自动将新系统状态转换为旧系统状态码
  • GPS记录: 记录状态变更时的GPS位置和地址信息
  • 容错处理: 异常不影响主业务流程

三、工作流程

graph TB
    A[转运任务状态变更] --> B[SysTaskServiceImpl.changeTaskStatus]
    B --> C[发布TaskStatusChangedEvent事件]
    C --> D[DispatchOrdRunningListener监听]
    D --> E{是否启用旧系统同步?}
    E -->|否| F[跳过同步]
    E -->|是| G{是否急救转运任务?}
    G -->|否| F
    G -->|是| H{调度单是否已同步?}
    H -->|否| F
    H -->|是| I[转换状态码]
    I --> J{状态需要同步?}
    J -->|否| F
    J -->|是| K[插入DispatchOrd_Running表]
    K --> L[记录日志]

四、状态映射关系

新系统状态 → 旧系统状态码映射:

新系统状态 TaskStatus枚举 旧系统状态码 旧系统状态描述
出发中 DEPARTING 4 已出车(去接患者途中)
任务中 IN_PROGRESS 6 已出车(服务中)
返程中 RETURNING 7 已送达(回程中)
已完成 COMPLETED 8 已返回
已取消 CANCELLED 10 取消

| 待处理 | PENDING | - | 不同步 |
| 已到达 | ARRIVED | - | 不同步 |

五、同步条件

满足以下**所有条件**时才会同步状态变更记录:

  1. ✅ 旧系统同步功能已启用(legacy.system.enabled=true
  2. ✅ 任务类型为急救转运(EMERGENCY_TRANSFER
  3. ✅ 任务已同步到旧系统(legacy_dispatch_ord_id 不为空)
  4. ✅ 新状态需要同步到旧系统(参见状态映射表)

六、使用示例

1. 自动触发(推荐)

当转运任务状态发生变更时,系统会自动触发同步:

// 在SysTaskServiceImpl中变更状态
sysTaskService.changeTaskStatus(taskId, TaskStatus.DEPARTING, "司机已出发");

// 系统自动:
// 1. 发布TaskStatusChangedEvent事件
// 2. DispatchOrdRunningListener监听并处理
// 3. 插入记录到DispatchOrd_Running表

2. 日志示例

成功同步的日志
2025-12-05 14:30:15 INFO DispatchOrdRunningListener - 收到任务状态变更事件,准备同步到DispatchOrd_Running,任务ID:1001,旧状态:PENDING,新状态:DEPARTING 2025-12-05 14:30:15 INFO DispatchOrdRunningListener - 开始同步状态变更记录到DispatchOrd_Running,DispatchOrdID: 12345, 状态码: 4, 状态描述: 已出车(去接患者途中) 2025-12-05 14:30:15 INFO DispatchOrdRunningListener - 状态变更记录已同步到DispatchOrd_Running,DispatchOrdID: 12345, 状态码: 4 (已出车(去接患者途中)), GPS: [113.264385, 23.12911], 地址: 广州市越秀区XX路XX号

跳过同步的日志
2025-12-05 14:30:15 DEBUG DispatchOrdRunningListener - 调度单未同步到旧系统,跳过DispatchOrd_Running同步,任务ID: 1001

七、数据记录内容

每次状态变更会记录以下信息:

字段 说明 数据来源
DispatchOrdIDDt 调度单ID sys_task_emergency.legacy_dispatch_ord_id
DispatchOrdState 状态码 从新系统TaskStatus转换而来
DispatchOrdStartDate 状态时间 当前时间
DispatchOrdStartOA 操作人ID TaskStatusChangedEvent.creatorId
OA_latitude 纬度 TaskStatusChangedEvent.latitude
OA_longitude 经度 TaskStatusChangedEvent.longitude
OA_address 地址 TaskStatusChangedEvent.address

八、监控和调试

1. 查看状态变更记录

-- SQL Server中查询最近的状态变更记录
SELECT TOP 20 
    DispatchOrdIDDt,
    DispatchOrdState,
    DispatchOrdStartDate,
    DispatchOrdStartOA,
    OA_latitude,
    OA_longitude,
    OA_address
FROM DispatchOrd_Running
ORDER BY DispatchOrdStartDate DESC

2. 查询特定调度单的状态变更历史

-- 查询某个调度单的所有状态变更记录
SELECT 
    DispatchOrdState,
    DispatchOrdStartDate,
    OA_latitude,
    OA_longitude,
    OA_address
FROM DispatchOrd_Running
WHERE DispatchOrdIDDt = 12345
ORDER BY DispatchOrdStartDate DESC

3. 统计今日状态变更次数

-- 统计今日各状态的变更次数
SELECT 
    DispatchOrdState,
    CASE DispatchOrdState
        WHEN 4 THEN '已出车(去接患者途中)'
        WHEN 6 THEN '已出车(服务中)'
        WHEN 7 THEN '已送达(回程中)'
        WHEN 8 THEN '已返回'
        WHEN 10 THEN '取消'
        ELSE '其他'
    END AS StateName,
    COUNT(*) AS ChangeCount
FROM DispatchOrd_Running
WHERE CONVERT(DATE, DispatchOrdStartDate) = CONVERT(DATE, GETDATE())
GROUP BY DispatchOrdState
ORDER BY DispatchOrdState

九、架构优势

1. 完全解耦

  • 业务逻辑与同步逻辑分离
  • 状态变更不依赖旧系统同步结果
  • 可独立测试和维护

2. 异步处理

  • 不阻塞主业务流程
  • 提高系统响应速度
  • 容错能力强

3. 自动化

  • 无需手动触发
  • 实时同步状态变更
  • 减少人工操作

4. 可追溯性

  • 完整记录每次状态变更
  • 包含GPS位置信息
  • 便于问题排查和审计

十、注意事项

1. 数据源配置

确保 LegacyTransferSyncMapper 使用SQL Server数据源:
java @DataSource(DataSourceType.SQLSERVER) public interface LegacyTransferSyncMapper { // ... }

2. 异步线程池

异步处理依赖线程池配置(AsyncConfig.java):
java @Configuration @EnableAsync public class AsyncConfig { @Bean(name = "taskExecutor") public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(100); // ... } }

3. 异常处理

监听器中的异常不会影响主业务:
- 记录详细日志
- 不抛出异常
- 不影响状态变更操作

4. 性能优化

  • 使用 @Async 异步处理
  • 只同步必要的状态变更
  • 智能过滤不需要同步的任务

十一、测试验证

1. 测试步骤

步骤1:创建并同步转运任务
```java
// 创建急救转运任务
Long taskId = sysTaskService.insertSysTask(createVO);

// 确保任务已同步到旧系统
legacySystemSyncService.syncDispatchOrderToLegacy(taskId);
```

步骤2:变更任务状态
java // 变更状态为"出发中" sysTaskService.changeTaskStatus(taskId, TaskStatus.DEPARTING, "司机已出发");

步骤3:验证SQL Server记录
sql -- 查询DispatchOrd_Running表 SELECT * FROM DispatchOrd_Running WHERE DispatchOrdIDDt = ( SELECT legacy_dispatch_ord_id FROM sys_task_emergency WHERE task_id = ? ) ORDER BY DispatchOrdStartDate DESC

2. 预期结果

测试场景 预期结果
急救转运任务状态变更 插入记录到DispatchOrd_Running
非急救转运任务状态变更 不插入记录
未同步的任务状态变更 不插入记录
不需要同步的状态(PENDING) 不插入记录
旧系统同步已禁用 不插入记录

十二、相关文件清单

新增文件

  • DispatchOrdRunningListener.java - 状态变更监听器

修改文件

  • LegacyTransferSyncMapper.java - 添加insertDispatchOrdRunning方法
  • LegacyTransferSyncMapper.xml - 添加插入SQL

依赖文件(无需修改)

  • SysTaskServiceImpl.java - 发布状态变更事件
  • TaskStatusChangedEvent.java - 状态变更事件
  • TaskStatusPushConverter.java - 状态转换工具
  • DispatchRunning.sql - 数据库表结构定义

十三、故障排查

问题1:状态变更没有同步到旧系统

排查步骤
1. 检查旧系统同步是否启用:legacy.system.enabled=true
2. 检查任务是否为急救转运任务
3. 检查调度单是否已同步:legacy_dispatch_ord_id 不为空
4. 查看日志确认是否有异常
5. 检查状态是否需要同步(参考状态映射表)

问题2:日志中出现异常

常见原因
- SQL Server连接失败
- 数据源配置错误
- 字段类型不匹配

解决方法
- 检查数据源配置
- 验证SQL Server连接
- 查看详细错误日志

问题3:性能问题

优化建议
- 调整线程池配置
- 检查SQL Server性能
- 优化数据库索引

十四、总结

本功能通过Spring事件驱动机制,实现了转运任务状态变更记录到旧系统的自动同步,具有以下特点:

  • 自动化:状态变更自动同步,无需手动操作
  • 解耦:业务逻辑与同步逻辑完全分离
  • 异步:不影响主业务性能
  • 完整:记录GPS位置等详细信息
  • 可靠:容错处理,异常不影响主流程
  • 可追溯:完整的状态变更历史记录