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

附加费用双向同步功能说明

功能概述

实现新系统 sys_task_additional_fee 表与旧系统 PaidMoney_Add 表之间的附加费用双向同步,确保两个系统的附加费用数据保持一致。

技术架构

核心实体

1. SysTaskAdditionalFee(新系统附加费用记录)

  • 表名: sys_task_additional_fee
  • 新增字段:
  • pid: 旧系统附加费用记录ID(PaidMoney_Add.id)
  • sync_status: 同步状态(0未同步,1同步中,2同步成功,3同步失败)
  • sync_time: 同步时间

2. PaidMoneyAdd(旧系统附加费用记录)

  • 表名: PaidMoney_Add
  • 关键字段:
  • id: 主键
  • ToServiceOrdID: 服务单ID
  • ToDispatchOrdID: 调度单ID
  • AddMoneyType: 附加费用类型
  • AddMoney: 附加费用金额
  • AddMoneyExplain: 附加费用说明
  • AddMoneyTime: 附加费用时间
  • AddMoneyOAID: 添加用户的OAID

关键关联

通过 SysTaskEmergency 表获取任务与旧系统订单的映射关系:
- legacy_service_ord_idToServiceOrdID
- legacy_dispatch_ord_idToDispatchOrdID

同步逻辑

1. 新系统 → 旧系统同步

触发时机

  • 新系统添加附加费用后自动触发

同步流程

  1. 添加附加费用后,调用 AdditionalFeeSyncService.syncAdditionalFeeToLegacy(feeId)
  2. 查询新系统附加费用记录和任务信息
  3. 获取 ToServiceOrdIDToDispatchOrdID
  4. 转换费用类型(新系统 → 旧系统)
  5. 构建 PaidMoneyAdd 对象并插入旧系统
  6. 更新新系统附加费用记录的 pidsync_statussync_time

费用类型映射(新 → 旧)

新系统字典值 旧系统AddMoneyType 说明
1 1 等待费
2 2 担架
3 3 居家ICU
4 4 医疗设备

数据映射

PaidMoneyAdd.ToServiceOrdID = emergency.legacyServiceOrdId
PaidMoneyAdd.ToDispatchOrdID = emergency.legacyDispatchOrdId
PaidMoneyAdd.AddMoneyType = Integer.parseInt(fee.feeType)
PaidMoneyAdd.AddMoney = fee.totalAmount
PaidMoneyAdd.AddMoneyExplain = fee.feeName + (备注)
PaidMoneyAdd.AddMoneyTime = fee.createdTime
PaidMoneyAdd.AddMoneyOAID = user.oaUserId

2. 旧系统 → 新系统同步

触发时机

  • 定时任务(每15分钟执行一次)
  • 手动调用 AdditionalFeeSyncService.syncAdditionalFeeFromLegacy(paidMoneyAddId)

同步流程

  1. 查询旧系统 PaidMoney_Add 记录
  2. 检查是否已同步(通过 pid 字段)
  3. 根据 ToServiceOrdID 查询新系统任务
  4. 验证 ToDispatchOrdID 是否匹配
  5. 转换费用类型(旧系统 → 新系统)
  6. 构建 SysTaskAdditionalFee 对象并插入新系统
  7. 设置 pidsync_status=2sync_time

费用类型映射(旧 → 新)

旧系统AddMoneyType 新系统字典值 说明
1 1 等待费
2 2 担架
3 3 居家ICU
4 4 医疗设备

数据映射

SysTaskAdditionalFee.taskId = emergency.taskId
SysTaskAdditionalFee.feeType = String.valueOf(paidMoneyAdd.addMoneyType)
SysTaskAdditionalFee.feeName = getFeeTypeName(feeType)
SysTaskAdditionalFee.unitAmount = paidMoneyAdd.addMoney
SysTaskAdditionalFee.quantity = 1
SysTaskAdditionalFee.totalAmount = paidMoneyAdd.addMoney
SysTaskAdditionalFee.remark = paidMoneyAdd.addMoneyExplain
SysTaskAdditionalFee.pid = paidMoneyAddId
SysTaskAdditionalFee.syncStatus = 2
SysTaskAdditionalFee.syncTime = now()

核心代码实现

文件清单

新增文件

  1. 实体类
  • PaidMoneyAdd.java - 旧系统附加费用记录实体
  1. Mapper接口
  • PaidMoneyAddMapper.java - 旧系统附加费用记录Mapper接口
  1. Mapper XML
  • PaidMoneyAddMapper.xml - 旧系统附加费用记录SQL映射
  1. Service接口
  • IAdditionalFeeSyncService.java - 附加费用同步服务接口
  1. Service实现
  • AdditionalFeeSyncServiceImpl.java - 附加费用同步服务实现
  1. 数据库脚本
  • additional_fee_sync_update.sql - 数据表更新脚本

修改文件

  1. 实体类
  • SysTaskAdditionalFee.java - 新增 pid、syncStatus、syncTime 字段
  1. Mapper接口
  • SysTaskAdditionalFeeMapper.java - 新增 selectByPid、updateSyncInfo、selectUnsyncedFees 方法
  1. Mapper XML
  • SysTaskAdditionalFeeMapper.xml - 更新映射和新增查询方法
  1. Service实现
  • SysTaskPaymentServiceImpl.java - 添加附加费用后触发同步
  1. 定时任务
  • LegacySystemSyncTask.java - 新增附加费用同步定时任务方法

数据源配置

使用 @DataSource 注解切换数据源:

// 访问新系统数据库(默认)
public void processNewSystem() {
    // 默认使用主数据源
}

// 访问旧系统数据库
@DataSource(DataSourceType.SQLSERVER)
public void processLegacySystem() {
    // 使用SQL Server数据源
}

同步状态管理

sync_status 状态值

  • 0 - 未同步: 新创建的附加费用记录,尚未同步到旧系统
  • 1 - 同步中: 正在执行同步操作
  • 2 - 同步成功: 已成功同步到旧系统
  • 3 - 同步失败: 同步过程中发生错误

状态流转

新附加费用记录 → 0(未同步) → 1(同步中) → 2(同步成功) 或 3(同步失败)
                                         ↓
                                      可重试

异常处理

同步失败场景

  1. 任务未同步到旧系统(缺少 ToServiceOrdID/ToDispatchOrdID)
  2. 旧系统数据库连接失败
  3. 数据插入冲突或约束违反
  4. 网络异常

处理策略

  1. 同步失败时标记 sync_status=3
  2. 记录详细错误日志
  3. 不影响主业务流程(异步同步)
  4. 可通过定时任务或手动触发重试

使用示例

手动触发同步

@Autowired
private IAdditionalFeeSyncService additionalFeeSyncService;

// 同步单条附加费用到旧系统
boolean success = additionalFeeSyncService.syncAdditionalFeeToLegacy(feeId);

// 从旧系统同步附加费用
boolean success = additionalFeeSyncService.syncAdditionalFeeFromLegacy(paidMoneyAddId);

// 批量同步
int count = additionalFeeSyncService.batchSyncAdditionalFeeToLegacy();
int count = additionalFeeSyncService.batchSyncAdditionalFeeFromLegacy(24); // 同步24小时内的记录

配置定时任务

新系统 → 旧系统同步

任务名称: 附加费用同步
任务组名: DEFAULT
调用目标: legacySystemSyncTask.syncAdditionalFeeToLegacy()
cron表达式: 0 0/10 * * * ? (每10分钟执行一次)

旧系统 → 新系统同步

任务名称: 附加费用反向同步
任务组名: DEFAULT
调用目标: legacySystemSyncTask.syncAdditionalFeeFromLegacy()
cron表达式: 0 0/15 * * * ? (每15分钟执行一次)

数据库更新

执行 SQL 脚本:
sql source sql/additional_fee_sync_update.sql

注意事项

  1. 前置条件: 任务必须已经同步到旧系统(有 ServiceOrdID 和 DispatchOrdID)
  2. 费用类型: 使用统一的字典值(1-等待费, 2-担架, 3-居家ICU, 4-医疗设备)
  3. 同步间隔: 新系统→旧系统立即同步,旧系统→新系统定时同步
  4. 错误处理: 同步失败不影响主业务,可以重试
  5. 性能优化: 批量同步限制每次100条记录,每条记录间隔1秒

验证测试

测试步骤

  1. 新增附加费用(新系统 → 旧系统)
  • 在APP中为转运任务添加附加费用
  • 检查新系统 sys_task_additional_fee 表的 sync_status 字段
  • 检查旧系统 PaidMoney_Add 表是否有对应记录
  1. 旧系统新增附加费用(旧系统 → 新系统)
  • 在旧系统中添加附加费用记录
  • 运行定时任务或手动调用同步方法
  • 检查新系统 sys_task_additional_fee 表是否有对应记录

查询验证SQL

-- 查看新系统附加费用及同步状态
SELECT id, task_id, fee_type, fee_name, total_amount, sync_status, pid
FROM sys_task_additional_fee
WHERE task_id = ?;

-- 查看旧系统附加费用(在SQL Server中执行)
SELECT id, ToServiceOrdID, ToDispatchOrdID, AddMoneyType, AddMoney, AddMoneyExplain
FROM PaidMoney_Add
WHERE ToServiceOrdID = ? AND ToDispatchOrdID = ?;

-- 查看未同步的附加费用
SELECT *
FROM sys_task_additional_fee
WHERE (sync_status = 0 OR sync_status = 3 OR sync_status IS NULL);

技术要点

  1. 双向同步: 支持新旧系统之间的双向数据同步
  2. 幂等性: 通过 pid 字段避免重复同步
  3. 事务性: 使用 @Transactional 确保数据一致性
  4. 异步处理: 同步不阻塞主业务流程
  5. 错误重试: 支持失败记录的重新同步