feat:订单导出

This commit is contained in:
dzc committed 2025-10-11 17:35:20 +08:00
1 parent 3fc386f8ff
commit c89a979427
9 files changed
+168 -13

No files matched your search

@@ -113,4 +113,11 @@ public enum TradeOrderStatusEnum implements ArrayValuable<Integer> {
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);
}
}
@@ -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<TradeOrderDO> list = tradeOrderQueryService.getOrderList(exportReqVO);
if (CollUtil.isEmpty(list)) return;
// 查询用户信息
Set<Long> userIds = CollUtil.unionDistinct(convertList(list, TradeOrderDO::getUserId), convertList(list, TradeOrderDO::getBrokerageUserId, Objects::nonNull));
Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(userIds);
// 查询订单项
List<TradeOrderItemDO> orderItems = tradeOrderQueryService.getOrderItemListByOrderId(convertSet(list, TradeOrderDO::getId));
Map<Long, List<TradeOrderItemDO>> orderItemMap = convertMultiMap(orderItems, TradeOrderItemDO::getOrderId);
// 组合
List<TradeOrderListExportVo> exportList = TradeOrderConvert.INSTANCE.convertList(list, orderItemMap, userMap);
ExcelUtils.write(response, "订单列表.xls", "数据", TradeOrderListExportVo.class, exportList);
}
}
@@ -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;
}
@@ -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<TradeOrderListExportVo> convertList(List<TradeOrderDO> list, Map<Long, List<TradeOrderItemDO>> orderMap, Map<Long, MemberUserRespDTO> memberUserMap) {
return CollectionUtils.convertList(list, order -> {
TradeOrderListExportVo exportEntity = new TradeOrderListExportVo();
// 购物车
List<TradeOrderItemDO> 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<TradeOrderItemDO> items);
@@ -151,6 +191,7 @@ public interface TradeOrderConvert {
orderVO.setLogs(convertList03(orderLogs));
return orderVO;
}
List<TradeOrderDetailRespVO.OrderLog> convertList03(List<TradeOrderLogDO> orderLogs);
TradeOrderDetailRespVO convert2(TradeOrderDO order, List<TradeOrderItemDO> items);
@@ -45,6 +45,23 @@ public interface TradeOrderMapper extends BaseMapperX<TradeOrderDO> {
.orderByDesc(TradeOrderDO::getId));
}
default List<TradeOrderDO> list(TradeOrderPageReqVO reqVO, Set<Long> userIds) {
return selectList(new LambdaQueryWrapperX<TradeOrderDO>()
.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<Map<String, Object>> selectOrderSummaryGroupByRefundStatus(TradeOrderPageReqVO reqVO, Set<Long> userIds) {
return selectMaps(new MPJLambdaWrapperX<TradeOrderDO>()
@@ -136,5 +153,4 @@ public interface TradeOrderMapper extends BaseMapperX<TradeOrderDO> {
.eq(TradeOrderDO::getCombinationActivityId, combinationActivityId)
);
}
}
@@ -58,6 +58,8 @@ public interface TradeOrderQueryService {
*/
List<TradeOrderDO> getOrderList(Collection<Long> ids);
List<TradeOrderDO> getOrderList(TradeOrderPageReqVO reqVO);
/**
* 【管理员】获得交易订单分页
*
@@ -87,6 +87,14 @@ public class TradeOrderQueryServiceImpl implements TradeOrderQueryService {
return tradeOrderMapper.selectBatchIds(ids);
}
@Override
public List<TradeOrderDO> getOrderList(TradeOrderPageReqVO reqVO) {
// 根据用户查询条件构建用户编号列表
Set<Long> userIds = buildQueryConditionUserIds(reqVO);
if (userIds == null) return new ArrayList<>();
return tradeOrderMapper.list(reqVO, userIds);
}
@Override
public PageResult<TradeOrderDO> getOrderPage(TradeOrderPageReqVO reqVO) {
// 根据用户查询条件构建用户编号列表
@@ -80,7 +80,7 @@ spring:
host: 127.0.0.1 # 地址
port: 6379 # 端口
database: 0 # 数据库索引
password: 123456 # 密码,建议生产环境开启
# password: 123456 # 密码,建议生产环境开启
--- #################### 定时任务相关配置 ####################
@@ -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'