9 changed files with 614 additions and 149 deletions
@ -0,0 +1,32 @@
|
||||
package com.logpm.factorydata.jinpai.enums; |
||||
|
||||
import org.springblade.common.model.IDict; |
||||
|
||||
/** |
||||
* 金牌工厂枚举 |
||||
* |
||||
* @author zhaoqiaobo |
||||
* @create 2024-04-28 |
||||
*/ |
||||
public enum WarehouseEnums implements IDict<String> { |
||||
|
||||
LONG_QUAN("0504FCC44EA9CFE315A2BFF661095382", "龙泉仓"), |
||||
CHONG_QING("D770E5FD47FB7A783CD9F0EBD3017096", "重庆仓"), |
||||
ZI_GONG("CDB3BB8B33D645DF1AFA51CFCE41472B", "自贡仓"), |
||||
BA_ZHONG("74CA17A22421ADA84DAB040EA0797894", "巴中仓"), |
||||
NAN_CHONG("99ADD9B8B77C0739752F38A9708C61CD", "南充仓"), |
||||
CHANG_SHA("F64AD5CEBCCC8EF3FB1A5D44E0547B6C", "长沙仓"), |
||||
WAN_ZHOUG("D33A52459F6127C2A0992D4070E4F169", "万州仓"), |
||||
LU_ZHOU("0A5067099226E0943E8BAA230B9AED7A", "泸州仓"), |
||||
DA_ZHOU("CE7D2E506DEB3020FB0FC3CB8C8B619F", "达州仓"), |
||||
KUN_MING("91540EF5F401F2AEF582E7C8683753C1", "昆明仓"), |
||||
WU_HAN("898F1156FADF8AE5E61C76F07187426A", "武汉仓"), |
||||
XI_AN("80F42D9EAE8851C057F275D05E4B987D", "西安仓"), |
||||
GUANG_YUAN("9D5F309EFB333FF88230AEC95302E051", "广元仓"), |
||||
; |
||||
|
||||
WarehouseEnums(String code, String text) { |
||||
init(code, text); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,360 @@
|
||||
package com.logpm.factorydata.jinpai.mq; |
||||
|
||||
import cn.hutool.core.collection.CollUtil; |
||||
import cn.hutool.core.date.DateUtil; |
||||
import cn.hutool.core.util.EnumUtil; |
||||
import cn.hutool.core.util.NumberUtil; |
||||
import cn.hutool.core.util.ObjectUtil; |
||||
import cn.hutool.core.util.RandomUtil; |
||||
import cn.hutool.core.util.StrUtil; |
||||
import cn.hutool.http.HttpUtil; |
||||
import cn.hutool.json.JSONArray; |
||||
import cn.hutool.json.JSONObject; |
||||
import cn.hutool.json.JSONUtil; |
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
||||
import com.logpm.factorydata.feign.IFactoryDataClient; |
||||
import com.logpm.factorydata.jinpai.entity.FactoryNodePushEntity; |
||||
import com.logpm.factorydata.jinpai.entity.PushOrderDetailEntity; |
||||
import com.logpm.factorydata.jinpai.entity.PushOrderEntity; |
||||
import com.logpm.factorydata.jinpai.enums.FactoryNodeEnums; |
||||
import com.logpm.factorydata.jinpai.enums.NodeMappingEnums; |
||||
import com.logpm.factorydata.jinpai.enums.NodeNeedEnums; |
||||
import com.logpm.factorydata.jinpai.enums.WarehouseEnums; |
||||
import com.logpm.factorydata.jinpai.pros.JinPaiProperties; |
||||
import com.logpm.factorydata.jinpai.service.FactoryNodePushService; |
||||
import com.logpm.factorydata.jinpai.service.PushOrderDetailService; |
||||
import com.logpm.factorydata.jinpai.service.PushOrderService; |
||||
import com.logpm.factorydata.jinpai.vo.OldFactoeyVO; |
||||
import com.logpm.factorydata.vo.PushData; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.springblade.common.constant.WorkNodeEnums; |
||||
import org.springblade.common.model.IDict; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.stream.Collectors; |
||||
|
||||
/** |
||||
* 监听业务系统推送给工厂的节点数据 |
||||
* |
||||
* @author zhaoqiaobo |
||||
* @create 2024-03-18 0:02 |
||||
*/ |
||||
@Slf4j |
||||
@Component |
||||
@AllArgsConstructor |
||||
public class NodeDataPushV2Listener { |
||||
|
||||
private final IFactoryDataClient factoryDataClient; |
||||
private final PushOrderDetailService pushOrderDetailService; |
||||
private final PushOrderService pushOrderService; |
||||
private final FactoryNodePushService factoryNodePushService; |
||||
private final JinPaiProperties jinPaiProperties; |
||||
|
||||
// @RabbitListener(bindings = @QueueBinding(
|
||||
// value = @Queue(name = FactoryDataConstants.Mq.Queues.JP_NODE_DATA_PUSH, durable = "true"),
|
||||
// exchange = @Exchange(name = FactoryDataConstants.Mq.Exchanges.NODE_DATA_PUSH_DELAYED, type = ExchangeTypes.TOPIC
|
||||
// , delayed = FactoryDataConstants.Mq.DELAYED),
|
||||
// key = FactoryDataConstants.Mq.RoutingKeys.JP_NODE_DATA_PUSH
|
||||
// ))
|
||||
public void nodeDataPushDelayed(String msg) { |
||||
// 直接调用nodeDataPush方法处理接收到的消息
|
||||
nodeDataPush(msg); |
||||
} |
||||
|
||||
// @RabbitListener(bindings = @QueueBinding(
|
||||
// value = @Queue(name = FactoryDataConstants.Mq.Queues.JP_NODE_DATA_PUSH, durable = "true"),
|
||||
// exchange = @Exchange(name = FactoryDataConstants.Mq.Exchanges.NODE_DATA_PUSH, type = ExchangeTypes.TOPIC),
|
||||
// key = FactoryDataConstants.Mq.RoutingKeys.JP_NODE_DATA_PUSH
|
||||
// ))
|
||||
// @Transactional(rollbackFor = Exception.class)
|
||||
public void nodeDataPush(String msg) { |
||||
// {"brand":"ZBOM","node":"TRANSFER_WAREHOUSE_DEPART","operator":"","operatorTime":"","content":[{"packageCode":"1423090693445"}]}
|
||||
log.info("接收到节点数据推送:{}", msg); |
||||
// 1 校验数据
|
||||
if (checkData(msg)) { |
||||
return; |
||||
} |
||||
JSONObject entries = JSONUtil.parseObj(msg); |
||||
// 节点
|
||||
String node = entries.getStr("node"); |
||||
String main = entries.getStr("main"); |
||||
WorkNodeEnums workNodeEnums = EnumUtil.fromString(WorkNodeEnums.class, node); |
||||
FactoryNodeEnums factoryByNodeAndStatus = NodeMappingEnums.getFactoryByNodeAndStatus(workNodeEnums); |
||||
// 2 获取业务数据
|
||||
List<PushData> content = entries.getBeanList("content", PushData.class); |
||||
if (CollUtil.isNotEmpty(content)) { |
||||
// 按订单分组
|
||||
Map<String, List<PushData>> orderGroup = content.stream().collect(Collectors.groupingBy(PushData::getOrderCode)); |
||||
for (Map.Entry<String, List<PushData>> stringListEntry : orderGroup.entrySet()) { |
||||
String sendOrderCode = stringListEntry.getKey(); |
||||
List<PushData> values = stringListEntry.getValue(); |
||||
// 先从新系统查,如果查不到,去老系统查一次
|
||||
Map<String, OldFactoeyVO> oldFactoeyVOMap = new HashMap<>(); |
||||
List<OldFactoeyVO> oldFactoeyVOS = null; |
||||
PushOrderEntity pushOrderEntity = new PushOrderEntity(); |
||||
if (CollUtil.isEmpty(oldFactoeyVOS)) { |
||||
// 去老系统查
|
||||
if (StrUtil.isNotEmpty(jinPaiProperties.getOldSystemHost()) && StrUtil.isNotEmpty(jinPaiProperties.getFindOldDataUrl())) { |
||||
try { |
||||
log.info("去老系统查询:{}", sendOrderCode); |
||||
// 工厂推送的一个订单可能分批次发货,对应的发货单号不一样。只能按包件+订单才能查到唯一的发运单号和工厂对接唯一标识
|
||||
String result = HttpUtil.get(jinPaiProperties.getOldSystemHost() + jinPaiProperties.getFindOldDataUrl() + "?orderCode=" + sendOrderCode); |
||||
log.info("老系统查询结果:{}", result); |
||||
if (StrUtil.isNotEmpty(result)) { |
||||
JSONObject jsonObject = JSONUtil.parseObj(result); |
||||
Integer code = jsonObject.getInt("code"); |
||||
if (NumberUtil.equals(code, 200)) { |
||||
JSONArray data = jsonObject.getJSONArray("data"); |
||||
if (CollUtil.isNotEmpty(data)) { |
||||
for (OldFactoeyVO oldFactoeyVO : data.toList(OldFactoeyVO.class)) { |
||||
String boxCodeList = oldFactoeyVO.getBoxCodeList(); |
||||
JSONArray boxCodeListJson = JSONUtil.parseArray(boxCodeList); |
||||
boxCodeListJson.forEach(item -> { |
||||
// 包件号+订单号 为一组组装工厂原始数据
|
||||
oldFactoeyVOMap.put(item.toString() + oldFactoeyVO.getCustomItemNo(), oldFactoeyVO); |
||||
}); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} catch (Exception e) { |
||||
log.error("老系统查询失败", e); |
||||
} |
||||
} |
||||
} |
||||
// 过滤掉本次不需要处理的数据
|
||||
List<PushData> filterData = values.stream().filter(item -> { |
||||
String packageCode = item.getPackageCode(); |
||||
String orderCode = item.getOrderCode(); |
||||
String warehouseName = item.getWarehouseName(); |
||||
String destinationWarehouse = item.getDestinationWarehouse(); |
||||
if (oldFactoeyVOMap.containsKey(packageCode + orderCode)) { |
||||
OldFactoeyVO oldFactoeyVO = oldFactoeyVOMap.get(packageCode + orderCode); |
||||
// 判断当前仓是否是末端仓
|
||||
Boolean isEnd = Boolean.FALSE; |
||||
if (StrUtil.equals(destinationWarehouse, warehouseName)) { |
||||
isEnd = Boolean.TRUE; |
||||
} |
||||
if (StrUtil.isEmpty(oldFactoeyVO.getWarehouse())) { |
||||
// 1 如果当前包条没有仓库 则是干线数据 按运单是否是末端仓推送
|
||||
if (isEnd) { |
||||
return true; |
||||
} else { |
||||
return false; |
||||
} |
||||
} else { |
||||
// 2 如果当前包条有仓库 则是仓配数据 按当前仓是否是金牌的末端仓推送, 如果到了运单末端仓,不是金牌的末端仓,则按运单末端仓回推
|
||||
String text = IDict.getByCode(WarehouseEnums.class, oldFactoeyVO.getWarehouse()).getText(); |
||||
if (StrUtil.equals(warehouseName, text)) { |
||||
return true; |
||||
} else { |
||||
if (isEnd) { |
||||
return true; |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
return false; |
||||
}).collect(Collectors.toList()); |
||||
// 需要推送的数据
|
||||
if (CollUtil.isNotEmpty(filterData)) { |
||||
// 所有已推数据
|
||||
Map<String, FactoryNodePushEntity> pushEntityMap = new HashMap<>(); |
||||
// 当前订单 当前节点的推送记录
|
||||
List<FactoryNodePushEntity> pushEntities = factoryNodePushService.list(Wrappers.<FactoryNodePushEntity>lambdaQuery() |
||||
.eq(FactoryNodePushEntity::getOrderCode, sendOrderCode) |
||||
.eq(FactoryNodePushEntity::getNode, factoryByNodeAndStatus.getCode()) |
||||
); |
||||
// 按 订单 + 运单号 + 发运单号 分组
|
||||
if (CollUtil.isNotEmpty(pushEntities)) { |
||||
// 过滤出当前节点当前订单已经推送过的
|
||||
pushEntityMap = pushEntities.stream().filter(pushEntity -> { |
||||
return StrUtil.equals(pushEntity.getNode(), factoryByNodeAndStatus.getCode().toString()); |
||||
}).collect(Collectors.toMap(i -> (i.getOrderCode() + i.getWaybillCode() + i.getTransportNo()), v -> v)); |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
Map<String, List<PushData>> orderWaybillGroup = filterData.stream().collect(Collectors.groupingBy(item -> item.getOrderCode() + item.getWaybillNumber() + oldFactoeyVOMap.get(item.getPackageCode() + item.getOrderCode()).getTransportNo())); |
||||
for (Map.Entry<String, List<PushData>> listEntry : orderWaybillGroup.entrySet()) { |
||||
|
||||
} |
||||
} |
||||
List<PushOrderDetailEntity> orderDetailEntities = null; |
||||
// 订单 warehouse 不为空为干线,否则为仓配,推送干线的同时回推仓配
|
||||
Map<String, List<PushOrderDetailEntity>> detailEntityMap = orderDetailEntities.stream() |
||||
.collect(Collectors.groupingBy(PushOrderDetailEntity::getCustomItemNo)); |
||||
// List<String> orderIds = orderDetailEntities.stream().map(PushOrderDetailEntity::getOrderId).collect(Collectors.toList());
|
||||
// Map<String, PushOrderEntity> pushOrderEntityMap = new HashMap<>();
|
||||
// if (CollUtil.isNotEmpty(orderIds)) {
|
||||
// List<PushOrderEntity> pushOrderEntities = pushOrderService.listByIds(orderIds);
|
||||
// if (CollUtil.isNotEmpty(pushOrderEntities)) {
|
||||
// pushOrderEntities.forEach(pushOrderEntity -> {
|
||||
// pushOrderEntityMap.put(orderCodeMap.get(pushOrderEntity.getId().toString()), pushOrderEntity);
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
List<FactoryNodePushEntity> pushEntities = null; |
||||
// 到站还是入库
|
||||
if (workNodeEnums.equals(WorkNodeEnums.FINAL_NET_ARRIVE_CAR)) { |
||||
Map<String, FactoryNodePushEntity> pushEntityMap = new HashMap<>(); |
||||
if (CollUtil.isNotEmpty(pushEntities)) { |
||||
pushEntityMap = pushEntities.stream().filter(pushEntity -> { |
||||
return StrUtil.equals(pushEntity.getNode(), FactoryNodeEnums.FINAL_NET_ARRIVE_CAR.getCode().toString()); |
||||
}).collect(Collectors.toMap(FactoryNodePushEntity::getOrderCode, v -> v)); |
||||
} |
||||
JSONObject mainJson = JSONUtil.parseObj(main); |
||||
// 到站 一个订单只发送一次
|
||||
// for (String orderCode : orderCodes) {
|
||||
if (pushEntityMap.containsKey(sendOrderCode)) { |
||||
continue; |
||||
} |
||||
String arriveFor = "carrier"; |
||||
// PushOrderEntity pushOrderEntity = pushOrderEntityMap.get(orderCode);
|
||||
if (ObjectUtil.isNotEmpty(pushOrderEntity) && StrUtil.isNotEmpty(pushOrderEntity.getWarehouse())) { |
||||
arriveFor = "stock"; |
||||
} |
||||
PushOrderDetailEntity pushOrderDetailEntity = detailEntityMap.get(sendOrderCode).get(0); |
||||
String boxCodeList = pushOrderDetailEntity.getBoxCodeList(); |
||||
JSONArray boxCodeListJson = JSONUtil.parseArray(boxCodeList); |
||||
// JSONArray details = new JSONArray();
|
||||
JSONObject detail = new JSONObject(); |
||||
boxCodeListJson.forEach(item -> { |
||||
// JSONObject jsonObject = new JSONObject();
|
||||
detail.set(item.toString(), 1); |
||||
// details.add(jsonObject);
|
||||
}); |
||||
if (!CollUtil.contains(pushEntityMap.keySet(), sendOrderCode)) { |
||||
JSONObject js = new JSONObject(); |
||||
js.set("extOrderNo", sendOrderCode); |
||||
js.set("extWaybillNO", mainJson.getStr("serviceNumber")); |
||||
js.set("detail", detail); |
||||
// js.set("shipNo", mainJson.getStr("waybillNumber"));
|
||||
js.set("shipNo", pushOrderDetailEntity.getShipNo()); |
||||
js.set("targetNo", pushOrderEntity.getTransportNo()); |
||||
js.set("targetType", 1); |
||||
js.set("doType", 32); |
||||
js.set("doLocation", ""); |
||||
js.set("doTime", DateUtil.now()); |
||||
js.set("sendSite", mainJson.getStr("sendWarehouseName")); |
||||
js.set("endSite", mainJson.getStr("warehouseName")); |
||||
js.set("passSite", mainJson.getStr("acceptWarehouseName")); |
||||
js.set("doRemark", ""); |
||||
js.set("reqSn", (RandomUtil.randomLong(100000000000000000L, 999999999999999999L)) + ""); |
||||
js.set("syscode", "huitong"); |
||||
js.set("carNo", mainJson.getStr("carNumber")); |
||||
js.set("carHangNo", ""); |
||||
js.set("driverName", mainJson.getStr("driverName")); |
||||
js.set("driverPhone", mainJson.getStr("driverMobile")); |
||||
js.set("carType", "A"); |
||||
js.set("carSize", "1"); |
||||
js.set("arriveFor", arriveFor); |
||||
log.info("推送工厂:{}", js); |
||||
String url = jinPaiProperties.getOldSystemHost() + jinPaiProperties.getOldSystemArrivedUrl(); |
||||
try { |
||||
if (jinPaiProperties.getEnable()) { |
||||
String result = HttpUtil.post(url, JSONUtil.toJsonStr(js)); |
||||
log.info("推送工厂结果:{}", result); |
||||
// 保存推送记录
|
||||
factoryNodePushService.save(FactoryNodePushEntity.builder() |
||||
.orderCode(sendOrderCode) |
||||
.node(FactoryNodeEnums.FINAL_NET_ARRIVE_CAR.getCode().toString()) |
||||
.content(JSONUtil.toJsonStr(js)) |
||||
.resultContent(result) |
||||
.build()); |
||||
} |
||||
} catch (Exception e) { |
||||
log.error("推送工厂失败:{}", e); |
||||
} |
||||
} |
||||
// }
|
||||
} else { |
||||
// 入库一个包件一次
|
||||
Map<String, FactoryNodePushEntity> pushEntityMap = new HashMap<>(); |
||||
if (CollUtil.isNotEmpty(pushEntities)) { |
||||
pushEntityMap = pushEntities.stream().filter(pushEntity -> { |
||||
return StrUtil.equals(pushEntity.getNode(), FactoryNodeEnums.END_WAREHOUSE_UNLOADING.getCode().toString()); |
||||
}).collect(Collectors.toMap(FactoryNodePushEntity::getPackageCode, v -> v)); |
||||
} |
||||
for (PushData pushData : values) { |
||||
if (!CollUtil.contains(pushEntityMap.keySet(), pushData.getPackageCode())) { |
||||
|
||||
String arriveFor = "stock"; |
||||
// PushOrderEntity pushOrderEntity = pushOrderEntityMap.get(pushData.getOrderCode());
|
||||
if (StrUtil.isEmpty(pushOrderEntity.getWarehouse())) { |
||||
arriveFor = "carrier"; |
||||
} |
||||
JSONObject js = new JSONObject(); |
||||
js.set("extOrderNo", pushData.getOrderCode()); |
||||
js.set("extWaybillNO", detailEntityMap.get(pushData.getOrderCode()).get(0).getCustomOrderNo()); |
||||
// js.set("transportNo", pushOrderEntityMap.get(pushData.getOrderCode()).getTransportNo());
|
||||
js.set("transportNo", pushOrderEntity.getTransportNo()); |
||||
js.set("doTime", entries.getStr("operatorTime")); |
||||
js.set("syscode", "huitong"); |
||||
js.set("reqSn", (RandomUtil.randomLong(100000000000000000L, 999999999999999999L)) + ""); |
||||
// js.set("reqSn", detailEntityMap.get(pushData.getOrderCode()).getShipNo());
|
||||
js.set("arriveFor", arriveFor); |
||||
JSONObject detailJson = new JSONObject(); |
||||
detailJson.set(pushData.getPackageCode(), 1); |
||||
js.set("detail", detailJson); |
||||
js.set("shipNo", detailEntityMap.get(pushData.getOrderCode()).get(0).getShipNo()); |
||||
log.info("推送工厂:{}", js); |
||||
String url = jinPaiProperties.getOldSystemHost() + jinPaiProperties.getOldSystemAlreadyStockedUrl(); |
||||
try { |
||||
if (jinPaiProperties.getEnable()) { |
||||
String result = HttpUtil.post(url, JSONUtil.toJsonStr(js)); |
||||
log.info("推送工厂结果:{}", result); |
||||
// 保存推送记录
|
||||
factoryNodePushService.save(FactoryNodePushEntity.builder() |
||||
.orderCode(pushData.getOrderCode()) |
||||
.node(FactoryNodeEnums.END_WAREHOUSE_UNLOADING.getCode().toString()) |
||||
.content(JSONUtil.toJsonStr(js)) |
||||
.packageCode(pushData.getPackageCode()) |
||||
.resultContent(result) |
||||
.build()); |
||||
} |
||||
} catch (Exception e) { |
||||
log.error("推送工厂失败:{}", e); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
private boolean checkData(String msg) { |
||||
if (StrUtil.isEmpty(msg)) { |
||||
return true; |
||||
} |
||||
if (!msg.contains("brand") || !msg.contains("content") || !msg.contains("node")) { |
||||
return true; |
||||
} |
||||
JSONObject entries = JSONUtil.parseObj(msg); |
||||
String node = entries.getStr("node"); |
||||
if (StrUtil.isEmpty(node)) { |
||||
return true; |
||||
} |
||||
// 不是志邦需要的节点数据直接不处理
|
||||
if (!EnumUtil.contains(NodeNeedEnums.class, node)) { |
||||
return true; |
||||
} |
||||
WorkNodeEnums workNodeEnums = EnumUtil.fromString(WorkNodeEnums.class, node); |
||||
if (ObjectUtil.isEmpty(workNodeEnums)) { |
||||
return true; |
||||
} |
||||
List<JSONObject> content = entries.getBeanList("content", JSONObject.class); |
||||
if (CollUtil.isEmpty(content)) { |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,44 @@
|
||||
package com.logpm.factorydata.jinpai.vo; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* 老系统查询工厂必要字段vo |
||||
* @author zhaoqiaobo |
||||
* @create 2024-04-30 |
||||
*/ |
||||
@Data |
||||
public class OldFactoeyVO implements Serializable { |
||||
|
||||
/** |
||||
* 唯一标识、目前是dd单号。但是dd单号不唯一 |
||||
*/ |
||||
private String orderId; |
||||
/** |
||||
* DD单号 |
||||
*/ |
||||
private String customItemNo; |
||||
/** |
||||
* 工厂对接唯一标识 |
||||
*/ |
||||
private String shipNo; |
||||
/** |
||||
* 仓库 |
||||
*/ |
||||
private String warehouse; |
||||
/** |
||||
* 发运单号 |
||||
*/ |
||||
private String transportNo; |
||||
/** |
||||
* ys单号 |
||||
*/ |
||||
private String customOrderNo; |
||||
/** |
||||
* 包件明细 "[\"0-XD7P\", \"0-XI6H\"]" |
||||
*/ |
||||
private String boxCodeList; |
||||
|
||||
} |
Loading…
Reference in new issue