diff --git a/src/main/java/com/project/logistics/domain/entity/LogisticsOrderEntity.java b/src/main/java/com/project/logistics/domain/entity/LogisticsOrderEntity.java index fb6db98..29d3a3e 100644 --- a/src/main/java/com/project/logistics/domain/entity/LogisticsOrderEntity.java +++ b/src/main/java/com/project/logistics/domain/entity/LogisticsOrderEntity.java @@ -11,6 +11,8 @@ import lombok.Data; import lombok.EqualsAndHashCode; import org.hibernate.annotations.Comment; +import java.util.Date; + @Data @EqualsAndHashCode(callSuper = true) @Entity @@ -71,4 +73,9 @@ public class LogisticsOrderEntity extends BaseEntity { @Column(name = "sf_current_state_code", length = 32) @TableField("sf_current_state_code") private String sfCurrentStateCode; + + @Comment("下单成功时间") + @Column(name = "order_time") + @TableField("order_time") + private Date orderTime; } diff --git a/src/main/java/com/project/logistics/domain/service/base/ErpService.java b/src/main/java/com/project/logistics/domain/service/base/ErpService.java index dd84863..7bd7ebb 100644 --- a/src/main/java/com/project/logistics/domain/service/base/ErpService.java +++ b/src/main/java/com/project/logistics/domain/service/base/ErpService.java @@ -10,6 +10,8 @@ public interface ErpService { JSONObject getShipmentOrderInfo(String orderNo) throws Exception; + JSONObject getSampleOrderInfoByNo(String orderNo) throws Exception; + /** * 回写运单号到 U9 */ diff --git a/src/main/java/com/project/logistics/domain/service/base/impl/ErpServiceImpl.java b/src/main/java/com/project/logistics/domain/service/base/impl/ErpServiceImpl.java index a7f348a..8e5fe35 100644 --- a/src/main/java/com/project/logistics/domain/service/base/impl/ErpServiceImpl.java +++ b/src/main/java/com/project/logistics/domain/service/base/impl/ErpServiceImpl.java @@ -58,6 +58,39 @@ public class ErpServiceImpl implements ErpService { } } + @Override + public JSONObject getSampleOrderInfoByNo(String orderNo) throws Exception { + log.info(">>> 正在通过专属 U9 管道查询单据: {}", orderNo); + String goLiveTime = sampleProperties.getGoLiveTime(); + + String sql = "SELECT TOP 1 " + + String.format(" a.%s as %s , " , SampleOrderInfoFieldEnum.orderNo.getFieldName() , SampleOrderInfoFieldEnum.orderNo.name()) + + String.format(" a.%s as %s , " , SampleOrderInfoFieldEnum.actualSendTime.getFieldName() , SampleOrderInfoFieldEnum.actualSendTime.name()) + + String.format(" a.%s as %s , " , SampleOrderInfoFieldEnum.salesman.getFieldName() , SampleOrderInfoFieldEnum.salesman.name()) + + String.format(" a.%s as %s , " , SampleOrderInfoFieldEnum.transportMethod.getFieldName() , SampleOrderInfoFieldEnum.transportMethod.name()) + + String.format(" a.%s as %s , " , SampleOrderInfoFieldEnum.recipientContact.getFieldName() , SampleOrderInfoFieldEnum.recipientContact.name()) + + String.format(" a.%s as %s , " , SampleOrderInfoFieldEnum.recipientMobile.getFieldName() , SampleOrderInfoFieldEnum.recipientMobile.name()) + + String.format(" a.%s as %s , " , SampleOrderInfoFieldEnum.recipientAddress.getFieldName() , SampleOrderInfoFieldEnum.recipientAddress.name()) + + String.format(" a.%s as %s , " , SampleOrderInfoFieldEnum.payer.getFieldName() , SampleOrderInfoFieldEnum.payer.name()) + + String.format(" a.%s as %s , " , SampleOrderInfoFieldEnum.waybillNo.getFieldName() , SampleOrderInfoFieldEnum.waybillNo.name()) + + String.format(" a.%s as %s , " , SampleOrderInfoFieldEnum.expressType.getFieldName() , SampleOrderInfoFieldEnum.expressType.name()) + + String.format(" a.%s as %s , " , SampleOrderInfoFieldEnum.fee.getFieldName() , SampleOrderInfoFieldEnum.fee.name()) + + String.format(" a.%s as %s " , SampleOrderInfoFieldEnum.quantity.getFieldName() , SampleOrderInfoFieldEnum.quantity.name()) + + "FROM InvDoc_LendTrans a WITH(NOLOCK) " + + "WHERE a.Org = '1002011064787026' " + // 指定组织 ID + " AND a.Status = 0 " + // 状态为开立/待处理 + " AND a.DescFlexField_PubDescSeg19 >= ? AND a.DocNo = ?"; + try { + Map result = u9JdbcTemplate.queryForMap(sql , goLiveTime , orderNo); + JSONObject json = new JSONObject(result); + log.info(">>> [U9查询成功]: \n{}", json.toString()); + return json; + } catch (Exception e) { + log.error(">>> [U9查询失败]: {}", e.getMessage()); + throw e; + } + } + @Override public void updateWaybillToErp(String orderNo, String waybillNo, String resourceCode, String orderType) throws Exception { log.info(">>> [U9回写] 准备将运单号 {} 写入 U9 单据 {}", waybillNo, orderNo); @@ -125,7 +158,7 @@ public class ErpServiceImpl implements ErpService { String goLiveTime = sampleProperties.getGoLiveTime(); // 具体条件请根据 U9 实际字段修改 - String sql = "SELECT DISTINCT" + + String sql = "SELECT" + String.format(" a.%s as %s , " , SampleOrderInfoFieldEnum.orderNo.getFieldName() , SampleOrderInfoFieldEnum.orderNo.name()) + String.format(" a.%s as %s , " , SampleOrderInfoFieldEnum.actualSendTime.getFieldName() , SampleOrderInfoFieldEnum.actualSendTime.name()) + String.format(" a.%s as %s , " , SampleOrderInfoFieldEnum.salesman.getFieldName() , SampleOrderInfoFieldEnum.salesman.name()) + @@ -139,9 +172,7 @@ public class ErpServiceImpl implements ErpService { String.format(" a.%s as %s , " , SampleOrderInfoFieldEnum.fee.getFieldName() , SampleOrderInfoFieldEnum.fee.name()) + String.format(" a.%s as %s " , SampleOrderInfoFieldEnum.quantity.getFieldName() , SampleOrderInfoFieldEnum.quantity.name()) + "FROM InvDoc_LendTrans a WITH(NOLOCK) " + - "LEFT JOIN InvDoc_LendLine b WITH(NOLOCK) ON b.LendTrans = a.ID " + - "LEFT JOIN Base_Organization_Trl c WITH(NOLOCK) ON b.Org = c.ID " + - "WHERE c.ID = '1002011064787026' " + // 指定组织 ID + "WHERE a.Org = '1002011064787026' " + // 指定组织 ID " AND a.Status = 0 " + // 状态为开立/待处理 " AND a.DescFlexField_PubDescSeg19 >= ? "; diff --git a/src/main/java/com/project/logistics/domain/strategy/handler/SfCreateOrderHandler.java b/src/main/java/com/project/logistics/domain/strategy/handler/SfCreateOrderHandler.java index 05d1178..39fe209 100644 --- a/src/main/java/com/project/logistics/domain/strategy/handler/SfCreateOrderHandler.java +++ b/src/main/java/com/project/logistics/domain/strategy/handler/SfCreateOrderHandler.java @@ -12,6 +12,7 @@ import com.project.logistics.domain.enums.*; import com.project.logistics.domain.service.SfApiService; import com.project.logistics.domain.service.WebDavService; import com.project.logistics.domain.service.base.ApiRetryTaskService; +import com.project.logistics.domain.service.base.ErpService; import com.project.logistics.domain.service.base.LogisticsOrderService; import com.project.logistics.domain.strategy.ApiTaskHandler; import lombok.extern.slf4j.Slf4j; @@ -19,6 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; +import java.util.Date; import java.util.Objects; @Slf4j @@ -37,6 +39,8 @@ public class SfCreateOrderHandler implements ApiTaskHandler { @Autowired private FixedRuleProperties fixedRuleProperties; + @Autowired + private ErpService erpService; @Override public String getActionCode() { return RetryActionEnum.SF_CREATE_ORDER.getCode(); @@ -48,8 +52,22 @@ public class SfCreateOrderHandler implements ApiTaskHandler { log.info(">>> 开始执行顺丰正式下单,单号: {}", order.getOrderNo()); // 1. 从 order_info 快照中解析出 U9 的原始数据 - JSONObject u9Data = JSON.parseObject(order.getOrderInfo()); + JSONObject u9Data; + boolean isShipment = OrderTypeEnum.SHIPMENT.getCode().equals(order.getOrderType()); + + if (isShipment) { + u9Data = JSON.parseObject(erpService.getShipmentOrderInfo(order.getOrderNo()).toString()); + } else { + // 需要在 ErpService 实现一个根据单号获取单个样品单详情的方法 + u9Data = JSON.parseObject(erpService.getSampleOrderInfoByNo(order.getOrderNo()).toString()); + } + + if (u9Data == null || u9Data.isEmpty()) { + throw new RuntimeException("实时获取 ERP 数据失败,单号可能在 U9 中已被删除"); + } + // 同步更新本地快照字段,确保数据一致 + order.setOrderInfo(u9Data.toJSONString()); // 2. 构造顺丰下单报文 (参考 PDF 第 2-10 页) JSONObject msgData = new JSONObject(); msgData.put("language", "zh-CN"); @@ -165,6 +183,7 @@ public class SfCreateOrderHandler implements ApiTaskHandler { // 5. 更新主表状态 order.setSfWaybillNo(waybillNo); + order.setOrderTime(new Date()); order.setOrderStatus(OrderStatusEnum.ORDER_SUBMITTED.getCode()); logisticsOrderService.updateById(order); diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index 3254eb7..3aa1aeb 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -73,14 +73,14 @@ logistics: windows: # 这个窗口设置10分钟有效期,配合10分钟一次的唤醒,只会跑一次 - name: "上午11点班次" - startTime: "11:00" - endTime: "11:10" + startTime: "11:08" + endTime: "11:08" intervalMinutes: 60 # 这个窗口在15-20点之间,每隔20分钟会真正跑一次逻辑 - name: "下午至傍晚波次" startTime: "15:00" endTime: "20:00" - intervalMinutes: 20 + intervalMinutes: 60 sample-scanner: enabled: true # 每 10 分钟唤醒一次 (系统开销微乎其微) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index adfb414..a8f8208 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -73,14 +73,14 @@ logistics: windows: # 这个窗口设置10分钟有效期,配合10分钟一次的唤醒,只会跑一次 - name: "上午11点班次" - startTime: "11:00" - endTime: "11:10" + startTime: "11:08" + endTime: "11:08" intervalMinutes: 60 # 这个窗口在15-20点之间,每隔20分钟会真正跑一次逻辑 - name: "下午至傍晚波次" - startTime: "15:00" - endTime: "20:00" - intervalMinutes: 20 + startTime: "15:08" + endTime: "20:08" + intervalMinutes: 60 sample-scanner: enabled: true # 每 10 分钟唤醒一次 (系统开销微乎其微) diff --git a/src/main/resources/favicon.ico b/src/main/resources/favicon.ico new file mode 100644 index 0000000..f93c5de Binary files /dev/null and b/src/main/resources/favicon.ico differ