Procházet zdrojové kódy

trade: 分销业务review代码修改

owen před 1 rokem
rodič
revize
a3e8b42be6
15 změnil soubory, kde provedl 183 přidání a 201 odebrání
  1. 77 68
      sql/mysql/brokerage.sql
  2. 7 0
      yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/LambdaQueryWrapperX.java
  3. 0 40
      yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageUserTypeEnum.java
  4. 2 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/vo/BrokerageRecordBaseVO.java
  5. 1 4
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/vo/BrokerageRecordPageReqVO.java
  6. 1 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/BrokerageUserController.java
  7. 2 5
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserPageReqVO.java
  8. 2 2
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/BrokerageRecordConvert.java
  9. 3 4
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/record/BrokerageRecordDO.java
  10. 8 0
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/user/BrokerageUserDO.java
  11. 1 4
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/record/BrokerageRecordMapper.java
  12. 11 32
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/user/BrokerageUserMapper.java
  13. 9 9
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/BrokerageRecordServiceImpl.java
  14. 2 3
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserService.java
  15. 57 26
      yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java

+ 77 - 68
sql/mysql/brokerage.sql

@@ -2,41 +2,50 @@
 create table trade_config
 (
     id                           bigint auto_increment comment '自增主键' primary key,
-    brokerage_enabled            bit                                    default 1                 not null comment '是否启用分佣',
-    brokerage_enabled_condition  tinyint                                default 0                 not null comment '分佣模式:1-人人分销 2-指定分销',
-    brokerage_bind_mode          tinyint                                default 0                 not null comment '分销关系绑定模式: 1-没有推广人,2-新用户, 3-扫码覆盖',
-    brokerage_post_urls          varchar(2000)                          default ''                null comment '分销海报图地址数组',
-    brokerage_first_percent      int                                    default 0                 not null comment '一级返佣比例',
-    brokerage_second_percent     int                                    default 0                 not null comment '二级返佣比例',
-    brokerage_withdraw_min_price int                                    default 0                 not null comment '用户提现最低金额',
-    brokerage_bank_names         varchar(200)                           default ''                not null comment '提现银行(字典类型=brokerage_bank_name)',
-    brokerage_frozen_days        int                                    default 7                 not null comment '佣金冻结时间(天)',
-    brokerage_withdraw_type      varchar(32)                            default '1,2,3,4'         not null comment '提现方式:1-钱包;2-银行卡;3-微信;4-支付宝',
-    creator                      varchar(64) collate utf8mb4_unicode_ci default ''                null comment '创建者',
-    create_time                  datetime                               default CURRENT_TIMESTAMP not null comment '创建时间',
-    updater                      varchar(64) collate utf8mb4_unicode_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 '租户编号'
+    brokerage_enabled            bit           default 1                 not null comment '是否启用分佣',
+    brokerage_enabled_condition  tinyint       default 0                 not null comment '分佣模式:1-人人分销 2-指定分销',
+    brokerage_bind_mode          tinyint       default 0                 not null comment '分销关系绑定模式: 1-没有推广人,2-新用户, 3-扫码覆盖',
+    brokerage_post_urls          varchar(2000) default ''                null comment '分销海报图地址数组',
+    brokerage_first_percent      int           default 0                 not null comment '一级返佣比例',
+    brokerage_second_percent     int           default 0                 not null comment '二级返佣比例',
+    brokerage_withdraw_min_price int           default 0                 not null comment '用户提现最低金额',
+    brokerage_bank_names         varchar(200)  default ''                not null comment '提现银行(字典类型=brokerage_bank_name)',
+    brokerage_frozen_days        int           default 7                 not null comment '佣金冻结时间(天)',
+    brokerage_withdraw_type      varchar(32)   default '1,2,3,4'         not null comment '提现方式:1-钱包;2-银行卡;3-微信;4-支付宝',
+    creator                      varchar(64)   default ''                null comment '创建者',
+    create_time                  datetime      default CURRENT_TIMESTAMP not null comment '创建时间',
+    updater                      varchar(64)   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 '交易中心配置';
 
+# alter table trade_brokerage_user
+#     add level int not null default 1 comment '等级' after frozen_price;
+# alter table trade_brokerage_user
+#     add path varchar(2000) null comment '路径' after level;
+
+
 -- 增加分销用户扩展表
 create table trade_brokerage_user
 (
     id                bigint auto_increment comment '用户编号' primary key,
-    bind_user_id      bigint                                                           null comment '推广员编号',
-    bind_user_time    datetime                                                         null comment '推广员绑定时间',
-    brokerage_enabled bit                                    default 1                 not null comment '是否成为推广员',
-    brokerage_time    datetime                                                         null comment '成为分销员时间',
-    price             int                                    default 0                 not null comment '可用佣金',
-    frozen_price      int                                    default 0                 not null comment '冻结佣金',
-    creator           varchar(64) collate utf8mb4_unicode_ci default ''                null comment '创建者',
-    create_time       datetime                               default CURRENT_TIMESTAMP not null comment '创建时间',
-    updater           varchar(64) collate utf8mb4_unicode_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 '分销用户';
+    bind_user_id      bigint                                null comment '推广员编号',
+    bind_user_time    datetime                              null comment '推广员绑定时间',
+    brokerage_enabled bit         default 1                 not null comment '是否成为推广员',
+    brokerage_time    datetime                              null comment '成为分销员时间',
+    price             int         default 0                 not null comment '可用佣金',
+    frozen_price      int         default 0                 not null comment '冻结佣金',
+    level             int         default 1                 not null comment '等级',
+    path              varchar(2000)                         null comment '路径',
+    creator           varchar(64) default ''                null comment '创建者',
+    create_time       datetime    default CURRENT_TIMESTAMP not null comment '创建时间',
+    updater           varchar(64) 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 '分销用户';
 
 create index idx_invite_user_id on trade_brokerage_user (bind_user_id) comment '推广员编号';
 create index idx_agent on trade_brokerage_user (brokerage_enabled) comment '是否成为推广员';
@@ -44,26 +53,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 '业务类型: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 '租户编号'
+    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_level int                                    not null comment '来源用户等级',
+    source_user_id    bigint                                 not null comment '来源用户编号',
+    creator           varchar(64)  default ''                null comment '创建者',
+    create_time       datetime     default CURRENT_TIMESTAMP not null comment '创建时间',
+    updater           varchar(64)  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 '佣金记录';
 
@@ -76,26 +85,26 @@ create table trade_brokerage_withdraw
 (
     id                  int auto_increment comment '编号'
         primary key,
-    user_id             bigint                                                           not null comment '用户编号',
-    price               int                                    default 0                 not null comment '提现金额',
-    fee_price           int                                    default 0                 not null comment '提现手续费',
-    total_price         int                                    default 0                 not null comment '当前总佣金',
-    type                tinyint                                default 0                 not null comment '提现类型:1-钱包;2-银行卡;3-微信;4-支付宝',
-    name                varchar(64)                                                      null comment '真实姓名',
-    account_no          varchar(64)                                                      null comment '账号',
-    bank_name           varchar(100)                                                     null comment '银行名称',
-    bank_address        varchar(200)                                                     null comment '开户地址',
-    account_qr_code_url varchar(512)                                                     null comment '收款码',
-    status              tinyint(2)                             default 0                 not null comment '状态:0-审核中,10-审核通过 20-审核不通过;预留:11 - 提现成功;21-提现失败',
-    audit_reason        varchar(128)                                                     null comment '审核驳回原因',
-    audit_time          datetime                                                         null comment '审核时间',
-    remark              varchar(500)                                                     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 '用户编号',
+    price               int         default 0                 not null comment '提现金额',
+    fee_price           int         default 0                 not null comment '提现手续费',
+    total_price         int         default 0                 not null comment '当前总佣金',
+    type                tinyint     default 0                 not null comment '提现类型:1-钱包;2-银行卡;3-微信;4-支付宝',
+    name                varchar(64)                           null comment '真实姓名',
+    account_no          varchar(64)                           null comment '账号',
+    bank_name           varchar(100)                          null comment '银行名称',
+    bank_address        varchar(200)                          null comment '开户地址',
+    account_qr_code_url varchar(512)                          null comment '收款码',
+    status              tinyint(2)  default 0                 not null comment '状态:0-审核中,10-审核通过 20-审核不通过;预留:11 - 提现成功;21-提现失败',
+    audit_reason        varchar(128)                          null comment '审核驳回原因',
+    audit_time          datetime                              null comment '审核时间',
+    remark              varchar(500)                          null comment '备注',
+    creator             varchar(64) default ''                null comment '创建者',
+    create_time         datetime    default CURRENT_TIMESTAMP not null comment '创建时间',
+    updater             varchar(64) 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 '佣金提现';
 

+ 7 - 0
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/LambdaQueryWrapperX.java

@@ -100,6 +100,13 @@ public class LambdaQueryWrapperX<T> extends LambdaQueryWrapper<T> {
         return betweenIfPresent(column, val1, val2);
     }
 
+    public LambdaQueryWrapperX<T> findInSetIfPresent(SFunction<T, ?> column, Object val) {
+        if (val != null) {
+            return (LambdaQueryWrapperX<T>) super.apply("FIND_IN_SET({0}, " + columnToString(column) + ")", val);
+        }
+        return this;
+    }
+
     // ========== 重写父类方法,方便链式调用 ==========
 
     @Override

+ 0 - 40
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageUserTypeEnum.java

@@ -1,40 +0,0 @@
-package cn.iocoder.yudao.module.trade.enums.brokerage;
-
-import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-import java.util.Arrays;
-
-// TODO @疯狂:是不是搞成层级,类似 level 这样?因为本质上,它是 1 级、2 级、3 级这样的关系哈
-/**
- * 分销用户类型枚举
- *
- * @author owen
- */
-@AllArgsConstructor
-@Getter
-public enum BrokerageUserTypeEnum implements IntArrayValuable {
-
-    ALL(0, "全部"),
-    FIRST(1, "一级推广人"),
-    SECOND(2, "二级推广人"),
-    ;
-
-    public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageUserTypeEnum::getType).toArray();
-
-    /**
-     * 类型
-     */
-    private final Integer type;
-    /**
-     * 名字
-     */
-    private final String name;
-
-    @Override
-    public int[] array() {
-        return ARRAYS;
-    }
-
-}

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

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

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

@@ -1,8 +1,6 @@
 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;
@@ -33,7 +31,6 @@ public class BrokerageRecordPageReqVO extends PageParam {
     private LocalDateTime[] createTime;
 
     @Schema(description = "用户类型")
-    @InEnum(value = BrokerageUserTypeEnum.class, message = "用户类型必须是 {value}")
-    private Integer sourceUserType;
+    private Integer sourceUserLevel;
 
 }

+ 1 - 2
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/BrokerageUserController.java

@@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.trade.convert.brokerage.user.BrokerageUserConvert
 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
 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.UserBrokerageSummaryBO;
 import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService;
 import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService;
@@ -96,7 +95,7 @@ public class BrokerageUserController {
         // 合计推广用户数量
         Map<Long, Long> brokerageUserCountMap = convertMap(userIds,
                 userId -> userId,
-                userId -> brokerageUserService.getBrokerageUserCountByBindUserId(userId, BrokerageUserTypeEnum.ALL));
+                userId -> brokerageUserService.getBrokerageUserCountByBindUserId(userId, null));
 
         // todo 合计提现
 

+ 2 - 5
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserPageReqVO.java

@@ -1,8 +1,6 @@
 package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.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;
@@ -29,9 +27,8 @@ public class BrokerageUserPageReqVO extends PageParam {
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private LocalDateTime[] createTime;
 
-    @Schema(description = "用户类型")
-    @InEnum(value = BrokerageUserTypeEnum.class, message = "用户类型必须是 {value}")
-    private Integer userType;
+    @Schema(description = "用户等级")
+    private Integer level;
 
     @Schema(description = "绑定时间")
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)

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

@@ -35,7 +35,7 @@ public interface BrokerageRecordConvert {
 
     default BrokerageRecordDO convert(BrokerageUserDO user, BrokerageRecordBizTypeEnum bizType, String bizId,
                                       Integer brokerageFrozenDays, int brokeragePrice, LocalDateTime unfreezeTime,
-                                      String title, Long sourceUserId, Integer sourceUserType) {
+                                      String title, Long sourceUserId, Integer sourceUserLevel) {
         brokerageFrozenDays = ObjectUtil.defaultIfNull(brokerageFrozenDays, 0);
         // 不冻结时,佣金直接就是结算状态
         Integer status = brokerageFrozenDays > 0
@@ -47,7 +47,7 @@ public interface BrokerageRecordConvert {
                 .setTitle(title)
                 .setDescription(StrUtil.format(bizType.getDescription(), String.format("¥%.2f", brokeragePrice / 100d)))
                 .setStatus(status).setFrozenDays(brokerageFrozenDays).setUnfreezeTime(unfreezeTime)
-                .setSourceUserType(sourceUserType).setSourceUserId(sourceUserId);
+                .setSourceUserLevel(sourceUserLevel).setSourceUserId(sourceUserId);
     }
 
     default PageResult<BrokerageRecordRespVO> convertPage(PageResult<BrokerageRecordDO> pageResult, Map<Long, MemberUserRespDTO> userMap) {

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

@@ -3,7 +3,6 @@ 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;
@@ -83,11 +82,11 @@ public class BrokerageRecordDO extends BaseDO {
     private LocalDateTime unfreezeTime;
 
     /**
-     * 来源用户类型
+     * 来源用户等级
      * <p>
-     * 枚举 {@link BrokerageUserTypeEnum},被推广用户和 {@link #userId} 的推广层级关系
+     * 被推广用户和 {@link #userId} 的推广层级关系
      */
-    private Integer sourceUserType;
+    private Integer sourceUserLevel;
     /**
      * 来源用户编号
      * <p>

+ 8 - 0
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/user/BrokerageUserDO.java

@@ -60,4 +60,12 @@ public class BrokerageUserDO extends BaseDO {
      */
     private Integer frozenPrice;
 
+    /**
+     * 等级
+     */
+    private Integer level;
+    /**
+     * 路径
+     */
+    private String path;
 }

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

@@ -5,7 +5,6 @@ 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;
@@ -24,14 +23,12 @@ 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())
+                .eqIfPresent(BrokerageRecordDO::getSourceUserLevel, reqVO.getSourceUserLevel())
                 .betweenIfPresent(BrokerageRecordDO::getCreateTime, reqVO.getCreateTime())
                 .orderByDesc(BrokerageRecordDO::getId));
     }

+ 11 - 32
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/user/BrokerageUserMapper.java

@@ -1,17 +1,15 @@
 package cn.iocoder.yudao.module.trade.dal.mysql.brokerage.user;
 
 import cn.hutool.core.lang.Assert;
-import cn.hutool.core.util.StrUtil;
 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.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
-import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
 
 /**
  * 分销用户 Mapper
@@ -21,35 +19,16 @@ import org.apache.ibatis.annotations.Select;
 @Mapper
 public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
 
-    default PageResult<BrokerageUserDO> selectPage(BrokerageUserPageReqVO reqVO) {
+    default PageResult<BrokerageUserDO> selectPage(BrokerageUserPageReqVO reqVO, List<Integer> levels) {
         return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageUserDO>()
                 .eqIfPresent(BrokerageUserDO::getBrokerageEnabled, reqVO.getBrokerageEnabled())
                 .betweenIfPresent(BrokerageUserDO::getCreateTime, reqVO.getCreateTime())
                 .betweenIfPresent(BrokerageUserDO::getBindUserTime, reqVO.getBindUserTime())
-                .and(reqVO.getBindUserId() != null, w -> buildBindUserCondition(reqVO, w))
+                .findInSetIfPresent(BrokerageUserDO::getPath, reqVO.getBindUserId())
+                .inIfPresent(BrokerageUserDO::getLevel, levels)
                 .orderByDesc(BrokerageUserDO::getId));
     }
 
-    static void buildBindUserCondition(BrokerageUserPageReqVO reqVO, LambdaQueryWrapper<BrokerageUserDO> wrapper) {
-        if (BrokerageUserTypeEnum.FIRST.getType().equals(reqVO.getUserType())) {
-            buildFirstBindUserCondition(reqVO.getBindUserId(), wrapper);
-        } else if (BrokerageUserTypeEnum.SECOND.getType().equals(reqVO.getUserType())) {
-            buildSecondBindUserCondition(reqVO.getBindUserId(), wrapper);
-        } else {
-            // TODO @疯狂:要不要把这个逻辑,挪到 Service 里,算出子用户有哪些,然后 IN?
-            buildFirstBindUserCondition(reqVO.getBindUserId(), wrapper);
-            buildSecondBindUserCondition(reqVO.getBindUserId(), wrapper.or()); // 通过 or 实现多个条件
-        }
-    }
-
-    static void buildFirstBindUserCondition(Long bindUserId, LambdaQueryWrapper<BrokerageUserDO> wrapper) {
-        wrapper.eq(BrokerageUserDO::getBindUserId, bindUserId);
-    }
-
-    static void buildSecondBindUserCondition(Long bindUserId, LambdaQueryWrapper<BrokerageUserDO> wrapper) {
-        wrapper.inSql(BrokerageUserDO::getBindUserId, StrUtil.format("SELECT id FROM trade_brokerage_user WHERE bind_user_id = {}", bindUserId));
-    }
-
     /**
      * 更新用户可用佣金(增加)
      *
@@ -128,7 +107,8 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
     default void updateBindUserIdAndBindUserTimeToNull(Long id) {
         update(null, new LambdaUpdateWrapper<BrokerageUserDO>()
                 .eq(BrokerageUserDO::getId, id)
-                .set(BrokerageUserDO::getBindUserId, null).set(BrokerageUserDO::getBindUserTime, null));
+                .set(BrokerageUserDO::getBindUserId, null).set(BrokerageUserDO::getBindUserTime, null)
+                .set(BrokerageUserDO::getLevel, 1).set(BrokerageUserDO::getPath, ""));
     }
 
     default void updateEnabledFalseAndBrokerageTimeToNull(Long id) {
@@ -137,11 +117,10 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
                 .set(BrokerageUserDO::getBrokerageEnabled, false).set(BrokerageUserDO::getBrokerageTime, null));
     }
 
-    default Long selectCountByBindUserId(Long bindUserId) {
-        return selectCount(BrokerageUserDO::getBindUserId, bindUserId);
+    default Long selectCountByBindUserIdAndLevelIn(Long bindUserId, List<Integer> levels) {
+        return selectCount(new LambdaQueryWrapperX<BrokerageUserDO>()
+                .findInSetIfPresent(BrokerageUserDO::getPath, bindUserId)
+                .inIfPresent(BrokerageUserDO::getLevel, levels));
     }
 
-    @Select("SELECT COUNT(1) from trade_brokerage_user WHERE bind_user_id IN (SELECT id FROM trade_brokerage_user WHERE bind_user_id = #{bindUserId})")
-    Long selectCountByBindUserIdInBindUserId(Long bindUserId);
-
 }

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

@@ -15,7 +15,6 @@ 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;
@@ -29,6 +28,7 @@ import javax.annotation.Resource;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * 佣金记录 Service 实现类
@@ -74,7 +74,7 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
         }
         // 1.2 计算一级分佣
         addBrokerage(firstUser, list, memberConfig.getBrokerageFrozenDays(), memberConfig.getBrokerageFirstPercent(),
-                bizType, BrokerageUserTypeEnum.FIRST);
+                bizType, 1);
 
         // 2.1 获得二级推广员
         if (firstUser.getBindUserId() == null) {
@@ -86,7 +86,7 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
         }
         // 2.2 计算二级分佣
         addBrokerage(secondUser, list, memberConfig.getBrokerageFrozenDays(), memberConfig.getBrokerageSecondPercent(),
-                bizType, BrokerageUserTypeEnum.SECOND);
+                bizType, 2);
     }
 
     @Override
@@ -142,10 +142,10 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
      * @param brokerageFrozenDays 冻结天数
      * @param brokeragePercent    佣金比例
      * @param bizType             业务类型
-     * @param sourceUserType      来源用户类型
+     * @param sourceUserLevel     来源用户等级
      */
     private void addBrokerage(BrokerageUserDO user, List<BrokerageAddReqBO> list, Integer brokerageFrozenDays,
-                              Integer brokeragePercent, BrokerageRecordBizTypeEnum bizType, BrokerageUserTypeEnum sourceUserType) {
+                              Integer brokeragePercent, BrokerageRecordBizTypeEnum bizType, Integer sourceUserLevel) {
         // 1.1 处理冻结时间
         LocalDateTime unfreezeTime = null;
         if (brokerageFrozenDays != null && brokerageFrozenDays > 0) {
@@ -157,12 +157,12 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
         for (BrokerageAddReqBO item : list) {
             // 计算金额
             Integer fixedPrice;
-            if (BrokerageUserTypeEnum.FIRST.equals(sourceUserType)) {
+            if (Objects.equals(sourceUserLevel, 1)) {
                 fixedPrice = item.getFirstFixedPrice();
-            } else if (BrokerageUserTypeEnum.SECOND.equals(sourceUserType)) {
+            } else if (Objects.equals(sourceUserLevel, 2)) {
                 fixedPrice = item.getSecondFixedPrice();
             } else {
-                throw new IllegalArgumentException(StrUtil.format("来源用户({}) 不合法", sourceUserType));
+                throw new IllegalArgumentException(StrUtil.format("用户等级({}) 不合法", sourceUserLevel));
             }
             int brokeragePrice = calculatePrice(item.getBasePrice(), brokeragePercent, fixedPrice);
             if (brokeragePrice <= 0) {
@@ -172,7 +172,7 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
             // 创建记录实体
             records.add(BrokerageRecordConvert.INSTANCE.convert(user, bizType, item.getBizId(),
                     brokerageFrozenDays, brokeragePrice, unfreezeTime, item.getTitle(),
-                    item.getSourceUserId(), sourceUserType.getType()));
+                    item.getSourceUserId(), sourceUserLevel));
         }
         if (CollUtil.isEmpty(records)) {
             return;

+ 2 - 3
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserService.java

@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.service.brokerage.user;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
-import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum;
 
 import java.util.Collection;
 import java.util.List;
@@ -91,10 +90,10 @@ public interface BrokerageUserService {
      * 获得推广用户数量
      *
      * @param bindUserId 绑定的推广员编号
-     * @param userType   用户类型
+     * @param level      推广用户等级
      * @return 推广用户数量
      */
-    Long getBrokerageUserCountByBindUserId(Long bindUserId, BrokerageUserTypeEnum userType);
+    Long getBrokerageUserCountByBindUserId(Long bindUserId, Integer level);
 
     /**
      * 【会员】绑定推广员

+ 57 - 26
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java

@@ -1,7 +1,10 @@
 package cn.iocoder.yudao.module.trade.service.brokerage.user;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
 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.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO;
 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
@@ -9,17 +12,13 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
 import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.user.BrokerageUserMapper;
 import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageBindModeEnum;
 import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageEnabledConditionEnum;
-import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum;
 import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
 import org.springframework.stereotype.Service;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
-import java.util.Collection;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
+import java.util.*;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
@@ -51,7 +50,8 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
 
     @Override
     public PageResult<BrokerageUserDO> getBrokerageUserPage(BrokerageUserPageReqVO pageReqVO) {
-        return brokerageUserMapper.selectPage(pageReqVO);
+        List<Integer> levels = buildUserQueryLevels(pageReqVO.getBindUserId(), pageReqVO.getLevel());
+        return brokerageUserMapper.selectPage(pageReqVO, levels);
     }
 
     @Override
@@ -66,10 +66,14 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
             return;
         }
 
+        // 绑定关系未发生变化
+        if (Objects.equals(brokerageUser.getBindUserId(), bindUserId)) {
+            return;
+        }
+
         // 情况二:修改推广员
         validateCanBindUser(brokerageUser, bindUserId);
-        brokerageUserMapper.updateById(new BrokerageUserDO().setId(id)
-                .setBindUserId(bindUserId).setBindUserTime(LocalDateTime.now()));
+        brokerageUserMapper.updateById(fillBindUserData(bindUserId, new BrokerageUserDO().setId(id)));
     }
 
     @Override
@@ -132,19 +136,12 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
     }
 
     @Override
-    public Long getBrokerageUserCountByBindUserId(Long bindUserId, BrokerageUserTypeEnum userType) {
-        switch (userType) {
-            case ALL: // TODO @疯狂:ALL 是不是不用搞个枚举,默认为空就是不过滤哈~
-                Long firstCount = brokerageUserMapper.selectCountByBindUserId(bindUserId);
-                Long secondCount = brokerageUserMapper.selectCountByBindUserIdInBindUserId(bindUserId);
-                return firstCount + secondCount;
-            case FIRST:
-                return brokerageUserMapper.selectCountByBindUserId(bindUserId);
-            case SECOND:
-                return brokerageUserMapper.selectCountByBindUserIdInBindUserId(bindUserId);
-            default:
-                return 0L;
+    public Long getBrokerageUserCountByBindUserId(Long bindUserId, Integer level) {
+        List<Integer> levels = buildUserQueryLevels(bindUserId, level);
+        if (CollUtil.isEmpty(levels)) {
+            return 0L;
         }
+        return brokerageUserMapper.selectCountByBindUserIdAndLevelIn(bindUserId, levels);
     }
 
     @Override
@@ -171,14 +168,30 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
                 brokerageUser.setBrokerageEnabled(true).setBrokerageTime(LocalDateTime.now());
             }
             brokerageUser.setBindUserId(bindUserId).setBindUserTime(LocalDateTime.now());
-            brokerageUserMapper.insert(brokerageUser);
+            brokerageUserMapper.insert(fillBindUserData(bindUserId, brokerageUser));
         } else {
-            brokerageUserMapper.updateById(new BrokerageUserDO().setId(userId)
-                    .setBindUserId(bindUserId).setBindUserTime(LocalDateTime.now()));
+            brokerageUserMapper.updateById(fillBindUserData(bindUserId, new BrokerageUserDO().setId(userId)));
         }
         return true;
     }
 
+    private BrokerageUserDO fillBindUserData(Long bindUserId, BrokerageUserDO brokerageUser) {
+        BrokerageUserDO bindUser = getBrokerageUser(bindUserId);
+
+        Integer bindUserLevel = 0;
+        String bindUserPath = "";
+        if (bindUser != null) {
+            bindUserLevel = ObjectUtil.defaultIfNull(bindUser.getLevel(), 0);
+            bindUserPath = bindUser.getPath();
+        }
+
+        String path = StrUtil.isEmpty(bindUserPath)
+                ? String.valueOf(bindUserId)
+                : String.format("%s,%s", bindUserPath, bindUserId);
+        return brokerageUser.setBindUserId(bindUserId).setBindUserTime(LocalDateTime.now())
+                .setLevel(bindUserLevel + 1).setPath(path);
+    }
+
     @Override
     public Boolean getUserBrokerageEnabled(Long userId) {
         // 全局分销功能是否开启
@@ -231,11 +244,29 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
             throw exception(BROKERAGE_BIND_SELF);
         }
 
-        // TODO @疯狂:这块是不是一直查询到根节点,中间不允许出现自己;就是不能形成环。虽然目前是 2 级,但是未来可能会改多级; = = 环的话,就会存在问题哈
-        // A->B->A:下级不能绑定自己的上级,   A->B->C->A可以!!
-        if (Objects.equals(user.getId(), bindUser.getBindUserId())) {
+        // 下级不能绑定自己的上级
+        if (StrUtil.split(bindUser.getPath(), ",").contains(String.valueOf(user.getId()))) {
             throw exception(BROKERAGE_BIND_LOOP);
         }
     }
 
+    private List<Integer> buildUserQueryLevels(Long bindUserId, Integer level) {
+        List<Integer> levels = new ArrayList<>(2);
+
+        BrokerageUserDO bindUser = getBrokerageUser(bindUserId);
+        if (bindUser == null) {
+            return levels;
+        }
+
+        if (level == null) {
+            // 默认查两层
+            levels.add(bindUser.getLevel() + 1);
+            levels.add(bindUser.getLevel() + 2);
+        } else {
+            levels.add(bindUser.getLevel() + level);
+        }
+        return levels;
+
+    }
+
 }