From 7b877255fbebf899fc6c6eda7a1c04af93ccfcfc Mon Sep 17 00:00:00 2001 From: c-chenxs1 <2499071264@qq.com> Date: Tue, 8 Sep 2026 13:40:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=A7=AF=E5=88=86=E5=95=86=E5=9F=8E-?= =?UTF-8?q?=E5=AF=B9=E8=B4=A6-=E5=8F=91=E7=A5=A8-=E4=BC=98=E5=8C=962?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/sys/services/SysFileService.java | 2 + .../sys/services/impl/SysFileServiceImpl.java | 5 + .../PointsMallInvoiceController.java | 25 +- .../invoice/models/PointsMallInvoiceInfo.java | 3 + .../service/PointsMallInvoiceService.java | 5 +- .../impl/PointsMallInvoiceServiceImpl.java | 129 +++++- .../mallbridge/dto/InvoiceInfoDTO.java | 2 + .../mallbridge/dto/QueryInvoiceInfoDTO.java | 1 + .../MallSplitSubOrderEventHandler.java | 2 +- .../service/MallInboundEventService.java | 67 ++- .../MallInvoiceApplyOutboundService.java | 3 +- .../service/MallInvoiceInfoQueryService.java | 40 +- .../MallOrderQueryOutboundService.java | 28 +- .../MallReconciliationInfoQueryService.java | 72 ++- .../support/AbstractMallBridgeSupport.java | 112 +++++ .../util/MallBridgeResponseUtil.java | 37 ++ .../param/PointsMallReconciliationParam.java | 4 + .../PointsMallReconciliationServiceImpl.java | 50 +-- .../zhgh/points-mall/invoice/index.html | 409 +++++++----------- .../points-mall/reconciliation/index.html | 61 ++- .../zhghh5/points-mall/order/index.html | 1 + 21 files changed, 707 insertions(+), 351 deletions(-) create mode 100644 src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/util/MallBridgeResponseUtil.java diff --git a/src/main/java/com/budwk/app/sys/services/SysFileService.java b/src/main/java/com/budwk/app/sys/services/SysFileService.java index 9976d46b..88f07f0f 100644 --- a/src/main/java/com/budwk/app/sys/services/SysFileService.java +++ b/src/main/java/com/budwk/app/sys/services/SysFileService.java @@ -25,6 +25,8 @@ public interface SysFileService extends BaseService { */ String uploadReturnUrl(String engine, TempFile file); + String uploadReturnUrl(String engine, String fileName, byte[] bytes); + /** * 分页 */ diff --git a/src/main/java/com/budwk/app/sys/services/impl/SysFileServiceImpl.java b/src/main/java/com/budwk/app/sys/services/impl/SysFileServiceImpl.java index df36d760..4f730181 100644 --- a/src/main/java/com/budwk/app/sys/services/impl/SysFileServiceImpl.java +++ b/src/main/java/com/budwk/app/sys/services/impl/SysFileServiceImpl.java @@ -69,6 +69,11 @@ public class SysFileServiceImpl extends BaseServiceImpl implements Sys return this.storageFile(engine, file, false); } + @Override + public String uploadReturnUrl(String engine, String fileName, byte[] bytes) { + return this.storageFile(engine, fileName, bytes, false); + } + @Override public Pagination page(Sys_file file) { return null; diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/invoice/controller/PointsMallInvoiceController.java b/src/main/java/com/budwk/app/zhgh/pointsmall/invoice/controller/PointsMallInvoiceController.java index f32cee59..b1962558 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/invoice/controller/PointsMallInvoiceController.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/invoice/controller/PointsMallInvoiceController.java @@ -37,13 +37,34 @@ public class PointsMallInvoiceController { @At @SaCheckPermission("points.mall.invoice") public Result infoPage(PointsMallInvoiceInfoPageParam param) { - return Result.success(pointsMallInvoiceService.infoPage(param)); + try { + return Result.success(pointsMallInvoiceService.infoPage(param)); + } catch (IllegalArgumentException e) { + return Result.error(e.getMessage()); + } } @At @SaCheckPermission("points.mall.invoice") public Result infoDetail(@Param("id") String id) { - return Result.success(pointsMallInvoiceService.infoDetail(id)); + try { + return Result.success(pointsMallInvoiceService.infoDetail(id)); + } catch (IllegalArgumentException e) { + return Result.error(e.getMessage()); + } + } + + @At + @org.nutz.mvc.annotation.POST + @SLog(tag = "积分商城发票管理", msg = "重新获取发票") + @SaCheckPermission("points.mall.invoice") + public Result retryInvoice(@Param("mainId") String mainId) { + try { + pointsMallInvoiceService.retryInvoice(mainId); + return Result.success(); + } catch (IllegalArgumentException e) { + return Result.error(e.getMessage()); + } } @At diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/invoice/models/PointsMallInvoiceInfo.java b/src/main/java/com/budwk/app/zhgh/pointsmall/invoice/models/PointsMallInvoiceInfo.java index 45922f11..45fee015 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/invoice/models/PointsMallInvoiceInfo.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/invoice/models/PointsMallInvoiceInfo.java @@ -16,6 +16,9 @@ import java.util.Date; @Comment("积分商城发票信息") public class PointsMallInvoiceInfo extends BaseModel implements Serializable { + // 详情实时读取供应商 PDF 生成结果:1 成功,2 失败,不以本地文件地址推断状态。 + private Integer status; + @Name @Column @Comment("ID") diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/invoice/service/PointsMallInvoiceService.java b/src/main/java/com/budwk/app/zhgh/pointsmall/invoice/service/PointsMallInvoiceService.java index 49d8e144..6a293735 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/invoice/service/PointsMallInvoiceService.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/invoice/service/PointsMallInvoiceService.java @@ -3,6 +3,7 @@ package com.budwk.app.zhgh.pointsmall.invoice.service; import com.budwk.app.base.page.Pagination; import com.budwk.app.base.service.BaseService; import com.budwk.app.zhgh.pointsmall.invoice.models.PointsMallInvoiceMain; +import com.budwk.app.zhgh.pointsmall.invoice.models.PointsMallInvoiceInfo; import com.budwk.app.zhgh.pointsmall.invoice.param.PointsMallInvoiceApplyParam; import com.budwk.app.zhgh.pointsmall.invoice.param.PointsMallInvoiceInfoPageParam; import com.budwk.app.zhgh.pointsmall.invoice.param.PointsMallInvoiceMainPageParam; @@ -19,7 +20,9 @@ public interface PointsMallInvoiceService extends BaseService infoPage(PointsMallInvoiceInfoPageParam param); - Record infoDetail(String id); + PointsMallInvoiceInfo infoDetail(String id); + + void retryInvoice(String mainId); Pagination orderPage(PointsMallInvoiceOrderPageParam param); diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/invoice/service/impl/PointsMallInvoiceServiceImpl.java b/src/main/java/com/budwk/app/zhgh/pointsmall/invoice/service/impl/PointsMallInvoiceServiceImpl.java index 808122d9..588ecc59 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/invoice/service/impl/PointsMallInvoiceServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/invoice/service/impl/PointsMallInvoiceServiceImpl.java @@ -13,11 +13,16 @@ import com.budwk.app.zhgh.pointsmall.invoice.param.PointsMallInvoiceMainPagePara import com.budwk.app.zhgh.pointsmall.invoice.param.PointsMallInvoiceOrderPageParam; import com.budwk.app.zhgh.pointsmall.invoice.service.PointsMallInvoiceService; import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallInvoiceApplyDTO; +import com.budwk.app.zhgh.pointsmall.mallbridge.dto.InvoiceInfoDTO; +import com.budwk.app.zhgh.pointsmall.mallbridge.dto.QueryInvoiceInfoDTO; +import com.budwk.app.zhgh.pointsmall.mallbridge.dto.GetInvoiceInfoDTO; import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallOutboundResult; import com.budwk.app.zhgh.pointsmall.mallbridge.service.MallInvoiceApplyOutboundService; +import com.budwk.app.zhgh.pointsmall.mallbridge.service.MallInvoiceInfoQueryService; import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderSub; import com.budwk.app.zhgh.pointsmall.supplier.models.PointsMallSupplier; import org.nutz.dao.Chain; +import org.nutz.trans.Atom; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; import org.nutz.dao.Sqls; @@ -25,8 +30,13 @@ import org.nutz.dao.entity.Record; import org.nutz.dao.sql.Sql; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import org.nutz.trans.Trans; import java.math.BigDecimal; +import com.budwk.app.zhgh.pointsmall.invoice.models.PointsMallInvoiceInfo; +import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallOrderEventDTO; +import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundResult; +import com.budwk.app.zhgh.pointsmall.mallbridge.service.MallInboundEventService; import java.util.List; import java.util.stream.Collectors; @@ -35,6 +45,10 @@ public class PointsMallInvoiceServiceImpl extends BaseServiceImpl infoPage(PointsMallInvoiceInfoPageParam param) { + if (StrUtil.isNotBlank(param.getMainId()) && dao().count(PointsMallInvoiceInfo.class, + Cnd.where("mainId", "=", param.getMainId()).and("delFlag", "=", false)) == 0) { + PointsMallInvoiceMain main = fetch(param.getMainId()); + PointsMallOrderSub order = main == null ? null : dao().fetch(PointsMallOrderSub.class, + Cnd.where("invoiceCode", "=", main.getSettlementId()).and("delFlag", "=", false)); + if (order != null) { + MallOrderEventDTO event = new MallOrderEventDTO(); + event.setSupplierId(order.getSupplierId()); + event.setOrderId(main.getSettlementId()); + MallInboundResult result = mallInboundEventService.invoiceInfo(event); + if (result.getResultCode() != 0) { + dao().update(PointsMallInvoiceMain.class, Chain.make("bSuccess", 1).add("failMsg", result.getMessage()), + Cnd.where("id", "=", main.getId())); + throw new IllegalArgumentException(result.getMessage()); + } + } + } Cnd cnd = Cnd.where("delFlag", "=", false); if (StrUtil.isNotBlank(param.getMainId())) { cnd.and("mainId", "=", param.getMainId()); @@ -87,13 +118,61 @@ public class PointsMallInvoiceServiceImpl extends BaseServiceImpl info.getInvoiceId().equals(item.getInvoiceId())).findFirst() + .orElseThrow(() -> new IllegalArgumentException("供应商未返回对应发票详情")); + info.setStatus(remote.getStatus()); + info.setRemark(remote.getRemark()); + if (!Integer.valueOf(1).equals(remote.getStatus())) { + info.setUrl(""); + info.setImageEncode(""); + } + return info; + } + + private MallOrderEventDTO invoiceEvent(String mainId) { + PointsMallInvoiceMain main = StrUtil.isBlank(mainId) ? null : dao().fetch(PointsMallInvoiceMain.class, + Cnd.where("id", "=", mainId).and("delFlag", "=", false)); + if (main == null) { + throw new IllegalArgumentException("开票申请记录不存在"); + } + PointsMallOrderSub order = dao().fetch(PointsMallOrderSub.class, + Cnd.where("invoiceCode", "=", main.getSettlementId()).and("delFlag", "=", false)); + if (order == null) { + throw new IllegalArgumentException("未找到结算单对应的供应商订单"); + } + MallOrderEventDTO event = new MallOrderEventDTO(); + event.setSupplierId(order.getSupplierId()); + event.setOrderId(main.getSettlementId()); + return event; + } + + @Override + public void retryInvoice(String mainId) { + MallInboundResult result = mallInboundEventService.invoiceInfo(invoiceEvent(mainId), true); + if (result.getResultCode() != 0) { + throw new IllegalArgumentException(result.getMessage()); + } + PointsMallInvoiceMain main = fetch(mainId); + if (!Integer.valueOf(0).equals(main.getBSuccess())) { + throw new IllegalArgumentException(StrUtil.blankToDefault(main.getFailMsg(), "供应商发票生成失败")); + } } @Override @@ -132,8 +211,8 @@ public class PointsMallInvoiceServiceImpl extends BaseServiceImpl { + dao().update(PointsMallInvoiceInfo.class, Chain.make("delFlag", true), + Cnd.where("mainId", "=", invoice.getId())); + dao().update(PointsMallInvoiceMain.class, Chain.make("delFlag", true), + Cnd.where("id", "=", invoice.getId())); + dao().update(PointsMallOrderSub.class, Chain.make("invoiceStatus", 0).add("invoiceCode", ""), + Cnd.where("supplierId", "=", param.getSupplierId()).and("orderId", "in", orderIds) + .and("invoiceCode", "=", settlementId).and("invoiceStatus", "in", new Integer[]{0, 2})); + }); + throw new IllegalArgumentException(result.getMessage()); + } invoice.setBSuccess(1); invoice.setSucOrderIds(""); invoice.setFailOrderIds(String.join(",", orderIds)); invoice.setFailMsg(result == null ? "供应商开票申请无响应" : result.getMessage()); updateIgnoreNull(invoice); + dao().update(PointsMallOrderSub.class, Chain.make("invoiceStatus", 0), + Cnd.where("supplierId", "=", param.getSupplierId()).and("orderId", "in", orderIds) + .and("invoiceCode", "=", settlementId).and("invoiceStatus", "=", 2)); throw new IllegalArgumentException(invoice.getFailMsg()); } - dao().update(PointsMallOrderSub.class, Chain.make("invoiceStatus", 2).add("invoiceCode", settlementId), - Cnd.where("supplierId", "=", param.getSupplierId()).and("orderId", "in", orderIds)); return "开票申请已生成,结算单号:" + settlementId; } @@ -189,11 +294,7 @@ public class PointsMallInvoiceServiceImpl extends BaseServiceImpl orderIds = StrUtil.splitTrim(param.getOrderId(), ","); - if (orderIds.size() > 1) { - cnd.and(field(alias, "orderId"), "in", orderIds); - } else { - cnd.and(field(alias, "orderId"), "like", "%" + param.getOrderId() + "%"); - } + cnd.and(field(alias, "orderId"), "in", orderIds); } if (StrUtil.isNotBlank(param.getStartDate())) { cnd.and(field(alias, "orderCompleteTime"), ">=", DateUtil.beginOfDay(DateUtil.parse(param.getStartDate()))); diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/InvoiceInfoDTO.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/InvoiceInfoDTO.java index 657ea471..ae05e848 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/InvoiceInfoDTO.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/InvoiceInfoDTO.java @@ -7,6 +7,8 @@ import java.time.LocalDate; @Data public class InvoiceInfoDTO { + private Integer status; + private String remark; private String invoiceId; private String invoiceCode; private LocalDate invoiceDate; diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/QueryInvoiceInfoDTO.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/QueryInvoiceInfoDTO.java index 293d8696..d77a32e0 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/QueryInvoiceInfoDTO.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/dto/QueryInvoiceInfoDTO.java @@ -4,6 +4,7 @@ import lombok.Data; @Data public class QueryInvoiceInfoDTO { + private Boolean retry; private String supplierId; private String token; private String settlementId; diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallSplitSubOrderEventHandler.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallSplitSubOrderEventHandler.java index 159a30df..01ef8cde 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallSplitSubOrderEventHandler.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallSplitSubOrderEventHandler.java @@ -94,7 +94,7 @@ public class MallSplitSubOrderEventHandler implements MallOrderEventHandler { // 调用外部服务获取子订单信息 MallOutboundResult result = mallOrderQueryOutboundService.orderQuery(queryDTO); if (result == null || result.getResultCode() != 0) { - throw new RuntimeException(result == null ? "获取订单详情返回为空" : result.getMessage()); + return MallInboundResult.fail(result == null ? 502 : result.getResultCode(), result == null ? "获取订单详情返回为空" : result.getMessage()); } orderInfoList = result.getOrderInfo(); } catch (Exception e) { diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallInboundEventService.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallInboundEventService.java index a212f205..84e4d5af 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallInboundEventService.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallInboundEventService.java @@ -47,6 +47,11 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Base64; +import java.util.stream.Collectors; +import com.budwk.app.sys.services.SysFileService; +import com.budwk.app.sys.enums.SysFileEngineTypeEnum; +import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallPictureOutboundResult; /** * 商城桥接订单事件入站服务。 @@ -62,6 +67,8 @@ public class MallInboundEventService extends AbstractMallBridgeSupport { @Inject private MallInvoiceInfoQueryService mallInvoiceInfoQueryService; @Inject + private SysFileService sysFileService; + @Inject private MallCancelPendingOrderEventHandler mallCancelPendingOrderEventHandler; @Inject private MallSplitSubOrderEventHandler mallSplitSubOrderEventHandler; @@ -424,6 +431,10 @@ public class MallInboundEventService extends AbstractMallBridgeSupport { } public MallInboundResult invoiceInfo(MallOrderEventDTO dto) { + return invoiceInfo(dto, false); + } + + public MallInboundResult invoiceInfo(MallOrderEventDTO dto, boolean retry) { String settlementId = dto.getOrderId(); if (StrUtil.hasBlank(dto.getSupplierId(), settlementId)) { return MallInboundResult.fail(400, "供应商和结算单号不能为空"); @@ -431,6 +442,7 @@ public class MallInboundEventService extends AbstractMallBridgeSupport { QueryInvoiceInfoDTO query = new QueryInvoiceInfoDTO(); query.setSupplierId(dto.getSupplierId()); query.setSettlementId(settlementId); + query.setRetry(retry); GetInvoiceInfoDTO result; try { result = mallInvoiceInfoQueryService.queryInvoicesInfo(query); @@ -444,14 +456,56 @@ public class MallInboundEventService extends AbstractMallBridgeSupport { if (main == null) { return MallInboundResult.fail(404, "开票申请记录不存在"); } + if (result == null || !settlementId.equals(result.getSettlementId())) { + return MallInboundResult.fail(502, "供应商返回的发票结算单不匹配"); + } Integer success = result.getBSuccess() == null ? 0 : result.getBSuccess(); + if (success == 0) { + if (result.getInvoiceInfos() == null || result.getInvoiceInfos().isEmpty() || StrUtil.isBlank(result.getSucOrderIds())) { + return MallInboundResult.fail(502, "供应商开票结果缺少发票明细或成功订单"); + } + try { + List fileIds = result.getInvoiceInfos().stream().map(InvoiceInfoDTO::getInvoiceId).collect(Collectors.toList()); + if (fileIds.stream().anyMatch(StrUtil::isBlank)) { + throw new IllegalArgumentException("供应商发票文件标识为空"); + } + MallPictureOutboundResult files = mallInvoiceInfoQueryService.queryInvoiceFiles(dto.getSupplierId(), settlementId, fileIds); + for (InvoiceInfoDTO item : result.getInvoiceInfos()) { + if (item.getStatus() != null && item.getStatus() != 1) { + throw new IllegalArgumentException("供应商发票尚未生成成功"); + } + String base64 = files.getImageEncodeMap() == null ? null : files.getImageEncodeMap().get(item.getInvoiceId()); + if (StrUtil.isBlank(base64)) { + throw new IllegalArgumentException("未获取到发票文件Base64:" + item.getInvoiceId()); + } + if (base64.startsWith("data:")) { + base64 = base64.substring(base64.indexOf(',') + 1); + } + byte[] bytes = Base64.getDecoder().decode(base64.replaceAll("\\s", "")); + if (bytes.length == 0) { + throw new IllegalArgumentException("发票文件内容为空"); + } + String fileType = StrUtil.blankToDefault(files.getFileType(), StrUtil.blankToDefault(item.getFileType(), "PDF")); + if (!fileType.matches("(?i)pdf|jpg|jpeg|png")) { + throw new IllegalArgumentException("不支持的发票文件类型:" + fileType); + } + String localUrl = sysFileService.uploadReturnUrl(SysFileEngineTypeEnum.MINIO.getValue(), + "invoice-" + java.util.UUID.randomUUID() + "." + fileType.toLowerCase(java.util.Locale.ROOT), bytes); + item.setUrl(localUrl); + item.setImageEncode(localUrl); + item.setFileType(fileType); + } + } catch (Exception e) { + log.error("发票文件同步失败,settlementId={}", settlementId, e); + return MallInboundResult.fail(502, "发票文件同步失败:" + e.getMessage()); + } + } + Trans.exec((Atom) () -> { main.setBSuccess(success); main.setSucOrderIds(result.getSucOrderIds()); main.setFailOrderIds(result.getFailOrderIds()); main.setFailMsg(result.getFailMsg()); - dao.updateIgnoreNull(main); - - if (success == 0 && result.getInvoiceInfos() != null) { + if (result.getInvoiceInfos() != null) { for (InvoiceInfoDTO item : result.getInvoiceInfos()) { PointsMallInvoiceInfo info = dao.fetch(PointsMallInvoiceInfo.class, Cnd.where("mainId", "=", main.getId()).and("invoiceId", "=", item.getInvoiceId()).and("delFlag", "=", false)); @@ -472,6 +526,11 @@ public class MallInboundEventService extends AbstractMallBridgeSupport { info.setFileType(item.getFileType()); info.setCheckCode(item.getCheckCode()); info.setInvoiceAddress(item.getInvoiceAddress()); + info.setRemark(item.getRemark()); + if (success != 0) { + info.setUrl(""); + info.setImageEncode(""); + } if (StrUtil.isBlank(info.getId())) { dao.insert(info); } else { @@ -490,6 +549,8 @@ public class MallInboundEventService extends AbstractMallBridgeSupport { dao.update(PointsMallOrderSub.class, Chain.make("invoiceStatus", 0), Cnd.where("supplierId", "=", dto.getSupplierId()) .and("orderId", "in", failOrderIds).and("delFlag", "=", false)); } + dao.updateIgnoreNull(main); + }); log.info("供应商发票信息更新完成,supplierId={},settlementId={}", dto.getSupplierId(), settlementId); return MallInboundResult.success(); } diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallInvoiceApplyOutboundService.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallInvoiceApplyOutboundService.java index 392b2875..1ac134dd 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallInvoiceApplyOutboundService.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallInvoiceApplyOutboundService.java @@ -3,6 +3,7 @@ package com.budwk.app.zhgh.pointsmall.mallbridge.service; import cn.hutool.http.HttpUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; +import com.budwk.app.zhgh.pointsmall.mallbridge.util.MallBridgeResponseUtil; import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallInvoiceApplyDTO; import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallOutboundResult; import com.budwk.app.zhgh.pointsmall.mallbridge.service.support.AbstractMallBridgeSupport; @@ -79,6 +80,6 @@ public class MallInvoiceApplyOutboundService extends AbstractMallBridgeSupport { if (StrUtil.isBlank(response)) { return MallOutboundResult.fail(502, "供应商开票申请无响应"); } - return JSONUtil.toBean(response, MallOutboundResult.class); + return JSONUtil.toBean(MallBridgeResponseUtil.parse(response), MallOutboundResult.class); } } diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallInvoiceInfoQueryService.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallInvoiceInfoQueryService.java index 50aabaad..96536683 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallInvoiceInfoQueryService.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallInvoiceInfoQueryService.java @@ -4,6 +4,7 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; +import com.budwk.app.zhgh.pointsmall.mallbridge.util.MallBridgeResponseUtil; import com.budwk.app.zhgh.pointsmall.mallbridge.dto.GetInvoiceInfoDTO; import com.budwk.app.zhgh.pointsmall.mallbridge.dto.QueryInvoiceInfoDTO; import com.budwk.app.zhgh.pointsmall.mallbridge.service.support.AbstractMallBridgeSupport; @@ -17,6 +18,9 @@ import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; import java.util.HashMap; +import java.util.List; +import com.budwk.app.zhgh.pointsmall.mallbridge.dto.PictureQueryDTO; +import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallPictureOutboundResult; /** * 商城桥接发票信息查询服务。 @@ -32,6 +36,40 @@ public class MallInvoiceInfoQueryService extends AbstractMallBridgeSupport { super(dao); } + public MallPictureOutboundResult queryInvoiceFiles(String supplierId, String settlementId, List fileIds) { + PointsMallSupplier supplier = dao.fetch(PointsMallSupplier.class, + Cnd.where("supplierId", "=", supplierId).and("delFlag", "=", false)); + if (supplier == null || StrUtil.isBlank(supplier.getSupplierApiUrl())) { + throw new IllegalArgumentException("供应商或供应商接口地址未配置"); + } + String apiUrl = conf.get("spdb.bab7.url", ""); + if (StrUtil.isBlank(apiUrl)) { + throw new IllegalArgumentException("未配置 BAB7 服务地址"); + } + PictureQueryDTO dto = new PictureQueryDTO(); + long timestamp = System.currentTimeMillis(); + dto.setSupplierId(supplierId); + dto.setToken(MallBridgeCryptoUtil.generateSign(supplierId, supplier.getClientId(), timestamp)); + dto.setTimestamp(timestamp); + dto.setQueryType("2"); + dto.setIdNumber(settlementId); + dto.setFileIdList(fileIds); + HashMap body = new HashMap<>(); + body.put("Address4", supplier.getSupplierApiUrl() + "/supplierOpenApi/pointOrder/queryFileBase64Info"); + body.put("BussDealMd", "P"); + body.put("SroNo", supplier.getSroNo()); + body.put("RsrvFld1", supplier.getClientId()); + body.put("AplParmObjct", MallBridgeCryptoUtil.sm4CbcEncrypt(JSONUtil.toJsonStr(dto), + conf.get("sm4cbc.keyHex", ""), conf.get("sm4cbc.ivHex", ""))); + String response = HttpUtil.createPost(apiUrl).contentType("application/json;charset=UTF-8") + .body(JSONUtil.toJsonStr(body)).execute().body(); + JSONObject payload = MallBridgeResponseUtil.parse(response); + if (payload.getInt("resultCode") != 0) { + throw new IllegalArgumentException(StrUtil.blankToDefault(payload.getStr("message"), "获取发票文件失败")); + } + return JSONUtil.toBean(payload, MallPictureOutboundResult.class); + } + /** * 查询指定结算单的发票信息。 */ @@ -82,7 +120,7 @@ public class MallInvoiceInfoQueryService extends AbstractMallBridgeSupport { if (StrUtil.isBlank(response)) { throw new IllegalArgumentException("没有查询到发票信息"); } - JSONObject responseJson = JSONUtil.parseObj(response); + JSONObject responseJson = MallBridgeResponseUtil.parse(response); if (responseJson.getInt("resultCode", -1) != 0) { throw new IllegalArgumentException(StrUtil.blankToDefault(responseJson.getStr("message"), "获取发票信息失败")); } diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallOrderQueryOutboundService.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallOrderQueryOutboundService.java index d6a079a2..f437aeff 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallOrderQueryOutboundService.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallOrderQueryOutboundService.java @@ -2,6 +2,7 @@ package com.budwk.app.zhgh.pointsmall.mallbridge.service; import cn.hutool.core.util.StrUtil; import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallOrderQueryDTO; import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallOutboundResult; @@ -85,6 +86,31 @@ public class MallOrderQueryOutboundService { .execute() .body(); log.info("9.2.2 获取订单详情调用结束,返回报文:{}", response); - return JSONUtil.toBean(response, MallOutboundResult.class); + JSONObject payload = JSONUtil.parseObj(response); + if (!payload.containsKey("resultCode")) { + JSONObject data = payload.getJSONObject("data"); + JSONObject body = data == null ? null : data.getJSONObject("Body"); + if (body == null) { + return MallOutboundResult.fail(502, "获取订单详情返回报文格式异常"); + } + JSONObject header = body.getJSONObject("RspSvcHeader"); + if (header == null || !"000000000000".equals(header.getStr("ReturnCode"))) { + return MallOutboundResult.fail(502, header == null ? "BAB7返回服务头缺失" : + StrUtil.blankToDefault(header.getStr("ReturnMsg"), "BAB7获取订单详情失败")); + } + JSONObject serviceBody = body.getJSONObject("RspSvcBody"); + if (serviceBody == null || !"200".equals(serviceBody.getStr("ReturnStCd"))) { + return MallOutboundResult.fail(502, "BAB7调用供应商订单详情接口失败"); + } + String content = serviceBody.getStr("ReturnCntnt"); + if (StrUtil.isBlank(content)) { + return MallOutboundResult.fail(502, "供应商订单详情返回内容为空"); + } + payload = JSONUtil.parseObj(content); + } + if (payload.getInt("resultCode") == null) { + return MallOutboundResult.fail(502, "供应商订单详情返回状态缺失"); + } + return JSONUtil.toBean(payload, MallOutboundResult.class); } } diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallReconciliationInfoQueryService.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallReconciliationInfoQueryService.java index adc283e9..70891998 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallReconciliationInfoQueryService.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/MallReconciliationInfoQueryService.java @@ -69,26 +69,8 @@ public class MallReconciliationInfoQueryService { .body(JSONUtil.toJsonStr(bodyMap)) .execute() .body(); - if (response == null) { - return Collections.emptyList(); - } - - JSONObject returnResult = JSONUtil.parseObj(response); - log.info("通过对账接口获取对账订单数据,响应结果:{}", returnResult); - if ("-1".equals(returnResult.getStr("resultCode"))) { - throw new IllegalArgumentException("查询对账信息异常:" + returnResult); - } - - MallOutboundPageResult mallOutboundPageResult = JSONUtil.toBean(returnResult, MallOutboundPageResult.class); - if (mallOutboundPageResult == null) { - return Collections.emptyList(); - } - - // 错误码为0表示查询成功,不等于0表示查询失败 - Integer resultCode = mallOutboundPageResult.getResultCode(); - if (resultCode != 0) { - log.info("通过对账接口获取对账订单数据,查询失败:{}", dto); - } + log.info("通过对账接口获取对账订单数据,响应结果:{}", response); + MallOutboundPageResult mallOutboundPageResult = parseReconciliationResponse(response); if (CollUtil.isEmpty(mallOutboundPageResult.getOrderInfos())) { return Collections.emptyList(); } @@ -109,11 +91,10 @@ public class MallReconciliationInfoQueryService { .body(JSONUtil.toJsonStr(bodyMap)) .execute() .body(); - mallOutboundPageResult = JSONUtil.toBean(response, MallOutboundPageResult.class); + mallOutboundPageResult = parseReconciliationResponse(response); log.info("9.2.4 对账接口-分页循环拉取,返回报文:{}", mallOutboundPageResult); - // 错误码为0表示查询成功,不等于0表示查询失败 - if (mallOutboundPageResult.getResultCode() != 0) { - log.info("通过对账接口获取对账订单数据,查询失败:{}", dto); + if (CollUtil.isEmpty(mallOutboundPageResult.getOrderInfos())) { + throw new IllegalArgumentException("供应商对账分页数据为空,页码:" + dto.getPage()); } orderInfoList.addAll(mallOutboundPageResult.getOrderInfos()); page++; @@ -123,6 +104,49 @@ public class MallReconciliationInfoQueryService { return orderInfoList; } + /** + * 解析 BAB7 包装或供应商直接返回的对账报文,并校验查询结果。 + */ + private MallOutboundPageResult parseReconciliationResponse(String response) { + if (StrUtil.isBlank(response)) { + throw new IllegalArgumentException("获取对账信息返回报文为空"); + } + JSONObject payload = JSONUtil.parseObj(response); + if (!payload.containsKey("resultCode")) { + JSONObject data = payload.getJSONObject("data"); + JSONObject body = data == null ? null : data.getJSONObject("Body"); + if (body == null) { + throw new IllegalArgumentException("获取对账信息返回报文格式异常"); + } + JSONObject header = body.getJSONObject("RspSvcHeader"); + if (header == null || !"000000000000".equals(header.getStr("ReturnCode"))) { + throw new IllegalArgumentException(header == null ? "BAB7返回服务头缺失" : + StrUtil.blankToDefault(header.getStr("ReturnMsg"), "BAB7获取对账信息失败")); + } + JSONObject serviceBody = body.getJSONObject("RspSvcBody"); + if (serviceBody == null || !"200".equals(serviceBody.getStr("ReturnStCd"))) { + throw new IllegalArgumentException("BAB7调用供应商对账接口失败"); + } + String content = serviceBody.getStr("ReturnCntnt"); + if (StrUtil.isBlank(content)) { + throw new IllegalArgumentException("供应商对账接口返回内容为空"); + } + payload = JSONUtil.parseObj(content); + } + Integer resultCode = payload.getInt("resultCode"); + if (resultCode == null) { + throw new IllegalArgumentException("供应商对账接口返回状态缺失"); + } + if (resultCode != 0) { + throw new IllegalArgumentException(StrUtil.blankToDefault(payload.getStr("message"), "供应商对账查询失败")); + } + MallOutboundPageResult result = JSONUtil.toBean(payload, MallOutboundPageResult.class); + if (CollUtil.isNotEmpty(result.getOrderInfos()) && (result.getTotalPage() == null || result.getTotalPage() < 1)) { + throw new IllegalArgumentException("供应商对账接口返回总页数无效"); + } + return result; + } + /** * 组装请求报文 * diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/support/AbstractMallBridgeSupport.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/support/AbstractMallBridgeSupport.java index 0be4563d..b9c2b7ce 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/support/AbstractMallBridgeSupport.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/service/support/AbstractMallBridgeSupport.java @@ -34,29 +34,77 @@ import java.util.stream.Collectors; *

只放通用转换和常量,具体接口业务放在各自服务中。

*/ public abstract class AbstractMallBridgeSupport { + /** + * 访问令牌有效期,单位为秒(1 小时)。 + */ protected static final long ACCESS_EXPIRE_SECONDS = 3600; + /** + * 刷新令牌有效期,单位为秒(7 天)。 + */ protected static final long REFRESH_EXPIRE_SECONDS = 86400L * 7; + /** + * 订单状态:待支付。 + */ protected static final int ORDER_PENDING_PAY = 0; + /** + * 订单状态:已支付。 + */ protected static final int ORDER_FINISH_PAY = 1; + /** + * 订单状态:处理中。 + */ protected static final int ORDER_IN_PROGRESS = 2; + /** + * 订单状态:已取消。 + */ protected static final int ORDER_CANCELLED = 3; + /** + * 订单状态:已收货。 + */ protected static final int ORDER_RECEIVED = 4; + /** + * 订单状态:已完成。 + */ protected static final int ORDER_COMPLETED = 5; + /** + * 订单状态:退换货。 + */ protected static final int ORDER_EXCHANGE = 6; + /** + * 订单状态:已退款。 + */ protected static final int ORDER_REFUNDED = 7; + /** + * 订单状态:已作废。 + */ protected static final int ORDER_ABOLISH = 8; + /** + * 供桥接服务查询和保存用户、订单、商品等数据的 DAO。 + */ protected final Dao dao; + /** + * 初始化桥接公共支撑类,复用业务服务传入的 DAO。 + */ protected AbstractMallBridgeSupport(Dao dao) { this.dao = dao; } + /** + * 检查订单事件及供应商、订单、主订单、用户标识是否齐全;不校验对应数据是否存在。 + */ protected boolean hasRequiredOrderEventFields(MallOrderEventDTO dto) { return dto != null && !StrUtil.hasBlank(dto.getSupplierId(), dto.getOrderId(), dto.getMainOrderId(), dto.getUserId()); } + /** + * 根据对外用户虚拟 ID 查询未禁用、未删除的系统用户。 + * + * @param virtualId 供应商接口传入的用户虚拟 ID,不是系统用户主键 + * @return 符合条件的用户;虚拟 ID 为空或用户不存在时返回 null + */ protected Sys_user fetchUser(String virtualId) { if (StrUtil.isBlank(virtualId)) { return null; @@ -65,6 +113,16 @@ public abstract class AbstractMallBridgeSupport { .and("disabled", "=", false).and("delFlag", "=", false)); } + /** + * 将退换货事件和详情转换为退换货记录,并从原子单补充商品图片及文件信息。 + * + * @param dto 订单事件,其中 userId 为用户虚拟 ID,保存时转换为系统用户主键 + * @param orderInfo 供应商返回的退换货单详情 + * @param sub 原子单,提供商品扩展信息 + * @param orderStatus 待保存的退换货订单状态 + * @return 尚未入库的退换货记录 + * @throws IllegalArgumentException 虚拟 ID 对应的有效用户不存在时抛出 + */ protected PointsMallOrderExchange toExchange(MallOrderEventDTO dto, OrderInfoDTO orderInfo, PointsMallOrderSub sub, Integer orderStatus) { Sys_user user = fetchUser(dto.getUserId()); if (user == null) { @@ -94,6 +152,9 @@ public abstract class AbstractMallBridgeSupport { return exchange; } + /** + * 按 SKU 将原子单的图片及文件信息覆盖到传入商品列表中;原子单重复 SKU 取首项,传入列表为空时返回空列表。 + */ protected List mergeProductInfo(List products, String subExtJson) { if (products == null || products.isEmpty()) { return Collections.emptyList(); @@ -115,6 +176,15 @@ public abstract class AbstractMallBridgeSupport { return products; } + /** + * 将供应商订单详情转换为主订单,金额为空时按零处理,现金支付标记初始化为 0。 + * + * @param supplierId 供应商标识 + * @param userId 已由虚拟 ID 查得的系统用户主键 + * @param orderInfo 供应商返回的订单详情 + * @param state 主订单状态 + * @return 尚未入库的主订单 + */ protected PointsMallOrderMain toMain(String supplierId, String userId, OrderInfoDTO orderInfo, Integer state) { PointsMallOrderMain main = new PointsMallOrderMain(); main.setOrderId(orderInfo.getOrderId()); @@ -142,6 +212,9 @@ public abstract class AbstractMallBridgeSupport { return main; } + /** + * 从主订单复制信息生成子订单;子订单号为空时使用主订单号,更新时间取当前时间,对账和发票状态初始化为 0。 + */ protected PointsMallOrderSub toSub(PointsMallOrderMain main, String subOrderId) { PointsMallOrderSub sub = new PointsMallOrderSub(); sub.setOrderId(StrUtil.blankToDefault(subOrderId, main.getOrderId())); @@ -171,6 +244,9 @@ public abstract class AbstractMallBridgeSupport { return sub; } + /** + * 将商品逐条保存到指定子订单,仅保存图片列表中的首张图片;商品列表为 null 时不处理。 + */ protected void insertProducts(String orderSubId, List products) { if (products == null) { return; @@ -188,6 +264,9 @@ public abstract class AbstractMallBridgeSupport { } } + /** + * 将查询记录转换为对外订单详情,统一日期和金额格式,并读取订单商品信息。 + */ protected OrderInfoDTO toOrderInfo(Record record) { OrderInfoDTO dto = new OrderInfoDTO(); dto.setOrderId(record.getString("orderId")); @@ -215,6 +294,9 @@ public abstract class AbstractMallBridgeSupport { return dto; } + /** + * 优先读取订单下未删除的子单商品;无商品记录时从 extJson 解析,扩展信息为空或为 null 字符串时返回空列表。 + */ protected List readProducts(String orderId, String extJson) { List products = dao.query(PointsMallOrderSubProduct.class, Cnd.where("orderSubId", "=", orderId).and("delFlag", "=", false)); if (!products.isEmpty()) { @@ -226,6 +308,9 @@ public abstract class AbstractMallBridgeSupport { return JSONUtil.toList(extJson, OrderProInfoDTO.class); } + /** + * 将子单商品转换为对外商品信息,单张图片包装为列表,并以 SKU 和图片地址填充文件标识及路径。 + */ protected OrderProInfoDTO toProductDTO(PointsMallOrderSubProduct product) { OrderProInfoDTO dto = new OrderProInfoDTO(); dto.setSku(product.getSku()); @@ -239,6 +324,9 @@ public abstract class AbstractMallBridgeSupport { return dto; } + /** + * 将发票记录转换为对外发票信息,并将开票时间转换为本地日期。 + */ protected InvoiceInfoDTO toInvoiceInfoDTO(PointsMallInvoiceInfo info) { InvoiceInfoDTO dto = new InvoiceInfoDTO(); dto.setInvoiceId(info.getInvoiceId()); @@ -257,6 +345,9 @@ public abstract class AbstractMallBridgeSupport { return dto; } + /** + * 解析日期字符串,将日期时间分隔符 T 替换为空格;空白值返回 null,非法日期由日期工具抛出异常。 + */ protected Date parseDate(String value) { if (StrUtil.isBlank(value)) { return null; @@ -264,6 +355,9 @@ public abstract class AbstractMallBridgeSupport { return DateUtil.parse(value.replace("T", " ")); } + /** + * 将日期值统一格式化为 yyyy-MM-dd HH:mm:ss;null 值返回 null。 + */ protected String formatDate(Object value) { if (value == null) { return null; @@ -271,10 +365,16 @@ public abstract class AbstractMallBridgeSupport { return DateUtil.format(Convert.toDate(value), "yyyy-MM-dd HH:mm:ss"); } + /** + * 使用系统默认时区将时间转换为日期;null 值返回 null。 + */ protected LocalDate toLocalDate(Date date) { return date == null ? null : date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); } + /** + * 拆分逗号分隔的标识,去除首尾空白、空项和重复项,保留首次出现的顺序;空白值返回空列表。 + */ protected List splitIds(String value) { if (StrUtil.isBlank(value)) { return Collections.emptyList(); @@ -286,18 +386,30 @@ public abstract class AbstractMallBridgeSupport { .collect(Collectors.toList()); } + /** + * 金额为 null 时返回零,否则保留原值。 + */ protected BigDecimal nvl(BigDecimal value) { return value == null ? BigDecimal.ZERO : value; } + /** + * 金额为 null 时返回指定默认值,否则保留原值。 + */ protected BigDecimal nvl(BigDecimal value, BigDecimal defaultValue) { return value == null ? defaultValue : value; } + /** + * 将对象转换为金额,无法转换或值为 null 时使用零作为默认值。 + */ protected BigDecimal decimal(Object value) { return Convert.toBigDecimal(value, BigDecimal.ZERO); } + /** + * 将字符串转换为整数;空白值或无法转换的值返回 null。 + */ protected Integer parseInteger(String value) { if (StrUtil.isBlank(value)) { return null; diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/util/MallBridgeResponseUtil.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/util/MallBridgeResponseUtil.java new file mode 100644 index 00000000..3d1c66c1 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/util/MallBridgeResponseUtil.java @@ -0,0 +1,37 @@ +package com.budwk.app.zhgh.pointsmall.mallbridge.util; + +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; + +/** 提取供应商业务响应,兼容 BAB7 包装报文。 */ +public class MallBridgeResponseUtil { + public static JSONObject parse(String response) { + if (StrUtil.isBlank(response)) { + throw new IllegalArgumentException("供应商接口返回为空"); + } + JSONObject payload = JSONUtil.parseObj(response); + if (!payload.containsKey("resultCode")) { + JSONObject data = payload.getJSONObject("data"); + JSONObject body = data == null ? null : data.getJSONObject("Body"); + JSONObject header = body == null ? null : body.getJSONObject("RspSvcHeader"); + if (header == null || !"000000000000".equals(header.getStr("ReturnCode"))) { + throw new IllegalArgumentException(header == null ? "BAB7返回报文格式异常" : + StrUtil.blankToDefault(header.getStr("ReturnMsg"), "BAB7调用失败")); + } + JSONObject serviceBody = body.getJSONObject("RspSvcBody"); + if (serviceBody == null || !"200".equals(serviceBody.getStr("ReturnStCd"))) { + throw new IllegalArgumentException("BAB7调用供应商接口失败"); + } + String content = serviceBody.getStr("ReturnCntnt"); + if (StrUtil.isBlank(content)) { + throw new IllegalArgumentException("供应商业务响应为空"); + } + payload = JSONUtil.parseObj(content); + } + if (payload.getInt("resultCode") == null) { + throw new IllegalArgumentException("供应商业务响应缺少结果码"); + } + return payload; + } +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/reconciliation/param/PointsMallReconciliationParam.java b/src/main/java/com/budwk/app/zhgh/pointsmall/reconciliation/param/PointsMallReconciliationParam.java index 04c3164a..8a81f2a4 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/reconciliation/param/PointsMallReconciliationParam.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/reconciliation/param/PointsMallReconciliationParam.java @@ -8,6 +8,10 @@ public class PointsMallReconciliationParam { private String supplierId; private Integer reconciliationType; private String orderId; + private String queryOrderId; + private String userId; + private Integer reconciliationStatus; + private Integer invoiceStatus; private String startDate; private String endDate; } diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/reconciliation/service/impl/PointsMallReconciliationServiceImpl.java b/src/main/java/com/budwk/app/zhgh/pointsmall/reconciliation/service/impl/PointsMallReconciliationServiceImpl.java index ca3edacc..d5563d73 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/reconciliation/service/impl/PointsMallReconciliationServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/reconciliation/service/impl/PointsMallReconciliationServiceImpl.java @@ -91,32 +91,28 @@ public class PointsMallReconciliationServiceImpl extends BaseServiceImpl orderIdList = null; - // 校验参数 - if (reconciliationType == 1) { - if (StrUtil.isBlank(reconciliationBO.getStartDate())) { - return Result.error("请选择开始日期"); - } - } else if (reconciliationType == 2) { // 历史异常订单对账 - if (StrUtil.isBlank(reconciliationBO.getOrderId())) { - return Result.error("订单号不能为空"); - } - orderIdList = StrUtil.splitTrim(reconciliationBO.getOrderId(), ","); - } else { - return Result.error("对账类型不正确"); + try { + checkReconciliationParam(reconciliationBO); + } catch (IllegalArgumentException e) { + return Result.error(e.getMessage()); } + Integer reconciliationType = reconciliationBO.getReconciliationType(); // 从浦发积分商城订单表查询对账订单 List orderInfoList = dao().query(PointsMallOrderSub.class, reconciliationCnd(reconciliationBO, "")); if (CollUtil.isEmpty(orderInfoList)) { return Result.error("浦发积分商城没有查询到对账订单数据"); } + Set orderIdList = orderInfoList.stream().map(PointsMallOrderSub::getOrderId).collect(Collectors.toSet()); + if (StrUtil.isNotBlank(reconciliationBO.getOrderId()) + && !orderIdList.containsAll(StrUtil.splitTrim(reconciliationBO.getOrderId(), ","))) { + return Result.error("部分勾选订单已不符合对账条件,请重新查询后选择"); + } QueryReconciliationInfoDTO queryReconciliationInfoDTO = new QueryReconciliationInfoDTO(); queryReconciliationInfoDTO.setSupplierId(reconciliationBO.getSupplierId()); queryReconciliationInfoDTO.setReconciliationType(reconciliationType); - queryReconciliationInfoDTO.setOrderId(orderIdList == null ? reconciliationBO.getOrderId() : String.join(",", orderIdList)); + queryReconciliationInfoDTO.setOrderId(String.join(",", orderIdList)); queryReconciliationInfoDTO.setStartDate(reconciliationBO.getStartDate()); queryReconciliationInfoDTO.setEndDate(reconciliationBO.getEndDate()); queryReconciliationInfoDTO.setPage(1); @@ -126,6 +122,7 @@ public class PointsMallReconciliationServiceImpl extends BaseServiceImpl orderIdList.contains(o.getOrderId())).collect(Collectors.toList()); String supplierId = reconciliationBO.getSupplierId(); result.forEach(o -> o.setSupplierId(supplierId)); // 根据供应商ID + 订单ID进行分组 @@ -291,22 +288,23 @@ public class PointsMallReconciliationServiceImpl extends BaseServiceImpl 1) { - cnd.and(field(alias, "orderId"), "in", orderIds); - } else { - cnd.and(field(alias, "orderId"), "like", "%" + param.getOrderId() + "%"); - } + cnd.and(field(alias, "orderId"), "in", StrUtil.splitTrim(param.getOrderId(), ",")); } - addDateRange(cnd, alias, param.getStartDate(), param.getEndDate()); return cnd; } @@ -336,8 +334,8 @@ public class PointsMallReconciliationServiceImpl extends BaseServiceImpl - - - - - - - 开票申请 - 可开票订单 @@ -36,13 +28,11 @@ layout("/layouts/platform.html"){ {{ invoiceResultName(row.bSuccess) }} - - - - + @@ -58,114 +48,18 @@ layout("/layouts/platform.html"){ > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{ orderTotalPoints }} - 计算 - - - - 取消 - 提交申请 - - - - - - - - - - - - - - - - - - - - - - - - - 查询 - 重置 - 用于开票 - - - - + + + - + + +