diff --git a/sql/mysql/mall.sql b/sql/mysql/mall.sql
new file mode 100644
index 000000000..70ce52af4
--- /dev/null
+++ b/sql/mysql/mall.sql
@@ -0,0 +1,2 @@
+INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name)
+VALUES ('核销订单', '', 2, 2, 2166, 'pick-up-order', 'ep:list', 'mall/trade/delivery/pickUpOrder/index', 'PickUpOrder');
\ No newline at end of file
diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/MPJLambdaWrapperX.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/MPJLambdaWrapperX.java
new file mode 100644
index 000000000..7950a2f96
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/MPJLambdaWrapperX.java
@@ -0,0 +1,313 @@
+package cn.iocoder.yudao.framework.mybatis.core.query;
+
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+import com.github.yulichang.toolkit.MPJWrappers;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import org.springframework.util.StringUtils;
+
+import java.util.Collection;
+import java.util.function.Consumer;
+
+/**
+ * 拓展 MyBatis Plus Join QueryWrapper 类,主要增加如下功能:
+ *
+ * 1. 拼接条件的方法,增加 xxxIfPresent 方法,用于判断值不存在的时候,不要拼接到条件中。
+ *
+ * @param 数据类型
+ */
+public class MPJLambdaWrapperX extends MPJLambdaWrapper {
+
+ public MPJLambdaWrapperX likeIfPresent(SFunction column, String val) {
+ MPJWrappers.lambdaJoin().like(column, val);
+ if (StringUtils.hasText(val)) {
+ return (MPJLambdaWrapperX) super.like(column, val);
+ }
+ return this;
+ }
+
+ public MPJLambdaWrapperX inIfPresent(SFunction column, Collection> values) {
+ if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
+ return (MPJLambdaWrapperX) super.in(column, values);
+ }
+ return this;
+ }
+
+ public MPJLambdaWrapperX inIfPresent(SFunction column, Object... values) {
+ if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
+ return (MPJLambdaWrapperX) super.in(column, values);
+ }
+ return this;
+ }
+
+ public MPJLambdaWrapperX eqIfPresent(SFunction column, Object val) {
+ if (ObjectUtil.isNotEmpty(val)) {
+ return (MPJLambdaWrapperX) super.eq(column, val);
+ }
+ return this;
+ }
+
+ public MPJLambdaWrapperX neIfPresent(SFunction column, Object val) {
+ if (ObjectUtil.isNotEmpty(val)) {
+ return (MPJLambdaWrapperX) super.ne(column, val);
+ }
+ return this;
+ }
+
+ public MPJLambdaWrapperX gtIfPresent(SFunction column, Object val) {
+ if (val != null) {
+ return (MPJLambdaWrapperX) super.gt(column, val);
+ }
+ return this;
+ }
+
+ public MPJLambdaWrapperX geIfPresent(SFunction column, Object val) {
+ if (val != null) {
+ return (MPJLambdaWrapperX) super.ge(column, val);
+ }
+ return this;
+ }
+
+ public MPJLambdaWrapperX ltIfPresent(SFunction column, Object val) {
+ if (val != null) {
+ return (MPJLambdaWrapperX) super.lt(column, val);
+ }
+ return this;
+ }
+
+ public MPJLambdaWrapperX leIfPresent(SFunction column, Object val) {
+ if (val != null) {
+ return (MPJLambdaWrapperX) super.le(column, val);
+ }
+ return this;
+ }
+
+ public MPJLambdaWrapperX betweenIfPresent(SFunction column, Object val1, Object val2) {
+ if (val1 != null && val2 != null) {
+ return (MPJLambdaWrapperX) super.between(column, val1, val2);
+ }
+ if (val1 != null) {
+ return (MPJLambdaWrapperX) ge(column, val1);
+ }
+ if (val2 != null) {
+ return (MPJLambdaWrapperX) le(column, val2);
+ }
+ return this;
+ }
+
+ public MPJLambdaWrapperX betweenIfPresent(SFunction column, Object[] values) {
+ Object val1 = ArrayUtils.get(values, 0);
+ Object val2 = ArrayUtils.get(values, 1);
+ return betweenIfPresent(column, val1, val2);
+ }
+
+ // ========== 重写父类方法,方便链式调用 ==========
+
+ @Override
+ public MPJLambdaWrapperX eq(boolean condition, SFunction column, Object val) {
+ super.eq(condition, column, val);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX eq(SFunction column, Object val) {
+ super.eq(column, val);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX orderByDesc(SFunction column) {
+ //noinspection unchecked
+ super.orderByDesc(true, column);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX last(String lastSql) {
+ super.last(lastSql);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX in(SFunction column, Collection> coll) {
+ super.in(column, coll);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectAll(Class> clazz) {
+ super.selectAll(clazz);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectAll(Class> clazz, String prefix) {
+ super.selectAll(clazz, prefix);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectAs(SFunction column, String alias) {
+ super.selectAs(column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectAs(String column, SFunction alias) {
+ super.selectAs(column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectAs(SFunction column, SFunction alias) {
+ super.selectAs(column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectAs(String index, SFunction column, SFunction alias) {
+ super.selectAs(index, column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectAsClass(Class source, Class> tag) {
+ super.selectAsClass(source, tag);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectSub(Class clazz, Consumer> consumer, SFunction alias) {
+ super.selectSub(clazz, consumer, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectSub(Class clazz, String st, Consumer> consumer, SFunction alias) {
+ super.selectSub(clazz, st, consumer, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectCount(SFunction column) {
+ super.selectCount(column);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectCount(Object column, String alias) {
+ super.selectCount(column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectCount(Object column, SFunction alias) {
+ super.selectCount(column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectCount(SFunction column, String alias) {
+ super.selectCount(column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectCount(SFunction column, SFunction alias) {
+ super.selectCount(column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectSum(SFunction column) {
+ super.selectSum(column);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectSum(SFunction column, String alias) {
+ super.selectSum(column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectSum(SFunction column, SFunction alias) {
+ super.selectSum(column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectMax(SFunction column) {
+ super.selectMax(column);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectMax(SFunction column, String alias) {
+ super.selectMax(column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectMax(SFunction column, SFunction alias) {
+ super.selectMax(column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectMin(SFunction column) {
+ super.selectMin(column);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectMin(SFunction column, String alias) {
+ super.selectMin(column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectMin(SFunction column, SFunction alias) {
+ super.selectMin(column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectAvg(SFunction column) {
+ super.selectAvg(column);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectAvg(SFunction column, String alias) {
+ super.selectAvg(column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectAvg(SFunction column, SFunction alias) {
+ super.selectAvg(column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectLen(SFunction column) {
+ super.selectLen(column);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectLen(SFunction column, String alias) {
+ super.selectLen(column, alias);
+ return this;
+ }
+
+ @Override
+ public MPJLambdaWrapperX selectLen(SFunction column, SFunction alias) {
+ super.selectLen(column, alias);
+ return this;
+ }
+
+}
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 9853d1813..5d4e07e78 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
@@ -24,8 +24,11 @@ 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 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;
@Tag(name = "管理后台 - 交易订单")
@@ -56,7 +59,9 @@ public class TradeOrderController {
}
// 查询用户信息
- Map userMap = memberUserApi.getUserMap(convertSet(pageResult.getList(), TradeOrderDO::getUserId));
+ Set userIds = CollUtil.unionDistinct(convertList(pageResult.getList(), TradeOrderDO::getUserId),
+ convertList(pageResult.getList(), TradeOrderDO::getBrokerageUserId, Objects::nonNull));
+ Map userMap = memberUserApi.getUserMap(userIds);
// 查询订单项
List orderItems = tradeOrderQueryService.getOrderItemListByOrderId(
convertSet(pageResult.getList(), TradeOrderDO::getId));
@@ -64,6 +69,13 @@ public class TradeOrderController {
return success(TradeOrderConvert.INSTANCE.convertPage(pageResult, orderItems, userMap));
}
+ @GetMapping("/summary")
+ @Operation(summary = "获得交易订单统计")
+ @PreAuthorize("@ss.hasPermission('trade:order:query')")
+ public CommonResult getOrderSummary(TradeOrderPageReqVO reqVO) {
+ return success(tradeOrderQueryService.getOrderSummary(reqVO));
+ }
+
@GetMapping("/get-detail")
@Operation(summary = "获得交易订单详情")
@Parameter(name = "id", description = "订单编号", required = true, example = "1")
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java
index 29875c8da..88f5b0cd4 100755
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java
@@ -145,4 +145,7 @@ public class TradeOrderBaseVO {
@Schema(description = "VIP 减免金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
private Integer vipPrice;
+ @Schema(description = "推广人编号", example = "1")
+ private Long brokerageUserId;
+
}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java
index b0def5a83..704067ed0 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java
@@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.trade.controller.admin.order.vo;
-import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
+import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@@ -14,24 +14,20 @@ public class TradeOrderPageItemRespVO extends TradeOrderBaseVO {
@Schema(description = "收件人地区名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "上海 上海市 普陀区")
private String receiverAreaName;
- /**
- * 订单项列表
- */
+ @Schema(description = "订单项列表", requiredMode = Schema.RequiredMode.REQUIRED)
private List- items;
- // TODO @xiaobai:使用 MemberUserRespVO 返回哈;DTO 不直接给前端
- /**
- * 用户信息
- */
- private MemberUserRespDTO user;
+ @Schema(description = "用户信息", requiredMode = Schema.RequiredMode.REQUIRED)
+ private MemberUserRespVO user;
+
+ @Schema(description = "推广人信息")
+ private MemberUserRespVO brokerageUser;
@Schema(description = "管理后台 - 交易订单的分页项的订单项目")
@Data
public static class Item extends TradeOrderItemBaseVO {
- /**
- * 属性数组
- */
+ @Schema(description = "属性列表", requiredMode = Schema.RequiredMode.REQUIRED)
private List properties;
}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderSummaryRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderSummaryRespVO.java
new file mode 100644
index 000000000..184c8db83
--- /dev/null
+++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderSummaryRespVO.java
@@ -0,0 +1,22 @@
+package cn.iocoder.yudao.module.trade.controller.admin.order.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "管理后台 - 交易订单统计 Response VO")
+@Data
+public class TradeOrderSummaryRespVO {
+
+ @Schema(description = "订单数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long orderCount;
+
+ @Schema(description = "订单金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long orderPayPrice;
+
+ @Schema(description = "退款单数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long afterSaleCount;
+
+ @Schema(description = "退款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
+ private Long afterSalePrice;
+
+}
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 40260ae4b..6e59df639 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
@@ -124,13 +124,17 @@ public interface TradeOrderConvert {
TradeOrderPageItemRespVO orderVO = convert(order, xOrderItems);
// 处理收货地址
orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId()));
- // 增加用户昵称
- orderVO.setUser(memberUserMap.get(orderVO.getUserId()));
+ // 增加用户信息
+ orderVO.setUser(convertUser(memberUserMap.get(orderVO.getUserId())));
+ // 增加推广人信息
+ orderVO.setBrokerageUser(convertUser(memberUserMap.get(orderVO.getBrokerageUserId())));
return orderVO;
});
return new PageResult<>(orderVOs, pageResult.getTotal());
}
+ MemberUserRespVO convertUser(MemberUserRespDTO memberUserRespDTO);
+
TradeOrderPageItemRespVO convert(TradeOrderDO order, List items);
ProductPropertyValueDetailRespVO convert(ProductPropertyValueDetailRespDTO bean);
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 fce4e0742..81abbdfc7 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
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.dal.mysql.order;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
@@ -11,6 +12,7 @@ import org.apache.ibatis.annotations.Mapper;
import java.time.LocalDateTime;
import java.util.List;
+import java.util.Map;
import java.util.Set;
@Mapper
@@ -42,6 +44,26 @@ public interface TradeOrderMapper extends BaseMapperX {
.orderByDesc(TradeOrderDO::getId));
}
+ default List