From 0545de88b49e41a319857d38958975f7e209ad4f Mon Sep 17 00:00:00 2001 From: wuweihua <88888888> Date: Wed, 11 Nov 2026 13:12:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=AE=A2=E5=8D=95=E8=AE=A1?= =?UTF-8?q?=E8=B4=B9=E5=A4=B1=E8=B4=A5=E5=8E=9F=E5=9B=A0=E7=9A=84=E4=BB=B7?= =?UTF-8?q?=E6=A0=BC=E5=91=A8=E6=9C=9F=E5=AD=97=E6=AE=B5=EF=BC=8C=E5=B9=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=89=8D=E7=AB=AF=E5=B1=95=E7=A4=BA=EF=BC=8C?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=9F=A5=E7=9C=8B=E4=BB=B7=E6=A0=BC=E5=91=A8?= =?UTF-8?q?=E6=9C=9F=E8=AF=A6=E6=83=85=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/vo/OrderBillFailReasonVo.java | 6 + .../service/impl/PrcOrderBillServiceImpl.java | 161 ++++++++++++++++- .../support/BillingFailReasonSupport.java | 43 +++-- .../OrderBillPriceCycleListDrawer.vue | 165 ++++++++++++++++++ bms-front/src/views/price/orderBill/index.vue | 91 +++++++++- .../detail/SetVersionDetailDrawer.vue | 1 + 6 files changed, 439 insertions(+), 28 deletions(-) create mode 100644 bms-front/src/views/price/orderBill/components/OrderBillPriceCycleListDrawer.vue diff --git a/bms-back/bms-system/src/main/java/com/bms/price/domain/vo/OrderBillFailReasonVo.java b/bms-back/bms-system/src/main/java/com/bms/price/domain/vo/OrderBillFailReasonVo.java index c3daba3d..b648ca49 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/domain/vo/OrderBillFailReasonVo.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/domain/vo/OrderBillFailReasonVo.java @@ -35,6 +35,12 @@ public class OrderBillFailReasonVo implements Serializable private String setType; private Long psvId; private String versionNo; + /** Price-cycle version effective time. */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date effectiveTime; + /** Price-cycle version expire time; null = open. */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date expireTime; private Long psdId; private BigDecimal weight; diff --git a/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcOrderBillServiceImpl.java b/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcOrderBillServiceImpl.java index 8ea5d8e9..b4dafebb 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcOrderBillServiceImpl.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/service/impl/PrcOrderBillServiceImpl.java @@ -46,6 +46,7 @@ import com.bms.customer.customerinfo.mapper.BmsCustomerMapper; import com.bms.system.mapper.SysUserMapper; import com.bms.system.service.IBmsBizRuleService; import com.bms.system.service.IBmsProductCodeMappingService; +import com.bms.price.domain.PrcCustomerPriceSet; import com.bms.price.domain.PrcIncomeBill; import com.bms.price.domain.PrcIncomeBillFee; import com.bms.price.domain.PrcOrderBill; @@ -53,6 +54,7 @@ import com.bms.price.domain.PrcOrderBillExportTask; import com.bms.price.domain.PrcOrderBillExt; import com.bms.price.domain.PrcPayBill; import com.bms.price.domain.PrcPayBillFee; +import com.bms.price.domain.PrcPriceSet; import com.bms.price.domain.PrcSurcharge; import com.bms.price.domain.BatchAddIncomeBillFeeTask; import com.bms.price.domain.ChargeWeightImportTask; @@ -83,11 +85,13 @@ import com.bms.price.enums.BillOrderStatus; import com.bms.price.enums.BillRefundStatus; import com.bms.price.enums.BillBillingFailStatus; import com.bms.price.enums.TmsOrderBillMatchType; +import com.bms.price.mapper.PrcCustomerPriceSetMapper; import com.bms.price.mapper.PrcIncomeBillFeeMapper; import com.bms.price.mapper.PrcIncomeBillMapper; import com.bms.price.mapper.PrcOrderBillExtMapper; import com.bms.price.mapper.PrcOrderBillMapper; import com.bms.price.mapper.PrcPriceSetDetailMapper; +import com.bms.price.mapper.PrcPriceSetMapper; import com.bms.price.mapper.PrcPriceSetVersionMapper; import com.bms.price.domain.PrcPriceSetDetail; import com.bms.price.domain.PrcPriceSetVersion; @@ -132,6 +136,12 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService @Autowired private PrcPriceSetDetailMapper priceSetDetailMapper; + @Autowired + private PrcCustomerPriceSetMapper customerPriceSetMapper; + + @Autowired + private PrcPriceSetMapper priceSetMapper; + /** TMS 实时状态查询使用客户主档案,不读取订单上的历史状态快照。 */ @Autowired private BmsCustomerMapper bmsCustomerMapper; @@ -498,9 +508,11 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService PrcPriceSetVersion ver = priceSetVersionMapper.selectPrcPriceSetVersionById(bill.getPsvId()); if (ver != null) { - vo.setVersionNo(ver.getVersionNo()); + applyFailReasonVersion(vo, ver); } } + // Soft-fail rows often leave package/version empty on the bill; resolve from customer bind. + fillFailReasonPackageVersionFromBind(vo, bill); if (bill.getPsdId() != null && priceSetDetailMapper != null) { PrcPriceSetDetail detail = priceSetDetailMapper.selectPrcPriceSetDetailById(bill.getPsdId()); @@ -512,10 +524,6 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService } String reason = bill.getErrorMessage(); if (StringUtils.isEmpty(reason)) - { - reason = bill.getMatchMessage(); - } - if (StringUtils.isEmpty(reason)) { reason = vo.getBillingFailStatusLabel(); } @@ -524,6 +532,141 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService return vo; } + /** + * When order-bill package / version is empty, do not keep empty snapshot fields. + * Resolve package from customer bind; match version by pickupDate then bizDate. + * Leave empty when still not found. + */ + private void fillFailReasonPackageVersionFromBind(OrderBillFailReasonVo vo, PrcOrderBill bill) + { + if (vo == null || bill == null) + { + return; + } + boolean needPackage = bill.getPriceSetId() == null + && StringUtils.isEmpty(bill.getPriceSetCode()) + && StringUtils.isEmpty(bill.getPriceSetName()); + boolean needVersion = bill.getPsvId() == null && StringUtils.isEmpty(vo.getVersionNo()); + if (!needPackage && !needVersion) + { + return; + } + if (needPackage) + { + vo.setPriceSetId(null); + vo.setPriceSetCode(null); + vo.setPriceSetName(null); + vo.setSetType(null); + } + if (needVersion) + { + vo.setPsvId(null); + vo.setVersionNo(null); + vo.setEffectiveTime(null); + vo.setExpireTime(null); + } + Long priceSetId = needPackage ? null : bill.getPriceSetId(); + PrcPriceSet set = null; + PrcPriceSetVersion version = null; + if (priceSetId != null) + { + set = priceSetMapper == null ? null : priceSetMapper.selectPrcPriceSetById(priceSetId); + version = needVersion ? selectVersionByPickupOrBiz(priceSetId, bill) : null; + } + else if (needPackage || needVersion) + { + if (StringUtils.isEmpty(bill.getCustomerCode()) || customerPriceSetMapper == null + || priceSetMapper == null || priceSetVersionMapper == null) + { + return; + } + List binds = + customerPriceSetMapper.selectEffectiveByCustomerCode(bill.getCustomerCode().trim()); + if (binds == null || binds.isEmpty()) + { + return; + } + for (PrcCustomerPriceSet bind : binds) + { + if (bind == null || bind.getPriceSetId() == null) + { + continue; + } + PrcPriceSet candidate = priceSetMapper.selectPrcPriceSetById(bind.getPriceSetId()); + if (candidate == null || !"E".equals(candidate.getStatus())) + { + continue; + } + String category = StringUtils.trim(candidate.getSetCategory()); + if (PrcPriceSet.CATEGORY_LABEL.equalsIgnoreCase(category)) + { + if (set == null) + { + set = candidate; + } + continue; + } + PrcPriceSetVersion hit = selectVersionByPickupOrBiz(candidate.getPriceSetId(), bill); + if (set == null) + { + set = candidate; + } + if (hit != null) + { + set = candidate; + version = hit; + break; + } + } + } + if (needPackage && set != null) + { + vo.setPriceSetId(set.getPriceSetId()); + vo.setPriceSetCode(set.getPriceSetCode()); + vo.setPriceSetName(set.getPriceSetName()); + vo.setSetType(set.getSetType()); + } + if (needVersion && version != null) + { + applyFailReasonVersion(vo, version); + } + } + + private static void applyFailReasonVersion(OrderBillFailReasonVo vo, PrcPriceSetVersion ver) + { + if (vo == null || ver == null) + { + return; + } + vo.setPsvId(ver.getPsvId()); + vo.setVersionNo(ver.getVersionNo()); + vo.setEffectiveTime(ver.getEffectiveTime()); + vo.setExpireTime(ver.getExpireTime()); + } + + /** Prefer pickupDate, then bizDate, for sales package version window match. */ + private PrcPriceSetVersion selectVersionByPickupOrBiz(Long priceSetId, PrcOrderBill bill) + { + if (priceSetId == null || priceSetVersionMapper == null || bill == null) + { + return null; + } + Date[] asOfList = new Date[] { bill.getPickupDate(), bill.getBizDate() }; + for (Date asOf : asOfList) + { + if (asOf == null) + { + continue; + } + PrcPriceSetVersion ver = priceSetVersionMapper.selectActiveByPriceSetAt(priceSetId, asOf); + if (ver != null) + { + return ver; + } + } + return null; + } + @Override public TmsPriceQuoteResult getBillByOrderNo(String orderNo) { @@ -1918,8 +2061,9 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService bill.setWeight(weight); bill.setBizDate(bizDate); bill.setTmsId(request.getTmsId() == null ? null : Long.valueOf(request.getTmsId())); - bill.setMatchSource(result.getMatchSource()); - bill.setMatchMessage(result.getMatchMessage()); + // Do not persist match_source / match_message on order bill. + bill.setMatchSource(null); + bill.setMatchMessage(null); bill.setPriceSetId(result.getPriceSetId()); bill.setPriceSetCode(result.getPriceSetCode()); bill.setPriceSetName(result.getPriceSetName()); @@ -3512,6 +3656,7 @@ public class PrcOrderBillServiceImpl implements IPrcOrderBillService failText = failText.substring(0, 1000); } bill.setErrorMessage(failText); - bill.setMatchMessage(failText); + bill.setMatchMessage(null); + bill.setMatchSource(null); } } diff --git a/bms-back/bms-system/src/main/java/com/bms/price/service/support/BillingFailReasonSupport.java b/bms-back/bms-system/src/main/java/com/bms/price/service/support/BillingFailReasonSupport.java index e3f72bdd..02c4435e 100644 --- a/bms-back/bms-system/src/main/java/com/bms/price/service/support/BillingFailReasonSupport.java +++ b/bms-back/bms-system/src/main/java/com/bms/price/service/support/BillingFailReasonSupport.java @@ -19,14 +19,14 @@ public final class BillingFailReasonSupport static { - TEMPLATES.put(Integer.valueOf(1), "\u3010\u9500\u552e\u4ef7\u672a\u5339\u914d\u4ea7\u54c1\u3011\n\u8ba2\u5355 {orderNo}\uff08\u8f6c\u5355\u53f7 {transferNo}\uff09\uff0c\u5ba2\u6237 {customer}\uff0c\u4ea7\u54c1 {product}\uff0c\u56fd\u5bb6 {country}\uff0c\u8ba1\u8d39\u65f6\u95f4 {bizDate}\u3002\n\u5728\u5ba2\u6237\u9500\u552e\u4ef7\u5957\u9910\u300c{priceSet}\u300d\u4e2d\u672a\u627e\u5230\u8be5\u4ea7\u54c1\uff0c\u8bf7\u68c0\u67e5\u5957\u9910\u4ea7\u54c1\u8303\u56f4\u6216\u4ea7\u54c1\u4ee3\u7801\u6620\u5c04\u3002"); - TEMPLATES.put(Integer.valueOf(2), "\u3010\u9500\u552e\u4ef7\u672a\u5339\u914d\u56fd\u5bb6\u3011\n\u8ba2\u5355 {orderNo}\uff08\u8f6c\u5355\u53f7 {transferNo}\uff09\uff0c\u5ba2\u6237 {customer}\uff0c\u4ea7\u54c1 {product}\uff0c\u76ee\u7684\u56fd\u5bb6 {country}\uff0c\u90ae\u7f16 {postcode}\uff0c\u8ba1\u8d39\u65f6\u95f4 {bizDate}\u3002\n\u5957\u9910\u300c{priceSet}\u300d\u7248\u672c {version}\u5df2\u547d\u4e2d\u4ea7\u54c1\uff0c\u4f46\u672a\u547d\u4e2d\u56fd\u5bb6/\u5206\u533a\uff0c\u8bf7\u8865\u9f50\u56fd\u5bb6\u4e0e\u5206\u533a\u4ef7\u683c\u3002"); - TEMPLATES.put(Integer.valueOf(3), "\u3010\u9500\u552e\u4ef7\u672a\u5339\u914d\u91cd\u91cf\u6bb5\u3011\n\u8ba2\u5355 {orderNo}\uff08\u8f6c\u5355\u53f7 {transferNo}\uff09\uff0c\u5ba2\u6237 {customer}\uff0c\u4ea7\u54c1 {product}\uff0c\u56fd\u5bb6 {country}\uff0c\u5206\u533a {zone}\uff0c\u8ba1\u8d39\u91cd {chargeWeight} kg\uff0c\u8ba1\u8d39\u65f6\u95f4 {bizDate}\u3002\n\u5957\u9910\u300c{priceSet}\u300d\u7248\u672c {version}\u5df2\u547d\u4e2d\u4ea7\u54c1\u4e0e\u56fd\u5bb6\uff0c\u4f46\u8ba1\u8d39\u91cd\u672a\u843d\u5728\u4ef7\u683c\u91cd\u91cf\u6bb5\u5185\uff0c\u8bf7\u68c0\u67e5\u91cd\u91cf\u6bb5\u8bbe\u7f6e\u3002"); - TEMPLATES.put(Integer.valueOf(23), "\u3010\u4ea7\u54c1\u4ef7\u672a\u5339\u914d\u4ea7\u54c1\u3011\n\u8ba2\u5355 {orderNo}\uff08\u8f6c\u5355\u53f7 {transferNo}\uff09\uff0c\u5ba2\u6237 {customer}\uff0c\u4ea7\u54c1 {product}\uff0c\u56fd\u5bb6 {country}\uff0c\u8ba1\u8d39\u65f6\u95f4 {bizDate}\u3002\n\u4ea7\u54c1\u4ef7\u76ee\u5f55\u4e2d\u672a\u627e\u5230\u8be5\u4ea7\u54c1\uff0c\u8bf7\u68c0\u67e5\u4ea7\u54c1\u4ef7\u6863\u6848\u662f\u5426\u5df2\u7ef4\u62a4\u3002"); - TEMPLATES.put(Integer.valueOf(24), "\u3010\u4ea7\u54c1\u4ef7\u672a\u5339\u914d\u56fd\u5bb6\u3011\n\u8ba2\u5355 {orderNo}\uff08\u8f6c\u5355\u53f7 {transferNo}\uff09\uff0c\u4ea7\u54c1 {product}\uff0c\u76ee\u7684\u56fd\u5bb6 {country}\uff0c\u90ae\u7f16 {postcode}\uff0c\u8ba1\u8d39\u65f6\u95f4 {bizDate}\u3002\n\u4ea7\u54c1\u4ef7\u5df2\u547d\u4e2d\u4ea7\u54c1\uff0c\u4f46\u672a\u547d\u4e2d\u56fd\u5bb6/\u5206\u533a\uff0c\u8bf7\u8865\u9f50\u4ea7\u54c1\u4ef7\u56fd\u5bb6\u4ef7\u683c\u3002"); - TEMPLATES.put(Integer.valueOf(25), "\u3010\u4ea7\u54c1\u4ef7\u672a\u5339\u914d\u91cd\u91cf\u6bb5\u3011\n\u8ba2\u5355 {orderNo}\uff08\u8f6c\u5355\u53f7 {transferNo}\uff09\uff0c\u4ea7\u54c1 {product}\uff0c\u56fd\u5bb6 {country}\uff0c\u5206\u533a {zone}\uff0c\u8ba1\u8d39\u91cd {chargeWeight} kg\uff0c\u8ba1\u8d39\u65f6\u95f4 {bizDate}\u3002\n\u4ea7\u54c1\u4ef7\u5df2\u547d\u4e2d\u4ea7\u54c1\u4e0e\u56fd\u5bb6\uff0c\u4f46\u8ba1\u8d39\u91cd\u672a\u843d\u5728\u91cd\u91cf\u6bb5\u5185\uff0c\u8bf7\u68c0\u67e5\u4ea7\u54c1\u4ef7\u91cd\u91cf\u6bb5\u3002"); - TEMPLATES.put(Integer.valueOf(4), "\u3010\u672a\u7ed1\u5b9a\u5957\u9910\u3011\n\u8ba2\u5355 {orderNo}\uff08\u8f6c\u5355\u53f7 {transferNo}\uff09\uff0c\u5ba2\u6237 {customer}\uff0c\u8ba1\u8d39\u65f6\u95f4 {bizDate}\u3002\n\u8be5\u5ba2\u6237\u672a\u7ed1\u5b9a\u9500\u552e\u4ef7\u5957\u9910\uff0c\u65e0\u6cd5\u6309\u5957\u9910\u53d6\u4ef7\uff0c\u8bf7\u5148\u5728\u5ba2\u6237/\u5957\u9910\u7ed1\u5b9a\u540e\u518d\u8ba1\u8d39\u3002"); - TEMPLATES.put(Integer.valueOf(5), "\u3010\u5957\u9910\u672a\u542f\u7528/\u65e0\u751f\u6548\u7248\u672c\u3011\n\u8ba2\u5355 {orderNo}\uff08\u8f6c\u5355\u53f7 {transferNo}\uff09\uff0c\u5ba2\u6237 {customer}\uff0c\u5957\u9910\u300c{priceSet}\u300d\uff0c\u8ba1\u8d39\u65f6\u95f4 {bizDate}\u3002\n\u8ba1\u8d39\u65e5\u6ca1\u6709\u53ef\u7528\u7684\u5957\u9910\u751f\u6548\u7248\u672c\uff0c\u8bf7\u68c0\u67e5\u5957\u9910\u542f\u7528\u72b6\u6001\u4e0e\u7248\u672c\u751f\u6548\u671f\u3002"); + TEMPLATES.put(Integer.valueOf(1), "【销售价未匹配产品】\n订单 {orderNo}(转单号 {transferNo}),客户 {customer},产品 {product},国家 {country},计费时间 {bizDate}。\n在客户销售价套餐「{priceSet}」中未找到该产品,请检查套餐产品范围或产品代码映射。"); + TEMPLATES.put(Integer.valueOf(2), "【销售价未匹配国家】\n订单 {orderNo}(转单号 {transferNo}),客户 {customer},产品 {product},目的国家 {country},邮编 {postcode},计费时间 {bizDate}。\n套餐「{priceSet}」版本 {version}已命中产品,但未命中国家/分区,请补齐国家与分区价格。"); + TEMPLATES.put(Integer.valueOf(3), "【销售价未匹配重量段】\n订单 {orderNo}(转单号 {transferNo}),客户 {customer},产品 {product},国家 {country},分区 {zone},计费重 {chargeWeight} kg,计费时间 {bizDate}。\n套餐「{priceSet}」版本 {version}已命中产品与国家,但计费重未落在价格重量段内,请检查重量段设置。"); + TEMPLATES.put(Integer.valueOf(23), "【产品价未匹配产品】\n订单 {orderNo}(转单号 {transferNo}),客户 {customer},产品 {product},国家 {country},计费时间 {bizDate}。\n产品价目录中未找到该产品,请检查产品价档案是否已维护。"); + TEMPLATES.put(Integer.valueOf(24), "【产品价未匹配国家】\n订单 {orderNo}(转单号 {transferNo}),产品 {product},目的国家 {country},邮编 {postcode},计费时间 {bizDate}。\n产品价已命中产品,但未命中国家/分区,请补齐产品价国家价格。"); + TEMPLATES.put(Integer.valueOf(25), "【产品价未匹配重量段】\n订单 {orderNo}(转单号 {transferNo}),产品 {product},国家 {country},分区 {zone},计费重 {chargeWeight} kg,计费时间 {bizDate}。\n产品价已命中产品与国家,但计费重未落在重量段内,请检查产品价重量段。"); + TEMPLATES.put(Integer.valueOf(4), "【未绑定套餐】\n订单 {orderNo}(转单号 {transferNo}),客户 {customer},计费时间 {bizDate}。\n该客户未绑定销售价套餐,无法按套餐取价,请先在客户/套餐绑定后再计费。"); + TEMPLATES.put(Integer.valueOf(5), "【套餐未启用/无生效版本】\n订单 {orderNo}(转单号 {transferNo}),客户 {customer},套餐「{priceSet}」,计费时间 {bizDate}。\n计费日没有可用的套餐生效版本,请检查套餐启用状态与版本生效期。"); } public static String buildDetail(OrderBillFailReasonVo vo, String fallback) @@ -40,13 +40,13 @@ public final class BillingFailReasonSupport if (StringUtils.isEmpty(tpl)) { StringBuilder sb = new StringBuilder(); - sb.append("\u3010").append(nz(vo.getBillingFailStatusLabel(), "\u8ba1\u8d39\u5931\u8d25")).append("\u3011\n"); - sb.append("\u8ba2\u5355 ").append(nz(vo.getOrderNo(), "-")); - sb.append("\uff08\u8f6c\u5355\u53f7 ").append(nz(vo.getTransferNo(), "-")).append("\uff09"); - sb.append("\uff0c\u5ba2\u6237 ").append(joinCodeName(vo.getCustomerCode(), vo.getCustomerName())); - sb.append("\uff0c\u4ea7\u54c1 ").append(joinCodeName(vo.getProductCode(), vo.getProductName())); - sb.append("\uff0c\u56fd\u5bb6 ").append(joinCodeName(vo.getCountryCode(), vo.getCountryName())); - sb.append("\uff0c\u8ba1\u8d39\u65f6\u95f4 ").append(fmtDate(vo.getBizDate())).append("\u3002\n"); + sb.append("【").append(nz(vo.getBillingFailStatusLabel(), "计费失败")).append("】\n"); + sb.append("订单 ").append(nz(vo.getOrderNo(), "-")); + sb.append("(转单号 ").append(nz(vo.getTransferNo(), "-")).append(")"); + sb.append(",客户 ").append(joinCodeName(vo.getCustomerCode(), vo.getCustomerName())); + sb.append(",产品 ").append(joinCodeName(vo.getProductCode(), vo.getProductName())); + sb.append(",国家 ").append(joinCodeName(vo.getCountryCode(), vo.getCountryName())); + sb.append(",计费时间 ").append(fmtDate(vo.getBizDate())).append("。\n"); sb.append(nz(fallback, nz(vo.getErrorMessage(), vo.getBillingFailStatusLabel()))); return sb.toString(); } @@ -60,7 +60,7 @@ public final class BillingFailReasonSupport ctx.put("zone", joinCodeName(vo.getZoneCode(), vo.getZoneName())); ctx.put("postcode", nz(vo.getDestPostcode(), "-")); ctx.put("priceSet", joinCodeName(vo.getPriceSetCode(), vo.getPriceSetName())); - ctx.put("version", nz(vo.getVersionNo(), "-")); + ctx.put("version", formatPriceCycle(vo.getEffectiveTime(), vo.getExpireTime(), vo.getVersionNo())); ctx.put("chargeWeight", fmtNum(vo.getChargeWeight())); ctx.put("bizDate", fmtDate(vo.getBizDate())); ctx.put("pickupDate", fmtDate(vo.getPickupDate())); @@ -71,7 +71,7 @@ public final class BillingFailReasonSupport } if (StringUtils.isNotEmpty(fallback) && !fallback.equals(vo.getBillingFailStatusLabel())) { - out = out + "\n\u8be6\u60c5\uff1a" + fallback; + out = out + "\n详情:" + fallback; } return out; } @@ -93,6 +93,15 @@ public final class BillingFailReasonSupport return code + "/" + name; } + private static String formatPriceCycle(Date effectiveTime, Date expireTime, String versionNo) + { + if (effectiveTime == null && expireTime == null) + { + return nz(versionNo, "-"); + } + return fmtDate(effectiveTime) + " ~ " + fmtDate(expireTime); + } + private static String fmtDate(Date d) { if (d == null) diff --git a/bms-front/src/views/price/orderBill/components/OrderBillPriceCycleListDrawer.vue b/bms-front/src/views/price/orderBill/components/OrderBillPriceCycleListDrawer.vue new file mode 100644 index 00000000..6d7bd565 --- /dev/null +++ b/bms-front/src/views/price/orderBill/components/OrderBillPriceCycleListDrawer.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/bms-front/src/views/price/orderBill/index.vue b/bms-front/src/views/price/orderBill/index.vue index 556faeac..0510d52b 100644 --- a/bms-front/src/views/price/orderBill/index.vue +++ b/bms-front/src/views/price/orderBill/index.vue @@ -342,10 +342,28 @@ {{ failReason.destPostcode || '-' }} - {{ joinCodeName(failReason.priceSetCode, failReason.priceSetName) }} +
+ {{ joinCodeName(failReason.priceSetCode, failReason.priceSetName) }} + 查看 +
- - {{ failReason.versionNo || '-' }} + +
+ {{ formatPriceCycle(failReason) }} + 查看 +
{{ failReason.weightLabel || formatWeightRange(failReason.weightMin, failReason.weightMax) }} @@ -380,6 +398,20 @@ 关闭 + + + + @@ -391,6 +423,8 @@ import ExcelExportFieldDialog from '@/components/ExcelExportFieldDialog/index.vu import { ORDER_BILL_EXPORT_FIELDS } from '@/utils/exportFieldDefs' import OrderSourceSyncLogDrawer from '../../monitor/orderSource/components/OrderSourceSyncLogDrawer.vue' import OrderBillProductCheckDrawer from './components/OrderBillProductCheckDrawer.vue' +import SetVersionDetailDrawer from '../set/components/detail/SetVersionDetailDrawer.vue' +import OrderBillPriceCycleListDrawer from './components/OrderBillPriceCycleListDrawer.vue' const tableRef = ref() const exportFieldRef = ref() @@ -1171,9 +1205,14 @@ const failReason = reactive({ zoneCode: '', zoneName: '', destPostcode: '', + priceSetId: null, priceSetCode: '', priceSetName: '', + setType: '', + psvId: null, versionNo: '', + effectiveTime: null, + expireTime: null, weightLabel: '', weightMin: null, weightMax: null, @@ -1225,6 +1264,37 @@ function formatDateTime(val) { ' ' + pad(d.getHours()) + ':' + pad(d.getMinutes()) + ':' + pad(d.getSeconds()) } +function formatPriceCycle(row) { + const r = row || {} + const eff = formatDateTime(r.effectiveTime) + const exp = formatDateTime(r.expireTime) + if (eff === '-' && exp === '-') { + return r.versionNo || '-' + } + return eff + ' ~ ' + exp +} + +const priceCycleDrawerVisible = ref(false) +const priceCycleVersion = ref(null) + +function openPriceCycleDetail() { + if (!failReason.psvId) return + priceCycleVersion.value = { + psvId: failReason.psvId, + versionNo: failReason.versionNo, + effectiveTime: failReason.effectiveTime ? formatDateTime(failReason.effectiveTime) : null, + expireTime: failReason.expireTime ? formatDateTime(failReason.expireTime) : null + } + priceCycleDrawerVisible.value = true +} + +const packageCycleDrawerVisible = ref(false) + +function openPackagePriceCycles() { + if (!failReason.priceSetId) return + packageCycleDrawerVisible.value = true +} + function applyFailReason(data, row) { const src = data || {} const base = row || {} @@ -1241,9 +1311,14 @@ function applyFailReason(data, row) { failReason.zoneCode = src.zoneCode || '' failReason.zoneName = src.zoneName || '' failReason.destPostcode = src.destPostcode || base.destPostcode || '' + failReason.priceSetId = src.priceSetId != null ? src.priceSetId : (base.priceSetId != null ? base.priceSetId : null) failReason.priceSetCode = src.priceSetCode || base.priceSetCode || '' failReason.priceSetName = src.priceSetName || base.priceSetName || '' + failReason.setType = src.setType || base.setType || '' + failReason.psvId = src.psvId != null ? src.psvId : (base.psvId != null ? base.psvId : null) failReason.versionNo = src.versionNo || '' + failReason.effectiveTime = src.effectiveTime || null + failReason.expireTime = src.expireTime || null failReason.weightLabel = src.weightLabel || base.weightLabel || '' failReason.weightMin = src.weightMin != null ? src.weightMin : base.weightMin failReason.weightMax = src.weightMax != null ? src.weightMax : base.weightMax @@ -1487,6 +1562,16 @@ onBeforeUnmount(() => { color: #0f172a; font-weight: 500; } +.fr-cycle-row { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: wrap; +} +.fr-cycle-btn { + flex-shrink: 0; + padding: 0; +} .fr-val-key { color: #c2410c; font-weight: 700; diff --git a/bms-front/src/views/price/set/components/detail/SetVersionDetailDrawer.vue b/bms-front/src/views/price/set/components/detail/SetVersionDetailDrawer.vue index f6cd0e45..a99e86d6 100644 --- a/bms-front/src/views/price/set/components/detail/SetVersionDetailDrawer.vue +++ b/bms-front/src/views/price/set/components/detail/SetVersionDetailDrawer.vue @@ -3,6 +3,7 @@ :model-value="modelValue" :title="title" size="72%" + append-to-body destroy-on-close @close="close" >