From 1cbacf987da4f3b13558c45336871876076b0c37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=8C=E5=85=88=E8=88=9C?= <2499071264@qq.com> Date: Wed, 29 Jul 2026 18:22:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=A7=AF=E5=88=86=E5=95=86=E5=9F=8E-?= =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E5=AE=9E=E7=8E=B0=E6=8B=86=E5=8D=95=E3=80=81?= =?UTF-8?q?=E7=A1=AE=E8=AE=A4=E6=94=B6=E8=B4=A72?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../h5/order/PointsMallH5OrderController.java | 6 - .../MallAbolishSubOrderEventHandler.java | 3 +- .../MallCancelSubOrderEventHandler.java | 3 +- .../MallConfirmReceiptEventHandler.java | 7 +- .../handlers/MallExchangeSubEventHandler.java | 3 +- .../MallSubOrderReturnEventHandler.java | 3 +- .../service/MallInboundEventService.java | 70 +++- .../order/enums/MallOrderStatusEnum.java | 48 +++ .../order/service/PointsMallOrderService.java | 5 +- .../impl/PointsMallOrderServiceImpl.java | 328 ++++++++++++++--- .../order/vo/PointsMallMobileOrderVO.java | 87 +++++ .../zhghh5/points-mall/order/index.html | 330 ++++++++++++------ 12 files changed, 710 insertions(+), 183 deletions(-) create mode 100644 src/main/java/com/budwk/app/zhgh/pointsmall/order/enums/MallOrderStatusEnum.java create mode 100644 src/main/java/com/budwk/app/zhgh/pointsmall/order/vo/PointsMallMobileOrderVO.java diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/h5/order/PointsMallH5OrderController.java b/src/main/java/com/budwk/app/zhgh/pointsmall/h5/order/PointsMallH5OrderController.java index cd260f7c..b2392a7a 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/h5/order/PointsMallH5OrderController.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/h5/order/PointsMallH5OrderController.java @@ -26,12 +26,6 @@ public class PointsMallH5OrderController { public void index() { } - @At("/stateList") - @SaCheckPermission("h5.points.mall") - public Result stateList() { - return Result.success(pointsMallOrderService.mobileOrderStates()); - } - @At("/pageData") @SaCheckPermission("h5.points.mall") public Result pageData(PointsMallMobileOrderPageParam param) { diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallAbolishSubOrderEventHandler.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallAbolishSubOrderEventHandler.java index 10a88205..b4b8854c 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallAbolishSubOrderEventHandler.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallAbolishSubOrderEventHandler.java @@ -4,6 +4,7 @@ import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallOrderEventDTO; import com.budwk.app.zhgh.pointsmall.mallbridge.event.MallOrderEventHandler; import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundResult; import com.budwk.app.zhgh.pointsmall.mallbridge.service.MallInboundEventService; +import com.budwk.app.zhgh.pointsmall.order.enums.MallOrderStatusEnum; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; @@ -24,6 +25,6 @@ public class MallAbolishSubOrderEventHandler implements MallOrderEventHandler { @Override public MallInboundResult handle(MallOrderEventDTO dto) { - return inboundEventService.updateSubOrderStatus(dto, MallInboundEventService.ORDER_ABOLISH); + return inboundEventService.updateSubOrderStatus(dto, MallOrderStatusEnum.ABOLISH); } } diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallCancelSubOrderEventHandler.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallCancelSubOrderEventHandler.java index 29d5e13a..2618ae14 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallCancelSubOrderEventHandler.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallCancelSubOrderEventHandler.java @@ -4,6 +4,7 @@ import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallOrderEventDTO; import com.budwk.app.zhgh.pointsmall.mallbridge.event.MallOrderEventHandler; import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundResult; import com.budwk.app.zhgh.pointsmall.mallbridge.service.MallInboundEventService; +import com.budwk.app.zhgh.pointsmall.order.enums.MallOrderStatusEnum; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; @@ -24,6 +25,6 @@ public class MallCancelSubOrderEventHandler implements MallOrderEventHandler { @Override public MallInboundResult handle(MallOrderEventDTO dto) { - return inboundEventService.updateSubOrderStatus(dto, MallInboundEventService.ORDER_CANCELLED); + return inboundEventService.updateSubOrderStatus(dto, MallOrderStatusEnum.CANCELLED); } } diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallConfirmReceiptEventHandler.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallConfirmReceiptEventHandler.java index 35d54853..246f65fd 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallConfirmReceiptEventHandler.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallConfirmReceiptEventHandler.java @@ -4,12 +4,17 @@ import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallOrderEventDTO; import com.budwk.app.zhgh.pointsmall.mallbridge.event.MallOrderEventHandler; import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundResult; import com.budwk.app.zhgh.pointsmall.mallbridge.service.MallInboundEventService; +import com.budwk.app.zhgh.pointsmall.order.enums.MallOrderStatusEnum; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; /** * MallConfirmReceiptEventHandler * orderType=6: 确认收货事件处理器。 + * 行为: 根据子单外部ID更新子单状态为已妥投(电商处已收货待用户callP侧确认收货)。 + * + *

注意:供应商侧“确认收货”对应 zhgh/callP 侧“已妥投(4)”, + * 不等同于 zhgh/callP 用户确认收货后的“已完成(5)”。

*/ @IocBean public class MallConfirmReceiptEventHandler implements MallOrderEventHandler { @@ -24,6 +29,6 @@ public class MallConfirmReceiptEventHandler implements MallOrderEventHandler { @Override public MallInboundResult handle(MallOrderEventDTO dto) { - return inboundEventService.updateSubOrderStatus(dto, MallInboundEventService.ORDER_COMPLETED); + return inboundEventService.updateSubOrderStatus(dto, MallOrderStatusEnum.RECEIVED); } } diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallExchangeSubEventHandler.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallExchangeSubEventHandler.java index f70ac17d..e381d1d7 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallExchangeSubEventHandler.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallExchangeSubEventHandler.java @@ -4,6 +4,7 @@ import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallOrderEventDTO; import com.budwk.app.zhgh.pointsmall.mallbridge.event.MallOrderEventHandler; import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundResult; import com.budwk.app.zhgh.pointsmall.mallbridge.service.MallInboundEventService; +import com.budwk.app.zhgh.pointsmall.order.enums.MallOrderStatusEnum; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; @@ -24,6 +25,6 @@ public class MallExchangeSubEventHandler implements MallOrderEventHandler { @Override public MallInboundResult handle(MallOrderEventDTO dto) { - return inboundEventService.updateSubOrderStatus(dto, MallInboundEventService.ORDER_EXCHANGE); + return inboundEventService.updateSubOrderStatus(dto, MallOrderStatusEnum.EXCHANGE); } } diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallSubOrderReturnEventHandler.java b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallSubOrderReturnEventHandler.java index 40abcee8..24f53cea 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallSubOrderReturnEventHandler.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/mallbridge/event/handlers/MallSubOrderReturnEventHandler.java @@ -4,6 +4,7 @@ import com.budwk.app.zhgh.pointsmall.mallbridge.dto.MallOrderEventDTO; import com.budwk.app.zhgh.pointsmall.mallbridge.event.MallOrderEventHandler; import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundResult; import com.budwk.app.zhgh.pointsmall.mallbridge.service.MallInboundEventService; +import com.budwk.app.zhgh.pointsmall.order.enums.MallOrderStatusEnum; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; @@ -24,6 +25,6 @@ public class MallSubOrderReturnEventHandler implements MallOrderEventHandler { @Override public MallInboundResult handle(MallOrderEventDTO dto) { - return inboundEventService.updateSubOrderStatus(dto, MallInboundEventService.ORDER_REFUNDED); + return inboundEventService.updateSubOrderStatus(dto, MallOrderStatusEnum.REFUNDED); } } 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 0396b89e..5844f3df 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 @@ -19,6 +19,7 @@ import com.budwk.app.zhgh.pointsmall.mallbridge.event.handlers.MallSubOrderRetur import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallInboundResult; import com.budwk.app.zhgh.pointsmall.mallbridge.model.MallOutboundResult; import com.budwk.app.zhgh.pointsmall.mallbridge.service.support.AbstractMallBridgeSupport; +import com.budwk.app.zhgh.pointsmall.order.enums.MallOrderStatusEnum; import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderMain; import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderSub; import com.budwk.app.zhgh.pointsmall.points.service.PointsMallPointsLockService; @@ -46,12 +47,6 @@ import java.util.Map; @IocBean(args = {"refer:dao"}) public class MallInboundEventService extends AbstractMallBridgeSupport { - public static final int ORDER_CANCELLED = 3; - public static final int ORDER_COMPLETED = 5; - public static final int ORDER_EXCHANGE = 6; - public static final int ORDER_REFUNDED = 7; - public static final int ORDER_ABOLISH = 8; - @Inject private PointsMallPointsLockService pointsMallPointsLockService; @Inject @@ -269,7 +264,18 @@ public class MallInboundEventService extends AbstractMallBridgeSupport { return sub; } - public MallInboundResult updateSubOrderStatus(MallOrderEventDTO dto, int state) { + /** + * 更新子单状态。 + * + *

订单类型为:6(确认收货)时,供应商侧“确认收货”对应 zhgh/callP 侧“已妥投(4)”, + * 需重新调用 9.2.2 获取订单详情接口,补充确认收货时间、发货时间、商品信息等字段。

+ * + * @param dto 请求参数 + * @param statusEnum zhgh/callP 侧订单状态枚举 + * @return 操作结果 + */ + public MallInboundResult updateSubOrderStatus(MallOrderEventDTO dto, MallOrderStatusEnum statusEnum) { + Integer state = statusEnum.getCode(); PointsMallOrderSub sub = dao.fetch(PointsMallOrderSub.class, Cnd.where("supplierId", "=", dto.getSupplierId()) .and("orderId", "=", dto.getOrderId()).and("delFlag", "=", false)); if (sub == null) { @@ -280,19 +286,24 @@ public class MallInboundEventService extends AbstractMallBridgeSupport { return MallInboundResult.success(); } Trans.exec((Atom) () -> { + if (statusEnum == MallOrderStatusEnum.RECEIVED) { + fillReceivedSubOrder(dto, sub); + } sub.setOrderState(state); - sub.setOrderUpdateTime(new Date()); - if (state == ORDER_RECEIVED) { + if (statusEnum != MallOrderStatusEnum.RECEIVED || sub.getOrderUpdateTime() == null) { + sub.setOrderUpdateTime(new Date()); + } + if (statusEnum == MallOrderStatusEnum.RECEIVED && sub.getOrderFinishTime() == null) { sub.setOrderFinishTime(new Date()); } - if (state == ORDER_COMPLETED) { + if (statusEnum == MallOrderStatusEnum.COMPLETED) { sub.setOrderCompleteTime(new Date()); } dao.updateIgnoreNull(sub); - if (state == ORDER_CANCELLED || state == ORDER_REFUNDED || state == ORDER_ABOLISH) { + if (statusEnum == MallOrderStatusEnum.CANCELLED || statusEnum == MallOrderStatusEnum.REFUNDED || statusEnum == MallOrderStatusEnum.ABOLISH) { pointsMallPointsLockService.releaseOrReturnSub(sub, state, nvl(sub.getRefund(), BigDecimal.ZERO)); } - if (state == ORDER_COMPLETED) { + if (statusEnum == MallOrderStatusEnum.COMPLETED) { pointsMallPointsLockService.deductCompletedSub(sub); } }); @@ -300,6 +311,41 @@ public class MallInboundEventService extends AbstractMallBridgeSupport { return MallInboundResult.success(); } + /** + * 订单类型为:6(确认收货)时,调用 9.2.2 获取订单详情接口,补充子单妥投相关信息。 + * + *

供应商侧确认收货只代表电商处已收货,对 zhgh/callP 侧应更新为已妥投(4), + * 等待 callP 用户侧确认收货后才进入已完成(5)。

+ */ + private void fillReceivedSubOrder(MallOrderEventDTO dto, PointsMallOrderSub sub) { + if (mallOrderQueryOutboundService == null) { + return; + } + MallOrderQueryDTO queryDTO = new MallOrderQueryDTO(); + queryDTO.setSupplierId(dto.getSupplierId()); + queryDTO.setOrderId(dto.getOrderId()); + queryDTO.setOrderType(2); + log.info("订单类型为:6(确认收货)时,调用9.2.2获取订单详情接口:{}", queryDTO); + try { + MallOutboundResult result = mallOrderQueryOutboundService.queryOrderInfo(queryDTO); + if (result == null || result.getResultCode() != 0 || result.getOrderInfo() == null || result.getOrderInfo().isEmpty()) { + log.error("订单类型为:6(确认收货)时,调用9.2.2 获取订单详情失败:{},{}", queryDTO, result == null ? null : result.getMessage()); + return; + } + OrderInfoDTO orderInfo = result.getOrderInfo().get(0); + sub.setOrderCreateTime(parseDate(orderInfo.getCreateTime())); + sub.setOrderUpdateTime(parseDate(orderInfo.getUpdateTime())); + sub.setOrderFinishTime(parseDate(orderInfo.getOrderFinishTime())); + sub.setDeliveryTime(parseDate(orderInfo.getDeliveryTime())); + sub.setDeliveryStatus(parseInteger(orderInfo.getDeliveryStatus())); + if (orderInfo.getOrderProInfos() != null) { + sub.setExtJson(JSONUtil.toJsonStr(orderInfo.getOrderProInfos())); + } + } catch (Exception e) { + log.error("订单类型为:6(确认收货)时,调用9.2.2 获取订单详情异常:{},{}", queryDTO, e.getMessage()); + } + } + public MallInboundResult invoiceInfo(MallOrderEventDTO dto) { String mainOrderId = StrUtil.blankToDefault(dto.getMainOrderId(), dto.getOrderId()); if (StrUtil.isBlank(mainOrderId)) { diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/order/enums/MallOrderStatusEnum.java b/src/main/java/com/budwk/app/zhgh/pointsmall/order/enums/MallOrderStatusEnum.java new file mode 100644 index 00000000..372b7473 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/order/enums/MallOrderStatusEnum.java @@ -0,0 +1,48 @@ +package com.budwk.app.zhgh.pointsmall.order.enums; + +import lombok.Getter; + +/** + * 积分商城订单状态枚举。 + * + *

zhgh/callP 侧订单状态与供应商商城订单状态是两套规则,不能混用。

+ */ +@Getter +public enum MallOrderStatusEnum { + // 待付款 - 主单状态 + PENDING_PAY(0, "待付款", false), + + // 已支付 - 主单状态 + FINISH_PAY(1, "已支付", false), + + // 进行中 - 子单状态 + IN_PROGRESS(2, "进行中", true), + + // 已取消 - 主单子单状态 + CANCELLED(3, "已取消", true), + + // 已妥投(电商处已收货待用户callP侧确认收货) + RECEIVED(4, "已妥投", true), + + // 已完成(callP侧用户确认收货) + COMPLETED(5, "已完成", true), + + // 已换货(退货换货表的订单状态) + EXCHANGE(6, "换货", true), + + // 已退货(退货换货表的订单状态) + REFUNDED(7, "退货", true), + + // 已废除 + ABOLISH(8, "废除", false); + + private final Integer code; + private final String description; + private final Boolean isSaveHis; + + MallOrderStatusEnum(Integer code, String description, Boolean isSaveHis) { + this.code = code; + this.description = description; + this.isSaveHis = isSaveHis; + } +} diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/order/service/PointsMallOrderService.java b/src/main/java/com/budwk/app/zhgh/pointsmall/order/service/PointsMallOrderService.java index b18def96..0784e429 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/order/service/PointsMallOrderService.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/order/service/PointsMallOrderService.java @@ -9,6 +9,7 @@ import com.budwk.app.zhgh.pointsmall.order.param.PointsMallMobileOrderReceivedPa import com.budwk.app.zhgh.pointsmall.order.param.PointsMallMobileOrderPageParam; import com.budwk.app.zhgh.pointsmall.supplier.models.PointsMallSupplier; import com.budwk.app.zhgh.pointsmall.order.param.PointsMallOrderPageParam; +import com.budwk.app.zhgh.pointsmall.order.vo.PointsMallMobileOrderVO; import org.nutz.dao.entity.Record; import java.util.List; @@ -19,9 +20,7 @@ public interface PointsMallOrderService extends BaseService Pagination pageSub(PointsMallOrderPageParam param); - Pagination mobileOrderPage(PointsMallMobileOrderPageParam param, String defaultUserId); - - List mobileOrderStates(); + Pagination mobileOrderPage(PointsMallMobileOrderPageParam param, String defaultUserId); Record supplierOrderUrl(String supplierId, String orderId, Integer orderType); diff --git a/src/main/java/com/budwk/app/zhgh/pointsmall/order/service/impl/PointsMallOrderServiceImpl.java b/src/main/java/com/budwk/app/zhgh/pointsmall/order/service/impl/PointsMallOrderServiceImpl.java index ea0f63cc..e335a1c0 100644 --- a/src/main/java/com/budwk/app/zhgh/pointsmall/order/service/impl/PointsMallOrderServiceImpl.java +++ b/src/main/java/com/budwk/app/zhgh/pointsmall/order/service/impl/PointsMallOrderServiceImpl.java @@ -1,32 +1,45 @@ package com.budwk.app.zhgh.pointsmall.order.service.impl; import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; import com.budwk.app.base.page.Pagination; import com.budwk.app.base.service.impl.BaseServiceImpl; import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderExchange; import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderMain; import com.budwk.app.zhgh.pointsmall.order.models.PointsMallOrderSub; +import com.budwk.app.zhgh.pointsmall.order.enums.MallOrderStatusEnum; import com.budwk.app.zhgh.pointsmall.order.param.PointsMallMobileOrderPageParam; import com.budwk.app.zhgh.pointsmall.order.param.PointsMallMobileOrderReceivedParam; import com.budwk.app.zhgh.pointsmall.order.param.PointsMallOrderPageParam; import com.budwk.app.zhgh.pointsmall.order.service.PointsMallOrderService; +import com.budwk.app.zhgh.pointsmall.order.vo.PointsMallMobileOrderVO; import com.budwk.app.zhgh.pointsmall.points.service.PointsMallPointsLockService; import com.budwk.app.zhgh.pointsmall.supplier.models.PointsMallSupplier; +import lombok.extern.slf4j.Slf4j; import org.nutz.dao.Chain; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; +import org.nutz.dao.pager.Pager; import org.nutz.dao.Sqls; import org.nutz.dao.entity.Record; import org.nutz.dao.sql.Sql; +import org.nutz.dao.util.Daos; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.trans.Atom; import org.nutz.trans.Trans; -import java.util.Arrays; import java.util.Date; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +@Slf4j @IocBean(args = {"refer:dao"}) public class PointsMallOrderServiceImpl extends BaseServiceImpl implements PointsMallOrderService { @@ -77,47 +90,45 @@ public class PointsMallOrderServiceImpl extends BaseServiceImpl mobileOrderPage(PointsMallMobileOrderPageParam param, String defaultUserId) { - Cnd cnd = Cnd.where("o.delFlag", "=", false); + public Pagination mobileOrderPage(PointsMallMobileOrderPageParam param, String defaultUserId) { String userId = StrUtil.blankToDefault(param.getUserId(), defaultUserId); - if (StrUtil.isNotBlank(userId)) { - cnd.and("o.userId", "=", userId); + if (StrUtil.isBlank(userId)) { + throw new RuntimeException("用户不存在"); } - if (param.getOrderState() != null && param.getOrderState() >= 0) { - cnd.and("o.orderState", "=", param.getOrderState()); + String orderState = param.getOrderState() == null ? "-1" : String.valueOf(param.getOrderState()); + List orderStateMain = Collections.singletonList("0"); + List orderStateSub = Arrays.asList("2", "4", "5", "3"); + List orderStateExchange = Arrays.asList("7", "6"); + + // 获取供应商列表 + List supplierList = dao().query(PointsMallSupplier.class, Cnd.where("delFlag", "=", false)); + // 构建供应商键值对Map,key为supplierId,value为supplierName + Map supplierNameMap = supplierList.stream() + .collect(Collectors.toMap(PointsMallSupplier::getSupplierId, PointsMallSupplier::getSupplierName)); + + Sql sql; + if (StrUtil.equals(orderState, "-1")) { // 全部订单,走主订单查询,查询所有主订单表 + sql = getMobileOrderPageSql(userId, orderState); + } else if (orderStateMain.contains(orderState)) { // 主订单状态,走主订单查询,查询主订单表 + sql = getMobileOrderMainPageSql(userId, orderState); + } else if (orderStateSub.contains(orderState)) { // 子订单状态,走子订单查询,查询子订单表 + sql = getMobileOrderSubPageSql(userId, orderState); + } else if (orderStateExchange.contains(orderState)) { // 退换货订单状态,走退换货查询,查询退换货订单表 + sql = getMobileOrderExchangePageSql(userId, orderState); + } else { + throw new RuntimeException("订单状态不正确"); } - if (StrUtil.isNotBlank(param.getSupplierId())) { - cnd.and("o.supplierId", "=", param.getSupplierId()); - } - if (StrUtil.isNotBlank(param.getOrderId())) { - cnd.and("o.orderId", "like", "%" + param.getOrderId() + "%"); - } - cnd.desc("o.orderCreateTime"); - Sql sql = Sqls.create("select o.*, s.supplierName, s.supplierOrderUrl, s.supplierReturnOrderUrl from points_mall_order_sub o left join points_mall_supplier s on o.supplierId = s.supplierId and s.delFlag = 0 $condition"); - sql.setCondition(cnd); - Pagination page = listPage(param.getPageNumber(), param.getPageSize(), sql); - for (Record item : page.getList()) { - item.put("productImgList", productImages(item.getString("orderId"))); + + Pagination page = listMobileOrderPage(param.getPageNumber(), param.getPageSize(), sql); + for (PointsMallMobileOrderVO item : page.getList()) { + // 塞入供应商名称 + item.setSupplierName(supplierNameMap.get(item.getSupplierId())); + // 处理商品信息 + fillProductInfo(item); } return page; } - @Override - public List mobileOrderStates() { - return Arrays.asList( - state(-1, "全部"), - state(0, "待付款"), - state(1, "已支付"), - state(2, "进行中"), - state(3, "已取消"), - state(4, "已妥投"), - state(5, "已完成"), - state(6, "换货"), - state(7, "退货"), - state(8, "已废除") - ); - } - @Override public Record supplierOrderUrl(String supplierId, String orderId, Integer orderType) { PointsMallSupplier supplier = dao().fetch(PointsMallSupplier.class, Cnd.where("supplierId", "=", supplierId).and("delFlag", "=", false)); @@ -138,18 +149,39 @@ public class PointsMallOrderServiceImpl extends BaseServiceImpl { - sub.setOrderState(5); - sub.setOrderCompleteTime(new Date()); - sub.setOrderUpdateTime(new Date()); - dao().updateIgnoreNull(sub); - pointsMallPointsLockService.deductCompletedSub(sub); - }); + log.info("积分商城H5用户确认收货开始,supplierId={},userId={},orderId={}", sub.getSupplierId(), sub.getUserId(), sub.getOrderId()); + try { + Trans.exec((Atom) () -> { + Date now = new Date(); + // 使用状态条件更新,避免重复确认收货导致积分重复扣减 + int update = dao().update(PointsMallOrderSub.class, + Chain.make("orderState", MallOrderStatusEnum.COMPLETED.getCode()) + .add("orderCompleteTime", now) + .add("orderUpdateTime", now), + Cnd.where("id", "=", sub.getId()) + .and("orderState", "=", MallOrderStatusEnum.RECEIVED.getCode()) + .and("delFlag", "=", false)); + if (update <= 0) { + throw new RuntimeException("更新订单失败,请重试"); + } + sub.setOrderState(MallOrderStatusEnum.COMPLETED.getCode()); + sub.setOrderCompleteTime(now); + sub.setOrderUpdateTime(now); + // 扣除用户积分、增加记录,并同步修改主单锁定积分 + pointsMallPointsLockService.deductCompletedSub(sub); + /// 更新主订单状态,所有子单callP端确认收货后,修改主单的状态为已完成 + updateMainOrderStatus(sub.getMainOrderId(), sub.getSupplierId()); + }); + } catch (Exception e) { + log.error(">>> 积分锁定失败:", e); + throw new RuntimeException("系统繁忙,请稍后重试"); + } + log.info("积分商城H5用户确认收货完成,supplierId={},userId={},orderId={}", sub.getSupplierId(), sub.getUserId(), sub.getOrderId()); return true; } @@ -221,12 +253,202 @@ public class PointsMallOrderServiceImpl extends BaseServiceImpl productImages(String orderId) { - Sql sql = Sqls.create("select picInfo from points_mall_order_sub_product where orderSubId=@orderId and delFlag=0 and picInfo is not null and picInfo<>'' order by createdAt asc"); - sql.params().set("orderId", orderId); - sql.setCallback(Sqls.callback.strList()); + /** + * 移动端订单分页(合并主单、子单、退换货单) + */ + private Sql getMobileOrderPageSql(String userId, String orderState) { + boolean filterOrderState = StrUtil.isNotBlank(orderState) && !StrUtil.equals(orderState, "-1"); + Sql sql = Sqls.create("select " + + "id, orderId, orderNumberId, supplierId, userId, totalPrice, wPayOrAPay, pointsPrice, cashPaid, " + + "orderState, orderCreateTime, createTime, orderType, extJson " + + "from (" + + "select id, orderId, orderNumberId, supplierId, userId, totalPrice, wPayOrAPay, pointsPrice, cashPaid, " + + "orderState, orderCreateTime, createdAt as createTime, 1 as orderType, extJson " + + "from points_mall_order_main " + + "where userId=@userId and orderId not in (" + + "select distinct mainOrderId from points_mall_order_sub where userId=@userId and delFlag=0 and mainOrderId is not null" + + ") and delFlag=0 " + + "union all " + + "select id, orderId, orderNumberId, supplierId, userId, totalPrice, wPayOrAPay, pointsPrice, null as cashPaid, " + + "orderState, orderCreateTime, createdAt as createTime, 2 as orderType, extJson " + + "from points_mall_order_sub " + + "where userId=@userId and delFlag=0 and orderState != 8" + + ") as mall_order " + + "where userId=@userId " + + (filterOrderState ? "and orderState=@orderState " : "") + + "order by createTime desc, orderType"); + sql.params().set("userId", userId); + if (filterOrderState) { + sql.params().set("orderState", orderState); + } + return sql; + } + + /** + * 移动端主单分页 + */ + private Sql getMobileOrderMainPageSql(String userId, String orderState) { + boolean filterOrderState = StrUtil.isNotBlank(orderState) && !StrUtil.equals(orderState, "-1"); + Sql sql = Sqls.create("select " + + "id, orderId, orderNumberId, supplierId, userId, totalPrice, wPayOrAPay, pointsPrice, cashPaid, " + + "orderState, orderCreateTime, createdAt as createTime, 1 as orderType, extJson " + + "from points_mall_order_main " + + "where userId=@userId and orderId not in (" + + "select distinct mainOrderId from points_mall_order_sub where userId=@userId and delFlag=0 and mainOrderId is not null" + + ") " + + (filterOrderState ? "and orderState=@orderState " : "") + + "and delFlag=0 order by createTime desc, orderType asc"); + sql.params().set("userId", userId); + if (filterOrderState) { + sql.params().set("orderState", orderState); + } + return sql; + } + + /** + * 移动端子单分页(合并主单+子单) + */ + private Sql getMobileOrderSubPageSql(String userId, String orderState) { + boolean filterOrderState = StrUtil.isNotBlank(orderState) && !StrUtil.equals(orderState, "-1"); + Sql sql = Sqls.create("select " + + "id, orderId, orderNumberId, supplierId, userId, totalPrice, wPayOrAPay, pointsPrice, " + + "orderState, orderCreateTime, createTime, orderType, extJson " + + "from (" + + "select id, orderId, orderNumberId, supplierId, userId, totalPrice, wPayOrAPay, pointsPrice, " + + "orderState, orderCreateTime, createdAt as createTime, 1 as orderType, extJson " + + "from points_mall_order_main " + + "where userId=@userId and orderId not in (" + + "select distinct mainOrderId from points_mall_order_sub where userId=@userId and delFlag=0 and mainOrderId is not null" + + ") and delFlag=0 " + + "union all " + + "select id, orderId, orderNumberId, supplierId, userId, totalPrice, wPayOrAPay, pointsPrice, " + + "orderState, orderCreateTime, createdAt as createTime, 2 as orderType, extJson " + + "from points_mall_order_sub " + + "where userId=@userId and delFlag=0 and orderState != 8" + + ") as mall_order " + + "where userId=@userId " + + (filterOrderState ? "and orderState=@orderState " : "") + + "order by createTime desc, orderType"); + sql.params().set("userId", userId); + if (filterOrderState) { + sql.params().set("orderState", orderState); + } + return sql; + } + + /** + * 移动端退换货单分页 + */ + private Sql getMobileOrderExchangePageSql(String userId, String orderState) { + boolean filterOrderState = StrUtil.isNotBlank(orderState) && !StrUtil.equals(orderState, "-1"); + Sql sql = Sqls.create("select " + + "moe.id as id, " + + "moe.orderId as orderId, " + + "null as orderNumberId, " + + "moe.supplierId as supplierId, " + + "moe.userId as userId, " + + "moe.totalPrice as totalPrice, " + + "moe.wPayOrAPay as wPayOrAPay, " + + "moe.pointsPrice as pointsPrice, " + + "moe.refund as refund, " + + "moe.orderState as orderState, " + + "moe.orderCreateTime as orderCreateTime, " + + "moe.createdAt as createTime, " + + "3 as orderType, " + + "moe.extJson as extJson, " + + "moe.orderMainId as mainOrderId, " + + "mos.pointsPrice as relPointsPrice " + + "from points_mall_order_exchange moe " + + "left join points_mall_order_sub mos on moe.orderMainId = mos.orderId " + + "where moe.userId=@userId " + + (filterOrderState ? "and moe.orderState=@orderState " : "") + + "and moe.delFlag=0 and moe.orderState != 8 order by moe.createdAt desc"); + sql.params().set("userId", userId); + if (filterOrderState) { + sql.params().set("orderState", orderState); + } + return sql; + } + + private void fillProductInfo(PointsMallMobileOrderVO record) { + if (StrUtil.isBlank(record.getExtJson())) { + return; + } + JSONArray array = null; + try { + array = JSONUtil.parseArray(record.getExtJson()); + } catch (Exception e) { + log.error("订单类型:{},订单号:{},商品信息:{}", record.getOrderType(), record.getOrderId(), record.getExtJson()); + } + if (array == null || array.isEmpty()) return; + int number = 0; + List imgUrlList = new ArrayList<>(); + for (int i = 0; i < array.size(); i++) { + JSONObject obj = array.getJSONObject(i); + Integer productNumber = obj.getInt("number"); + number = number + (productNumber == null ? 0 : productNumber); + if (i < 3) { + String filePath = obj.getStr("filePath"); + if (StrUtil.isNotEmpty(filePath)) { + imgUrlList.add(filePath); + } + } + } + record.setProductNum(number); + record.setProductImgList(imgUrlList); + } + + /** + * 更新主订单状态,所有子单取消、退货或完成后,修改主单状态为已完成。 + */ + private void updateMainOrderStatus(String mainOrderId, String supplierId) { + if (StrUtil.hasBlank(mainOrderId, supplierId)) { + return; + } + int count = dao().count(PointsMallOrderSub.class, Cnd.where("mainOrderId", "=", mainOrderId) + .and("supplierId", "=", supplierId).and("delFlag", "=", false)); + if (count == 0) { + return; + } + // 只有一个子单主订单随子单变化 + if (count == 1) { + // 修改主订单状态为完成 + dao().update(PointsMallOrderMain.class, + Chain.make("orderState", MallOrderStatusEnum.COMPLETED.getCode()).add("orderUpdateTime", new Date()), + Cnd.where("orderId", "=", mainOrderId).and("supplierId", "=", supplierId).and("delFlag", "=", false)); + log.info("主订单只有一个子单,则更新主订单状态为已完成"); + return; + } + log.info("查询所有子订单的状态是否都为已取消、退款或已完成收货"); + List finishedStatus = Arrays.asList( + MallOrderStatusEnum.CANCELLED.getCode(), + MallOrderStatusEnum.REFUNDED.getCode(), + MallOrderStatusEnum.COMPLETED.getCode() + ); + int finishedCount = dao().count(PointsMallOrderSub.class, Cnd.where("mainOrderId", "=", mainOrderId) + .and("supplierId", "=", supplierId) + .and("orderState", "in", finishedStatus) + .and("delFlag", "=", false)); + // 如果所有子订单都已取消、已退货或已完成收货,则更新主订单状态为已完成 + if (count == finishedCount) { + // 修改主订单状态为完成 + dao().update(PointsMallOrderMain.class, + Chain.make("orderState", MallOrderStatusEnum.COMPLETED.getCode()).add("orderUpdateTime", new Date()), + Cnd.where("orderId", "=", mainOrderId).and("supplierId", "=", supplierId).and("delFlag", "=", false)); + log.info("所有子订单都已取消、已退货或已完成收货,则更新主订单状态为已完成"); + } + } + + private Pagination listMobileOrderPage(Integer pageNumber, int pageSize, Sql sql) { + pageNumber = getPageNumber(pageNumber); + pageSize = getPageSize(pageSize); + Pager pager = dao().createPager(pageNumber, pageSize); + pager.setRecordCount((int) Daos.queryCount(dao(), sql)); + sql.setPager(pager); + sql.setEntity(dao().getEntity(PointsMallMobileOrderVO.class)); + sql.setCallback(Sqls.callback.entities()); dao().execute(sql); - return sql.getList(String.class); + return new Pagination<>(pageNumber, pageSize, pager.getRecordCount(), sql.getList(PointsMallMobileOrderVO.class)); } private String appendOrderId(String url, String orderId) { @@ -236,10 +458,4 @@ public class PointsMallOrderServiceImpl extends BaseServiceImpl productImgList; +} diff --git a/src/main/resources/views/platform/zhghh5/points-mall/order/index.html b/src/main/resources/views/platform/zhghh5/points-mall/order/index.html index 98e63682..90947f73 100644 --- a/src/main/resources/views/platform/zhghh5/points-mall/order/index.html +++ b/src/main/resources/views/platform/zhghh5/points-mall/order/index.html @@ -3,7 +3,7 @@ layout("/layouts/platform_h5.html"){ #-->
-
+
剩余积分
@@ -14,69 +14,125 @@ layout("/layouts/platform_h5.html"){
- +
- - - +
+ +
+
+
+
+ {{ tab.name }} +
+
+
|
+
+
+ {{ tab.name }} +
+
+
- -
-
-
- {{ item.supplierName || "积分商城" }} - -
- {{ orderStateName(item.orderState) }} -
+ + +
+
+
+ {{ item.supplierName || "积分商城" }} + + {{ getOrderTypeName(item.orderType) }} +
+
+ {{ orderStateName(item.orderState) }} +
+
-
- -
+
+
+
+
+ +
+
+
+
+ +
+
-
-
- 订单号: - {{ item.orderId }} +
+
+ 积分已支付,待“支付宝/微信/其他”支付 +
+
+ 关联发货单号: + {{ item.orderMainId }} +
+
+ 原发货单消耗积分: + {{ item.relPointsPrice }} +
+
+ 支付宝/微信/其他: + {{ item.wPayOrAPay }} +
+
+ 退回积分: + {{ item.refund }} +
+
+ 订单编号: + {{ item.orderNumberId }} +
+
+ 订单号: + {{ item.orderId }} +
+
+ 消费积分: + {{ item.pointsPrice || 0 }} +
+
+ 运费: + ¥ {{ item.freightCost }} +
+
+ 创建时间: + {{ item.orderCreateTime || "-" }} +
-
- 消费积分: - {{ item.pointsPrice || 0 }} -
-
- 运费: - ¥ {{ item.freightCost }} -
-
- 创建时间: - {{ item.orderCreateTime || "-" }} -
-
-
- 确认收货 - 查看订单 -
-
+
+
+
+ 确认收货 + 查看订单 +
+
+
-
- + + +