|
@@ -45,6 +45,7 @@ import com.sckw.transport.model.enuma.ApproveStatusEnum;
|
|
|
import com.sckw.transport.model.enuma.CarWaybillDetailEnum;
|
|
import com.sckw.transport.model.enuma.CarWaybillDetailEnum;
|
|
|
import com.sckw.transport.model.enuma.CarWaybillNdexTopEnum;
|
|
import com.sckw.transport.model.enuma.CarWaybillNdexTopEnum;
|
|
|
import com.sckw.transport.model.enuma.CarWaybillTableTopEnum;
|
|
import com.sckw.transport.model.enuma.CarWaybillTableTopEnum;
|
|
|
|
|
+import com.sckw.transport.model.param.WaybillOrderNodeReq;
|
|
|
import com.sckw.transport.model.param.WaybillOrderReq;
|
|
import com.sckw.transport.model.param.WaybillOrderReq;
|
|
|
import com.sckw.transport.model.param.WaybillOrderResp;
|
|
import com.sckw.transport.model.param.WaybillOrderResp;
|
|
|
import com.sckw.transport.model.vo.*;
|
|
import com.sckw.transport.model.vo.*;
|
|
@@ -125,6 +126,7 @@ public class KwtWaybillOrderV1Service {
|
|
|
private final KwtWaybillOrderSubtaskRepository kwtWaybillOrderSubtaskRepository;
|
|
private final KwtWaybillOrderSubtaskRepository kwtWaybillOrderSubtaskRepository;
|
|
|
private final KwtLogisticsOrderRepository kwtLogisticsOrderRepository;
|
|
private final KwtLogisticsOrderRepository kwtLogisticsOrderRepository;
|
|
|
private final KwtWaybillOrderTicketRepository kwtWaybillOrderTicketRepository;
|
|
private final KwtWaybillOrderTicketRepository kwtWaybillOrderTicketRepository;
|
|
|
|
|
+ private final KwtWaybillOrderNodeRepository kwtWaybillOrderNodeRepository;
|
|
|
@Resource
|
|
@Resource
|
|
|
private StreamBridge streamBridge;
|
|
private StreamBridge streamBridge;
|
|
|
@DubboReference(version = "1.0.0", group = "design", check = false)
|
|
@DubboReference(version = "1.0.0", group = "design", check = false)
|
|
@@ -3459,4 +3461,195 @@ public class KwtWaybillOrderV1Service {
|
|
|
orderBillStatusStatistics.setOrderNum(String.valueOf(finalStausAndBillOrdersMap.getOrDefault(c.getCode(), new ArrayList<>()).size()));
|
|
orderBillStatusStatistics.setOrderNum(String.valueOf(finalStausAndBillOrdersMap.getOrDefault(c.getCode(), new ArrayList<>()).size()));
|
|
|
return orderBillStatusStatistics;
|
|
return orderBillStatusStatistics;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 查询运单节点轨迹时间线
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param req 请求参数
|
|
|
|
|
+ * @return 节点轨迹列表
|
|
|
|
|
+ * @author system
|
|
|
|
|
+ * @date 2025/06/24
|
|
|
|
|
+ */
|
|
|
|
|
+ public List<WaybillOrderNodeVo> queryWaybillOrderNodeTimeline(WaybillOrderNodeReq req) {
|
|
|
|
|
+ log.info("查询运单节点轨迹,请求参数:{}", JSON.toJSONString(req));
|
|
|
|
|
+
|
|
|
|
|
+ // 查询节点轨迹数据
|
|
|
|
|
+ List<KwtWaybillOrderNode> nodes = kwtWaybillOrderNodeRepository.queryNodesByOrderId(
|
|
|
|
|
+ req.getWOrderId(), req.getWSubtaskId());
|
|
|
|
|
+
|
|
|
|
|
+ if (CollectionUtils.isEmpty(nodes)) {
|
|
|
|
|
+ return new ArrayList<>();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 查询运单子单信息,用于获取商品名称和重量
|
|
|
|
|
+ Set<Long> subtaskIds = nodes.stream()
|
|
|
|
|
+ .map(KwtWaybillOrderNode::getWSubtaskId)
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+ List<KwtWaybillOrderSubtask> subtasks = kwtWaybillOrderSubtaskRepository.listByIds(subtaskIds);
|
|
|
|
|
+ Map<Long, KwtWaybillOrderSubtask> subtaskMap = subtasks.stream()
|
|
|
|
|
+ .collect(Collectors.toMap(KwtWaybillOrderSubtask::getId, Function.identity()));
|
|
|
|
|
+
|
|
|
|
|
+ // 查询物流订单商品信息
|
|
|
|
|
+ Set<Long> logisticsOrderIds = subtasks.stream()
|
|
|
|
|
+ .map(KwtWaybillOrderSubtask::getLOrderId)
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+ List<KwtLogisticsOrderGoods> goodsList = kwtLogisticsOrderGoodsRepository.queryByLogOrderIds(
|
|
|
|
|
+ new ArrayList<>(logisticsOrderIds));
|
|
|
|
|
+ Map<Long, KwtLogisticsOrderGoods> goodsMap = goodsList.stream()
|
|
|
|
|
+ .collect(Collectors.toMap(KwtLogisticsOrderGoods::getLOrderId, Function.identity(), (k1, k2) -> k1));
|
|
|
|
|
+
|
|
|
|
|
+ // 查询过磅单据信息(如果有地磅)
|
|
|
|
|
+ Set<Long> nodeIds = nodes.stream()
|
|
|
|
|
+ .filter(n -> n.getWeighbridgeId() != null)
|
|
|
|
|
+ .map(KwtWaybillOrderNode::getId)
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+ Map<Long, KwtWaybillOrderTicket> ticketMap = new HashMap<>();
|
|
|
|
|
+ if (!nodeIds.isEmpty()) {
|
|
|
|
|
+ // 这里假设根据wSubtaskId和地址ID查询
|
|
|
|
|
+ // 实际可能需要根据具体业务调整查询逻辑
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 单位字典
|
|
|
|
|
+ Map<String, Map<String, String>> dict = remoteSystemService.queryDictByType(
|
|
|
|
|
+ List.of(DictTypeEnum.UNIT_TYPE.getType()));
|
|
|
|
|
+ Map<String, String> unitMap = CollectionUtils.isNotEmpty(dict) ?
|
|
|
|
|
+ dict.get(DictTypeEnum.UNIT_TYPE.getType()) : new HashMap<>(NumberConstant.SIXTEEN);
|
|
|
|
|
+
|
|
|
|
|
+ // 转换为VO对象
|
|
|
|
|
+ List<WaybillOrderNodeVo> voList = new ArrayList<>();
|
|
|
|
|
+ for (KwtWaybillOrderNode node : nodes) {
|
|
|
|
|
+ WaybillOrderNodeVo vo = new WaybillOrderNodeVo();
|
|
|
|
|
+ vo.setId(node.getId());
|
|
|
|
|
+ vo.setCreateTime(DateUtils.format(node.getCreateTime(), DateUtils.DATE_TIME_PATTERN));
|
|
|
|
|
+ vo.setOrderStatus(node.getOrderStatus());
|
|
|
|
|
+ vo.setTruckNo(node.getTruckNo());
|
|
|
|
|
+ vo.setDriverName(node.getDriverName());
|
|
|
|
|
+ vo.setWeighbridgeName(node.getWeighbridgeName());
|
|
|
|
|
+ vo.setLng(node.getLng());
|
|
|
|
|
+ vo.setLat(node.getLat());
|
|
|
|
|
+ vo.setHasWeighbridge(node.getWeighbridgeId() != null);
|
|
|
|
|
+
|
|
|
|
|
+ // 构建状态描述
|
|
|
|
|
+ KwtWaybillOrderSubtask subtask = subtaskMap.get(node.getWSubtaskId());
|
|
|
|
|
+ String statusDesc = buildStatusDescription(node, subtask, goodsMap, unitMap);
|
|
|
|
|
+ vo.setStatusDesc(statusDesc);
|
|
|
|
|
+
|
|
|
|
|
+ // 构建地址信息
|
|
|
|
|
+ String address = buildAddressFromLatLng(node.getLng(), node.getLat());
|
|
|
|
|
+ vo.setAddress(address);
|
|
|
|
|
+
|
|
|
|
|
+ voList.add(vo);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return voList;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 构建状态描述文本
|
|
|
|
|
+ * 格式:车辆【川A5478C】司机【张三】装载货物【铁矿石】【参运】【28.70吨】
|
|
|
|
|
+ */
|
|
|
|
|
+ private String buildStatusDescription(KwtWaybillOrderNode node,
|
|
|
|
|
+ KwtWaybillOrderSubtask subtask,
|
|
|
|
|
+ Map<Long, KwtLogisticsOrderGoods> goodsMap,
|
|
|
|
|
+ Map<String, String> unitMap) {
|
|
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
|
|
+
|
|
|
|
|
+ // 状态名称
|
|
|
|
|
+ String statusName = CarWaybillEnum.getAlias(node.getOrderStatus());
|
|
|
|
|
+ if (StringUtils.isNotBlank(statusName)) {
|
|
|
|
|
+ sb.append(statusName);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 车辆信息
|
|
|
|
|
+ if (StringUtils.isNotBlank(node.getTruckNo())) {
|
|
|
|
|
+ sb.append(" 车辆【").append(node.getTruckNo()).append("】");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 司机信息
|
|
|
|
|
+ if (StringUtils.isNotBlank(node.getDriverName())) {
|
|
|
|
|
+ sb.append(" 司机【").append(node.getDriverName()).append("】");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 货物信息
|
|
|
|
|
+ if (subtask != null) {
|
|
|
|
|
+ KwtLogisticsOrderGoods goods = goodsMap.get(subtask.getLOrderId());
|
|
|
|
|
+ if (goods != null && StringUtils.isNotBlank(goods.getGoodsName())) {
|
|
|
|
|
+ sb.append(" 装载货物【").append(goods.getGoodsName()).append("】");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 状态标签
|
|
|
|
|
+ String statusLabel = getStatusLabel(node.getOrderStatus());
|
|
|
|
|
+ if (StringUtils.isNotBlank(statusLabel)) {
|
|
|
|
|
+ sb.append(" 【").append(statusLabel).append("】");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 重量信息(根据状态显示不同的重量)
|
|
|
|
|
+ String weight = getWeightByStatus(node.getOrderStatus(), subtask);
|
|
|
|
|
+ String unit = unitMap.getOrDefault(subtask.getUnit(), "吨");
|
|
|
|
|
+ if (StringUtils.isNotBlank(weight)) {
|
|
|
|
|
+ sb.append(" 【").append(weight).append(unit).append("】");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 地磅信息
|
|
|
|
|
+ if (StringUtils.isNotBlank(node.getWeighbridgeName())) {
|
|
|
|
|
+ sb.append(" 地磅【").append(node.getWeighbridgeName()).append("】");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return sb.toString();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据状态获取标签
|
|
|
|
|
+ */
|
|
|
|
|
+ private String getStatusLabel(Integer status) {
|
|
|
|
|
+ if (status == null) {
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+ // 根据具体业务逻辑返回标签,如:参运、实装、实卸等
|
|
|
|
|
+ if (status.equals(CarWaybillEnum.COMPLETION_LOADING.getCode())) {
|
|
|
|
|
+ return "实装";
|
|
|
|
|
+ } else if (status.equals(CarWaybillEnum.COMPLETION_UNLOADING.getCode())) {
|
|
|
|
|
+ return "实卸";
|
|
|
|
|
+ } else if (status.equals(CarWaybillEnum.EXIT_COMPLETED.getCode())) {
|
|
|
|
|
+ return "参运";
|
|
|
|
|
+ }
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据状态获取对应的重量
|
|
|
|
|
+ */
|
|
|
|
|
+ private String getWeightByStatus(Integer status, KwtWaybillOrderSubtask subtask) {
|
|
|
|
|
+ if (status == null || subtask == null) {
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 根据状态返回不同的重量
|
|
|
|
|
+ if (status.equals(CarWaybillEnum.EXIT_COMPLETED.getCode())) {
|
|
|
|
|
+ // 参运显示委托量
|
|
|
|
|
+ return String.valueOf(subtask.getEntrustAmount());
|
|
|
|
|
+ } else if (status.equals(CarWaybillEnum.COMPLETION_LOADING.getCode())) {
|
|
|
|
|
+ // 装货显示实装量
|
|
|
|
|
+ return String.valueOf(subtask.getLoadAmount());
|
|
|
|
|
+ } else if (status.equals(CarWaybillEnum.COMPLETION_UNLOADING.getCode())) {
|
|
|
|
|
+ // 卸货显示实卸量
|
|
|
|
|
+ return String.valueOf(subtask.getUnloadAmount());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据经纬度构建地址信息
|
|
|
|
|
+ * 实际项目中可以调用地图服务API进行逆地理编码
|
|
|
|
|
+ */
|
|
|
|
|
+ private String buildAddressFromLatLng(String lng, String lat) {
|
|
|
|
|
+ if (StringUtils.isBlank(lng) || StringUtils.isBlank(lat)) {
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+ // 这里可以调用高德/百度等地图API进行逆地理编码
|
|
|
|
|
+ // 暂时返回经纬度格式
|
|
|
|
|
+ return String.format("经度:%s, 纬度:%s", lng, lat);
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|