From de7dde6adbcdd54da04a7baba65508ee89b224d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E5=AE=87=E5=A5=87?= Date: Fri, 11 Apr 2025 00:02:14 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=AE=A2=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/controller/xkt/AlipayController.java | 11 +- .../controller/xkt/StoreOrderController.java | 13 ++ .../xkt/vo/order/StoreOrderUpdateReqVO.java | 122 ++++++++++++ .../ruoyi/xkt/dto/order/StoreOrderAddDTO.java | 13 +- .../xkt/dto/order/StoreOrderDetailAddDTO.java | 19 ++ .../xkt/dto/order/StoreOrderUpdateDTO.java | 19 ++ .../com/ruoyi/xkt/enums/EOrderAction.java | 6 +- .../xkt/service/IAlipayCallbackService.java | 2 +- .../ruoyi/xkt/service/IStoreOrderService.java | 15 +- .../impl/AlipayCallbackServiceImpl.java | 5 +- .../service/impl/StoreOrderServiceImpl.java | 183 +++++++++++++++--- 11 files changed, 363 insertions(+), 45 deletions(-) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderUpdateReqVO.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderDetailAddDTO.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderUpdateDTO.java diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AlipayController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AlipayController.java index 2fd69d1f8..8df4ce822 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AlipayController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AlipayController.java @@ -72,19 +72,19 @@ public class AlipayController extends XktBaseController { //1. 商家需要验证该通知数据中的 out_trade_no 是否为商家系统中创建的订单号。 StoreOrder order = storeOrderService.getByOrderNo(alipayCallback.getOutTradeNo()); if (order == null) { - logger.info("支付宝回调订单匹配失败:{}", params); + logger.warn("支付宝回调订单匹配失败:{}", params); return FAILURE; } //2. 判断 total_amount 是否确实为该订单的实际金额(即商家订单创建时的金额)。 if (!NumberUtil.equals(order.getTotalAmount(), alipayCallback.getTotalAmount())) { - logger.info("支付宝回调订单金额匹配失败:{}", params); + logger.warn("支付宝回调订单金额匹配失败:{}", params); return FAILURE; } //3. 校验通知中的 seller_id(或者 seller_email)是否为 out_trade_no 这笔单据的对应的操作方 // (有的时候,一个商家可能有多个 seller_id/seller_email)。 //4. 验证 app_id 是否为该商家本身。 if (!StrUtil.equals(paymentManger.getAppId(), alipayCallback.getAppId())) { - logger.info("支付宝回调应用ID异常:{}", params); + logger.warn("支付宝回调应用ID异常:{}", params); return FAILURE; } //5. 处理支付宝回调信息 @@ -103,13 +103,14 @@ public class AlipayController extends XktBaseController { return SUCCESS; } if (EProcessStatus.INIT.getValue().equals(info.getProcessStatus())) { - alipayCallbackService.processOrderPay(info); + //更新回调状态和订单状态,创建收款单 + alipayCallbackService.processOrderPaid(info); } else { logger.warn("支付回调重复请求处理: {}", info.getId()); } return SUCCESS; } else { - logger.info("支付宝验签未通过:{}", params); + logger.warn("支付宝验签未通过:{}", params); return FAILURE; } } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreOrderController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreOrderController.java index 9c87e2eab..dba06bf35 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreOrderController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreOrderController.java @@ -10,9 +10,11 @@ import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.web.controller.xkt.vo.order.StoreOrderAddReqVO; import com.ruoyi.web.controller.xkt.vo.order.StoreOrderPayReqVO; import com.ruoyi.web.controller.xkt.vo.order.StoreOrderPayRespVO; +import com.ruoyi.web.controller.xkt.vo.order.StoreOrderUpdateReqVO; import com.ruoyi.xkt.dto.order.StoreOrderAddDTO; import com.ruoyi.xkt.dto.order.StoreOrderAddResult; import com.ruoyi.xkt.dto.order.StoreOrderInfo; +import com.ruoyi.xkt.dto.order.StoreOrderUpdateDTO; import com.ruoyi.xkt.enums.EPayChannel; import com.ruoyi.xkt.enums.EPayPage; import com.ruoyi.xkt.manager.PaymentManager; @@ -60,6 +62,17 @@ public class StoreOrderController extends XktBaseController { return success(respVO); } + @PreAuthorize("@ss.hasPermi('system:order:add')") + @Log(title = "订单", businessType = BusinessType.UPDATE) + @ApiOperation("修改订单") + @PostMapping("modify") + public R modify(@Valid @RequestBody StoreOrderUpdateReqVO vo) { + StoreOrderUpdateDTO dto = BeanUtil.toBean(vo, StoreOrderUpdateDTO.class); + dto.setOrderUserId(SecurityUtils.getUserId()); + StoreOrderInfo result = storeOrderService.modifyOrder(dto); + return success(result.getOrder().getId()); + } + @PreAuthorize("@ss.hasPermi('system:order:add')") @Log(title = "订单", businessType = BusinessType.OTHER) @ApiOperation("支付订单") diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderUpdateReqVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderUpdateReqVO.java new file mode 100644 index 000000000..5aace9e4b --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderUpdateReqVO.java @@ -0,0 +1,122 @@ +package com.ruoyi.web.controller.xkt.vo.order; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Date; +import java.util.List; + +/** + * @author liangyq + * @date 2025-04-02 22:31 + */ +@ApiModel("订单修改参数") +@Data +public class StoreOrderUpdateReqVO { + /** + * 订单ID + */ + @NotNull(message = "订单ID不能为空") + @ApiModelProperty(value = "订单ID") + private Long id; + /** + * 档口ID + */ + @NotNull(message = "档口ID不能为空") + @ApiModelProperty(value = "档口ID") + private Long storeId; + /** + * 订单备注 + */ + @ApiModelProperty(value = "订单备注") + private String orderRemark; + /** + * 物流ID + */ + @NotNull(message = "物流ID不能为空") + @ApiModelProperty(value = "物流ID") + private Long expressId; + /** + * 收货人-名称 + */ + @NotEmpty(message = "收货人名称不能为空") + @ApiModelProperty(value = "收货人-名称") + private String destinationContactName; + /** + * 收货人-电话 + */ + @NotEmpty(message = "收货人电话不能为空") + @ApiModelProperty(value = "收货人-电话") + private String destinationContactPhoneNumber; + /** + * 收货人-省编码 + */ + @NotEmpty(message = "收货人省编码不能为空") + @ApiModelProperty(value = "收货人-省编码") + private String destinationProvinceCode; + /** + * 收货人-市编码 + */ + @NotEmpty(message = "收货人市编码不能为空") + @ApiModelProperty(value = "收货人-市编码") + private String destinationCityCode; + /** + * 收货人-区县编码 + */ + @NotEmpty(message = "收货人区县编码不能为空") + @ApiModelProperty(value = "收货人-区县编码") + private String destinationCountyCode; + /** + * 收货人-详细地址 + */ + @NotEmpty(message = "收货人详细地址不能为空") + @ApiModelProperty(value = "收货人-详细地址") + private String destinationDetailAddress; + /** + * 发货方式[1:货其再发 2:有货先发] + */ + @NotNull(message = "发货方式不能为空") + @ApiModelProperty(value = "发货方式[1:货其再发 2:有货先发]") + private Integer deliveryType; + /** + * 最晚发货时间 + */ + @ApiModelProperty(value = "最晚发货时间") + private Date deliveryEndTime; + /** + * 明细列表 + */ + @Valid + @NotEmpty(message = "订单明细不能为空") + @ApiModelProperty(value = "明细列表") + private List detailList; + +// @NotNull(message = "是否发起支付不能为空") +// @ApiModelProperty(value = "是否发起支付") +// private Boolean beginPay; +// +// @NotNull(message = "支付渠道不能为空") +// @ApiModelProperty(value = "支付渠道[1:支付宝]") +// private Integer payChannel; +// +// @NotNull(message = "支付来源不能为空") +// @ApiModelProperty(value = "支付来源[1:电脑网站 2:手机网站]") +// private Integer payFrom; + + @ApiModel(value = "明细") + @Data + public static class Detail { + + @NotNull(message = "商品颜色尺码ID不能为空") + @ApiModelProperty(value = "商品颜色尺码ID") + private Long storeProdColorSizeId; + + @NotNull(message = "商品数量不能为空") + @ApiModelProperty(value = "商品数量") + private Integer goodsQuantity; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderAddDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderAddDTO.java index 584721319..564d95650 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderAddDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderAddDTO.java @@ -62,17 +62,6 @@ public class StoreOrderAddDTO { /** * 明细列表 */ - private List detailList; + private List detailList; - @Data - public static class Detail { - /** - * 商品颜色尺码ID - */ - private Long storeProdColorSizeId; - /** - * 商品数量 - */ - private Integer goodsQuantity; - } } diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderDetailAddDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderDetailAddDTO.java new file mode 100644 index 000000000..55e54446e --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderDetailAddDTO.java @@ -0,0 +1,19 @@ +package com.ruoyi.xkt.dto.order; + +import lombok.Data; + +/** + * @author liangyq + * @date 2025-04-10 23:06 + */ +@Data +public class StoreOrderDetailAddDTO { + /** + * 商品颜色尺码ID + */ + private Long storeProdColorSizeId; + /** + * 商品数量 + */ + private Integer goodsQuantity; +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderUpdateDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderUpdateDTO.java new file mode 100644 index 000000000..7f22d958f --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderUpdateDTO.java @@ -0,0 +1,19 @@ +package com.ruoyi.xkt.dto.order; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +/** + * @author liangyq + * @date 2025-04-10 22:46 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class StoreOrderUpdateDTO extends StoreOrderAddDTO{ + /** + * 订单ID + */ + private Long id; +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EOrderAction.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EOrderAction.java index 375798e3e..e54fed64e 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/enums/EOrderAction.java +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EOrderAction.java @@ -11,8 +11,10 @@ import lombok.Getter; @AllArgsConstructor public enum EOrderAction { - ADD_ORDER(1, "下单"), - PAID_ORDER(2, "支付"), + INSERT(1, "新增"), + UPDATE(2, "修改"), + DELETE(3, "删除"), + PAY(4, "支付"), ; private final Integer value; diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IAlipayCallbackService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IAlipayCallbackService.java index 1cf25cd44..536558d5a 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IAlipayCallbackService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IAlipayCallbackService.java @@ -29,5 +29,5 @@ public interface IAlipayCallbackService { * * @param info */ - void processOrderPay(AlipayCallback info); + void processOrderPaid(AlipayCallback info); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java index bac6d9af2..d52fd84e7 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java @@ -4,9 +4,12 @@ import com.ruoyi.xkt.domain.StoreOrder; import com.ruoyi.xkt.dto.order.StoreOrderAddDTO; import com.ruoyi.xkt.dto.order.StoreOrderAddResult; import com.ruoyi.xkt.dto.order.StoreOrderInfo; +import com.ruoyi.xkt.dto.order.StoreOrderUpdateDTO; import com.ruoyi.xkt.enums.EPayChannel; import com.ruoyi.xkt.enums.EPayPage; +import java.math.BigDecimal; + /** * @author liangyq * @date 2025-04-02 13:16 @@ -24,6 +27,14 @@ public interface IStoreOrderService { StoreOrderAddResult createOrder(StoreOrderAddDTO storeOrderAddDTO, boolean beginPay, EPayChannel payChannel, EPayPage payPage); + /** + * 更新订单 + * + * @param storeOrderUpdateDTO + * @return + */ + StoreOrderInfo modifyOrder(StoreOrderUpdateDTO storeOrderUpdateDTO); + /** * 通过订单号获取订单 * @@ -44,7 +55,9 @@ public interface IStoreOrderService { * TODO 更新扣除手续费后的金额 * * @param storeOrderId + * @param totalAmount + * @param realTotalAmount * @return */ - StoreOrderInfo paySuccess(Long storeOrderId); + StoreOrderInfo paySuccess(Long storeOrderId, BigDecimal totalAmount, BigDecimal realTotalAmount); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/AlipayCallbackServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AlipayCallbackServiceImpl.java index 5ca98fb38..7de42ef31 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/AlipayCallbackServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AlipayCallbackServiceImpl.java @@ -46,14 +46,15 @@ public class AlipayCallbackServiceImpl implements IAlipayCallbackService { @Transactional @Override - public void processOrderPay(AlipayCallback info) { + public void processOrderPaid(AlipayCallback info) { //更新回调状态 info.setProcessStatus(EProcessStatus.SUCCESS.getValue()); alipayCallbackMapper.updateById(info); //更新订单状态 StoreOrder order = storeOrderService.getByOrderNo(info.getOutTradeNo()); Assert.notNull(order); - StoreOrderInfo orderInfo = storeOrderService.paySuccess(order.getId()); + StoreOrderInfo orderInfo = storeOrderService.paySuccess(order.getId(), info.getTotalAmount(), + info.getReceiptAmount()); //创建收款单 financeBillService.createCollectionBillAfterOrderPaid(orderInfo, info.getId(), EPayChannel.ALI_PAY); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java index d839d711b..98b722bba 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java @@ -12,10 +12,7 @@ import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.bean.BeanValidators; import com.ruoyi.xkt.domain.*; import com.ruoyi.xkt.dto.express.ExpressContactDTO; -import com.ruoyi.xkt.dto.order.StoreOrderAddDTO; -import com.ruoyi.xkt.dto.order.StoreOrderAddResult; -import com.ruoyi.xkt.dto.order.StoreOrderInfo; -import com.ruoyi.xkt.dto.order.StoreOrderOperationRecordAddDTO; +import com.ruoyi.xkt.dto.order.*; import com.ruoyi.xkt.enums.*; import com.ruoyi.xkt.manager.PaymentManager; import com.ruoyi.xkt.mapper.*; @@ -23,6 +20,7 @@ import com.ruoyi.xkt.service.IExpressService; import com.ruoyi.xkt.service.IOperationRecordService; import com.ruoyi.xkt.service.IStoreOrderService; import com.ruoyi.xkt.service.IVoucherSequenceService; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -35,6 +33,7 @@ import java.util.stream.Collectors; * @author liangyq * @date 2025-04-02 13:19 */ +@Slf4j @Service public class StoreOrderServiceImpl implements IStoreOrderService { @Autowired @@ -79,7 +78,7 @@ public class StoreOrderServiceImpl implements IStoreOrderService { int orderGoodsQuantity = 0; BigDecimal orderGoodsAmount = BigDecimal.ZERO; BigDecimal orderExpressFee = BigDecimal.ZERO; - for (StoreOrderAddDTO.Detail detail : storeOrderAddDTO.getDetailList()) { + for (StoreOrderDetailAddDTO detail : storeOrderAddDTO.getDetailList()) { StoreProductColorSize spcs = spcsMap.get(detail.getStoreProdColorSizeId()); StoreOrderDetail orderDetail = new StoreOrderDetail(); orderDetailList.add(orderDetail); @@ -164,7 +163,8 @@ public class StoreOrderServiceImpl implements IStoreOrderService { orderDetailIdList.add(storeOrderDetail.getId()); }); //操作记录 - addOperationRecords(orderId, orderDetailIdList, orderUserId, new Date(), EOrderAction.ADD_ORDER); + addOperationRecords(orderId, EOrderAction.INSERT, orderDetailIdList, EOrderAction.INSERT, orderUserId, + new Date()); StoreOrderInfo orderInfo = new StoreOrderInfo(order, orderDetailList); String rtnStr = null; if (beginPay) { @@ -175,6 +175,125 @@ public class StoreOrderServiceImpl implements IStoreOrderService { return new StoreOrderAddResult(orderInfo, rtnStr); } + @Transactional + @Override + public StoreOrderInfo modifyOrder(StoreOrderUpdateDTO storeOrderUpdateDTO) { + //原订单 + StoreOrder order = storeOrderMapper.selectById(storeOrderUpdateDTO.getId()); + if (!BeanValidators.exists(order)) { + throw new ServiceException("订单[" + storeOrderUpdateDTO.getId() + "]不存在"); + } + Long orderUserId = storeOrderUpdateDTO.getOrderUserId(); + Long storeId = storeOrderUpdateDTO.getStoreId(); + Long expressId = storeOrderUpdateDTO.getExpressId(); + //校验 + if (!EOrderStatus.PENDING_PAYMENT.getValue().equals(order.getOrderStatus()) + && !EPayStatus.PAID.getValue().equals(order.getPayStatus())) { + throw new ServiceException("订单[" + storeOrderUpdateDTO.getId() + "]已完成支付,无法修改"); + } + expressService.checkExpress(expressId); + checkDelivery(storeOrderUpdateDTO.getDeliveryType(), storeOrderUpdateDTO.getDeliveryEndTime()); + Map spcsMap = checkOrderDetailThenRtnSpcsMap(storeId, + storeOrderUpdateDTO.getDetailList()); + //快递费配置 + ExpressFeeConfig expressFeeConfig = expressService.getExpressFeeConfig(expressId, + storeOrderUpdateDTO.getDestinationProvinceCode(), storeOrderUpdateDTO.getDestinationCityCode(), + storeOrderUpdateDTO.getDestinationCountyCode()); + Assert.isTrue(BeanValidators.exists(expressFeeConfig), "无快递费用配置"); + boolean isFirstExpressItem = true; + //生成订单明细 + List orderDetailList = new ArrayList<>(storeOrderUpdateDTO.getDetailList().size()); + int orderGoodsQuantity = 0; + BigDecimal orderGoodsAmount = BigDecimal.ZERO; + BigDecimal orderExpressFee = BigDecimal.ZERO; + for (StoreOrderDetailAddDTO detail : storeOrderUpdateDTO.getDetailList()) { + StoreProductColorSize spcs = spcsMap.get(detail.getStoreProdColorSizeId()); + StoreOrderDetail orderDetail = new StoreOrderDetail(); + orderDetailList.add(orderDetail); + orderDetail.setStoreProdColorSizeId(spcs.getId()); + orderDetail.setStoreProdId(spcs.getStoreProdId()); + orderDetail.setDetailStatus(EOrderStatus.PENDING_PAYMENT.getValue()); + orderDetail.setPayStatus(order.getPayStatus()); + orderDetail.setExpressStatus(EExpressStatus.INIT.getValue()); + //计算明细费用 + BigDecimal goodsPrice = calcPrice(orderUserId, spcs); + Integer goodsQuantity = detail.getGoodsQuantity(); + BigDecimal goodsAmount = NumberUtil.mul(goodsPrice, BigDecimal.valueOf(goodsQuantity)); + BigDecimal expressFee; + if (isFirstExpressItem) { + if (goodsQuantity == 1) { + expressFee = expressFeeConfig.getFirstItemAmount(); + } else { + BigDecimal nextAmount = NumberUtil.mul(expressFeeConfig.getNextItemAmount(), + BigDecimal.valueOf(goodsQuantity - 1)); + expressFee = NumberUtil.add(expressFeeConfig.getFirstItemAmount(), nextAmount); + } + isFirstExpressItem = false; + } else { + expressFee = NumberUtil.mul(expressFeeConfig.getNextItemAmount(), BigDecimal.valueOf(goodsQuantity)); + } + BigDecimal totalAmount = NumberUtil.add(goodsAmount, expressFee); + orderDetail.setGoodsPrice(goodsPrice); + orderDetail.setGoodsQuantity(goodsQuantity); + orderDetail.setGoodsAmount(goodsAmount); + orderDetail.setExpressFee(expressFee); + orderDetail.setTotalAmount(totalAmount); + orderDetail.setDelFlag(Constants.UNDELETED); + orderDetail.setVersion(0L); + //计算订单费用 + orderGoodsQuantity = orderGoodsQuantity + goodsQuantity; + orderGoodsAmount = NumberUtil.add(orderGoodsAmount, goodsAmount); + orderExpressFee = NumberUtil.add(orderExpressFee, expressFee); + } + order.setStoreId(storeId); + order.setOrderUserId(orderUserId); + order.setOrderRemark(storeOrderUpdateDTO.getOrderRemark()); + order.setGoodsQuantity(orderGoodsQuantity); + order.setGoodsAmount(orderGoodsAmount); + order.setExpressFee(orderExpressFee); + order.setTotalAmount(NumberUtil.add(orderGoodsAmount, orderExpressFee)); + order.setExpressId(expressId); + //发货人信息 + ExpressContactDTO expressContactDTO = expressService.getStoreContact(storeId); + order.setOriginContactName(expressContactDTO.getContactName()); + order.setOriginContactPhoneNumber(expressContactDTO.getContactPhoneNumber()); + order.setOriginProvinceCode(expressContactDTO.getProvinceCode()); + order.setOriginCityCode(expressContactDTO.getCityCode()); + order.setOriginCountyCode(expressContactDTO.getCountyCode()); + order.setOriginDetailAddress(expressContactDTO.getDetailAddress()); + //收货人信息 + order.setDestinationContactName(storeOrderUpdateDTO.getDestinationContactName()); + order.setDestinationContactPhoneNumber(storeOrderUpdateDTO.getDestinationContactPhoneNumber()); + order.setDestinationProvinceCode(storeOrderUpdateDTO.getDestinationProvinceCode()); + order.setDestinationCityCode(storeOrderUpdateDTO.getDestinationCityCode()); + order.setDestinationCountyCode(storeOrderUpdateDTO.getDestinationCountyCode()); + order.setDestinationDetailAddress(storeOrderUpdateDTO.getDestinationDetailAddress()); + order.setDeliveryType(storeOrderUpdateDTO.getDeliveryType()); + order.setDeliveryEndTime(storeOrderUpdateDTO.getDeliveryEndTime()); + //落库 + int r = storeOrderMapper.updateById(order); + if (r == 0) { + throw new ServiceException(Constants.VERSION_LOCK_ERROR_COMMON_MSG); + } + //删除原明细 + StoreOrderDetail delete = new StoreOrderDetail(); + delete.setDelFlag(Constants.DELETED); + storeOrderDetailMapper.update(delete, Wrappers.lambdaUpdate(StoreOrderDetail.class) + .eq(StoreOrderDetail::getStoreOrderId, order.getId())); + //重新生成明细 + Long orderId = order.getId(); + List orderDetailIdList = new ArrayList<>(orderDetailList.size()); + orderDetailList.forEach(storeOrderDetail -> { + storeOrderDetail.setStoreOrderId(orderId); + storeOrderDetailMapper.insert(storeOrderDetail); + orderDetailIdList.add(storeOrderDetail.getId()); + }); + //操作记录 + addOperationRecords(orderId, EOrderAction.UPDATE, orderDetailIdList, EOrderAction.INSERT, orderUserId, + new Date()); + return new StoreOrderInfo(order, orderDetailList); + } + @Override public StoreOrder getByOrderNo(String orderNo) { Assert.notNull(orderNo); @@ -213,13 +332,23 @@ public class StoreOrderServiceImpl implements IStoreOrderService { @Transactional @Override - public StoreOrderInfo paySuccess(Long storeOrderId) { + public StoreOrderInfo paySuccess(Long storeOrderId, BigDecimal totalAmount, BigDecimal realTotalAmount) { Assert.notNull(storeOrderId); StoreOrder order = storeOrderMapper.selectById(storeOrderId); Assert.isTrue(EOrderType.SALES_ORDER.getValue().equals(order.getOrderType()), "订单类型异常"); Assert.isTrue(BeanValidators.exists(order), "订单不存在"); - Assert.isTrue(order.getPayStatus().equals(EPayStatus.PAYING.getValue()), "订单支付状态异常"); + if (!order.getPayStatus().equals(EPayStatus.PAYING.getValue()) + || !order.getOrderStatus().equals(EOrderStatus.PENDING_PAYMENT.getValue())) { + log.error("订单状态异常,更新支付结果失败: id = {}", storeOrderId); + throw new ServiceException("订单状态异常"); + } + if (NumberUtil.equals(order.getTotalAmount(), totalAmount)) { + log.error("订单支付金额异常,更新支付结果失败: id = {} totalAmount = {} realTotalAmount = {}", + storeOrderId, totalAmount, realTotalAmount); + throw new ServiceException("订单支付金额异常"); + } + order.setOrderStatus(EOrderStatus.PENDING_SHIPMENT.getValue()); order.setPayStatus(EPayStatus.PAID.getValue()); //TODO 暂时使用总金额 order.setRealTotalAmount(order.getTotalAmount()); @@ -233,8 +362,12 @@ public class StoreOrderServiceImpl implements IStoreOrderService { .eq(SimpleEntity::getDelFlag, Constants.UNDELETED)); List orderDetailIdList = new ArrayList<>(orderDetails.size()); for (StoreOrderDetail orderDetail : orderDetails) { - Assert.isTrue(orderDetail.getPayStatus().equals(EPayStatus.PAYING.getValue()), - "订单明细支付状态异常"); + if (!orderDetail.getPayStatus().equals(EPayStatus.PAYING.getValue()) + || !orderDetail.getDetailStatus().equals(EOrderStatus.PENDING_PAYMENT.getValue())) { + log.error("订单明细状态异常,更新支付结果失败: id = {}", storeOrderId); + throw new ServiceException("订单明细状态异常"); + } + orderDetail.setDetailStatus(EOrderStatus.PENDING_SHIPMENT.getValue()); orderDetail.setPayStatus(EPayStatus.PAID.getValue()); orderDetail.setRealTotalAmount(orderDetail.getTotalAmount()); int orderDetailSuccess = storeOrderDetailMapper.updateById(orderDetail); @@ -244,7 +377,8 @@ public class StoreOrderServiceImpl implements IStoreOrderService { orderDetailIdList.add(orderDetail.getId()); } //操作记录 - addOperationRecords(storeOrderId, orderDetailIdList, null, new Date(), EOrderAction.PAID_ORDER); + addOperationRecords(storeOrderId, EOrderAction.PAY, orderDetailIdList, EOrderAction.PAY, null, + new Date()); return new StoreOrderInfo(order, orderDetails); } @@ -258,19 +392,20 @@ public class StoreOrderServiceImpl implements IStoreOrderService { * 添加操作记录 * * @param orderId + * @param orderAction * @param orderDetailIds + * @param detailAction * @param operatorId * @param operationTime - * @param action */ - private void addOperationRecords(Long orderId, List orderDetailIds, Long operatorId, Date operationTime, - EOrderAction action) { + private void addOperationRecords(Long orderId, EOrderAction orderAction, List orderDetailIds, + EOrderAction detailAction, Long operatorId, Date operationTime) { List addDTOList = new ArrayList<>(1 + CollUtil.emptyIfNull(orderDetailIds).size()); StoreOrderOperationRecordAddDTO addDTO = new StoreOrderOperationRecordAddDTO(); addDTO.setTargetId(orderId); addDTO.setTargetType(EOrderTargetTypeAction.ORDER.getValue()); - addDTO.setAction(action.getValue()); + addDTO.setAction(orderAction.getValue()); addDTO.setOperatorId(operatorId); addDTO.setOperationTime(operationTime); addDTOList.add(addDTO); @@ -278,7 +413,7 @@ public class StoreOrderServiceImpl implements IStoreOrderService { StoreOrderOperationRecordAddDTO detailAddDTO = new StoreOrderOperationRecordAddDTO(); detailAddDTO.setTargetId(orderDetailId); detailAddDTO.setTargetType(EOrderTargetTypeAction.ORDER_DETAIL.getValue()); - addDTO.setAction(action.getValue()); + addDTO.setAction(detailAction.getValue()); addDTO.setOperatorId(operatorId); addDTO.setOperationTime(operationTime); addDTOList.add(addDTO); @@ -322,9 +457,13 @@ public class StoreOrderServiceImpl implements IStoreOrderService { private void checkDelivery(Integer deliveryType, Date deliveryEndTime) { EDeliveryType deliveryTypeEnum = EDeliveryType.of(deliveryType); Assert.notNull(deliveryTypeEnum, "发货方式异常"); - if (deliveryEndTime != null - && deliveryTypeEnum != EDeliveryType.PARTIAL_SHIPMENT) { - throw new ServiceException("有货先发才能设置最晚发货时间"); + if (deliveryEndTime != null) { + if (deliveryTypeEnum != EDeliveryType.PARTIAL_SHIPMENT) { + throw new ServiceException("有货先发才能设置最晚发货时间"); + } + if (deliveryEndTime.before(new Date())) { + throw new ServiceException("最晚发货时间不能早于当前时间"); + } } } @@ -336,11 +475,11 @@ public class StoreOrderServiceImpl implements IStoreOrderService { * @return 商品颜色尺码集合 */ private Map checkOrderDetailThenRtnSpcsMap(Long storeId, - List detailList) { + List detailList) { Assert.notNull(storeId, "档口不能为空"); Assert.notEmpty(detailList, "商品不能为空"); Set spcsIds = detailList.stream() - .map(StoreOrderAddDTO.Detail::getStoreProdColorSizeId) + .map(StoreOrderDetailAddDTO::getStoreProdColorSizeId) .filter(Objects::nonNull) .collect(Collectors.toSet()); //下单商品颜色尺码 @@ -353,7 +492,7 @@ public class StoreOrderServiceImpl implements IStoreOrderService { Map spMap = storeProductMapper.selectByIds(spIdList).stream() .collect(Collectors.toMap(StoreProduct::getId, o -> o)); Set spcsIdCheckSet = new HashSet<>(detailList.size()); - for (StoreOrderAddDTO.Detail detail : detailList) { + for (StoreOrderDetailAddDTO detail : detailList) { Assert.notNull(detail.getStoreProdColorSizeId(), "商品颜色尺码异常"); Integer goodsQuantity = detail.getGoodsQuantity(); if (Objects.isNull(goodsQuantity) || goodsQuantity <= 0) {