package com.xiaopeng.operation.service.impl;
|
|
import com.xiaopeng.api.feignClient.vehicleConvoy.XpVehicleClient;
|
import com.xiaopeng.api.model.operation.XpElectronicFenceArea;
|
import com.xiaopeng.api.model.vehicleConvoy.XpVehicle;
|
import com.xiaopeng.common.core.domain.R;
|
import com.xiaopeng.operation.config.UidVinBindingConfig;
|
import com.xiaopeng.operation.dto.PriorityMatchResult;
|
import com.xiaopeng.operation.dto.PriorityMatchResult.FailReason;
|
import com.xiaopeng.operation.service.IXpElectronicFenceAreaService;
|
import com.xiaopeng.operation.service.UidVinPriorityMatcher;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.stereotype.Service;
|
|
import javax.annotation.Resource;
|
import java.util.Objects;
|
|
/**
|
* UID-VIN 优先匹配执行器实现
|
* <p>
|
* 匹配流程:查绑定配置 → 查询车辆状态 → 校验可用条件 → 返回结果
|
* </p>
|
*/
|
@Slf4j
|
@Service
|
public class UidVinPriorityMatcherImpl implements UidVinPriorityMatcher {
|
|
@Resource
|
private UidVinBindingConfig uidVinBindingConfig;
|
|
@Resource
|
private XpVehicleClient xpVehicleClient;
|
|
@Resource
|
private IXpElectronicFenceAreaService xpElectronicFenceAreaService;
|
|
@Override
|
public PriorityMatchResult tryPriorityMatch(String uid, String orderNo, String electronicAreaId) {
|
log.info("[人车订单绑定测试] ===== 开始优先匹配, uid={}, orderNo={}, electronicAreaId={} =====", uid, orderNo, electronicAreaId);
|
|
// 1. 查询绑定配置
|
log.info("[人车订单绑定测试] 步骤1: 查询UID绑定配置, uid={}", uid);
|
String vin = uidVinBindingConfig.getBoundVin(uid);
|
if (vin == null) {
|
log.info("[人车订单绑定测试] 步骤1结果: 该UID无绑定VIN, uid={}, orderNo={}", uid, orderNo);
|
return PriorityMatchResult.fail(FailReason.NO_BINDING);
|
}
|
log.info("[人车订单绑定测试] 步骤1结果: 找到绑定关系, uid={}, vin={}", uid, vin);
|
|
// 2. 查询车辆状态
|
log.info("[人车订单绑定测试] 步骤2: 调用车队服务查询车辆状态, vin={}", vin);
|
R<XpVehicle> vehicleR = xpVehicleClient.findByVehicleVin(vin);
|
log.info("[人车订单绑定测试] 步骤2: 车队服务返回, code={}, data={}", vehicleR.getCode(), vehicleR.getData() != null ? "有数据" : "null");
|
if (vehicleR.getCode() != R.SUCCESS || vehicleR.getData() == null) {
|
log.info("[人车订单绑定测试] 步骤2结果: 车辆不存在或查询失败, uid={}, vin={}, orderNo={}, responseCode={}", uid, vin, orderNo, vehicleR.getCode());
|
return PriorityMatchResult.fail(FailReason.VEHICLE_NOT_FOUND);
|
}
|
|
XpVehicle vehicle = vehicleR.getData();
|
log.info("[人车订单绑定测试] 步骤2结果: 车辆信息获取成功, vin={}, plateNumber={}, operatingStatus={}, state={}, vehicleType={}, electronicId={}",
|
vin, vehicle.getPlateNumber(), vehicle.getOperatingStatus(), vehicle.getState(), vehicle.getVehicleType(), vehicle.getElectronicId());
|
|
// 3. 校验车辆可用条件:operatingStatus=1, state=0, vehicleType!=1
|
log.info("[人车订单绑定测试] 步骤3: 校验车辆可用条件 (operatingStatus==1 && state==0 && vehicleType!=1)");
|
if (!isVehicleAvailable(vehicle)) {
|
if (!Objects.equals(vehicle.getState(), 0)) {
|
log.info("[人车订单绑定测试] 步骤3结果: 车辆已接单(state={}), 当前有未完成订单, 无法指派, uid={}, vin={}, plateNumber={}, orderNo={}",
|
vehicle.getState(), uid, vin, vehicle.getPlateNumber(), orderNo);
|
} else {
|
log.info("[人车订单绑定测试] 步骤3结果: 车辆不可用, uid={}, vin={}, orderNo={}, operatingStatus={}, state={}, vehicleType={}",
|
uid, vin, orderNo, vehicle.getOperatingStatus(), vehicle.getState(), vehicle.getVehicleType());
|
}
|
return PriorityMatchResult.fail(FailReason.VEHICLE_UNAVAILABLE);
|
}
|
log.info("[人车订单绑定测试] 步骤3结果: 车辆可用条件校验通过");
|
|
// 4. 校验电子围栏一致性:将 areaId 转换为 fenceId,与车辆的 electronicId 比较
|
log.info("[人车订单绑定测试] 步骤4: 校验电子围栏一致性, 订单围栏区域ID={}, 车辆围栏ID={}", electronicAreaId, vehicle.getElectronicId());
|
if (!isSameElectronicFence(vehicle, electronicAreaId)) {
|
log.info("[人车订单绑定测试] 步骤4结果: 围栏不一致, uid={}, vin={}, orderNo={}, vehicleElectronicId={}, electronicAreaId={}",
|
uid, vin, orderNo, vehicle.getElectronicId(), electronicAreaId);
|
return PriorityMatchResult.fail(FailReason.WRONG_AREA);
|
}
|
log.info("[人车订单绑定测试] 步骤4结果: 围栏校验通过");
|
|
// 5. 所有校验通过
|
log.info("[人车订单绑定测试] ===== 匹配成功, uid={}, vin={}, orderNo={} =====", uid, vin, orderNo);
|
return PriorityMatchResult.success(vin);
|
}
|
|
/**
|
* 校验车辆是否可用:运营中(1)、空闲(0)、非测试车(!=1)
|
*/
|
private boolean isVehicleAvailable(XpVehicle vehicle) {
|
return Objects.equals(vehicle.getOperatingStatus(), 1)
|
&& Objects.equals(vehicle.getState(), 0)
|
&& !Objects.equals(vehicle.getVehicleType(), 1);
|
}
|
|
/**
|
* 校验车辆是否在同一电子围栏内
|
* <p>
|
* electronicAreaId 是围栏区域ID,需要通过 IXpElectronicFenceAreaService 查询
|
* 对应的围栏ID(electronicId),再与车辆的 electronicId 比较。
|
*/
|
private boolean isSameElectronicFence(XpVehicle vehicle, String electronicAreaId) {
|
if (electronicAreaId == null || vehicle.getElectronicId() == null) {
|
log.info("[人车订单绑定测试] 围栏校验: 参数为空, electronicAreaId={}, vehicleElectronicId={}", electronicAreaId, vehicle.getElectronicId());
|
return false;
|
}
|
try {
|
XpElectronicFenceArea area = xpElectronicFenceAreaService.getById(Long.parseLong(electronicAreaId));
|
if (area == null || area.getElectronicId() == null) {
|
log.info("[人车订单绑定测试] 围栏校验: 围栏区域不存在或无关联围栏, electronicAreaId={}", electronicAreaId);
|
return false;
|
}
|
boolean same = Objects.equals(vehicle.getElectronicId(), area.getElectronicId());
|
log.info("[人车订单绑定测试] 围栏校验: 车辆围栏ID={}, 区域关联围栏ID={}, 是否一致={}", vehicle.getElectronicId(), area.getElectronicId(), same);
|
return same;
|
} catch (NumberFormatException e) {
|
log.info("[人车订单绑定测试] 围栏校验: electronicAreaId格式异常, electronicAreaId={}", electronicAreaId);
|
return false;
|
}
|
}
|
}
|