From c89a97942739277aee638cd876bbb3c415bffae5 Mon Sep 17 00:00:00 2001 From: dzc <2388224167@qq.com> Date: Sat, 11 Oct 2025 17:35:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E8=AE=A2=E5=8D=95=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../enums/order/TradeOrderStatusEnum.java | 7 +++ .../admin/order/TradeOrderController.java | 33 ++++++++-- .../order/vo/TradeOrderListExportVo.java | 60 +++++++++++++++++++ .../convert/order/TradeOrderConvert.java | 41 +++++++++++++ .../dal/mysql/order/TradeOrderMapper.java | 18 +++++- .../service/order/TradeOrderQueryService.java | 2 + .../order/TradeOrderQueryServiceImpl.java | 8 +++ .../src/main/resources/application-local.yaml | 2 +- .../src/main/resources/application.yaml | 10 ++-- 9 files changed, 168 insertions(+), 13 deletions(-) create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderListExportVo.java diff --git a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java index d1f90eb..47a5466 100644 --- a/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java +++ b/yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/order/TradeOrderStatusEnum.java @@ -113,4 +113,11 @@ public enum TradeOrderStatusEnum implements ArrayValuable { return ObjectUtils.equalsAny(status, DELIVERED.getStatus(), COMPLETED.getStatus()); } + public static TradeOrderStatusEnum valueOfByStatus(Integer status) { + return Arrays.stream(values()) + .filter(value -> ObjectUtil.equal(value.getStatus(), status)) + .findFirst() + .orElse(null); + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java index 6a4d449..6689596 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java @@ -1,8 +1,10 @@ package cn.iocoder.yudao.module.trade.controller.admin.order; import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.module.member.api.user.MemberUserApi; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.*; @@ -23,14 +25,14 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import java.io.IOException; +import java.util.*; +import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @Tag(name = "管理后台 - 交易订单") @@ -189,4 +191,23 @@ public class TradeOrderController { return success(TradeOrderConvert.INSTANCE.convert2(tradeOrder, null)); } + @GetMapping("/export-excel") + @Operation(summary = "导出订单Excel") + @ApiAccessLog(operateType = EXPORT) + public void exportOrderExcel(@Valid TradeOrderPageReqVO exportReqVO, HttpServletResponse response) throws IOException { + // 查询订单 + List list = tradeOrderQueryService.getOrderList(exportReqVO); + if (CollUtil.isEmpty(list)) return; + // 查询用户信息 + Set userIds = CollUtil.unionDistinct(convertList(list, TradeOrderDO::getUserId), convertList(list, TradeOrderDO::getBrokerageUserId, Objects::nonNull)); + Map userMap = memberUserApi.getUserMap(userIds); + // 查询订单项 + List orderItems = tradeOrderQueryService.getOrderItemListByOrderId(convertSet(list, TradeOrderDO::getId)); + Map> orderItemMap = convertMultiMap(orderItems, TradeOrderItemDO::getOrderId); + // 组合 + List exportList = TradeOrderConvert.INSTANCE.convertList(list, orderItemMap, userMap); + + ExcelUtils.write(response, "订单列表.xls", "数据", TradeOrderListExportVo.class, exportList); + } + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderListExportVo.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderListExportVo.java new file mode 100644 index 0000000..818b7e2 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderListExportVo.java @@ -0,0 +1,60 @@ +package cn.iocoder.yudao.module.trade.controller.admin.order.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 订单导出类 + */ +@Schema(description = "管理后台 - 订单导出 Response VO") +@Data +@ExcelIgnoreUnannotated +public class TradeOrderListExportVo { + + @ExcelProperty("订单编号") + private Long id; + + @ExcelProperty("订单状态") + private String orderStatus; + + @ExcelProperty("订单商品描述") + private String orderDesc; + + @ExcelProperty("商品数量") + private String orderCount; + + @ExcelProperty("商品总金额") + private String orderTotalPrice; + + @ExcelProperty("支付总金额") + private String orderPayPrice; + + @ExcelProperty("买家姓名") + private String nickname; + + @ExcelProperty("收件人名称") + private String receiverName; + + @ExcelProperty("收件人手机") + private String receiverMobile; + + @ExcelProperty("收件人地区") + private String receiverArea; + + @ExcelProperty("收件人详细地址") + private String receiverDetailAddress; + + @ExcelProperty("发货物流单号") + private String logisticsNo; + + @ExcelProperty("发货时间") + private LocalDateTime deliveryTime; + + @ExcelProperty("下单时间") + private LocalDateTime createTime; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java index 45462a5..5df494f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.trade.convert.order; import cn.hutool.core.util.BooleanUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; @@ -31,6 +32,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderLogDO; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO; import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO; @@ -42,9 +44,12 @@ import org.mapstruct.Mappings; import org.mapstruct.Named; import org.mapstruct.factory.Mappers; +import java.math.BigDecimal; +import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap; @@ -132,6 +137,41 @@ public interface TradeOrderConvert { return new PageResult<>(orderVOs, pageResult.getTotal()); } + default List convertList(List list, Map> orderMap, Map memberUserMap) { + + return CollectionUtils.convertList(list, order -> { + TradeOrderListExportVo exportEntity = new TradeOrderListExportVo(); + // 购物车 + List xOrderItems = orderMap.get(order.getId()); + // 用户 + MemberUserRespDTO user = memberUserMap.get(order.getUserId()); + + exportEntity.setId(order.getId()); + exportEntity.setOrderStatus(TradeOrderStatusEnum.valueOfByStatus(order.getStatus()).getName()); + + String orderDesc = ""; + if (ObjectUtil.isNotEmpty(xOrderItems)) { + orderDesc = xOrderItems.stream().map(item -> item.getSpuName() + "x" + item.getCount()).collect(Collectors.joining(";")); + } + Integer totalCount = xOrderItems.stream().mapToInt(TradeOrderItemDO::getCount).sum(); + exportEntity.setOrderCount(totalCount + "件商品"); + exportEntity.setOrderDesc(orderDesc); + exportEntity.setOrderTotalPrice(BigDecimal.valueOf(order.getTotalPrice()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP) + "元"); + exportEntity.setOrderPayPrice(BigDecimal.valueOf(order.getPayPrice()).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP) + "元"); + exportEntity.setNickname(user.getNickname()); + exportEntity.setReceiverName(order.getReceiverName()); + exportEntity.setReceiverMobile(order.getReceiverMobile()); + exportEntity.setReceiverArea(AreaUtils.format(order.getReceiverAreaId())); + exportEntity.setReceiverDetailAddress(order.getReceiverDetailAddress()); + exportEntity.setLogisticsNo(order.getLogisticsNo()); + if (ObjectUtil.isNotEmpty(order.getDeliveryTime())) { + exportEntity.setDeliveryTime(order.getDeliveryTime()); + } + exportEntity.setCreateTime(order.getCreateTime()); + return exportEntity; + }); + } + MemberUserRespVO convertUser(MemberUserRespDTO memberUserRespDTO); TradeOrderPageItemRespVO convert(TradeOrderDO order, List items); @@ -151,6 +191,7 @@ public interface TradeOrderConvert { orderVO.setLogs(convertList03(orderLogs)); return orderVO; } + List convertList03(List orderLogs); TradeOrderDetailRespVO convert2(TradeOrderDO order, List items); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java index 9ea87e8..5c57601 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java @@ -45,6 +45,23 @@ public interface TradeOrderMapper extends BaseMapperX { .orderByDesc(TradeOrderDO::getId)); } + default List list(TradeOrderPageReqVO reqVO, Set userIds) { + return selectList(new LambdaQueryWrapperX() + .likeIfPresent(TradeOrderDO::getNo, reqVO.getNo()) + .eqIfPresent(TradeOrderDO::getUserId, reqVO.getUserId()) + .eqIfPresent(TradeOrderDO::getDeliveryType, reqVO.getDeliveryType()) + .inIfPresent(TradeOrderDO::getUserId, userIds) + .eqIfPresent(TradeOrderDO::getType, reqVO.getType()) + .eqIfPresent(TradeOrderDO::getStatus, reqVO.getStatus()) + .eqIfPresent(TradeOrderDO::getPayChannelCode, reqVO.getPayChannelCode()) + .eqIfPresent(TradeOrderDO::getTerminal, reqVO.getTerminal()) + .eqIfPresent(TradeOrderDO::getLogisticsId, reqVO.getLogisticsId()) + .inIfPresent(TradeOrderDO::getPickUpStoreId, reqVO.getPickUpStoreIds()) + .likeIfPresent(TradeOrderDO::getPickUpVerifyCode, reqVO.getPickUpVerifyCode()) + .betweenIfPresent(TradeOrderDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(TradeOrderDO::getId)); + } + // TODO @疯狂:如果用 map 返回,要不这里直接用 TradeOrderSummaryRespVO 返回?也算合理,就当 sql 查询出这么个玩意~~ default List> selectOrderSummaryGroupByRefundStatus(TradeOrderPageReqVO reqVO, Set userIds) { return selectMaps(new MPJLambdaWrapperX() @@ -136,5 +153,4 @@ public interface TradeOrderMapper extends BaseMapperX { .eq(TradeOrderDO::getCombinationActivityId, combinationActivityId) ); } - } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java index d250964..015c169 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java @@ -58,6 +58,8 @@ public interface TradeOrderQueryService { */ List getOrderList(Collection ids); + List getOrderList(TradeOrderPageReqVO reqVO); + /** * 【管理员】获得交易订单分页 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java index c51aee1..8b0d01e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java @@ -87,6 +87,14 @@ public class TradeOrderQueryServiceImpl implements TradeOrderQueryService { return tradeOrderMapper.selectBatchIds(ids); } + @Override + public List getOrderList(TradeOrderPageReqVO reqVO) { + // 根据用户查询条件构建用户编号列表 + Set userIds = buildQueryConditionUserIds(reqVO); + if (userIds == null) return new ArrayList<>(); + return tradeOrderMapper.list(reqVO, userIds); + } + @Override public PageResult getOrderPage(TradeOrderPageReqVO reqVO) { // 根据用户查询条件构建用户编号列表 diff --git a/yudao-server/src/main/resources/application-local.yaml b/yudao-server/src/main/resources/application-local.yaml index 7e86831..4285195 100644 --- a/yudao-server/src/main/resources/application-local.yaml +++ b/yudao-server/src/main/resources/application-local.yaml @@ -80,7 +80,7 @@ spring: host: 127.0.0.1 # 地址 port: 6379 # 端口 database: 0 # 数据库索引 - password: 123456 # 密码,建议生产环境开启 + # password: 123456 # 密码,建议生产环境开启 --- #################### 定时任务相关配置 #################### diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index 7a48bcf..325c183 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -3,8 +3,8 @@ spring: name: yudao-server profiles: - active: prod -# active: local + # active: prod + active: local main: allow-circular-references: true # 允许循环依赖,因为项目是三层架构,无法避免这个情况。 @@ -366,10 +366,10 @@ pf4j: sto: -# 正式环境 + # 正式环境 api_url: 'https://cloudinter-linkgateway.sto.cn/gateway/link.do' -# 测试环境 -# api_url: 'http://cloudinter-linkgatewaytest.sto.cn/gateway/link.do' + # 测试环境 + # api_url: 'http://cloudinter-linkgatewaytest.sto.cn/gateway/link.do' from_appkey: 'CAKWRKlMXSPewDL' from_code: 'CAKWRKlMXSPewDL' to_appkey: 'sto_oms'