From 2c86a8bd60deed0dd0e044bad6fb83f75d19a332 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期日, 26 十月 2025 15:05:50 +0800
Subject: [PATCH] Merge branch 'feature-task'

---
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleSyncServiceImpl.java |  319 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 319 insertions(+), 0 deletions(-)

diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleSyncServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleSyncServiceImpl.java
new file mode 100644
index 0000000..b9f4b69
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VehicleSyncServiceImpl.java
@@ -0,0 +1,319 @@
+package com.ruoyi.system.service.impl;
+
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.domain.entity.SysDept;
+import com.ruoyi.system.domain.VehicleInfo;
+import com.ruoyi.system.domain.VehicleSyncDTO;
+import com.ruoyi.system.mapper.SysDeptMapper;
+import com.ruoyi.system.service.IVehicleInfoService;
+import com.ruoyi.system.service.IVehicleSyncDataService;
+import com.ruoyi.system.service.IVehicleSyncService;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 杞﹁締鍚屾鏈嶅姟瀹炵幇
+ * 
+ * 鑱岃矗锛氬皢浠� SQL Server 鏌ヨ鍒扮殑杞﹁締鏁版嵁鍚屾鍒� MySQL
+ * 
+ * 鏁版嵁娴佸悜锛氭帴鏀� DTO 鈫� 鍚屾鍒� MySQL
+ * 
+ * @author ruoyi
+ * @date 2025-10-20
+ */
+@Service
+public class VehicleSyncServiceImpl implements IVehicleSyncService
+{
+    private static final Logger log = LoggerFactory.getLogger(VehicleSyncServiceImpl.class);
+
+    @Autowired
+    private IVehicleInfoService vehicleInfoService;
+
+    @Autowired
+    private SysDeptMapper sysDeptMapper;
+
+
+    /**
+     * 鍚屾杞﹁締鏁版嵁鍒癕ySQL
+     * 
+     * @param vehicles 浠嶴QL Server鏌ヨ鐨勮溅杈嗗垪琛�
+     * @return 鍚屾缁撴灉
+     */
+    @Override
+    @Transactional
+    public AjaxResult syncVehicles(List<VehicleSyncDTO> vehicles)
+    {
+        if (vehicles == null || vehicles.isEmpty())
+        {
+            return AjaxResult.error("杞﹁締鏁版嵁涓虹┖锛屾棤娉曞悓姝�");
+        }
+
+        try
+        {
+            log.info("寮�濮嬪悓姝� {} 鏉¤溅杈嗘暟鎹埌 MySQL...", vehicles.size());
+
+            int insertCount = 0;
+            int updateCount = 0;
+            int skipCount = 0;
+            Map<String, String> errorMessages = new HashMap<>();
+
+            for (VehicleSyncDTO vehicleDTO : vehicles)
+            {
+                try
+                {
+                    // 鎻愬彇杞︾墝鍙凤紙鍘婚櫎鎷彿涓殑鍐呭锛�
+                    String plateNumber = extractPlateNumber(vehicleDTO.getCarLicense());
+                    
+                    if (StringUtils.isBlank(plateNumber))
+                    {
+                        log.warn("杞﹁締 CarID={} 杞︾墝鍙蜂负绌猴紝璺宠繃鍚屾", vehicleDTO.getCarId());
+                        skipCount++;
+                        continue;
+                    }
+
+                    // 鏌ヨ杞﹁締鏄惁瀛樺湪
+                    VehicleInfo existingVehicle = findVehicleByPlateNumber(plateNumber);
+
+                    // 瑙f瀽閮ㄩ棬淇℃伅
+                    Long deptId = parseDeptIdFromCarOrdClass(vehicleDTO.getCarOrdClass());
+
+                    if (existingVehicle != null)
+                    {
+                        // 鏇存柊杞﹁締淇℃伅
+                        existingVehicle.setCarId(vehicleDTO.getCarId());
+                        existingVehicle.setDeptId(deptId);
+                        // 鍙互閫夋嫨鏄惁鏇存柊鍏朵粬瀛楁
+                        vehicleInfoService.updateVehicleInfo(existingVehicle);
+                        updateCount++;
+                        log.debug("鏇存柊杞﹁締: {} (CarID={}), 閮ㄩ棬ID={}", plateNumber, vehicleDTO.getCarId(), deptId);
+                    }
+                    else
+                    {
+                        // 鏂板杞﹁締淇℃伅
+                        VehicleInfo newVehicle = new VehicleInfo();
+                        newVehicle.setVehicleNo(plateNumber);
+                        newVehicle.setCarId(vehicleDTO.getCarId());
+                        newVehicle.setDeptId(deptId);
+                        newVehicle.setStatus("0");
+                        newVehicle.setPlatformCode("LEGACY"); // 鏍囪涓烘棫绯荤粺鍚屾
+                        newVehicle.setRemark("浠庢棫绯荤粺鍚屾锛孋arID: " + vehicleDTO.getCarId());
+                        vehicleInfoService.insertVehicleInfo(newVehicle);
+                        insertCount++;
+                        log.debug("鏂板杞﹁締: {} (CarID={}), 閮ㄩ棬ID={}", plateNumber, vehicleDTO.getCarId(), deptId);
+                    }
+                }
+                catch (Exception e)
+                {
+                    String errorMsg = String.format("鍚屾杞﹁締 CarID=%d 澶辫触: %s", 
+                            vehicleDTO.getCarId(), e.getMessage());
+                    log.error(errorMsg, e);
+                    errorMessages.put("CarID_" + vehicleDTO.getCarId(), errorMsg);
+                }
+            }
+
+            String resultMsg = String.format(
+                    "杞﹁締鍚屾瀹屾垚 - 鏂板: %d, 鏇存柊: %d, 璺宠繃: %d, 澶辫触: %d",
+                    insertCount, updateCount, skipCount, errorMessages.size());
+
+            log.info(resultMsg);
+
+            Map<String, Object> result = new HashMap<>();
+            result.put("insertCount", insertCount);
+            result.put("updateCount", updateCount);
+            result.put("skipCount", skipCount);
+            result.put("errorCount", errorMessages.size());
+            result.put("errors", errorMessages);
+
+            if (errorMessages.isEmpty())
+            {
+                return AjaxResult.success(resultMsg, result);
+            }
+            else
+            {
+                return AjaxResult.warn(resultMsg, result);
+            }
+        }
+        catch (Exception e)
+        {
+            log.error("鍚屾杞﹁締鏁版嵁鍒� MySQL 澶辫触", e);
+            return AjaxResult.error("鍚屾澶辫触: " + e.getMessage());
+        }
+    }
+
+
+    /**
+     * 鎻愬彇杞︾墝鍙凤紙鍘婚櫎鎷彿涓殑鍐呭锛�
+     * 渚嬪锛氭禉A12345锛堝椹帮級 -> 娴橝12345
+     * 
+     * @param carLicense 鍘熷杞︾墝鍙�
+     * @return 鎻愬彇鍚庣殑杞︾墝鍙�
+     */
+    private String extractPlateNumber(String carLicense)
+    {
+        if (StringUtils.isBlank(carLicense))
+        {
+            return null;
+        }
+
+        // 鍘婚櫎绌烘牸
+        String license = carLicense.trim();
+        
+        // 鏌ユ壘宸︽嫭鍙蜂綅缃紙鏀寔涓枃鍜岃嫳鏂囨嫭鍙凤級
+        int leftBracketIndex = license.indexOf('(');
+        int leftBracketIndexCn = license.indexOf('锛�');
+        
+        // 鍙栨渶灏忕殑鏈夋晥鎷彿浣嶇疆
+        int bracketIndex = -1;
+        if (leftBracketIndex >= 0 && leftBracketIndexCn >= 0)
+        {
+            bracketIndex = Math.min(leftBracketIndex, leftBracketIndexCn);
+        }
+        else if (leftBracketIndex >= 0)
+        {
+            bracketIndex = leftBracketIndex;
+        }
+        else if (leftBracketIndexCn >= 0)
+        {
+            bracketIndex = leftBracketIndexCn;
+        }
+        
+        // 濡傛灉鎵惧埌鎷彿锛屾埅鍙栨嫭鍙峰墠鐨勯儴鍒嗭紱鍚﹀垯杩斿洖鍘熷瓧绗︿覆
+        if (bracketIndex > 0)
+        {
+            return license.substring(0, bracketIndex).trim();
+        }
+        
+        return license;
+    }
+
+    /**
+     * 鏍规嵁杞︾墝鍙锋煡鎵捐溅杈嗭紙妯$硦鍖归厤锛�
+     * 
+     * @param plateNumber 杞︾墝鍙�
+     * @return 杞﹁締淇℃伅
+     */
+    private VehicleInfo findVehicleByPlateNumber(String plateNumber)
+    {
+        // 鍏堝皾璇曠簿纭尮閰�
+        VehicleInfo vehicle = vehicleInfoService.selectVehicleInfoByPlateNumber(plateNumber);
+        
+        if (vehicle != null)
+        {
+            return vehicle;
+        }
+        
+        // 濡傛灉绮剧‘鍖归厤澶辫触锛屽皾璇曟ā绯婂尮閰嶏紙鏌ヨ鎵�鏈夎溅杈嗭紝鎵惧埌鍖呭惈璇ヨ溅鐗屽彿鐨勶級
+        VehicleInfo query = new VehicleInfo();
+        List<VehicleInfo> allVehicles = vehicleInfoService.selectVehicleInfoList(query);
+        
+        for (VehicleInfo v : allVehicles)
+        {
+            if (StringUtils.isNotBlank(v.getVehicleNo()))
+            {
+                // 濡傛灉鏁版嵁搴撲腑鐨勮溅鐗屽彿鍖呭惈鏌ヨ鐨勮溅鐗屽彿锛屾垨鏌ヨ鐨勮溅鐗屽彿鍖呭惈鏁版嵁搴撲腑鐨勮溅鐗屽彿
+                String dbPlateNumber = extractPlateNumber(v.getVehicleNo());
+                if (plateNumber.contains(dbPlateNumber) || dbPlateNumber.contains(plateNumber))
+                {
+                    return v;
+                }
+            }
+        }
+        
+        return null;
+    }
+
+    /**
+     * 浠� CarOrdClass 瑙f瀽閮ㄩ棬ID锛屽苟杞崲涓哄垎鍏徃ID
+     * CarOrdClass鏍煎紡鍙兘鏄細ZB銆丠B.TI绛�
+     * 闇�瑕佹媶鍒嗗苟鍦╯ys_dept涓尮閰峝ispatch_order_class瀛楁
+     * 
+     * @param carOrdClass 杞﹁締鍗曟嵁绫诲瀷缂栫爜
+     * @return 鍒嗗叕鍙窱D锛屽鏋滄湭鎵惧埌杩斿洖null
+     */
+    private Long parseDeptIdFromCarOrdClass(String carOrdClass)
+    {
+        if (StringUtils.isBlank(carOrdClass))
+        {
+            log.debug("CarOrdClass涓虹┖锛屾棤娉曡В鏋愰儴闂�");
+            return null;
+        }
+
+        // 鎷嗗垎CarOrdClass锛屽彲鑳界殑鍒嗛殧绗︼細. , 绌烘牸
+        String[] codes = carOrdClass.split("[.,\\s]+");
+        
+        for (String code : codes)
+        {
+            if (StringUtils.isBlank(code))
+            {
+                continue;
+            }
+            
+            code = code.trim();
+            
+            // 鏌ヨ鍖归厤dispatch_order_class鐨勯儴闂�
+            SysDept dept = findDeptByDispatchOrderClass(code);
+            if (dept != null)
+            {
+                log.debug("閫氳繃dispatch_order_class='{}' 鎵惧埌閮ㄩ棬: {} (ID={})", 
+                        code, dept.getDeptName(), dept.getDeptId());
+                
+                // 灏嗛儴闂↖D杞崲涓哄垎鍏徃ID
+                Long branchCompanyId = sysDeptMapper.selectBranchCompanyIdByDeptId(dept.getDeptId());
+                if (branchCompanyId != null)
+                {
+                    log.debug("灏嗛儴闂↖D {} 杞崲涓哄垎鍏徃ID: {}", dept.getDeptId(), branchCompanyId);
+                    return branchCompanyId;
+                }
+                else
+                {
+                    log.warn("閮ㄩ棬ID {} 鏃犳硶杞崲涓哄垎鍏徃ID锛屽彲鑳芥槸鎬诲叕鍙告垨鏁版嵁寮傚父", dept.getDeptId());
+                    return null;
+                }
+            }
+        }
+        
+        log.warn("鏈壘鍒板尮閰岰arOrdClass='{}' 鐨勯儴闂�", carOrdClass);
+        return null;
+    }
+
+    /**
+     * 鏍规嵁dispatch_order_class鏌ヨ閮ㄩ棬
+     * 
+     * @param dispatchOrderClass 璋冨害鍗曠紪鐮�
+     * @return 閮ㄩ棬淇℃伅
+     */
+    private SysDept findDeptByDispatchOrderClass(String dispatchOrderClass)
+    {
+        if (StringUtils.isBlank(dispatchOrderClass))
+        {
+            return null;
+        }
+
+        try
+        {
+            SysDept query = new SysDept();
+            query.setDispatchOrderClass(dispatchOrderClass);
+            List<SysDept> depts = sysDeptMapper.selectDeptList(query);
+            
+            if (depts != null && !depts.isEmpty())
+            {
+                // 杩斿洖绗竴涓尮閰嶇殑閮ㄩ棬
+                return depts.get(0);
+            }
+        }
+        catch (Exception e)
+        {
+            log.error("鏌ヨdispatch_order_class='{}' 鐨勯儴闂ㄥけ璐�", dispatchOrderClass, e);
+        }
+        
+        return null;
+    }
+}

--
Gitblit v1.9.1