自动识别
parent
1fc09bb9d3
commit
8e2427369f
|
|
@ -0,0 +1,27 @@
|
|||
package com.njzscloud.dispose.cst.order.config;
|
||||
|
||||
import com.njzscloud.dispose.cst.order.service.TruckWeighingEventListener;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 车辆称重配置
|
||||
* 用于初始化车辆称重事件监听器
|
||||
*
|
||||
* @author ljw
|
||||
*/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class TruckWeighingConfig implements CommandLineRunner {
|
||||
|
||||
private final TruckWeighingEventListener truckWeighingEventListener;
|
||||
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
log.info("启动车辆称重事件监听器");
|
||||
truckWeighingEventListener.init();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package com.njzscloud.dispose.cst.order.constant;
|
||||
|
||||
/**
|
||||
* 语音提示常量
|
||||
*
|
||||
* @author ljw
|
||||
*/
|
||||
public class VoiceConstants {
|
||||
|
||||
private VoiceConstants() {
|
||||
// 工具类,防止实例化
|
||||
}
|
||||
|
||||
public static final String VOICE_WELCOME = "欢迎光临";
|
||||
public static final String VOICE_WEIGHING = "正在称重请稍候";
|
||||
public static final String VOICE_PLEASE_PASS = "请通行";
|
||||
public static final String VOICE_WEIGH_COMPLETE = "称重完成";
|
||||
public static final String VOICE_ORDER_NOT_FOUND = "订单不存在";
|
||||
public static final String VOICE_SYSTEM_ERROR = "系统异常";
|
||||
public static final String VOICE_WEIGH_FAILED = "称重失败";
|
||||
public static final String VOICE_STATUS_ERROR = "状态异常";
|
||||
public static final String VOICE_SETTLEMENT_ERROR = "结算异常";
|
||||
public static final String VOICE_UNCHECKED = "未看料";
|
||||
}
|
||||
|
|
@ -109,7 +109,7 @@ public class OrderController {
|
|||
* 车辆进场
|
||||
*/
|
||||
@PostMapping("/truck_coming")
|
||||
public R<?> truckComing(@RequestBody TruckComingParam param) {
|
||||
public synchronized R<?> truckComing(@RequestBody TruckComingParam param) {
|
||||
orderService.truckComing(param);
|
||||
return R.success();
|
||||
}
|
||||
|
|
@ -118,7 +118,7 @@ public class OrderController {
|
|||
* 看料
|
||||
*/
|
||||
@PostMapping("/check")
|
||||
public R<?> check(@RequestBody CheckGoodsParam checkGoodsParam) {
|
||||
public synchronized R<?> check(@RequestBody CheckGoodsParam checkGoodsParam) {
|
||||
orderService.check(checkGoodsParam);
|
||||
return R.success();
|
||||
}
|
||||
|
|
@ -127,7 +127,7 @@ public class OrderController {
|
|||
* 车辆出场
|
||||
*/
|
||||
@PostMapping("/truck_leaving")
|
||||
public R<?> truckLeaving(@RequestBody TruckLeavingParam leavingParam) {
|
||||
public synchronized R<?> truckLeaving(@RequestBody TruckLeavingParam leavingParam) {
|
||||
orderService.truckLeaving(leavingParam);
|
||||
return R.success();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,4 +21,11 @@ public interface OrderTransMapper extends BaseMapper<OrderTransEntity> {
|
|||
|
||||
IPage<OrderTransResult> paging(Page<Object> page, @Param("ew") QueryWrapper<?> ew);
|
||||
|
||||
/**
|
||||
* 根据车牌号查找运输订单
|
||||
* @param licensePlate 车牌号
|
||||
* @return 运输订单结果
|
||||
*/
|
||||
OrderTransResult getByLicensePlate(@Param("licensePlate") String licensePlate);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.njzscloud.common.core.ex.Exceptions;
|
||||
import com.njzscloud.common.core.fastjson.Fastjson;
|
||||
import com.njzscloud.common.core.tuple.Tuple2;
|
||||
import com.njzscloud.common.mp.support.PageParam;
|
||||
import com.njzscloud.common.mp.support.PageResult;
|
||||
import com.njzscloud.common.security.util.SecurityUtil;
|
||||
|
|
@ -27,9 +26,6 @@ import com.njzscloud.dispose.cst.order.pojo.result.OrderTransResult;
|
|||
import com.njzscloud.dispose.cst.order.pojo.vo.Scope;
|
||||
import com.njzscloud.dispose.cst.truck.mapper.TruckMapper;
|
||||
import com.njzscloud.dispose.cst.truck.pojo.entity.TruckEntity;
|
||||
import com.njzscloud.dispose.dev.DiscoverTruckMsg;
|
||||
import com.njzscloud.dispose.dev.ObtainTruckDataResultMsg;
|
||||
import com.njzscloud.dispose.dev.WbsHandle;
|
||||
import com.njzscloud.dispose.finance.constant.ScopeStrategy;
|
||||
import com.njzscloud.dispose.finance.pojo.entity.ExpenseItemEntity;
|
||||
import com.njzscloud.dispose.finance.service.ExpenseItemService;
|
||||
|
|
@ -42,12 +38,8 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.njzscloud.dispose.dev.DevMittEvent.DISCOVER_TRUCK;
|
||||
import static com.njzscloud.dispose.dev.DevMittEvent.OBTAIN_TRUCK_DATA_REPLY;
|
||||
|
||||
/**
|
||||
* 收/销订单
|
||||
*
|
||||
|
|
@ -66,55 +58,6 @@ public class OrderService extends ServiceImpl<OrderMapper, OrderEntity> {
|
|||
private final CustomerMapper customerMapper;
|
||||
private final OrderExpenseItemsService orderExpenseItemsService;
|
||||
|
||||
{
|
||||
DISCOVER_TRUCK.on(this::a);
|
||||
OBTAIN_TRUCK_DATA_REPLY.on(this::b);
|
||||
}
|
||||
|
||||
|
||||
public void a(Tuple2<DiscoverTruckMsg, WbsHandle> param) {
|
||||
DiscoverTruckMsg param0 = param.get_0();
|
||||
WbsHandle param1 = param.get_1();
|
||||
|
||||
// 车头照
|
||||
String image = param0.getImage();
|
||||
// 写库要加锁
|
||||
String licensePlate = param0.getLicensePlate();
|
||||
// 找订单
|
||||
|
||||
// 发语音
|
||||
|
||||
// 进前置、出前置
|
||||
|
||||
// 进场
|
||||
|
||||
// 获取磅重、车斗照片
|
||||
param1.obtainTruckData(1L);
|
||||
param1.playVoice(image, 2);
|
||||
param1.open();
|
||||
return;
|
||||
// 出场
|
||||
|
||||
}
|
||||
|
||||
ReentrantLock reentrantLock = new ReentrantLock();
|
||||
|
||||
public void b(Tuple2<ObtainTruckDataResultMsg, WbsHandle> param) {
|
||||
ObtainTruckDataResultMsg it0 = param.get_0();
|
||||
WbsHandle it1 = param.get_1();
|
||||
// 车斗照
|
||||
Long orderId = it0.getOrderId();
|
||||
String image = it0.getImage();
|
||||
Integer weight = it0.getWeight();
|
||||
it1.open();
|
||||
it1.playVoice(image, 2);
|
||||
|
||||
synchronized (this) {
|
||||
// 写库要加锁
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void add(CreateOrderParam param) {
|
||||
// 订单信息
|
||||
|
|
|
|||
|
|
@ -0,0 +1,481 @@
|
|||
package com.njzscloud.dispose.cst.order.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.njzscloud.common.core.tuple.Tuple2;
|
||||
import com.njzscloud.common.oss.util.AliOSS;
|
||||
import com.njzscloud.dispose.cst.order.constant.*;
|
||||
import com.njzscloud.dispose.cst.order.mapper.OrderTransMapper;
|
||||
import com.njzscloud.dispose.cst.order.pojo.entity.OrderEntity;
|
||||
import com.njzscloud.dispose.cst.order.pojo.entity.OrderTransEntity;
|
||||
import com.njzscloud.dispose.cst.order.pojo.result.OrderTransResult;
|
||||
import com.njzscloud.dispose.dev.DiscoverTruckMsg;
|
||||
import com.njzscloud.dispose.dev.ObtainTruckDataResultMsg;
|
||||
import com.njzscloud.dispose.dev.WbsHandle;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 车辆称重业务服务
|
||||
* 处理磅房称重相关的所有业务逻辑
|
||||
*
|
||||
* @author ljw
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TruckWeighingBusinessService {
|
||||
|
||||
private final OrderService orderService;
|
||||
private final OrderTransMapper orderTransMapper;
|
||||
|
||||
/**
|
||||
* 请求数据 - 处理车辆识别
|
||||
*/
|
||||
public void requestData(Tuple2<DiscoverTruckMsg, WbsHandle> param) {
|
||||
DiscoverTruckMsg truckMsg = param.get_0();
|
||||
WbsHandle handle = param.get_1();
|
||||
// 车牌号
|
||||
String licensePlate = truckMsg.getLicensePlate();
|
||||
// 是否为前置道闸
|
||||
boolean isFront = truckMsg.isFront();
|
||||
// 根据车牌号查找运输订单
|
||||
OrderTransResult orderTrans = orderTransMapper.getByLicensePlate(licensePlate);
|
||||
if (orderTrans == null) {
|
||||
log.warn("未找到车牌号 {} 对应的运输订单", licensePlate);
|
||||
handle.playVoice(VoiceConstants.VOICE_ORDER_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证订单业务状态
|
||||
if (!validateOrderBusinessStatus(orderTrans)) {
|
||||
handle.playVoice(VoiceConstants.VOICE_STATUS_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
// 使用同步锁确保数据一致性
|
||||
synchronized (this) {
|
||||
try {
|
||||
log.info("开始处理车辆 {} 进出场请求,前置道闸: {}", licensePlate, isFront ? "是" : "否");
|
||||
|
||||
// 判断是进场还是出场
|
||||
boolean isComing = isTruckComing(orderTrans);
|
||||
boolean isLeaving = isTruckLeaving(orderTrans);
|
||||
if (isLeaving) {
|
||||
// 出场时检查是否已看料
|
||||
if (!CheckStatus.YiKanLiao.equals(orderTrans.getCheckStatus())) {
|
||||
handle.playVoice(licensePlate + VoiceConstants.VOICE_UNCHECKED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!isComing && !isLeaving) {
|
||||
log.warn("订单 {} 状态不允许进出场操作,当前状态:订单={},运输={}",
|
||||
orderTrans.getId(), orderTrans.getOrderStatus(), orderTrans.getTransStatus());
|
||||
handle.playVoice(VoiceConstants.VOICE_STATUS_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isFront) {
|
||||
// 前置道闸:还未上磅,只负责开门让车辆通过
|
||||
log.info("前置道闸开门,车辆 {} 进入磅区", licensePlate);
|
||||
handle.playVoice(VoiceConstants.VOICE_WELCOME);
|
||||
handle.open();
|
||||
} else {
|
||||
// 后置道闸:车辆已过磅,负责称重和算账,但不开门
|
||||
log.info("后置道闸开始称重,车辆 {},订单ID: {}", licensePlate, orderTrans.getId());
|
||||
handle.playVoice(VoiceConstants.VOICE_WEIGHING);
|
||||
handle.obtainTruckData(orderTrans.getId());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("处理车辆 {} 识别异常", licensePlate, e);
|
||||
handle.playVoice(VoiceConstants.VOICE_SYSTEM_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理数据 - 处理磅重数据
|
||||
*/
|
||||
public void disposeData(Tuple2<ObtainTruckDataResultMsg, WbsHandle> param) {
|
||||
ObtainTruckDataResultMsg dataMsg = param.get_0();
|
||||
WbsHandle wbsHandle = param.get_1();
|
||||
|
||||
Long orderTransId = dataMsg.getOrderId();
|
||||
String image = dataMsg.getImage();
|
||||
Integer weight = dataMsg.getWeight();
|
||||
Boolean success = dataMsg.getSuccess();
|
||||
|
||||
// 检查数据获取是否成功
|
||||
if (!Boolean.TRUE.equals(success) || weight == null || weight <= 0) {
|
||||
log.warn("获取车辆数据失败或重量无效,订单ID: {}, 重量: {}", orderTransId, weight);
|
||||
wbsHandle.playVoice(VoiceConstants.VOICE_WEIGH_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
try {
|
||||
log.info("开始处理称重数据,运输ID: {}, 重量: {}kg", orderTransId, weight);
|
||||
|
||||
// 根据运输ID获取订单信息
|
||||
OrderTransResult orderTrans = orderTransMapper.getById(orderTransId);
|
||||
if (orderTrans == null) {
|
||||
log.warn("未找到运输订单 {}", orderTransId);
|
||||
wbsHandle.playVoice(VoiceConstants.VOICE_ORDER_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
if (!CheckStatus.YiKanLiao.equals(orderTrans.getCheckStatus())) {
|
||||
wbsHandle.playVoice(orderTrans.getTruckLicensePlate() + VoiceConstants.VOICE_UNCHECKED);
|
||||
return;
|
||||
}
|
||||
|
||||
// 根据当前状态处理称重数据
|
||||
processWeighingData(orderTrans, weight, image, wbsHandle);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("处理车辆称重数据异常,订单ID: {}", orderTransId, e);
|
||||
wbsHandle.playVoice(VoiceConstants.VOICE_SYSTEM_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理称重数据
|
||||
*/
|
||||
private void processWeighingData(OrderTransResult orderTrans, Integer weight, String image, WbsHandle wbsHandle) {
|
||||
// 根据当前状态判断是进场还是出场
|
||||
if (TransStatus.YunShuZhong.equals(orderTrans.getTransStatus())) {
|
||||
// 进场:设置相应重量,完成后开门
|
||||
handleTruckComingData(orderTrans, weight, image);
|
||||
wbsHandle.playVoice(VoiceConstants.VOICE_PLEASE_PASS);
|
||||
wbsHandle.open();
|
||||
} else if (TransStatus.YiJinChang.equals(orderTrans.getTransStatus())) {
|
||||
// 出场:设置相应重量并计算净重、账目,等待支付完成后再开门
|
||||
handleTruckLeavingData(orderTrans, weight, image);
|
||||
wbsHandle.playVoice(VoiceConstants.VOICE_WEIGH_COMPLETE);
|
||||
// TODO: 触发算账流程,支付完成后调用 completePaymentAndOpenGate 方法开门
|
||||
processSettlementAndWaitForPayment(orderTrans, wbsHandle);
|
||||
} else {
|
||||
log.warn("运输订单 {} 状态 {} 不支持称重操作", orderTrans.getId(), orderTrans.getTransStatus());
|
||||
wbsHandle.playVoice(VoiceConstants.VOICE_STATUS_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理进场称重数据
|
||||
*/
|
||||
private void handleTruckComingData(OrderTransResult orderTrans, Integer weight, String bodyPhoto) {
|
||||
OrderTransEntity transEntity = new OrderTransEntity();
|
||||
transEntity.setId(orderTrans.getId());
|
||||
transEntity.setTransStatus(TransStatus.YiJinChang);
|
||||
transEntity.setInTime(LocalDateTime.now());
|
||||
|
||||
// 上传车斗照片并设置URL
|
||||
if (bodyPhoto != null && !bodyPhoto.trim().isEmpty()) {
|
||||
String photoUrl = uploadBase64Image(bodyPhoto, "truck_body_in_" + orderTrans.getId());
|
||||
transEntity.setInBodyPhoto(photoUrl);
|
||||
}
|
||||
|
||||
// 设置重量(进场)
|
||||
setWeightByOrderType(transEntity, orderTrans, weight, true);
|
||||
|
||||
orderTransMapper.updateById(transEntity);
|
||||
log.info("车辆进场称重完成,订单ID: {}, 重量: {}kg", orderTrans.getId(), weight);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理出场称重数据
|
||||
*/
|
||||
private void handleTruckLeavingData(OrderTransResult orderTrans, Integer weight, String bodyPhoto) {
|
||||
OrderTransEntity transEntity = new OrderTransEntity();
|
||||
transEntity.setId(orderTrans.getId());
|
||||
transEntity.setTransStatus(TransStatus.YiChuChang);
|
||||
transEntity.setOutTime(LocalDateTime.now());
|
||||
|
||||
// 上传车斗照片并设置URL
|
||||
if (bodyPhoto != null && !bodyPhoto.trim().isEmpty()) {
|
||||
String photoUrl = uploadBase64Image(bodyPhoto, "truck_body_out_" + orderTrans.getId());
|
||||
transEntity.setOutBodyPhoto(photoUrl);
|
||||
}
|
||||
|
||||
// 设置重量(出场)
|
||||
setWeightByOrderType(transEntity, orderTrans, weight, false);
|
||||
|
||||
// 计算净重
|
||||
calculateAndSetNetWeight(transEntity, orderTrans);
|
||||
|
||||
orderTransMapper.updateById(transEntity);
|
||||
Integer settleWeight = transEntity.getSettleWeight();
|
||||
log.info("车辆出场称重完成,订单ID: {}, 重量: {}kg, 净重: {}kg",
|
||||
orderTrans.getId(), weight, settleWeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据订单类型设置重量
|
||||
*/
|
||||
private void setWeightByOrderType(OrderTransEntity transEntity, OrderTransResult orderTrans, Integer weight, boolean isComing) {
|
||||
if (OrderCategory.HuiShouYuYue.equals(orderTrans.getOrderCategory())) {
|
||||
// 回收预约单:进场称毛重,出场称皮重
|
||||
if (isComing) {
|
||||
transEntity.setRoughWeight(weight);
|
||||
} else {
|
||||
transEntity.setTareWeight(weight);
|
||||
// 更新车辆皮重
|
||||
orderService.updateTruckHisTareWeight(orderTrans.getTruckId(), weight);
|
||||
}
|
||||
} else if (OrderCategory.XiaoShouYuYue.equals(orderTrans.getOrderCategory())) {
|
||||
// 销售预约单:进场称皮重,出场称毛重
|
||||
if (isComing) {
|
||||
transEntity.setTareWeight(weight);
|
||||
// 更新车辆皮重
|
||||
orderService.updateTruckHisTareWeight(orderTrans.getTruckId(), weight);
|
||||
} else {
|
||||
transEntity.setRoughWeight(weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算并设置净重
|
||||
*/
|
||||
private void calculateAndSetNetWeight(OrderTransEntity transEntity, OrderTransResult orderTrans) {
|
||||
Integer roughWeight = transEntity.getRoughWeight() != null ? transEntity.getRoughWeight() : orderTrans.getRoughWeight();
|
||||
Integer tareWeight = transEntity.getTareWeight() != null ? transEntity.getTareWeight() : orderTrans.getTareWeight();
|
||||
|
||||
if (roughWeight != null && tareWeight != null && roughWeight > tareWeight) {
|
||||
Integer settleWeight = roughWeight - tareWeight;
|
||||
transEntity.setSettleWeight(settleWeight);
|
||||
log.debug("计算净重完成,毛重: {}kg, 皮重: {}kg, 净重: {}kg", roughWeight, tareWeight, settleWeight);
|
||||
} else {
|
||||
log.warn("无法计算净重,毛重: {}, 皮重: {}", roughWeight, tareWeight);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传base64编码的图片到阿里云OSS
|
||||
*/
|
||||
private String uploadBase64Image(String base64Image, String fileNamePrefix) {
|
||||
if (base64Image == null || base64Image.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
// 移除base64前缀(如"data:image/jpeg;base64,")
|
||||
String base64Data;
|
||||
if (base64Image.contains(",")) {
|
||||
base64Data = base64Image.substring(base64Image.indexOf(",") + 1);
|
||||
} else {
|
||||
base64Data = base64Image;
|
||||
}
|
||||
|
||||
// 解码base64字符串为字节数组
|
||||
byte[] imageBytes = Base64.getDecoder().decode(base64Data);
|
||||
|
||||
// 生成文件名
|
||||
String fileName = fileNamePrefix + "_" + System.currentTimeMillis() + ".jpg";
|
||||
|
||||
// 创建ByteArrayInputStream并上传到OSS
|
||||
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(imageBytes)) {
|
||||
// 使用AliOSS直接上传
|
||||
String url = AliOSS.uploadFile(fileName, "image/jpeg", inputStream);
|
||||
|
||||
log.info("车斗照片上传成功: {}", url);
|
||||
return url;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("上传base64车斗照片失败", e);
|
||||
// 上传失败时返回原始base64字符串作为降级方案
|
||||
return base64Image;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为进场操作
|
||||
* 订单状态为进行中,运输状态为运输中
|
||||
*/
|
||||
private boolean isTruckComing(OrderTransResult orderTrans) {
|
||||
return OrderStatus.JinXingZhong.equals(orderTrans.getOrderStatus()) &&
|
||||
TransStatus.YunShuZhong.equals(orderTrans.getTransStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为出场操作
|
||||
* 订单状态为进行中,运输状态为已进场
|
||||
*/
|
||||
private boolean isTruckLeaving(OrderTransResult orderTrans) {
|
||||
return OrderStatus.JinXingZhong.equals(orderTrans.getOrderStatus()) &&
|
||||
TransStatus.YiJinChang.equals(orderTrans.getTransStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证订单业务状态
|
||||
*/
|
||||
private boolean validateOrderBusinessStatus(OrderTransResult orderTrans) {
|
||||
// 检查订单状态
|
||||
if (!OrderStatus.JinXingZhong.equals(orderTrans.getOrderStatus())) {
|
||||
log.warn("订单状态异常,订单ID: {}, 当前状态: {}", orderTrans.getId(), orderTrans.getOrderStatus());
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查运输状态
|
||||
TransStatus transStatus = orderTrans.getTransStatus();
|
||||
if (!TransStatus.YunShuZhong.equals(transStatus) && !TransStatus.YiJinChang.equals(transStatus)) {
|
||||
log.warn("运输状态异常,订单ID: {}, 当前状态: {}", orderTrans.getId(), transStatus);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查订单类型
|
||||
if (orderTrans.getOrderCategory() == null) {
|
||||
log.warn("订单类型为空,订单ID: {}", orderTrans.getId());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查订单下所有运输记录是否都已完成
|
||||
*/
|
||||
private boolean checkAllTransCompleted(Long orderId) {
|
||||
try {
|
||||
// 查询该订单下的所有运输记录
|
||||
List<OrderTransEntity> transList = orderTransMapper.selectList(
|
||||
Wrappers.<OrderTransEntity>lambdaQuery()
|
||||
.eq(OrderTransEntity::getOrderId, orderId)
|
||||
.eq(OrderTransEntity::getDeleted, Boolean.FALSE)
|
||||
);
|
||||
|
||||
if (transList.isEmpty()) {
|
||||
log.warn("订单 {} 下没有找到运输记录", orderId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查所有运输记录的状态是否都为已完成
|
||||
boolean allCompleted = transList.stream()
|
||||
.allMatch(trans -> TransStatus.YiWanCheng.equals(trans.getTransStatus()));
|
||||
|
||||
if (allCompleted) {
|
||||
log.info("订单 {} 下所有 {} 条运输记录都已完成", orderId, transList.size());
|
||||
} else {
|
||||
long completedCount = transList.stream()
|
||||
.filter(trans -> TransStatus.YiWanCheng.equals(trans.getTransStatus()))
|
||||
.count();
|
||||
log.info("订单 {} 下 {}/{} 条运输记录已完成", orderId, completedCount, transList.size());
|
||||
}
|
||||
|
||||
return allCompleted;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("检查订单 {} 运输完成状态异常", orderId, e);
|
||||
// 出现异常时保守处理,返回false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理结算并等待支付完成
|
||||
*/
|
||||
private void processSettlementAndWaitForPayment(OrderTransResult orderTrans, WbsHandle wbsHandle) {
|
||||
try {
|
||||
log.info("开始处理订单 {} 的结算流程", orderTrans.getId());
|
||||
|
||||
// TODO: 执行算账逻辑
|
||||
// 这里应该调用财务结算服务,计算费用并生成支付订单
|
||||
// calculateSettlement(orderTrans);
|
||||
|
||||
// 模拟支付完成通知(实际应该通过支付回调或消息队列处理)
|
||||
// 在实际生产环境中,应该:
|
||||
// 1. 调用财务服务计算费用
|
||||
// 2. 生成支付订单
|
||||
// 3. 等待支付完成的通知(通过消息队列或回调)
|
||||
// 4. 支付完成后调用 completePaymentAndOpenGate 方法
|
||||
|
||||
log.info("订单 {} 结算流程启动,等待支付完成", orderTrans.getId());
|
||||
|
||||
// TODO: 在实际支付完成后调用以下方法
|
||||
// completePaymentAndOpenGate(orderTrans, wbsHandle);
|
||||
|
||||
// 临时实现:直接完成(用于测试)
|
||||
simulatePaymentCompletion(orderTrans, wbsHandle);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("处理订单 {} 结算异常", orderTrans.getId(), e);
|
||||
handleBusinessException(wbsHandle, "结算处理失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 模拟支付完成(测试用)
|
||||
*/
|
||||
private void simulatePaymentCompletion(OrderTransResult orderTrans, WbsHandle wbsHandle) {
|
||||
// 在实际应用中,这里应该通过消息队列或定时任务等待支付完成
|
||||
// 这里只是为了演示流程,实际应该移除
|
||||
try {
|
||||
// 模拟支付处理时间
|
||||
Thread.sleep(2000);
|
||||
completePaymentAndOpenGate(orderTrans, wbsHandle);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
log.error("模拟支付完成被中断", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付完成并开门
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void completePaymentAndOpenGate(OrderTransResult orderTrans, WbsHandle wbsHandle) {
|
||||
synchronized (this) {
|
||||
try {
|
||||
// 更新运输状态为已完成
|
||||
OrderTransEntity transEntity = new OrderTransEntity();
|
||||
transEntity.setId(orderTrans.getId());
|
||||
transEntity.setTransStatus(TransStatus.YiWanCheng);
|
||||
transEntity.setFinishTime(LocalDateTime.now());
|
||||
orderTransMapper.updateById(transEntity);
|
||||
|
||||
// 检查该订单下所有运输记录是否都已完成
|
||||
boolean allTransCompleted = checkAllTransCompleted(orderTrans.getOrderId());
|
||||
|
||||
if (allTransCompleted) {
|
||||
// 更新订单状态为已完成
|
||||
OrderEntity orderEntity = new OrderEntity();
|
||||
orderEntity.setId(orderTrans.getOrderId());
|
||||
orderEntity.setOrderStatus(OrderStatus.YiWanCheng);
|
||||
orderEntity.setFinishTime(LocalDateTime.now());
|
||||
orderService.updateById(orderEntity);
|
||||
log.info("订单 {} 所有运输记录已完成,订单状态更新为已完成", orderTrans.getOrderId());
|
||||
} else {
|
||||
log.info("订单 {} 还有未完成的运输记录,暂不更新订单状态", orderTrans.getOrderId());
|
||||
}
|
||||
|
||||
// 开门放行
|
||||
wbsHandle.playVoice(VoiceConstants.VOICE_PLEASE_PASS);
|
||||
wbsHandle.open();
|
||||
|
||||
log.info("运输记录 {} 支付完成,开门放行", orderTrans.getId());
|
||||
|
||||
} catch (Exception e) {
|
||||
handleBusinessException(wbsHandle, "完成订单 " + orderTrans.getId() + " 支付并开门异常", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理业务异常
|
||||
*/
|
||||
private void handleBusinessException(WbsHandle wbsHandle, String message, Exception e) {
|
||||
log.error("业务处理异常: {}", message, e);
|
||||
try {
|
||||
wbsHandle.playVoice(VoiceConstants.VOICE_SYSTEM_ERROR);
|
||||
} catch (Exception voiceException) {
|
||||
log.error("播放语音失败", voiceException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.njzscloud.dispose.cst.order.service;
|
||||
|
||||
import com.njzscloud.common.core.tuple.Tuple2;
|
||||
import com.njzscloud.dispose.dev.DiscoverTruckMsg;
|
||||
import com.njzscloud.dispose.dev.ObtainTruckDataResultMsg;
|
||||
import com.njzscloud.dispose.dev.WbsHandle;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static com.njzscloud.dispose.dev.DevMittEvent.DISCOVER_TRUCK;
|
||||
import static com.njzscloud.dispose.dev.DevMittEvent.OBTAIN_TRUCK_DATA_REPLY;
|
||||
|
||||
/**
|
||||
* 车辆称重事件监听器
|
||||
* 负责处理磅房设备的车辆识别和称重数据事件
|
||||
*
|
||||
* @author ljw
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class TruckWeighingEventListener {
|
||||
|
||||
private final TruckWeighingBusinessService businessService;
|
||||
|
||||
|
||||
/**
|
||||
* 初始化事件监听器
|
||||
*/
|
||||
public void init() {
|
||||
log.info("初始化车辆称重事件监听器");
|
||||
DISCOVER_TRUCK.on(this::requestData);
|
||||
OBTAIN_TRUCK_DATA_REPLY.on(this::disposeData);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求数据 - 处理车辆识别
|
||||
*/
|
||||
public void requestData(Tuple2<DiscoverTruckMsg, WbsHandle> param) {
|
||||
businessService.requestData(param);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理数据 - 处理磅重数据
|
||||
*/
|
||||
public void disposeData(Tuple2<ObtainTruckDataResultMsg, WbsHandle> param) {
|
||||
businessService.disposeData(param);
|
||||
}
|
||||
}
|
||||
|
|
@ -140,4 +140,18 @@
|
|||
${ew.customSqlSegment}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getByLicensePlate" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
<include refid="Base_Column_List"/>
|
||||
FROM cst_order_trans cot
|
||||
LEFT JOIN cst_order co on co.id = cot.order_id
|
||||
LEFT JOIN gds_goods gg on gg.id = co.goods_id
|
||||
LEFT JOIN gds_goods_category ggc on ggc.id = gg.goods_category_id
|
||||
WHERE cot.truck_license_plate = #{licensePlate}
|
||||
AND cot.trans_status IN ('YunShuZhong', 'YiJinChang')
|
||||
AND cot.deleted = 0
|
||||
ORDER BY cot.create_time DESC
|
||||
LIMIT 1
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
|||
Loading…
Reference in New Issue