From 856e4056c2962aa7d4e46e7aa08d5f3beacee244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E5=AE=87=E5=A5=87?= Date: Mon, 14 Apr 2025 19:08:18 +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 --- .../controller/xkt/StoreOrderController.java | 34 +- .../xkt/vo/order/StoreOrderCancelReqVO.java | 20 + .../xkt/vo/order/StoreOrderInfoVO.java | 10 + .../xkt/vo/order/StoreOrderPageItemVO.java | 399 ++++++++++++++++++ .../xkt/vo/order/StoreOrderQueryVO.java | 93 ++++ .../com/ruoyi/common/constant/Constants.java | 2 + .../java/com/ruoyi/common/core/page/Page.java | 10 +- .../com/ruoyi/common/core/page/PageVO.java | 48 +++ .../com/ruoyi/xkt/domain/ExpressRegion.java | 4 +- .../xkt/domain/StoreOrderOperationRecord.java | 2 +- .../com/ruoyi/xkt/dto/order/OrderOptDTO.java | 23 + .../xkt/dto/order/StoreOrderInfoDTO.java | 4 + .../StoreOrderOperationRecordAddDTO.java | 2 +- .../order/StoreOrderOperationRecordDTO.java | 2 +- .../xkt/dto/order/StoreOrderPageItemDTO.java | 46 ++ .../xkt/dto/order/StoreOrderQueryDTO.java | 73 ++++ .../com/ruoyi/xkt/enums/EOrderAction.java | 1 + .../com/ruoyi/xkt/enums/EOrderStatus.java | 1 + .../com/ruoyi/xkt/manager/PaymentManager.java | 9 + .../manager/impl/AliPaymentMangerImpl.java | 49 ++- .../ruoyi/xkt/mapper/StoreOrderMapper.java | 6 + .../ruoyi/xkt/service/IExpressService.java | 8 + .../ruoyi/xkt/service/IStoreOrderService.java | 16 + .../xkt/service/impl/ExpressServiceImpl.java | 16 + .../service/impl/StoreOrderServiceImpl.java | 136 +++++- .../resources/mapper/StoreOrderMapper.xml | 48 +++ 26 files changed, 1039 insertions(+), 23 deletions(-) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderCancelReqVO.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderPageItemVO.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderQueryVO.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/page/PageVO.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/dto/order/OrderOptDTO.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderPageItemDTO.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderQueryDTO.java 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 c62b0b5cd..c1bb3746a 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 @@ -1,9 +1,11 @@ package com.ruoyi.web.controller.xkt; import cn.hutool.core.bean.BeanUtil; +import com.github.pagehelper.Page; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.XktBaseController; import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.page.PageVO; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.SecurityUtils; @@ -18,6 +20,7 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -53,7 +56,7 @@ public class StoreOrderController extends XktBaseController { return success(respVO); } - @PreAuthorize("@ss.hasPermi('system:order:add')") + @PreAuthorize("@ss.hasPermi('system:order:edit')") @Log(title = "订单", businessType = BusinessType.UPDATE) @ApiOperation("修改订单") @PutMapping("edit") @@ -61,6 +64,7 @@ public class StoreOrderController extends XktBaseController { StoreOrderUpdateDTO dto = BeanUtil.toBean(vo, StoreOrderUpdateDTO.class); dto.setOrderUserId(SecurityUtils.getUserId()); StoreOrderExt result = storeOrderService.modifyOrder(dto); + //TODO 非下单人,不允许修改 return success(result.getOrder().getId()); } @@ -78,6 +82,19 @@ public class StoreOrderController extends XktBaseController { return success(respVO); } + @PreAuthorize("@ss.hasPermi('system:order:edit')") + @Log(title = "订单", businessType = BusinessType.UPDATE) + @PutMapping("cancel") + public R cancel(@Valid @RequestBody StoreOrderCancelReqVO vo) { + OrderOptDTO dto = OrderOptDTO.builder() + .storeOrderId(vo.getStoreOrderId()) + .operatorId(SecurityUtils.getUserId()) + .build(); + storeOrderService.cancelOrder(dto); + //TODO 非下单人,不允许取消 + return success(); + } + @PreAuthorize("@ss.hasPermi('system:order:query')") @ApiOperation(value = "订单详情") @GetMapping(value = "/{id}") @@ -87,6 +104,21 @@ public class StoreOrderController extends XktBaseController { return success(BeanUtil.toBean(infoDTO, StoreOrderInfoVO.class)); } + + @PreAuthorize("@ss.hasPermi('system:order:list')") + @ApiOperation(value = "订单分页查询") + @PostMapping("/page") + public R> page(@Validated @RequestBody StoreOrderQueryVO vo) { + StoreOrderQueryDTO queryDTO = BeanUtil.toBean(vo, StoreOrderQueryDTO.class); + if (1 == vo.getSrcPage()) { + queryDTO.setOrderUserId(SecurityUtils.getUserId()); + } else { + //TODO 当前档口 + } + Page pageDTO = storeOrderService.page(queryDTO); + return success(PageVO.of(pageDTO, StoreOrderPageItemVO.class)); + } + /** * 根据支付渠道匹配支付类 * diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderCancelReqVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderCancelReqVO.java new file mode 100644 index 000000000..16dd1b2e7 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderCancelReqVO.java @@ -0,0 +1,20 @@ +package com.ruoyi.web.controller.xkt.vo.order; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * @author liangyq + * @date 2025-04-07 18:16 + */ +@ApiModel +@Data +public class StoreOrderCancelReqVO { + + @NotNull(message = "订单ID不能为空") + @ApiModelProperty(value = "订单ID") + private Long storeOrderId; +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderInfoVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderInfoVO.java index aa9f48974..cdf838011 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderInfoVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderInfoVO.java @@ -25,6 +25,16 @@ public class StoreOrderInfoVO { */ @ApiModelProperty(value = "档口ID") private Long storeId; + /** + * 档口名称 + */ + @ApiModelProperty(value = "档口名称") + private String storeName; + /** + * 品牌名称 + */ + @ApiModelProperty(value = "品牌名称") + private String brandName; /** * 下单用户ID */ diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderPageItemVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderPageItemVO.java new file mode 100644 index 000000000..1560aaa93 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderPageItemVO.java @@ -0,0 +1,399 @@ +package com.ruoyi.web.controller.xkt.vo.order; + +import com.ruoyi.xkt.dto.order.StoreOrderDTO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + +/** + * @author liangyq + * @date 2025-04-14 11:18 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class StoreOrderPageItemVO extends StoreOrderDTO { + /** + * 订单ID + */ + @ApiModelProperty(value = "订单ID") + private Long id; + /** + * 档口ID + */ + @ApiModelProperty(value = "档口ID") + private Long storeId; + /** + * 档口名称 + */ + @ApiModelProperty(value = "档口名称") + private String storeName; + /** + * 品牌名称 + */ + @ApiModelProperty(value = "品牌名称") + private String brandName; + /** + * 下单用户ID + */ + @ApiModelProperty(value = "下单用户ID") + private Long orderUserId; + /** + * 订单号 + */ + @ApiModelProperty(value = "订单号") + private String orderNo; + /** + * 订单类型[1:销售订单 2:退货订单] + */ + @ApiModelProperty(value = "订单类型[1:销售订单 2:退货订单]") + private Integer orderType; + /** + * 订单状态(1开头为销售订单状态,2开头为退货订单状态)[10:已取消 11:待付款 12:待发货 13:已发货 14:已完成 21:售后中 22:售后拒绝 23:平台介入 24:售后完成] + */ + @ApiModelProperty(value = "订单状态(1开头为销售订单状态,2开头为退货订单状态)[10:已取消 11:待付款 12:待发货 13:已发货 14:已完成 21:售后中 22:售后拒绝 23:平台介入 24:售后完成]") + private Integer orderStatus; + /** + * 支付状态[1:初始 2:支付中 3:已支付] + */ + @ApiModelProperty(value = "支付状态[1:初始 2:支付中 3:已支付]") + private Integer payStatus; + /** + * 订单备注 + */ + @ApiModelProperty(value = "订单备注") + private String orderRemark; + /** + * 商品数量 + */ + @ApiModelProperty(value = "商品数量") + private Integer goodsQuantity; + /** + * 商品金额 + */ + @ApiModelProperty(value = "商品金额") + private BigDecimal goodsAmount; + /** + * 快递费 + */ + @ApiModelProperty(value = "快递费") + private BigDecimal expressFee; + /** + * 总金额(商品金额+快递费) + */ + @ApiModelProperty(value = "总金额") + private BigDecimal totalAmount; + /** + * 实际总金额(总金额-支付渠道服务费) + */ + @ApiModelProperty(value = "实际总金额") + private BigDecimal realTotalAmount; + /** + * 退货原订单ID + */ + @ApiModelProperty(value = "退货原订单ID") + private Long refundOrderId; + /** + * 退货原因 + */ + @ApiModelProperty(value = "退货原因") + private Integer refundReasonCode; + /** + * 退货拒绝原因 + */ + @ApiModelProperty(value = "退货拒绝原因") + private String refundRejectReason; + /** + * 物流ID + */ + @ApiModelProperty(value = "物流ID") + private Long expressId; + /** + * 发货人-名称 + */ + @ApiModelProperty(value = "发货人-名称") + private String originContactName; + /** + * 发货人-电话 + */ + @ApiModelProperty(value = "发货人-电话") + private String originContactPhoneNumber; + /** + * 发货人-省编码 + */ + @ApiModelProperty(value = "发货人-省编码") + private String originProvinceCode; + /** + * 发货人-市编码 + */ + @ApiModelProperty(value = "发货人-市编码") + private String originCityCode; + /** + * 发货人-区县编码 + */ + @ApiModelProperty(value = "发货人-区县编码") + private String originCountyCode; + /** + * 发货人-详细地址 + */ + @ApiModelProperty(value = "发货人-详细地址") + private String originDetailAddress; + /** + * 收货人-名称 + */ + @ApiModelProperty(value = "收货人-名称") + private String destinationContactName; + /** + * 收货人-电话 + */ + @ApiModelProperty(value = "收货人-电话") + private String destinationContactPhoneNumber; + /** + * 收货人-省编码 + */ + @ApiModelProperty(value = "收货人-省编码") + private String destinationProvinceCode; + /** + * 收货人-市编码 + */ + @ApiModelProperty(value = "收货人-市编码") + private String destinationCityCode; + /** + * 收货人-区县编码 + */ + @ApiModelProperty(value = "收货人-区县编码") + private String destinationCountyCode; + /** + * 收货人-详细地址 + */ + @ApiModelProperty(value = "收货人-详细地址") + private String destinationDetailAddress; + /** + * 发货方式[1:货其再发 2:有货先发] + */ + @ApiModelProperty(value = "发货方式[1:货其再发 2:有货先发]") + private Integer deliveryType; + /** + * 最晚发货时间 + */ + @ApiModelProperty(value = "最晚发货时间") + private Date deliveryEndTime; + /** + * 自动完成时间 + */ + @ApiModelProperty(value = "自动完成时间") + private Date autoEndTime; + /** + * 凭证日期 + */ + @ApiModelProperty(value = "凭证日期") + private Date voucherDate; + /** + * 删除标志(0代表存在 2代表删除) + */ + @ApiModelProperty(value = "删除标志(0代表存在 2代表删除)") + private String delFlag; + /** + * 创建者 + */ + @ApiModelProperty(value = "创建者") + private String createBy; + /** + * 创建时间 + */ + @ApiModelProperty(value = "创建时间") + private Date createTime; + /** + * 更新者 + */ + @ApiModelProperty(value = "更新者") + private String updateBy; + /** + * 更新时间 + */ + @ApiModelProperty(value = "更新时间") + private Date updateTime; + + @ApiModelProperty(value = "快递名") + private String expressName; + + @ApiModelProperty(value = "发货人-省名称") + private String originProvinceName; + + @ApiModelProperty(value = "发货人-市名称") + private String originCityName; + + @ApiModelProperty(value = "发货人-区县名称") + private String originCountyName; + + @ApiModelProperty(value = "收货人-省名称") + private String destinationProvinceName; + + @ApiModelProperty(value = "收货人-市名称") + private String destinationCityName; + + @ApiModelProperty(value = "收货人-区县名称") + private String destinationCountyName; + + @ApiModelProperty(value = "订单明细") + private List orderDetails; + + @ApiModel + @Data + public static class Detail { + /** + * 预览图url + */ + @ApiModelProperty(value = "预览图url") + private String firstMainPicUrl; + /** + * 订单明细ID + */ + @ApiModelProperty(value = "订单明细ID") + private Long id; + /** + * 订单ID + */ + @ApiModelProperty(value = "订单ID") + private Long storeOrderId; + /** + * 商品颜色尺码ID + */ + @ApiModelProperty(value = "商品颜色尺码ID") + private Long storeProdColorSizeId; + /** + * 商品ID + */ + @ApiModelProperty(value = "商品ID") + private Long storeProdId; + /** + * 订单明细状态(同订单状态)[10:已取消 11:待付款 12:待发货 13:已发货 14:已完成 21:售后中 22:售后拒绝 23:平台介入 24:售后完成] + */ + @ApiModelProperty(value = "订单明细状态(同订单状态)[10:已取消 11:待付款 12:待发货 13:已发货 14:已完成 21:售后中 22:售后拒绝 23:平台介入 24:售后完成]") + private Integer detailStatus; + /** + * 支付状态[1:初始 2:支付中 3:已支付] + */ + @ApiModelProperty(value = "支付状态[1:初始 2:支付中 3:已支付]") + private Integer payStatus; + /** + * 物流ID + */ + @ApiModelProperty(value = "物流ID") + private Long expressId; + /** + * 物流类型[1:平台物流 2:档口物流] + */ + @ApiModelProperty(value = "物流类型[1:平台物流 2:档口物流]") + private Integer expressType; + /** + * 物流状态[1:初始 2:下单中 3:已下单 4:取消中 5:已揽件 6:拦截中 99:已结束] + */ + @ApiModelProperty(value = "物流状态[1:初始 2:下单中 3:已下单 4:取消中 5:已揽件 6:拦截中 99:已结束]") + private Integer expressStatus; + /** + * 物流请求单号 + */ + @ApiModelProperty(value = "物流请求单号") + private String expressReqNo; + /** + * 物流运单号(快递单号),档口/用户自己填写时可能存在多个,使用“,”分割 + */ + @ApiModelProperty(value = "物流运单号(快递单号),档口/用户自己填写时可能存在多个,使用“,”分割") + private String expressWaybillNo; + /** + * 商品单价 + */ + @ApiModelProperty(value = "商品单价") + private BigDecimal goodsPrice; + /** + * 商品数量 + */ + @ApiModelProperty(value = "商品数量") + private Integer goodsQuantity; + /** + * 商品金额(商品单价*商品数量) + */ + @ApiModelProperty(value = "商品金额") + private BigDecimal goodsAmount; + /** + * 快递费 + */ + @ApiModelProperty(value = "快递费") + private BigDecimal expressFee; + /** + * 总金额(商品金额+快递费) + */ + @ApiModelProperty(value = "总金额") + private BigDecimal totalAmount; + /** + * 实际总金额(总金额-支付渠道服务费) + */ + @ApiModelProperty(value = "实际总金额") + private BigDecimal realTotalAmount; + /** + * 退货原订单明细ID + */ + @ApiModelProperty(value = "退货原订单明细ID") + private Long refundOrderDetailId; + /** + * 退货原因 + */ + @ApiModelProperty(value = "退货原因") + private Integer refundReasonCode; + /** + * 退货拒绝原因 + */ + @ApiModelProperty(value = "退货拒绝原因") + private String refundRejectReason; + /** + * 删除标志(0代表存在 2代表删除) + */ + @ApiModelProperty(value = "删除标志(0代表存在 2代表删除)") + private String delFlag; + /** + * 创建者 + */ + @ApiModelProperty(value = "创建者") + private String createBy; + /** + * 创建时间 + */ + @ApiModelProperty(value = "创建时间") + private Date createTime; + /** + * 更新者 + */ + @ApiModelProperty(value = "更新者") + private String updateBy; + /** + * 更新时间 + */ + @ApiModelProperty(value = "更新时间") + private Date updateTime; + + @ApiModelProperty(value = "档口商品名称") + private String prodName; + + @ApiModelProperty(value = "商品货号") + private String prodArtNum; + + @ApiModelProperty(value = "商品标题") + private String prodTitle; + + @ApiModelProperty(value = "档口颜色ID") + private Long storeColorId; + + @ApiModelProperty(value = "颜色名称") + private String colorName; + + @ApiModelProperty(value = "商品尺码") + private Integer size; + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderQueryVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderQueryVO.java new file mode 100644 index 000000000..8e8ea93d4 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/order/StoreOrderQueryVO.java @@ -0,0 +1,93 @@ +package com.ruoyi.web.controller.xkt.vo.order; + +import com.ruoyi.web.controller.xkt.vo.BasePageVO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; +import java.util.Date; + +/** + * @author liangyq + * @date 2025-04-14 12:54 + */ +@ApiModel +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class StoreOrderQueryVO extends BasePageVO { + /** + * 档口ID + */ + @ApiModelProperty(value = "档口ID") + private Long storeId; +// /** +// * 下单用户ID +// */ +// @ApiModelProperty(value = "下单用户ID") +// private Long orderUserId; + /** + * 订单号(模糊) + */ + @ApiModelProperty(value = "订单号(模糊)") + private String orderNo; + /** + * 订单状态(1开头为销售订单状态,2开头为退货订单状态)[10:已取消 11:待付款 12:待发货 13:已发货 14:已完成 21:售后中 22:售后拒绝 23:平台介入 24:售后完成] + */ + @ApiModelProperty(value = "订单状态(1开头为销售订单状态,2开头为退货订单状态)[10:已取消 11:待付款 12:待发货 13:已发货 14:已完成 21:售后中 22:售后拒绝 23:平台介入 24:售后完成]") + private Integer orderStatus; + /** + * 收货人-名称(模糊) + */ + @ApiModelProperty(value = "收货人-名称(模糊)") + private String destinationContactName; + /** + * 收货人-电话(模糊) + */ + @ApiModelProperty(value = "收货人-电话(模糊)") + private String destinationContactPhoneNumber; + /** + * 发货方式[1:货其再发 2:有货先发] + */ + @ApiModelProperty(value = "发货方式[1:货其再发 2:有货先发]") + private Integer deliveryType; + /** + * 下单开始时间 + */ + @ApiModelProperty(value = "下单开始时间") + private Date orderTimeBegin; + /** + * 下单结束时间 + */ + @ApiModelProperty(value = "下单结束时间") + private Date orderTimeEnd; + /** + * 支付开始时间 + */ + @ApiModelProperty(value = "支付开始时间") + private Date payTimeBegin; + /** + * 支付结束时间 + */ + @ApiModelProperty(value = "支付结束时间") + private Date payTimeEnd; + + /** + * 物流运单号(模糊) + */ + @ApiModelProperty(value = "物流运单号(模糊)") + private String expressWaybillNo; + /** + * 商品货号(模糊) + */ + @ApiModelProperty(value = "商品货号(模糊)") + private String prodArtNum; + + @NotNull(message = "来源页面不能为空") + @ApiModelProperty(value = "来源页面[1:卖家订单列表 2:档口订单列表]") + private Integer srcPage; + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index ac10be5ee..431cc280b 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -204,6 +204,8 @@ public class Constants public static final String VERSION_LOCK_ERROR_COMMON_MSG = "系统繁忙,请稍后再试"; + public static final String REGION_MAP_CACHE_KEY = "REGION_MAP"; + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/page/Page.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/page/Page.java index bef47f9e2..0c5c0d0b6 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/core/page/Page.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/page/Page.java @@ -2,7 +2,6 @@ package com.ruoyi.common.core.page; import cn.hutool.core.bean.BeanUtil; import com.github.pagehelper.PageInfo; -import com.ruoyi.common.constant.HttpStatus; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -58,6 +57,15 @@ public class Page implements Serializable { return page; } + public static Page convert(com.github.pagehelper.Page srcPage) { + Page page = new Page<>(); + page.setTotal(srcPage.getTotal()); + page.setPageNum(srcPage.getPageNum()); + page.setPageSize(srcPage.getPageSize()); + page.setList(srcPage.getResult()); + return page; + } + public static Page empty(int pageSize, int pageNum) { Page page = new Page<>(); diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/page/PageVO.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/page/PageVO.java new file mode 100644 index 000000000..deec32d8a --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/page/PageVO.java @@ -0,0 +1,48 @@ +package com.ruoyi.common.core.page; + +import cn.hutool.core.bean.BeanUtil; +import io.swagger.annotations.ApiModelProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.List; + +/** + * 鞋库通Page分页对象 + * + * @author ruoyi + */ +@NoArgsConstructor +@AllArgsConstructor +@Data +@Accessors(chain = true) +public class PageVO implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("当前页") + private Long pageNum; + + @ApiModelProperty("每页记录数") + private Long pageSize; + + @ApiModelProperty("总记录数") + private Long total; + + @ApiModelProperty("结果集") + private List list; + + public static PageVO of(Page page, Class clazz) { + return new PageVO<>(page.getPageNum(), page.getPageSize(), page.getTotal(), + BeanUtil.copyToList(page.getList(), clazz)); + } + + public static PageVO of(com.github.pagehelper.Page page, Class clazz) { + return new PageVO<>((long) page.getPageNum(), (long) page.getPageSize(), page.getTotal(), + BeanUtil.copyToList(page.getResult(), clazz)); + } + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/domain/ExpressRegion.java b/xkt/src/main/java/com/ruoyi/xkt/domain/ExpressRegion.java index 2d24cd031..a9ad760d9 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/domain/ExpressRegion.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/ExpressRegion.java @@ -6,6 +6,8 @@ import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString; +import java.io.Serializable; + /** * 物流行政区划 * @@ -15,7 +17,7 @@ import lombok.ToString; @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class ExpressRegion extends SimpleEntity { +public class ExpressRegion extends SimpleEntity implements Serializable { /** * 地区编码,基于行政区划代码做扩展,唯一约束 */ diff --git a/xkt/src/main/java/com/ruoyi/xkt/domain/StoreOrderOperationRecord.java b/xkt/src/main/java/com/ruoyi/xkt/domain/StoreOrderOperationRecord.java index 4229a6b21..738c8d9b7 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/domain/StoreOrderOperationRecord.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/StoreOrderOperationRecord.java @@ -26,7 +26,7 @@ public class StoreOrderOperationRecord extends SimpleEntity { */ private Integer targetType; /** - * 节点事件[1:下单 2:支付 3:取消 4:发货 5:完成 6:申请售后 7:寄回 8:售后拒绝 9:平台介入 10:售后完成] + * 节点事件 */ private Integer action; /** diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/order/OrderOptDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/order/OrderOptDTO.java new file mode 100644 index 000000000..aaa8cf935 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/order/OrderOptDTO.java @@ -0,0 +1,23 @@ +package com.ruoyi.xkt.dto.order; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author liangyq + * @date 2025-04-14 18:52 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class OrderOptDTO { + + private Long storeOrderId; + + private Long operatorId; + + private String remark; +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderInfoDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderInfoDTO.java index b78b7d507..a5a78df96 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderInfoDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderInfoDTO.java @@ -15,6 +15,10 @@ import java.util.List; @ToString(callSuper = true) public class StoreOrderInfoDTO extends StoreOrderDTO { + private String storeName; + + private String brandName; + private String expressName; private String originProvinceName; diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderOperationRecordAddDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderOperationRecordAddDTO.java index 93547883e..b8286f9e6 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderOperationRecordAddDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderOperationRecordAddDTO.java @@ -19,7 +19,7 @@ public class StoreOrderOperationRecordAddDTO { */ private Integer targetType; /** - * 节点事件[1:下单 2:支付 3:取消 4:发货 5:完成 6:申请售后 7:寄回 8:售后拒绝 9:平台介入 10:售后完成] + * 节点事件 */ private Integer action; /** diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderOperationRecordDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderOperationRecordDTO.java index 28637fbaf..a51f42cdb 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderOperationRecordDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderOperationRecordDTO.java @@ -25,7 +25,7 @@ public class StoreOrderOperationRecordDTO { */ private Integer targetType; /** - * 节点事件[1:下单 2:支付 3:取消 4:发货 5:完成 6:申请售后 7:寄回 8:售后拒绝 9:平台介入 10:售后完成] + * 节点事件 */ private Integer action; /** diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderPageItemDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderPageItemDTO.java new file mode 100644 index 000000000..babe865d6 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderPageItemDTO.java @@ -0,0 +1,46 @@ +package com.ruoyi.xkt.dto.order; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.List; + +/** + * @author liangyq + * @date 2025-04-14 11:18 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class StoreOrderPageItemDTO extends StoreOrderDTO { + + private String storeName; + + private String brandName; + + private String expressName; + + private String originProvinceName; + + private String originCityName; + + private String originCountyName; + + private String destinationProvinceName; + + private String destinationCityName; + + private String destinationCountyName; + + private List orderDetails; + + @Data + @EqualsAndHashCode(callSuper = true) + @ToString(callSuper = true) + public static class Detail extends StoreOrderDetailDTO { + + private String firstMainPicUrl; + } + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderQueryDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderQueryDTO.java new file mode 100644 index 000000000..fcc6c231e --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/order/StoreOrderQueryDTO.java @@ -0,0 +1,73 @@ +package com.ruoyi.xkt.dto.order; + +import com.ruoyi.xkt.dto.BasePageDTO; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import java.util.Date; + +/** + * @author liangyq + * @date 2025-04-14 12:54 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class StoreOrderQueryDTO extends BasePageDTO { + /** + * 档口ID + */ + private Long storeId; + /** + * 下单用户ID + */ + private Long orderUserId; + /** + * 订单号(模糊) + */ + private String orderNo; + /** + * 订单状态(1开头为销售订单状态,2开头为退货订单状态)[10:已取消 11:待付款 12:待发货 13:已发货 14:已完成 21:售后中 22:售后拒绝 23:平台介入 24:售后完成] + */ + private Integer orderStatus; + /** + * 收货人-名称(模糊) + */ + private String destinationContactName; + /** + * 收货人-电话(模糊) + */ + private String destinationContactPhoneNumber; + /** + * 发货方式[1:货其再发 2:有货先发] + */ + private Integer deliveryType; + /** + * 下单开始时间 + */ + private Date orderTimeBegin; + /** + * 下单结束时间 + */ + private Date orderTimeEnd; + /** + * 支付开始时间 + */ + private Date payTimeBegin; + /** + * 支付结束时间 + */ + private Date payTimeEnd; + + /** + * 物流运单号(模糊) + */ + private String expressWaybillNo; + /** + * 商品货号(模糊) + */ + private String prodArtNum; + + +} 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 e54fed64e..11082a9ab 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/enums/EOrderAction.java +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EOrderAction.java @@ -15,6 +15,7 @@ public enum EOrderAction { UPDATE(2, "修改"), DELETE(3, "删除"), PAY(4, "支付"), + CANCEL(5, "取消"), ; private final Integer value; diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EOrderStatus.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EOrderStatus.java index 183ebdeb3..9e71b9e3c 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/enums/EOrderStatus.java +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EOrderStatus.java @@ -1,5 +1,6 @@ package com.ruoyi.xkt.enums; +import com.ruoyi.common.exception.ServiceException; import lombok.AllArgsConstructor; import lombok.Getter; diff --git a/xkt/src/main/java/com/ruoyi/xkt/manager/PaymentManager.java b/xkt/src/main/java/com/ruoyi/xkt/manager/PaymentManager.java index 31835f92b..db32306b5 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/manager/PaymentManager.java +++ b/xkt/src/main/java/com/ruoyi/xkt/manager/PaymentManager.java @@ -25,4 +25,13 @@ public interface PaymentManager { */ String payOrder(StoreOrderExt order, EPayPage payFrom); + /** + * 是否已支付 + * 此方法通常用来判否,如果返回true还需要核对支付金额等相关信息才可确定是否完成支付!! + * + * @param orderNo 订单号 + * @return + */ + boolean isOrderPaid(String orderNo); + } diff --git a/xkt/src/main/java/com/ruoyi/xkt/manager/impl/AliPaymentMangerImpl.java b/xkt/src/main/java/com/ruoyi/xkt/manager/impl/AliPaymentMangerImpl.java index a0371a600..b9159164b 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/manager/impl/AliPaymentMangerImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/manager/impl/AliPaymentMangerImpl.java @@ -1,11 +1,16 @@ package com.ruoyi.xkt.manager.impl; +import cn.hutool.core.lang.Assert; import com.alibaba.fastjson2.JSON; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.diagnosis.DiagnosisUtils; +import com.alipay.api.domain.AlipayTradeQueryModel; import com.alipay.api.request.AlipayTradePagePayRequest; +import com.alipay.api.request.AlipayTradeQueryRequest; import com.alipay.api.request.AlipayTradeWapPayRequest; +import com.alipay.api.response.AlipayTradeQueryResponse; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.xkt.dto.finance.AlipayReqDTO; import com.ruoyi.xkt.dto.order.StoreOrderExt; @@ -13,7 +18,6 @@ import com.ruoyi.xkt.enums.EPayChannel; import com.ruoyi.xkt.enums.EPayPage; import com.ruoyi.xkt.enums.EPayStatus; import com.ruoyi.xkt.manager.PaymentManager; -import io.jsonwebtoken.lang.Assert; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; @@ -119,4 +123,47 @@ public class AliPaymentMangerImpl implements PaymentManager { } } + @Override + public boolean isOrderPaid(String orderNo) { + Assert.notEmpty(orderNo); + AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl, appId, privateKey, DEFAULT_FORMAT, charset, + alipayPublicKey, signType); + // 构造请求参数以调用接口 + AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); + AlipayTradeQueryModel model = new AlipayTradeQueryModel(); + model.setOutTradeNo(orderNo); + request.setBizModel(model); + AlipayTradeQueryResponse response = null; + try { + response = alipayClient.execute(request); + if (response.isSuccess()) { + String tradeStatus = JSON.parseObject(response.getBody()) + .getJSONObject("alipay_trade_query_response") + .getString("trade_status"); + //交易支付成功 + if ("TRADE_SUCCESS".equals(tradeStatus) + //交易结束,不可退款 + || "TRADE_FINISHED".equals(tradeStatus)) { + return true; + } + return false; + } else { + //获取诊断链接 + String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response); + log.warn("查询订单支付结果异常: {}", diagnosisUrl); + //获取错误码 + String subCode = JSON.parseObject(response.getBody()) + .getJSONObject("alipay_trade_query_response") + .getString("sub_code"); + if ("ACQ.TRADE_NOT_EXIST".equals(subCode)) { + //交易不存在 + return false; + } + } + } catch (Exception e) { + log.error("查询订单支付结果异常", e); + } + throw new ServiceException("查询订单支付结果失败"); + } + } diff --git a/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreOrderMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreOrderMapper.java index 0732924ca..c12e3c059 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreOrderMapper.java +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreOrderMapper.java @@ -2,12 +2,18 @@ package com.ruoyi.xkt.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.xkt.domain.StoreOrder; +import com.ruoyi.xkt.dto.order.StoreOrderPageItemDTO; +import com.ruoyi.xkt.dto.order.StoreOrderQueryDTO; import org.springframework.stereotype.Repository; +import java.util.List; + /** * @author liangyq * @date 2025-04-02 12:48 */ @Repository public interface StoreOrderMapper extends BaseMapper { + + List listStoreOrderPageItem(StoreOrderQueryDTO queryDTO); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IExpressService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IExpressService.java index 0cf538286..aae8659d4 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IExpressService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IExpressService.java @@ -7,6 +7,7 @@ import com.ruoyi.xkt.dto.express.ExpressContactDTO; import java.util.Collection; import java.util.List; +import java.util.Map; /** * @author liangyq @@ -55,4 +56,11 @@ public interface IExpressService { * @return */ List listRegionByCode(Collection regionCodes); + + /** + * 获取缓存的行政编码 + * + * @return + */ + Map getRegionMapCache(); } 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 e9037bcb6..46117eb83 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java @@ -1,5 +1,6 @@ package com.ruoyi.xkt.service; +import com.github.pagehelper.Page; import com.ruoyi.xkt.domain.StoreOrder; import com.ruoyi.xkt.dto.order.*; import com.ruoyi.xkt.enums.EPayChannel; @@ -48,6 +49,14 @@ public interface IStoreOrderService { */ StoreOrderInfoDTO getInfo(Long storeOrderId); + /** + * 分页查询订单 + * + * @param queryDTO + * @return + */ + Page page(StoreOrderQueryDTO queryDTO); + /** * 准备支付订单 * @@ -65,4 +74,11 @@ public interface IStoreOrderService { * @return */ StoreOrderExt paySuccess(Long storeOrderId, BigDecimal totalAmount, BigDecimal realTotalAmount); + + /** + * 取消订单 + * + * @param opt + */ + void cancelOrder(OrderOptDTO opt); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/ExpressServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/ExpressServiceImpl.java index 52764471c..c7187ab5f 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/ExpressServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/ExpressServiceImpl.java @@ -4,6 +4,8 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.lang.Assert; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.utils.bean.BeanValidators; import com.ruoyi.xkt.domain.Express; import com.ruoyi.xkt.domain.ExpressFeeConfig; @@ -20,6 +22,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -46,6 +49,8 @@ public class ExpressServiceImpl implements IExpressService { private ExpressRegionMapper expressRegionMapper; @Autowired private StoreMapper storeMapper; + @Autowired + private RedisCache redisCache; @Override public void checkExpress(Long expressId) { @@ -115,4 +120,15 @@ public class ExpressServiceImpl implements IExpressService { return expressRegionMapper.selectList(Wrappers.lambdaQuery(ExpressRegion.class) .in(ExpressRegion::getRegionCode, regionCodes)); } + + @Override + public Map getRegionMapCache() { + Map regionMap = redisCache.getCacheMap(Constants.REGION_MAP_CACHE_KEY); + if (regionMap == null || regionMap.isEmpty()) { + regionMap = expressRegionMapper.selectList(Wrappers.emptyWrapper()).stream() + .collect(Collectors.toMap(ExpressRegion::getRegionCode, Function.identity())); + redisCache.setCacheMap(Constants.REGION_MAP_CACHE_KEY, regionMap); + } + return regionMap; + } } 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 7eec085f7..e52c4448b 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 @@ -6,6 +6,8 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.NumberUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.SimpleEntity; import com.ruoyi.common.core.domain.XktBaseEntity; @@ -14,6 +16,7 @@ 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.*; +import com.ruoyi.xkt.dto.storeProductFile.StoreProdMainPicDTO; import com.ruoyi.xkt.enums.*; import com.ruoyi.xkt.manager.PaymentManager; import com.ruoyi.xkt.mapper.*; @@ -34,6 +37,8 @@ import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; +import static com.ruoyi.common.constant.Constants.ORDER_NUM_1; + /** * @author liangyq * @date 2025-04-02 13:19 @@ -46,6 +51,8 @@ public class StoreOrderServiceImpl implements IStoreOrderService { @Autowired private StoreOrderDetailMapper storeOrderDetailMapper; @Autowired + private StoreMapper storeMapper; + @Autowired private StoreProductMapper storeProductMapper; @Autowired private StoreProductColorSizeMapper storeProductColorSizeMapper; @@ -64,7 +71,7 @@ public class StoreOrderServiceImpl implements IStoreOrderService { @Autowired private List paymentManagers; - @Transactional + @Transactional(rollbackFor = Exception.class) @Override public StoreOrderAddResult createOrder(StoreOrderAddDTO storeOrderAddDTO, boolean beginPay, EPayChannel payChannel, EPayPage payPage) { @@ -196,7 +203,7 @@ public class StoreOrderServiceImpl implements IStoreOrderService { return new StoreOrderAddResult(orderExt, rtnStr); } - @Transactional + @Transactional(rollbackFor = Exception.class) @Override public StoreOrderExt modifyOrder(StoreOrderUpdateDTO storeOrderUpdateDTO) { //原订单 @@ -348,21 +355,28 @@ public class StoreOrderServiceImpl implements IStoreOrderService { List detailInfos = BeanUtil.copyToList(details, StoreOrderDetailInfoDTO.class); orderInfo.setOrderDetails(detailInfos); + //档口信息 + Store store = storeMapper.selectById(order.getStoreId()); + if (store != null) { + orderInfo.setStoreName(store.getStoreName()); + orderInfo.setBrandName(store.getBrandName()); + } //物流信息 Express express = expressService.getById(order.getExpressId()); orderInfo.setExpressName(Optional.ofNullable(express).map(Express::getExpressName).orElse(null)); - Map regionNameMap = expressService.listRegionByCode(Arrays - .asList(order.getDestinationProvinceCode(), order.getDestinationCityCode(), - order.getDestinationCountyCode(), order.getOriginProvinceCode(), - order.getOriginCityCode(), order.getOriginCountyCode())) - .stream() - .collect(Collectors.toMap(ExpressRegion::getRegionCode, ExpressRegion::getRegionName)); - orderInfo.setDestinationProvinceName(regionNameMap.get(orderInfo.getDestinationProvinceCode())); - orderInfo.setDestinationCityName(regionNameMap.get(orderInfo.getDestinationCityCode())); - orderInfo.setDestinationCountyName(regionNameMap.get(orderInfo.getDestinationCountyCode())); - orderInfo.setOriginProvinceName(regionNameMap.get(orderInfo.getOriginProvinceCode())); - orderInfo.setOriginCityName(regionNameMap.get(orderInfo.getOriginCityCode())); - orderInfo.setOriginCountyName(regionNameMap.get(orderInfo.getOriginCountyCode())); + Map regionMap = expressService.getRegionMapCache(); + orderInfo.setDestinationProvinceName(Optional.ofNullable(regionMap.get(orderInfo.getDestinationProvinceCode())) + .map(ExpressRegion::getParentRegionName).orElse(null)); + orderInfo.setDestinationCityName(Optional.ofNullable(regionMap.get(orderInfo.getDestinationCityCode())) + .map(ExpressRegion::getParentRegionName).orElse(null)); + orderInfo.setDestinationCountyName(Optional.ofNullable(regionMap.get(orderInfo.getDestinationCountyCode())) + .map(ExpressRegion::getParentRegionName).orElse(null)); + orderInfo.setOriginProvinceName(Optional.ofNullable(regionMap.get(orderInfo.getOriginProvinceCode())) + .map(ExpressRegion::getParentRegionName).orElse(null)); + orderInfo.setOriginCityName(Optional.ofNullable(regionMap.get(orderInfo.getOriginCityCode())) + .map(ExpressRegion::getParentRegionName).orElse(null)); + orderInfo.setOriginCountyName(Optional.ofNullable(regionMap.get(orderInfo.getOriginCountyCode())) + .map(ExpressRegion::getParentRegionName).orElse(null)); //商品信息 for (StoreOrderDetailInfoDTO detailInfo : detailInfos) { detailInfo.setFileList(storeProductFileMapper.selectListByStoreProdId(detailInfo.getStoreProdId())); @@ -370,7 +384,52 @@ public class StoreOrderServiceImpl implements IStoreOrderService { return orderInfo; } - @Transactional + @Override + public Page page(StoreOrderQueryDTO queryDTO) { + Page page = PageHelper.startPage(queryDTO.getPageNum(), queryDTO.getPageSize()); + storeOrderMapper.listStoreOrderPageItem(queryDTO); + if (CollUtil.isNotEmpty(page.getResult())) { + List list = page.getResult(); + Set soIds = list.stream().map(StoreOrderPageItemDTO::getId).collect(Collectors.toSet()); + List orderDetailList = storeOrderDetailMapper.selectList(Wrappers + .lambdaQuery(StoreOrderDetail.class).eq(SimpleEntity::getDelFlag, Constants.UNDELETED) + .in(StoreOrderDetail::getStoreOrderId, soIds)); + List spIds = orderDetailList.stream().map(StoreOrderDetail::getStoreProdId).distinct() + .collect(Collectors.toList()); + Map mainPicMap = storeProductFileMapper.selectMainPicByStoreProdIdList(spIds, + FileType.MAIN_PIC.getValue(), ORDER_NUM_1).stream() + .collect(Collectors.toMap(StoreProdMainPicDTO::getStoreProdId, StoreProdMainPicDTO::getFileUrl, + (o, n) -> n)); + Map> orderDetailGroup = BeanUtil.copyToList(orderDetailList, + StoreOrderPageItemDTO.Detail.class) + .stream() + .collect(Collectors.groupingBy(StoreOrderDetailDTO::getStoreOrderId)); + Map regionMap = expressService.getRegionMapCache(); + for (StoreOrderPageItemDTO order : list) { + //物流信息 + order.setDestinationProvinceName(Optional.ofNullable(regionMap.get(order.getDestinationProvinceCode())) + .map(ExpressRegion::getParentRegionName).orElse(null)); + order.setDestinationCityName(Optional.ofNullable(regionMap.get(order.getDestinationCityCode())) + .map(ExpressRegion::getParentRegionName).orElse(null)); + order.setDestinationCountyName(Optional.ofNullable(regionMap.get(order.getDestinationCountyCode())) + .map(ExpressRegion::getParentRegionName).orElse(null)); + order.setOriginProvinceName(Optional.ofNullable(regionMap.get(order.getOriginProvinceCode())) + .map(ExpressRegion::getParentRegionName).orElse(null)); + order.setOriginCityName(Optional.ofNullable(regionMap.get(order.getOriginCityCode())) + .map(ExpressRegion::getParentRegionName).orElse(null)); + order.setOriginCountyName(Optional.ofNullable(regionMap.get(order.getOriginCountyCode())) + .map(ExpressRegion::getParentRegionName).orElse(null)); + order.setOrderDetails(orderDetailGroup.get(order.getId())); + for (StoreOrderPageItemDTO.Detail detail : order.getOrderDetails()) { + //首图 + detail.setFirstMainPicUrl(mainPicMap.get(detail.getStoreProdId())); + } + } + } + return page; + } + + @Transactional(rollbackFor = Exception.class) @Override public StoreOrderExt preparePayOrder(Long storeOrderId) { Assert.notNull(storeOrderId); @@ -399,7 +458,7 @@ public class StoreOrderServiceImpl implements IStoreOrderService { return new StoreOrderExt(order, orderDetails); } - @Transactional + @Transactional(rollbackFor = Exception.class) @Override public StoreOrderExt paySuccess(Long storeOrderId, BigDecimal totalAmount, BigDecimal realTotalAmount) { Assert.notNull(storeOrderId); @@ -451,6 +510,51 @@ public class StoreOrderServiceImpl implements IStoreOrderService { return new StoreOrderExt(order, orderDetails); } + @Transactional(rollbackFor = Exception.class) + @Override + public void cancelOrder(OrderOptDTO opt) { + Assert.notNull(opt.getStoreOrderId()); + StoreOrder order = storeOrderMapper.selectById(opt.getStoreOrderId()); + Assert.isTrue(BeanValidators.exists(order), "订单不存在"); + EOrderStatus oStatus = EOrderStatus.of(order.getOrderStatus()); + EPayStatus pStatus = EPayStatus.of(order.getPayStatus()); + if (EOrderStatus.PENDING_PAYMENT != oStatus) { + throw new ServiceException("订单[" + order.getOrderNo() + "]状态为[" + oStatus.getLabel() + "],无法取消"); + } + if (EPayStatus.PAID == pStatus) { + throw new ServiceException("订单[" + order.getOrderNo() + "]已支付完成,无法取消"); + } + //目前只有支付宝 + PaymentManager paymentManager = getPaymentManager(EPayChannel.ALI_PAY); + boolean isPaid = paymentManager.isOrderPaid(order.getOrderNo()); + if (isPaid) { + throw new ServiceException("订单[" + order.getOrderNo() + "]已支付,无法取消"); + } + //订单已取消 + order.setOrderStatus(EOrderStatus.CANCELLED.getValue()); + int orderSuccess = storeOrderMapper.updateById(order); + if (orderSuccess == 0) { + throw new ServiceException(Constants.VERSION_LOCK_ERROR_COMMON_MSG); + } + List orderDetails = storeOrderDetailMapper.selectList( + Wrappers.lambdaQuery(StoreOrderDetail.class) + .eq(StoreOrderDetail::getStoreOrderId, order.getId()) + .eq(SimpleEntity::getDelFlag, Constants.UNDELETED)); + List orderDetailIdList = new ArrayList<>(orderDetails.size()); + for (StoreOrderDetail orderDetail : orderDetails) { + //明细已取消 + orderDetail.setDetailStatus(EOrderStatus.CANCELLED.getValue()); + int orderDetailSuccess = storeOrderDetailMapper.updateById(orderDetail); + if (orderDetailSuccess == 0) { + throw new ServiceException(Constants.VERSION_LOCK_ERROR_COMMON_MSG); + } + orderDetailIdList.add(orderDetail.getId()); + } + //操作记录 + addOperationRecords(order.getId(), EOrderAction.CANCEL, orderDetailIdList, EOrderAction.CANCEL, + opt.getOperatorId(), new Date()); + } + private void checkPreparePayStatus(Integer payStatus) { if (!EPayStatus.INIT.getValue().equals(payStatus) && !EPayStatus.PAYING.getValue().equals(payStatus)) { throw new ServiceException("订单状态异常无法发起支付"); diff --git a/xkt/src/main/resources/mapper/StoreOrderMapper.xml b/xkt/src/main/resources/mapper/StoreOrderMapper.xml index ccfbb80d3..69e344bad 100644 --- a/xkt/src/main/resources/mapper/StoreOrderMapper.xml +++ b/xkt/src/main/resources/mapper/StoreOrderMapper.xml @@ -2,4 +2,52 @@ + \ No newline at end of file