Browse Source

trade: 分销业务后台功能:推广订单列表

owen 1 year ago
parent
commit
6c193f723f

+ 19 - 17
sql/mysql/brokerage.sql

@@ -44,24 +44,26 @@ create index idx_agent on trade_brokerage_user (brokerage_enabled) comment '是
 
 create table trade_brokerage_record
 (
-    id            int auto_increment comment '编号'
+    id               int auto_increment comment '编号'
         primary key,
-    user_id       bigint                                                           not null comment '用户编号',
-    biz_id        varchar(64)                            default ''                not null comment '业务编号',
-    biz_type      tinyint                                default 0                 not null comment '业务类型:0-订单,1-提现',
-    title         varchar(64)                            default ''                not null comment '标题',
-    price         int                                    default 0                 not null comment '金额',
-    total_price   int                                    default 0                 not null comment '当前总佣金',
-    description   varchar(500)                           default ''                not null comment '说明',
-    status        tinyint                                default 0                 not null comment '状态:0-待结算,1-已结算,2-已取消',
-    frozen_days   int                                    default 0                 not null comment '冻结时间(天)',
-    unfreeze_time datetime                                                         null comment '解冻时间',
-    creator       varchar(64) collate utf8mb4_general_ci default ''                null comment '创建者',
-    create_time   datetime                               default CURRENT_TIMESTAMP not null comment '创建时间',
-    updater       varchar(64) collate utf8mb4_general_ci default ''                null comment '更新者',
-    update_time   datetime                               default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
-    deleted       bit                                    default b'0'              not null comment '是否删除',
-    tenant_id     bigint                                 default 0                 not null comment '租户编号'
+    user_id          bigint                                                           not null comment '用户编号',
+    biz_id           varchar(64)                            default ''                not null comment '业务编号',
+    biz_type         tinyint                                default 0                 not null comment '业务类型:1-订单,2-提现',
+    title            varchar(64)                            default ''                not null comment '标题',
+    price            int                                    default 0                 not null comment '金额',
+    total_price      int                                    default 0                 not null comment '当前总佣金',
+    description      varchar(500)                           default ''                not null comment '说明',
+    status           tinyint                                default 0                 not null comment '状态:0-待结算,1-已结算,2-已取消',
+    frozen_days      int                                    default 0                 not null comment '冻结时间(天)',
+    unfreeze_time    datetime                                                         null comment '解冻时间',
+    source_user_type tinyint                                                          not null comment '来源用户类型:1-一级推广用户,2-二级推广用户',
+    source_user_id   bigint                                                           not null comment '来源用户编号',
+    creator          varchar(64) collate utf8mb4_general_ci default ''                null comment '创建者',
+    create_time      datetime                               default CURRENT_TIMESTAMP not null comment '创建时间',
+    updater          varchar(64) collate utf8mb4_general_ci default ''                null comment '更新者',
+    update_time      datetime                               default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
+    deleted          bit                                    default b'0'              not null comment '是否删除',
+    tenant_id        bigint                                 default 0                 not null comment '租户编号'
 )
     comment '佣金记录';
 

+ 15 - 1
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/BrokerageRecordController.java

@@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.trade.controller.admin.brokerage.record;
 
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+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.brokerage.record.vo.BrokerageRecordPageReqVO;
 import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordRespVO;
 import cn.iocoder.yudao.module.trade.convert.brokerage.record.BrokerageRecordConvert;
@@ -19,8 +21,12 @@ import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
+import java.util.Map;
+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 = "管理后台 - 佣金记录")
 @RestController
@@ -31,6 +37,9 @@ public class BrokerageRecordController {
     @Resource
     private BrokerageRecordService brokerageRecordService;
 
+    @Resource
+    private MemberUserApi memberUserApi;
+
     @GetMapping("/get")
     @Operation(summary = "获得佣金记录")
     @Parameter(name = "id", description = "编号", required = true, example = "1024")
@@ -45,7 +54,12 @@ public class BrokerageRecordController {
     @PreAuthorize("@ss.hasPermission('trade:brokerage-record:query')")
     public CommonResult<PageResult<BrokerageRecordRespVO>> getBrokerageRecordPage(@Valid BrokerageRecordPageReqVO pageVO) {
         PageResult<BrokerageRecordDO> pageResult = brokerageRecordService.getBrokerageRecordPage(pageVO);
-        return success(BrokerageRecordConvert.INSTANCE.convertPage(pageResult));
+
+        Set<Long> userIds = convertSet(pageResult.getList(), BrokerageRecordDO::getUserId);
+        userIds.addAll(convertList(pageResult.getList(), BrokerageRecordDO::getSourceUserId));
+        Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(userIds);
+
+        return success(BrokerageRecordConvert.INSTANCE.convertPage(pageResult, userMap));
     }
 
 }

+ 5 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/vo/BrokerageRecordBaseVO.java

@@ -57,4 +57,9 @@ public class BrokerageRecordBaseVO {
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private LocalDateTime unfreezeTime;
 
+    @Schema(description = "来源用户类型")
+    private Integer sourceUserType;
+
+    @Schema(description = "来源用户编号")
+    private Long sourceUserId;
 }

+ 6 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/vo/BrokerageRecordPageReqVO.java

@@ -1,6 +1,8 @@
 package cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo;
 
 import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import cn.iocoder.yudao.framework.common.validation.InEnum;
+import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -30,4 +32,8 @@ public class BrokerageRecordPageReqVO extends PageParam {
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private LocalDateTime[] createTime;
 
+    @Schema(description = "用户类型")
+    @InEnum(value = BrokerageUserTypeEnum.class, message = "用户类型必须是 {value}")
+    private Integer sourceUserType;
+
 }

+ 15 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/vo/BrokerageRecordRespVO.java

@@ -19,4 +19,19 @@ public class BrokerageRecordRespVO extends BrokerageRecordBaseVO {
     @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
     private LocalDateTime createTime;
 
+
+    // ========== 用户信息 ==========
+
+    @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png")
+    private String userAvatar;
+    @Schema(description = "用户昵称", example = "李四")
+    private String userNickname;
+
+
+    // ========== 来源用户信息 ==========
+
+    @Schema(description = "来源用户头像", example = "https://www.iocoder.cn/xxx.png")
+    private String sourceUserAvatar;
+    @Schema(description = "来源用户昵称", example = "李四")
+    private String sourceUserNickname;
 }

+ 20 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/BrokerageRecordConvert.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.convert.brokerage.record;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
 import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordRespVO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
@@ -13,6 +14,8 @@ import org.mapstruct.factory.Mappers;
 
 import java.time.LocalDateTime;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
 
 /**
  * 佣金记录 Convert
@@ -32,7 +35,7 @@ public interface BrokerageRecordConvert {
 
     default BrokerageRecordDO convert(BrokerageUserDO user, BrokerageRecordBizTypeEnum bizType, String bizId,
                                       Integer brokerageFrozenDays, int brokerage, LocalDateTime unfreezeTime,
-                                      String title) {
+                                      String title, Long sourceUserId, Integer sourceUserType) {
         brokerageFrozenDays = ObjectUtil.defaultIfNull(brokerageFrozenDays, 0);
         // 不冻结时,佣金直接就是结算状态
         Integer status = brokerageFrozenDays > 0
@@ -48,7 +51,22 @@ public interface BrokerageRecordConvert {
                 .setDescription(StrUtil.format(bizType.getDescription(), String.format("¥%.2f", brokerage / 100d)))
                 .setStatus(status)
                 .setFrozenDays(brokerageFrozenDays)
-                .setUnfreezeTime(unfreezeTime);
+                .setUnfreezeTime(unfreezeTime)
+                .setSourceUserType(sourceUserType)
+                .setSourceUserId(sourceUserId);
     }
 
+    default PageResult<BrokerageRecordRespVO> convertPage(PageResult<BrokerageRecordDO> pageResult, Map<Long, MemberUserRespDTO> userMap) {
+        PageResult<BrokerageRecordRespVO> result = convertPage(pageResult);
+
+        for (BrokerageRecordRespVO respVO : result.getList()) {
+            Optional.ofNullable(userMap.get(respVO.getUserId())).ifPresent(user ->
+                    respVO.setUserNickname(user.getNickname()).setUserAvatar(user.getAvatar()));
+
+            Optional.ofNullable(userMap.get(respVO.getSourceUserId())).ifPresent(user ->
+                    respVO.setSourceUserNickname(user.getNickname()).setSourceUserAvatar(user.getAvatar()));
+        }
+
+        return result;
+    }
 }

+ 16 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/record/BrokerageRecordDO.java

@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record;
 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
 import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
+import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum;
 import com.baomidou.mybatisplus.annotation.KeySequence;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
@@ -32,6 +33,8 @@ public class BrokerageRecordDO extends BaseDO {
     private Integer id;
     /**
      * 用户编号
+     * <p>
+     * 关联 MemberUserDO.id
      */
     private Long userId;
     /**
@@ -79,4 +82,17 @@ public class BrokerageRecordDO extends BaseDO {
      */
     private LocalDateTime unfreezeTime;
 
+    /**
+     * 来源用户类型
+     * <p>
+     * 枚举 {@link BrokerageUserTypeEnum}
+     */
+    private Integer sourceUserType;
+    /**
+     * 来源用户编号
+     * <p>
+     * 关联 MemberUserDO.id
+     */
+    private Long sourceUserId;
+
 }

+ 5 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/record/BrokerageRecordMapper.java

@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordPageReqVO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO;
+import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum;
 import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import org.apache.ibatis.annotations.Mapper;
@@ -23,10 +24,14 @@ import java.util.List;
 public interface BrokerageRecordMapper extends BaseMapperX<BrokerageRecordDO> {
 
     default PageResult<BrokerageRecordDO> selectPage(BrokerageRecordPageReqVO reqVO) {
+        boolean sourceUserTypeCondition = reqVO.getSourceUserType() != null &&
+                !BrokerageUserTypeEnum.ALL.getType().equals(reqVO.getSourceUserType());
+
         return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageRecordDO>()
                 .eqIfPresent(BrokerageRecordDO::getUserId, reqVO.getUserId())
                 .eqIfPresent(BrokerageRecordDO::getBizType, reqVO.getBizType())
                 .eqIfPresent(BrokerageRecordDO::getStatus, reqVO.getStatus())
+                .eq(sourceUserTypeCondition, BrokerageRecordDO::getSourceUserType, reqVO.getSourceUserType())
                 .betweenIfPresent(BrokerageRecordDO::getCreateTime, reqVO.getCreateTime())
                 .orderByDesc(BrokerageRecordDO::getId));
     }

+ 4 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/bo/BrokerageAddReqBO.java

@@ -34,4 +34,8 @@ public class BrokerageAddReqBO {
      */
     private Integer secondFixedPrice;
 
+    /**
+     * 来源用户编号
+     */
+    private Long sourceUserId;
 }

+ 17 - 8
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/BrokerageRecordServiceImpl.java

@@ -14,6 +14,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
 import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.record.BrokerageRecordMapper;
 import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
 import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
+import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum;
 import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO;
 import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
 import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService;
@@ -27,7 +28,6 @@ import javax.annotation.Resource;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.function.Function;
 
 /**
  * 佣金记录 Service 实现类
@@ -72,7 +72,8 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
             return;
         }
         // 1.2 计算一级分佣
-        addBrokerage(firstUser, list, memberConfig.getBrokerageFrozenDays(), memberConfig.getBrokerageFirstPercent(), BrokerageAddReqBO::getFirstFixedPrice, bizType);
+        addBrokerage(firstUser, list, memberConfig.getBrokerageFrozenDays(), memberConfig.getBrokerageFirstPercent(),
+                bizType, BrokerageUserTypeEnum.FIRST);
 
         // 2.1 获得二级推广员
         if (firstUser.getBindUserId() == null) {
@@ -83,7 +84,8 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
             return;
         }
         // 2.2 计算二级分佣
-        addBrokerage(secondUser, list, memberConfig.getBrokerageFrozenDays(), memberConfig.getBrokerageSecondPercent(), BrokerageAddReqBO::getSecondFixedPrice, bizType);
+        addBrokerage(secondUser, list, memberConfig.getBrokerageFrozenDays(), memberConfig.getBrokerageSecondPercent(),
+                bizType, BrokerageUserTypeEnum.SECOND);
     }
 
     @Override
@@ -138,12 +140,11 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
      * @param list                佣金增加参数列表
      * @param brokerageFrozenDays 冻结天数
      * @param brokeragePercent    佣金比例
-     * @param fixedPriceFun       固定佣金
      * @param bizType             业务类型
+     * @param sourceUserType      来源用户类型
      */
     private void addBrokerage(BrokerageUserDO user, List<BrokerageAddReqBO> list, Integer brokerageFrozenDays,
-                              Integer brokeragePercent, Function<BrokerageAddReqBO, Integer> fixedPriceFun,
-                              BrokerageRecordBizTypeEnum bizType) {
+                              Integer brokeragePercent, BrokerageRecordBizTypeEnum bizType, BrokerageUserTypeEnum sourceUserType) {
         // 1.1 处理冻结时间
         LocalDateTime unfreezeTime = null;
         if (brokerageFrozenDays != null && brokerageFrozenDays > 0) {
@@ -153,12 +154,20 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
         int totalBrokerage = 0;
         List<BrokerageRecordDO> records = new ArrayList<>();
         for (BrokerageAddReqBO item : list) {
-            int brokeragePerItem = calculatePrice(item.getBasePrice(), brokeragePercent, fixedPriceFun.apply(item));
+            Integer fixedPrice = 0;
+            if (BrokerageUserTypeEnum.FIRST.equals(sourceUserType)) {
+                fixedPrice = item.getFirstFixedPrice();
+            } else if (BrokerageUserTypeEnum.SECOND.equals(sourceUserType)) {
+                fixedPrice = item.getSecondFixedPrice();
+            }
+
+            int brokeragePerItem = calculatePrice(item.getBasePrice(), brokeragePercent, fixedPrice);
             if (brokeragePerItem <= 0) {
                 continue;
             }
             records.add(BrokerageRecordConvert.INSTANCE.convert(user, bizType, item.getBizId(),
-                    brokerageFrozenDays, brokeragePerItem, unfreezeTime, bizType.getTitle()));
+                    brokerageFrozenDays, brokeragePerItem, unfreezeTime, bizType.getTitle(),
+                    item.getSourceUserId(), sourceUserType.getType()));
             totalBrokerage += brokeragePerItem;
         }
         if (CollUtil.isEmpty(records)) {