wlzboy
23 小时以前 6b29bd596f8b48485d3506bfba4a1e0ea6c7df99
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java
@@ -3,6 +3,7 @@
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.*;
import com.ruoyi.system.domain.SysTask;
import com.ruoyi.system.domain.SysTaskEmergency;
import com.ruoyi.system.domain.VehicleInfo;
import com.ruoyi.system.domain.enums.TaskStatus;
@@ -17,6 +18,9 @@
import com.ruoyi.system.mapper.VehicleInfoMapper;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.IWechatTaskNotifyService;
import com.ruoyi.system.service.INotifyTaskService;
import com.ruoyi.system.service.INotifyDispatchService;
import com.ruoyi.system.domain.NotifyTask;
import com.ruoyi.system.utils.TaskStatusConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -28,8 +32,10 @@
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
 * 旧系统转运单同步Service业务层处理
@@ -66,92 +72,147 @@
    @Autowired
    private IWechatTaskNotifyService wechatTaskNotifyService;
    @Autowired
    private INotifyTaskService notifyTaskService;
    @Autowired
    private INotifyDispatchService notifyDispatchService;
    /**
     * 同步指定日期范围的旧系统转运单到新系统
     *
     * @param daysAgo 多少天前的数据(如7表示7天前的数据)
     * 优化:将多天范围拆分为逐天循环,每次仅查询1天数据,避免大数据量导致SQL Server超时
     *
     * @param daysAgo 多少天前的数据(如7表示同步最近7天的数据)
     * @return 成功同步的转运单数量
     */
    @Override
    public int syncLegacyTransferOrders(int daysAgo) {
        log.info("开始同步{}天前的旧系统转运单数据", daysAgo);
        try {
            // 参数验证
            if (daysAgo <= 0) {
                log.error("天数参数必须大于0");
                return 0;
            }
            // 计算日期范围
            Date startDate = DateUtils.addDays(new Date(), -daysAgo);
            String startDateStr = DateUtils.parseDateToStr("yyyy-MM-dd", startDate);
            // 从SQL Server查询转运单数据
            List<Map<String, Object>> transferOrders = legacyTransferSyncMapper.selectTransferOrders(startDateStr);
            if (transferOrders == null || transferOrders.isEmpty()) {
                log.info("未查询到{}天前的转运单数据", daysAgo);
                return 0;
//            log.info("[转运单同步] 开始同步,范围: 最近{}天", daysAgo);
            int totalSuccessCount = 0;
            int totalDays = daysAgo + 1;
            // 按天拆分,每次只同步1天的数据,避免大范围查询超时
            for (int i = daysAgo; i >= 0; i--) {
                Date dayStart = DateUtils.addDays(new Date(), -i);
                String dayStartStr = DateUtils.parseDateToStr("yyyy-MM-dd", dayStart) + " 00:00:00";
                String dayEndStr   = DateUtils.parseDateToStr("yyyy-MM-dd", dayStart) + " 23:59:59";
                int dayIndex = totalDays - i;
//                log.info("[转运单同步] 处理天 {}/{}: {}", dayIndex, totalDays, dayStartStr);
                int daySuccessCount = syncSingleDayOrders(dayStartStr, dayEndStr);
                totalSuccessCount += daySuccessCount;
//                log.info("[转运单同步] {} 完成,新增同步: {}条,累计: {}条", dayStartStr, daySuccessCount, totalSuccessCount);
            }
            log.info("查询到{}条转运单数据,开始同步...", transferOrders.size());
            int successCount = 0;
            int totalCount = transferOrders.size();
            int processedCount = 0;
            for (Map<String, Object> order : transferOrders) {
                processedCount++;
                try {
                    Long serviceOrdID = MapValueUtils.getLongValue(order, "ServiceOrdID");
                    Long dispatchOrdID = MapValueUtils.getLongValue(order, "DispatchOrdID");
                    // 检查参数有效性
                    if (serviceOrdID==null || serviceOrdID<=0) {
                        log.warn("第{}条数据服务单ID为空,跳过处理", processedCount);
                        continue;
                    }
                    log.debug("正在处理第{}/{}条转运单: ServiceOrdID={}, DispatchOrdID={}",
                             processedCount, totalCount, serviceOrdID, dispatchOrdID);
                    // 检查是否已同步
                    if (isTransferOrderSynced(serviceOrdID, dispatchOrdID)) {
                        log.debug("转运单已同步,跳过: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID);
                        //进行更新操作
                        updateTransferOrder(serviceOrdID, dispatchOrdID, order);
                        continue;
                    }
                    // 同步单个转运单
                    boolean success = syncSingleTransferOrder(serviceOrdID, dispatchOrdID, order);
                    if (success) {
                        successCount++;
                    }
                    // 控制同步频率,避免请求过快
                    Thread.sleep(100);
                } catch (InterruptedException ie) {
                    log.warn("同步任务被中断");
                    Thread.currentThread().interrupt();
                    break;
                } catch (Exception e) {
                    log.error("同步单个转运单失败: ServiceOrdID={}, DispatchOrdID={}",
                             MapValueUtils.getStringValue(order, "ServiceOrdID"),
                             MapValueUtils.getStringValue(order, "DispatchOrdID"), e);
                }
            }
            log.info("同步完成,共处理{}条转运单,成功同步{}条转运单数据", totalCount, successCount);
            return successCount;
//            log.info("[转运单同步] 全部完成,共新增同步 {}条", totalSuccessCount);
            return totalSuccessCount;
        } catch (Exception e) {
            log.error("同步{}天前的旧系统转运单数据异常", daysAgo, e);
            return 0;
        }
    }
    /**
     * 同步单天的转运单数据(Keyset游标分页)
     *
     * @param startDateStr 开始日期字符串(yyyy-MM-dd)
     * @param endDateStr   结束日期字符串(yyyy-MM-dd)
     * @return 成功同步的转运单数量
     */
    private int syncSingleDayOrders(String startDateStr, String endDateStr) {
        final int PAGE_SIZE = 5;
        long lastId = 0L;
        int successCount = 0;
        int pageNum = 0;
        int totalProcessed = 0;
        try {
            while (true) {
                List<Map<String, Object>> transferOrders = legacyTransferSyncMapper.selectTransferOrders(startDateStr, endDateStr, lastId, PAGE_SIZE);
                if (transferOrders == null || transferOrders.isEmpty()) {
                    break;
                }
                pageNum++;
                int totalCount = transferOrders.size();
                int processedCount = 0;
//                log.info("[转运单同步] {} 第{}页,获取{}.条数据,lastId={}", startDateStr, pageNum, totalCount, lastId);
                for (Map<String, Object> order : transferOrders) {
                    processedCount++;
                    totalProcessed++;
                    try {
                        Long serviceOrdID = MapValueUtils.getLongValue(order, "ServiceOrdID");
                        Long dispatchOrdID = MapValueUtils.getLongValue(order, "DispatchOrdID");
                        if (serviceOrdID == null || serviceOrdID <= 0) {
                            log.warn("第{}条数据服务单ID为空,跳过处理", processedCount);
                            continue;
                        }
                        // 检查是否已同步
                        if (isTransferOrderSynced(serviceOrdID, dispatchOrdID)) {
                            log.debug("[转运单同步] 已存在,执行更新: ServiceOrdID={}", serviceOrdID);
                            updateTransferOrder(serviceOrdID, dispatchOrdID, order);
                            continue;
                        }
                        // 同步单个转运单
                        log.info("[转运单同步] 新增同步: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID);
                        boolean success = syncSingleTransferOrder(serviceOrdID, dispatchOrdID, order);
                        if (success) {
                            successCount++;
                            log.info("[转运单同步] 同步成功: ServiceOrdID={}, 当天新增累计: {}", serviceOrdID, successCount);
                        } else {
                            log.warn("[转运单同步] 同步失败: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID);
                        }
                        // 控制同步频率,避免请求过快
                        Thread.sleep(100);
                    } catch (InterruptedException ie) {
                        log.warn("同步任务被中断");
                        Thread.currentThread().interrupt();
                        return successCount;
                    } catch (Exception e) {
                        log.error("同步单个转运单失败: ServiceOrdID={}, DispatchOrdID={}",
                                MapValueUtils.getStringValue(order, "ServiceOrdID"),
                                MapValueUtils.getStringValue(order, "DispatchOrdID"), e);
                    }
                }
                // 更新游标为本页最后一条的 ServiceOrdID
                Map<String, Object> lastOrder = transferOrders.get(transferOrders.size() - 1);
                Long lastServiceOrdID = MapValueUtils.getLongValue(lastOrder, "ServiceOrdID");
                if (lastServiceOrdID != null && lastServiceOrdID > 0) {
                    lastId = lastServiceOrdID;
                } else {
                    break;
                }
                // 本页未满一页,说明已无更多数据
                if (totalCount < PAGE_SIZE) {
                    break;
                }
            }
//            log.info("[转运单同步] {} 分页完成,共处理: {}条,新增同步: {}条", startDateStr, totalProcessed, successCount);
        } catch (Exception e) {
            log.error("同步单天转运单数据异常: date={}", startDateStr, e);
        }
        return successCount;
    }
    
    /**
@@ -271,7 +332,13 @@
//                log.info("转运单同步成功: ServiceOrdID={}, DispatchOrdID={}, 创建的任务ID={}", serviceOrdID, dispatchOrdID, result);
                try {
                    notifyTransferOrderByWechat((long) result, serviceOrdID, dispatchOrdID, serviceOrdNo, ServiceOrd_CC_Time, dept, order);
                    // 直接使用方法头部已查询的 emergency 获取 taskId
                    Long taskId = emergency.getTaskId();
                    if (taskId != null) {
                        notifyTransferOrderByWechat(taskId, serviceOrdID, dispatchOrdID, serviceOrdNo, ServiceOrd_CC_Time, dept, order);
                    } else {
                        log.warn("更新后找不到taskId,跳过通知: ServiceOrdID={}", serviceOrdID);
                    }
                } catch (Exception e) {
                    log.error("转运单同步成功后发送微信通知失败: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID, e);
                }
@@ -345,13 +412,13 @@
            createTaskVo.setDeptId(deptId);
            int result = sysTaskService.insertTask(createTaskVo,serviceOrdID,dispatchOrdID, serviceOrdNo, taskCreatorId,createUserName, deptId, ServiceOrd_CC_Time, ServiceOrd_CC_Time);
            Long taskId = sysTaskService.insertTask(createTaskVo,serviceOrdID,dispatchOrdID, serviceOrdNo, taskCreatorId,createUserName, deptId, ServiceOrd_CC_Time, ServiceOrd_CC_Time);
            if (result > 0) {
//                log.info("转运单同步成功: ServiceOrdID={}, DispatchOrdID={}, 创建的任务ID={}", serviceOrdID, dispatchOrdID, result);
            if (taskId != null && taskId > 0) {
//                log.info("转运单同步成功: ServiceOrdID={}, DispatchOrdID={}, 创建的任务ID={}", serviceOrdID, dispatchOrdID, taskId);
                try {
                    notifyTransferOrderByWechat((long) result, serviceOrdID, dispatchOrdID, serviceOrdNo, ServiceOrd_CC_Time, dept, order);
                    notifyTransferOrderByWechat(taskId, serviceOrdID, dispatchOrdID, serviceOrdNo, ServiceOrd_CC_Time, dept, order);
                } catch (Exception e) {
                    log.error("转运单同步成功后发送微信通知失败: ServiceOrdID={}, DispatchOrdID={}", serviceOrdID, dispatchOrdID, e);
                }
@@ -477,8 +544,8 @@
               createTaskVo.setServiceOrdVIP("0");
           }
           Integer FromHQ2_is = MapValueUtils.getIntegerValue(order, "FromHQ2_is");
           if(IntegerUtil.isNotEmpty(FromHQ2_is)){
           Integer FromHQ_is = MapValueUtils.getIntegerValue(order, "FromHQ_is");
           if(IntegerUtil.isNotEmpty(FromHQ_is)){
               createTaskVo.setFromHQ2_is("1");
           }else{
               createTaskVo.setFromHQ2_is("0");
@@ -504,11 +571,20 @@
                }
            }
            createTaskVo.setPatient(patientInfo);
            //1000公里,提取数字
            //1000公里,提取数字(支持小数)
            String ServiceOrdTraDistance=MapValueUtils.getStringValue(order, "ServiceOrdTraDistance");
            if(ServiceOrdTraDistance!=null){
                ServiceOrdTraDistance=ServiceOrdTraDistance.replaceAll("[^0-9]", "");
                createTaskVo.setDistance(new BigDecimal(ServiceOrdTraDistance));
                // 保留数字和小数点,移除其他字符
                ServiceOrdTraDistance=ServiceOrdTraDistance.replaceAll("[^0-9.]", "");
                // 处理多个小数点的情况,只保留第一个
                int firstDotIndex = ServiceOrdTraDistance.indexOf('.');
                if (firstDotIndex != -1) {
                    ServiceOrdTraDistance = ServiceOrdTraDistance.substring(0, firstDotIndex + 1)
                        + ServiceOrdTraDistance.substring(firstDotIndex + 1).replace(".", "");
                }
                if (!ServiceOrdTraDistance.isEmpty() && !ServiceOrdTraDistance.equals(".")) {
                    createTaskVo.setTransferDistance(new BigDecimal(ServiceOrdTraDistance));
                }
            }
            
@@ -598,7 +674,7 @@
                String carLicense = legacyTransferSyncMapper.selectCarLicenseByCarID(carID);
                if (StringUtils.isNotEmpty(carLicense)) {
                    // 根据车牌号查询新系统中的车辆ID
                    log.info("转运任务,ServiceOrdID:{},车辆车牌:{}",serviceOrdID,carLicense);
//                    log.info("转运任务,ServiceOrdID:{},车辆车牌:{}",serviceOrdID,carLicense);
//                    log.debug("车辆车牌号: {}", carLicense);
                    
                    // 首先尝试通过VehicleInfoMapper查询车辆信息
@@ -619,7 +695,7 @@
                                List<Long> vehicleIds = new ArrayList<>();
                                vehicleIds.add(vehicleInfo.getVehicleId());
                                createTaskVo.setVehicleIds(vehicleIds);
                                log.debug("转运任务,ServiceOrdID:{} 通过车牌号找到车辆信息: vehicle_id={}, vehicle_no={}",serviceOrdID, vehicleInfo.getVehicleId(), vehicleInfo.getVehicleNo());
//                                log.debug("转运任务,ServiceOrdID:{} 通过车牌号找到车辆信息: vehicle_id={}, vehicle_no={}",serviceOrdID, vehicleInfo.getVehicleId(), vehicleInfo.getVehicleNo());
                            } else {
                                log.warn("转运任务,ServiceOrdID:{} 未找到对应的车辆信息: car_id={}, vehicle_no={}",serviceOrdID, carID, carLicense);
                            }
@@ -632,7 +708,7 @@
                            List<Long> vehicleIds = new ArrayList<>();
                            vehicleIds.add(vehicleInfo.getVehicleId());
                            createTaskVo.setVehicleIds(vehicleIds);
                            log.debug("通过车牌号找到车辆信息: vehicle_id={}, vehicle_no={}", vehicleInfo.getVehicleId(), vehicleInfo.getVehicleNo());
//                            log.debug("通过车牌号找到车辆信息: vehicle_id={}, vehicle_no={}", vehicleInfo.getVehicleId(), vehicleInfo.getVehicleNo());
                        } else {
                            log.warn("未找到对应的车辆信息: vehicle_no={}", carLicense);
                        }
@@ -829,7 +905,7 @@
                return String.join(",", diseaseIds);
            }
            
            log.info("查询到病情信息,服务单ID: {}, 病情数量: {}", serviceOrdID, diseaseIds != null ? diseaseIds.size() : 0);
//            log.info("查询到病情信息,服务单ID: {}, 病情数量: {}", serviceOrdID, diseaseIds != null ? diseaseIds.size() : 0);
            return null;
        } catch (Exception e) {
            log.error("查询病情信息异常,服务单ID: {}", serviceOrdID, e);
@@ -847,27 +923,124 @@
                                             SysDept dept,
                                             Map<String, Object> order) {
        try {
            // 获取通知接收人列表
            List<SysUser> receivers = getWechatNotifyUsers(dispatchOrdID, dept);
            if (receivers == null || receivers.isEmpty()) {
//                log.info("旧系统同步转运单无可用微信接收人,taskId={}", taskId);
            // 1. 获取执行人列表
            List<TaskCreateVO.AssigneeInfo> assignees = queryAssignees(dispatchOrdID);
            if (assignees.isEmpty()) {
//                log.info("旧系统同步转运单无执行人,taskId={}", taskId);
                return;
            }
            // 提取接收人 ID 列表
            List<Long> userIds = new ArrayList<>();
            for (SysUser user : receivers) {
                if (user != null && user.getUserId() != null) {
                    userIds.add(user.getUserId());
            // 2. 查询任务获取showTaskCode
            SysTask sysTask = sysTaskService.getTaskDetail(taskId);
            String showTaskCode = sysTask != null ? sysTask.getShowTaskCode() : serviceOrdNo;
            // 3. 构建通知内容
            String notifyContent = buildLegacyNotifyContent(showTaskCode, serviceOrdCcTime, order);
            // 4. 查询该taskId已有的通知记录,收集已存在的userId集合
            List<NotifyTask> existingTasks = notifyTaskService.selectByTaskIdAndType(taskId, NotifyTask.NOTIFY_TYPE_TASK_ASSIGN);
            Set<Long> existingUserIds = new HashSet<>();
            List<NotifyTask> pendingTasks = new ArrayList<>();
            if (existingTasks != null && !existingTasks.isEmpty()) {
                for (NotifyTask t : existingTasks) {
                    existingUserIds.add(t.getUserId());
                    // 将未完成的记录收集给待分发列表
                    if (!NotifyTask.STATUS_COMPLETED.equals(t.getStatus())) {
                        pendingTasks.add(t);
                    }
                }
            }
            // 调用统一的微信通知服务
            int successCount = wechatTaskNotifyService.sendTaskNotifyMessage(taskId, userIds);
//            log.info("旧系统同步转运单微信通知发送完成,taskId={}, 成功={}", taskId, successCount);
            // 5. 只对新执行人创建通知任务
            List<NotifyTask> notifyTasks = new ArrayList<>(pendingTasks);
            for (TaskCreateVO.AssigneeInfo assignee : assignees) {
                if (assignee == null || assignee.getUserId() == null) {
                    continue;
                }
                // 该用户已有通知记录,跳过
                if (existingUserIds.contains(assignee.getUserId())) {
//                    log.info("用户已有通知记录,跳过创建,taskId={}, userId={}", taskId, assignee.getUserId());
                    continue;
                }
                SysUser user = sysUserService.selectUserById(assignee.getUserId());
                if (user == null) {
                    log.warn("找不到执行人用户信息,userId={}", assignee.getUserId());
                    continue;
                }
                NotifyTask notifyTask = new NotifyTask();
                notifyTask.setTaskId(taskId);
                notifyTask.setTaskCode(showTaskCode);
                notifyTask.setNotifyType(NotifyTask.NOTIFY_TYPE_TASK_ASSIGN);
                notifyTask.setUserId(user.getUserId());
                notifyTask.setUserName(user.getNickName());
                notifyTask.setUserPhone(user.getPhonenumber());
                notifyTask.setTitle("转运单任务派单通知");
                notifyTask.setContent(notifyContent);
                notifyTask.setCreateBy("系统同步");
                NotifyTask created = notifyTaskService.createNotifyTask(notifyTask);
                if (created != null) {
                    notifyTasks.add(created);
//                    log.info("创建通知任务成功,id={}, userId={}", created.getId(), user.getUserId());
                }
            }
            // 6. 分发通知任务
            if (!notifyTasks.isEmpty()) {
                int successCount = notifyDispatchService.dispatchNotifies(notifyTasks);
//                log.info("旧系统同步转运单通知分发完成,taskId={}, 分发数量={}, 成功数量={}",
//                        taskId, notifyTasks.size(), successCount);
            }
//            else {
//                log.info("旧系统同步转运单无需新增通知,taskId={}", taskId);
//            }
            // 5. 同时保留原有的微信通知服务(兼容)
            // List<Long> userIds = new ArrayList<>();
            // for (TaskCreateVO.AssigneeInfo assignee : assignees) {
            //     if (assignee != null && assignee.getUserId() != null) {
            //         userIds.add(assignee.getUserId());
            //     }
            // }
            // if (!userIds.isEmpty()) {
            //     int wxCount = wechatTaskNotifyService.sendTaskNotifyMessage(taskId, userIds);
            //     log.info("旧系统同步转运单微信通知发送完成,taskId={}, 成功={}", taskId, wxCount);
            // }
        } catch (Exception e) {
            log.error("notifyTransferOrderByWechat发生异常, serviceOrdID={}, dispatchOrdID={}", serviceOrdID, dispatchOrdID, e);
        }
    }
    /**
     * 构建旧系统同步转运单的通知内容
     */
    private String buildLegacyNotifyContent(String serviceOrdNo, Date serviceOrdCcTime, Map<String, Object> order) {
        StringBuilder content = new StringBuilder();
        content.append("您有新的转运任务,任务单号:").append(serviceOrdNo);
        // 出发时间
        if (serviceOrdCcTime != null) {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            content.append(",出发时间:").append(df.format(serviceOrdCcTime));
        }
        // 出发地
        String departure = MapValueUtils.getStringValue(order, "ServiceOrdTraVia");
        if (StringUtils.isNotEmpty(departure)) {
            content.append(",出发地:").append(departure);
        }
        // 目的地
        String destination = MapValueUtils.getStringValue(order, "ServiceOrdTraEnd");
        if (StringUtils.isNotEmpty(destination)) {
            content.append(",目的地:").append(destination);
        }
        content.append(",请及时处理。");
        return content.toString();
    }
    private List<SysUser> getWechatNotifyUsers(Long dispatchOrdID, SysDept dept) {
@@ -875,7 +1048,7 @@
            List<SysUser> result = new ArrayList<>();
            List<TaskCreateVO.AssigneeInfo> assignees = queryAssignees(dispatchOrdID);
            if (assignees != null && !assignees.isEmpty()) {
            if (!assignees.isEmpty()) {
                for (TaskCreateVO.AssigneeInfo assigneeInfo : assignees) {
                    if (assigneeInfo == null || assigneeInfo.getUserId() == null) {
                        continue;