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.VehicleDept;
|
import com.ruoyi.system.domain.VehicleSyncDTO;
|
import com.ruoyi.system.mapper.SysDeptMapper;
|
import com.ruoyi.system.mapper.VehicleInfoMapper;
|
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.ArrayList;
|
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;
|
|
@Autowired
|
private VehicleInfoMapper vehicleInfoMapper;
|
|
|
/**
|
* 同步车辆数据到MySQL
|
*
|
* @param vehicles 从SQL 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);
|
|
// 解析所有分公司ID(CarOrdClass可能包含多个编码,如:HB,TI)
|
List<VehicleDept> vehicleDepts = parseVehicleDepts(vehicleDTO.getCarOrdClass());
|
|
// 设置默认的主部门ID(第一个分公司)
|
Long primaryDeptId = null;
|
if (!vehicleDepts.isEmpty()) {
|
primaryDeptId = vehicleDepts.get(0).getDeptId();
|
}
|
|
if (existingVehicle != null)
|
{
|
// 更新车辆信息
|
existingVehicle.setCarId(vehicleDTO.getCarId());
|
existingVehicle.setDeptId(primaryDeptId); // 设置主部门
|
vehicleInfoService.updateVehicleInfo(existingVehicle);
|
|
// 更新车辆-分公司关联
|
syncVehicleDepts(existingVehicle.getVehicleId(), vehicleDepts);
|
|
updateCount++;
|
log.debug("更新车辆: {} (CarID={}), 关联分公司数: {}",
|
plateNumber, vehicleDTO.getCarId(), vehicleDepts.size());
|
}
|
else
|
{
|
// 新增车辆信息
|
VehicleInfo newVehicle = new VehicleInfo();
|
newVehicle.setVehicleNo(plateNumber);
|
newVehicle.setCarId(vehicleDTO.getCarId());
|
newVehicle.setDeptId(primaryDeptId); // 设置主部门
|
newVehicle.setStatus("0");
|
newVehicle.setPlatformCode("LEGACY"); // 标记为旧系统同步
|
newVehicle.setRemark("从旧系统同步,CarID: " + vehicleDTO.getCarId());
|
vehicleInfoService.insertVehicleInfo(newVehicle);
|
|
// 新增车辆-分公司关联
|
syncVehicleDepts(newVehicle.getVehicleId(), vehicleDepts);
|
|
insertCount++;
|
log.debug("新增车辆: {} (CarID={}), 关联分公司数: {}",
|
plateNumber, vehicleDTO.getCarId(), vehicleDepts.size());
|
}
|
}
|
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(奔驰) -> 浙A12345
|
*
|
* @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 解析多个分公司关联
|
* CarOrdClass格式可能是:HB、HB,TI、HB.TI等
|
*
|
* @param carOrdClass 车辆单据类型编码
|
* @return 车辆-分公司关联列表
|
*/
|
private List<VehicleDept> parseVehicleDepts(String carOrdClass)
|
{
|
List<VehicleDept> vehicleDepts = new ArrayList<>();
|
|
if (StringUtils.isBlank(carOrdClass))
|
{
|
log.debug("CarOrdClass为空,无法解析分公司");
|
return vehicleDepts;
|
}
|
|
// 拆分CarOrdClass,可能的分隔符:, . 空格
|
String[] codes = carOrdClass.split("[.,\\s]+");
|
|
for (String code : codes)
|
{
|
if (StringUtils.isBlank(code))
|
{
|
continue;
|
}
|
|
code = code.trim();
|
|
// 查询匹配dispatch_order_class或service_order_class的部门
|
SysDept dept = findDeptByOrderClass(code);
|
if (dept != null && dept.getParentId() != null && dept.getParentId() == 100L)
|
{
|
// 只处理分公司(parent_id=100)
|
VehicleDept vehicleDept = new VehicleDept();
|
vehicleDept.setDeptId(dept.getDeptId());
|
vehicleDept.setOrderClass(code);
|
vehicleDept.setCreateBy("system");
|
vehicleDepts.add(vehicleDept);
|
|
log.debug("通过order_class='{}' 找到分公司: {} (ID={})",
|
code, dept.getDeptName(), dept.getDeptId());
|
}
|
else
|
{
|
log.debug("未找到匹配order_class='{}' 的分公司", code);
|
}
|
}
|
|
return vehicleDepts;
|
}
|
|
/**
|
* 同步车辆-分公司关联
|
*
|
* @param vehicleId 车辆ID
|
* @param vehicleDepts 分公司关联列表
|
*/
|
private void syncVehicleDepts(Long vehicleId, List<VehicleDept> vehicleDepts)
|
{
|
if (vehicleId == null || vehicleDepts == null)
|
{
|
return;
|
}
|
|
// 先删除旧的关联
|
vehicleInfoMapper.deleteVehicleDeptByVehicleId(vehicleId);
|
|
// 再插入新的关联
|
if (!vehicleDepts.isEmpty())
|
{
|
for (VehicleDept vd : vehicleDepts)
|
{
|
vd.setVehicleId(vehicleId);
|
}
|
vehicleInfoMapper.batchInsertVehicleDept(vehicleDepts);
|
log.debug("同步车辆ID={} 的分公司关联,数量: {}", vehicleId, vehicleDepts.size());
|
}
|
}
|
|
/**
|
* 根据order_class查询部门(同时匹配dispatch_order_class和service_order_class)
|
*
|
* @param orderClass 编码
|
* @return 部门信息
|
*/
|
private SysDept findDeptByOrderClass(String orderClass)
|
{
|
if (StringUtils.isBlank(orderClass))
|
{
|
return null;
|
}
|
|
try
|
{
|
// 先尝试匹配dispatch_order_class
|
SysDept query = new SysDept();
|
query.setDispatchOrderClass(orderClass);
|
List<SysDept> depts = sysDeptMapper.selectDeptList(query);
|
|
if (depts != null && !depts.isEmpty())
|
{
|
return depts.get(0);
|
}
|
|
// 如果没有找到,尝试匹配service_order_class
|
query = new SysDept();
|
query.setServiceOrderClass(orderClass);
|
depts = sysDeptMapper.selectDeptList(query);
|
|
if (depts != null && !depts.isEmpty())
|
{
|
return depts.get(0);
|
}
|
}
|
catch (Exception e)
|
{
|
log.error("查询order_class='{}' 的部门失败", orderClass, e);
|
}
|
|
return null;
|
}
|
}
|