Commit 3b5215db21a0fd69a525eff5e221c0eac47f3ecb

Authored by 芋道源码
Committed by Gitee
2 parents 87c55784 4e9be7a1

!611 分销用户管理、Review代码修改

Merge pull request !611 from 疯狂的世界/brokerate
Showing 55 changed files with 1044 additions and 597 deletions
sql/mysql/brokerage.sql
... ... @@ -3,8 +3,8 @@ create table trade_config
3 3 (
4 4 id bigint auto_increment comment '自增主键' primary key,
5 5 brokerage_enabled bit default 1 not null comment '是å¦å¯ç”¨åˆ†ä½£',
6   - brokerage_enabled_condition tinyint default 0 not null comment '分佣模å¼ï¼š0-人人分销 1-指定分销',
7   - brokerage_bind_mode tinyint default 0 not null comment '分销关系绑定模å¼: 0-没有推广人,1-新用户',
  6 + brokerage_enabled_condition tinyint default 0 not null comment '分佣模å¼ï¼š1-人人分销 2-指定分销',
  7 + brokerage_bind_mode tinyint default 0 not null comment '分销关系绑定模å¼: 1-没有推广人,2-新用户, 3-扫ç è¦†ç›–',
8 8 brokerage_post_urls varchar(2000) default '' null comment 'åˆ†é”€æµ·æŠ¥å›¾åœ°å€æ•°ç»„',
9 9 brokerage_first_percent int default 0 not null comment '一级返佣比例',
10 10 brokerage_second_percent int default 0 not null comment '二级返佣比例',
... ... @@ -23,22 +23,22 @@ create table trade_config
23 23 -- 增加分销用户扩展表
24 24 create table trade_brokerage_user
25 25 (
26   - id bigint auto_increment comment '用户编å·' primary key,
27   - brokerage_user_id bigint not null comment '推广员编å·',
28   - brokerage_bind_time datetime null comment '推广员绑定时间',
29   - brokerage_enabled bit default 1 not null comment 'æ˜¯å¦æˆä¸ºæŽ¨å¹¿å‘˜',
30   - brokerage_time datetime null comment 'æˆä¸ºåˆ†é”€å‘˜æ—¶é—´',
31   - brokerage_price int default 0 not null comment 'å¯ç”¨ä½£é‡‘',
32   - frozen_brokerage_price int default 0 not null comment '冻结佣金',
33   - creator varchar(64) collate utf8mb4_unicode_ci default '' null comment '创建者',
34   - create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
35   - updater varchar(64) collate utf8mb4_unicode_ci default '' null comment '更新者',
36   - update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment 'æ›´æ–°æ—¶é—´',
37   - deleted bit default b'0' not null comment '是å¦åˆ é™¤',
38   - tenant_id bigint default 0 not null comment '租户编å·'
  26 + id bigint auto_increment comment '用户编å·' primary key,
  27 + bind_user_id bigint null comment '推广员编å·',
  28 + bind_user_time datetime null comment '推广员绑定时间',
  29 + brokerage_enabled bit default 1 not null comment 'æ˜¯å¦æˆä¸ºæŽ¨å¹¿å‘˜',
  30 + brokerage_time datetime null comment 'æˆä¸ºåˆ†é”€å‘˜æ—¶é—´',
  31 + price int default 0 not null comment 'å¯ç”¨ä½£é‡‘',
  32 + frozen_price int default 0 not null comment '冻结佣金',
  33 + creator varchar(64) collate utf8mb4_unicode_ci default '' null comment '创建者',
  34 + create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
  35 + updater varchar(64) collate utf8mb4_unicode_ci default '' null comment '更新者',
  36 + update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment 'æ›´æ–°æ—¶é—´',
  37 + deleted bit default b'0' not null comment '是å¦åˆ é™¤',
  38 + tenant_id bigint default 0 not null comment '租户编å·'
39 39 ) comment '分销用户';
40 40  
41   -create index idx_invite_user_id on trade_brokerage_user (brokerage_user_id) comment '推广员编å·';
  41 +create index idx_invite_user_id on trade_brokerage_user (bind_user_id) comment '推广员编å·';
42 42 create index idx_agent on trade_brokerage_user (brokerage_enabled) comment 'æ˜¯å¦æˆä¸ºæŽ¨å¹¿å‘˜';
43 43  
44 44  
... ... @@ -104,14 +104,15 @@ create index idx_audit_status on trade_brokerage_withdraw (status) comment '状æ
104 104 insert into system_dict_type(type, name)
105 105 values ('brokerage_enabled_condition', '分佣模å¼');
106 106 insert into system_dict_data(dict_type, label, value, sort, remark)
107   -values ('brokerage_enabled_condition', '人人分销', 0, 0, '所有用户都å¯ä»¥åˆ†é”€'),
108   - ('brokerage_enabled_condition', '指定分销', 1, 1, 'ä»…å¯åŽå°æ‰‹åŠ¨è®¾ç½®æŽ¨å¹¿å‘˜');
  107 +values ('brokerage_enabled_condition', '人人分销', 1, 1, '所有用户都å¯ä»¥åˆ†é”€'),
  108 + ('brokerage_enabled_condition', '指定分销', 2, 2, 'ä»…å¯åŽå°æ‰‹åŠ¨è®¾ç½®æŽ¨å¹¿å‘˜');
109 109  
110 110 insert into system_dict_type(type, name)
111 111 values ('brokerage_bind_mode', '分销关系绑定模å¼');
112 112 insert into system_dict_data(dict_type, label, value, sort, remark)
113   -values ('brokerage_bind_mode', '没有推广人', 0, 0, 'åªè¦ç”¨æˆ·æ²¡æœ‰æŽ¨å¹¿äººï¼Œéšæ—¶éƒ½å¯ä»¥ç»‘定推广关系'),
114   - ('brokerage_bind_mode', '新用户', 1, 1, '仅新用户注册时æ‰èƒ½ç»‘定推广关系');
  113 +values ('brokerage_bind_mode', '没有推广人', 1, 1, 'åªè¦ç”¨æˆ·æ²¡æœ‰æŽ¨å¹¿äººï¼Œéšæ—¶éƒ½å¯ä»¥ç»‘定推广关系'),
  114 + ('brokerage_bind_mode', '新用户', 2, 2, '仅新用户注册时æ‰èƒ½ç»‘定推广关系'),
  115 + ('brokerage_bind_mode', '扫ç è¦†ç›–', 3, 3, 'å¦‚æžœç”¨æˆ·å·²ç»æœ‰æŽ¨å¹¿äººï¼ŒæŽ¨å¹¿äººä¼šè¢«å˜æ›´');
115 116  
116 117 insert into system_dict_type(type, name)
117 118 values ('brokerage_withdraw_type', '佣金æçŽ°ç±»åž‹');
... ... @@ -124,8 +125,8 @@ values ('brokerage_withdraw_type', '钱包', 1, 1),
124 125 insert into system_dict_type(type, name)
125 126 values ('brokerage_record_biz_type', '佣金记录业务类型');
126 127 insert into system_dict_data(dict_type, label, value, sort)
127   -values ('brokerage_record_biz_type', '订å•返佣', 0, 0),
128   - ('brokerage_record_biz_type', '申请æçް', 1, 1);
  128 +values ('brokerage_record_biz_type', '订å•返佣', 1, 1),
  129 + ('brokerage_record_biz_type', '申请æçް', 2, 2);
129 130  
130 131 insert into system_dict_type(type, name)
131 132 values ('brokerage_record_status', '佣金记录状æ€');
... ... @@ -185,12 +186,15 @@ SELECT @parentId := LAST_INSERT_ID();
185 186 INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
186 187 VALUES ('分销用户查询', 'trade:brokerage-user:query', 3, 1, @parentId, '', '', '', 0);
187 188 INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
188   -VALUES ('分销用户修改推广员', 'trade:brokerage-user:update-brokerage-user', 3, 2, @parentId, '', '', '', 0);
  189 +VALUES ('分销用户推广人查询', 'trade:brokerage-user:user-query', 3, 2, @parentId, '', '', '', 0);
189 190 INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
190   -VALUES ('分销用户清除推广员', 'trade:brokerage-user:clear-brokerage-user', 3, 3, @parentId, '', '', '', 0);
  191 +VALUES ('åˆ†é”€ç”¨æˆ·æŽ¨å¹¿è®¢å•æŸ¥è¯¢', 'trade:brokerage-user:order-query', 3, 3, @parentId, '', '', '', 0);
191 192 INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
192 193 VALUES ('分销用户修改推广资格', 'trade:brokerage-user:update-brokerage-enable', 3, 4, @parentId, '', '', '', 0);
193   -
  194 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
  195 +VALUES ('分销用户修改推广员', 'trade:brokerage-user:update-brokerage-user', 3, 5, @parentId, '', '', '', 0);
  196 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
  197 +VALUES ('分销用户清除推广员', 'trade:brokerage-user:clear-brokerage-user', 3, 6, @parentId, '', '', '', 0);
194 198  
195 199 -- 增加èœå•:佣金记录
196 200 INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status, component_name)
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/util/MoneyUtils.java renamed to yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/MoneyUtils.java
1   -package cn.iocoder.yudao.module.pay.util;
  1 +package cn.iocoder.yudao.framework.common.util.number;
2 2  
3 3 import cn.hutool.core.util.NumberUtil;
4 4  
... ... @@ -23,6 +23,17 @@ public class MoneyUtils {
23 23 return calculateRatePrice(price, rate, 0, RoundingMode.HALF_UP).intValue();
24 24 }
25 25  
  26 + /**
  27 + * 计算百分比金额,向下传入
  28 + *
  29 + * @param price 金额
  30 + * @param rate 百分比,例如说 56.77% 则传入 56.77
  31 + * @return 百分比金额
  32 + */
  33 + public static Integer calculateRatePriceFloor(Integer price, Double rate) {
  34 + return calculateRatePrice(price, rate, 0, RoundingMode.FLOOR).intValue();
  35 + }
  36 +
26 37 /**
27 38 * 计算百分比金额
28 39 *
... ...
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApi.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.api.brokerage;
  2 +
  3 +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserDTO;
  4 +
  5 +/**
  6 + * 分销 API 接口
  7 + *
  8 + * @author owen
  9 + */
  10 +public interface BrokerageApi {
  11 +
  12 + /**
  13 + * 获得分销用户
  14 + *
  15 + * @param userId 用户编号
  16 + * @return 分销用户信息
  17 + */
  18 + BrokerageUserDTO getBrokerageUser(Long userId);
  19 +
  20 + /**
  21 + * 绑定推广员
  22 + *
  23 + * @param userId 用户编号
  24 + * @param bindUserId 推广员编号
  25 + * @param isNewUser 是否为新用户
  26 + * @return 是否绑定
  27 + */
  28 + boolean bindUser(Long userId, Long bindUserId, Boolean isNewUser);
  29 +}
... ...
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/dto/BrokerageUserDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.api.brokerage.dto;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import java.time.LocalDateTime;
  6 +
  7 +/**
  8 + * 分销用户 DTO
  9 + *
  10 + * @author owen
  11 + */
  12 +@Data
  13 +public class BrokerageUserDTO {
  14 +
  15 + /**
  16 + * 用户编号
  17 + * <p>
  18 + * 对应 MemberUserDO 的 id 字段
  19 + */
  20 + private Long id;
  21 +
  22 + /**
  23 + * 推广员编号
  24 + * <p>
  25 + * 关联 MemberUserDO 的 id 字段
  26 + */
  27 + private Long bindUserId;
  28 + /**
  29 + * 推广员绑定时间
  30 + */
  31 + private LocalDateTime bindUserTime;
  32 +
  33 + /**
  34 + * 推广资格
  35 + */
  36 + private Boolean brokerageEnabled;
  37 + /**
  38 + * 成为分销员时间
  39 + */
  40 + private LocalDateTime brokerageTime;
  41 +
  42 + /**
  43 + * 可用佣金
  44 + */
  45 + private Integer price;
  46 + /**
  47 + * 冻结佣金
  48 + */
  49 + private Integer frozenPrice;
  50 +
  51 +}
... ...
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
... ... @@ -77,5 +77,12 @@ public interface ErrorCodeConstants {
77 77  
78 78 // ========== 分销用户 模块 1011007000 ==========
79 79 ErrorCode BROKERAGE_USER_NOT_EXISTS = new ErrorCode(1011007000, "分销用户不存在");
  80 + ErrorCode BROKERAGE_USER_FROZEN_PRICE_NOT_ENOUGH = new ErrorCode(1011007001, "用户冻结佣金({})数量不足");
  81 + ErrorCode BROKERAGE_BIND_SELF = new ErrorCode(1011007002, "不能绑定自己");
  82 + ErrorCode BROKERAGE_BIND_USER_NOT_ENABLED = new ErrorCode(1011007003, "绑定用户没有推广资格");
  83 + ErrorCode BROKERAGE_BIND_CONDITION_ADMIN = new ErrorCode(1011007004, "仅可在后台绑定推广员");
  84 + ErrorCode BROKERAGE_BIND_MODE_REGISTER = new ErrorCode(1011007005, "只有在注册时可以绑定");
  85 + ErrorCode BROKERAGE_BIND_OVERRIDE = new ErrorCode(1011007006, "已绑定了推广人");
  86 + ErrorCode BROKERAGE_BIND_LOOP = new ErrorCode(1011007007, "下级不能绑定自己的上级");
80 87  
81 88 }
... ...
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageBindModeEnum.java
... ... @@ -15,16 +15,18 @@ import java.util.Arrays;
15 15 @Getter
16 16 public enum BrokerageBindModeEnum implements IntArrayValuable {
17 17  
18   - // TODO @疯狂:要不从 1 开始?
19 18 /**
20 19 * 只要用户没有推广人,随时都可以绑定分销关系
21 20 */
22   - ANYTIME(0, "没有推广人"),
  21 + ANYTIME(1, "没有推广人"),
23 22 /**
24 23 * 仅新用户注册时才能绑定推广关系
25 24 */
26   - REGISTER(1, "新用户"),
27   - // TODO @疯狂:要加个 2,每次扫码都覆盖
  25 + REGISTER(2, "新用户"),
  26 + /**
  27 + * 每次扫码都覆盖
  28 + */
  29 + OVERRIDE(3, "扫码覆盖"),
28 30 ;
29 31  
30 32 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageBindModeEnum::getMode).toArray();
... ...
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageEnabledConditionEnum.java
... ... @@ -15,15 +15,14 @@ import java.util.Arrays;
15 15 @Getter
16 16 public enum BrokerageEnabledConditionEnum implements IntArrayValuable {
17 17  
18   - // TODO @疯狂:这个也从 1 开始哇
19 18 /**
20 19 * 所有用户都可以分销
21 20 */
22   - ALL(0, "人人分销"),
  21 + ALL(1, "人人分销"),
23 22 /**
24 23 * 仅可后台手动设置推广员
25 24 */
26   - ADMIN(1, "指定分销"),
  25 + ADMIN(2, "指定分销"),
27 26 ;
28 27  
29 28 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageEnabledConditionEnum::getCondition).toArray();
... ...
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageRecordBizTypeEnum.java
... ... @@ -15,9 +15,8 @@ import java.util.Arrays;
15 15 @Getter
16 16 public enum BrokerageRecordBizTypeEnum implements IntArrayValuable {
17 17  
18   - // TODO @疯狂:这个也从 1 开始哇
19   - ORDER(0, "获得推广佣金", "获得推广佣金 {}", true),
20   - WITHDRAW(1, "提现申请", "提现申请扣除佣金 {}", false),
  18 + ORDER(1, "获得推广佣金", "获得推广佣金 {}", true),
  19 + WITHDRAW(2, "提现申请", "提现申请扣除佣金 {}", false),
21 20 ;
22 21  
23 22 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageRecordBizTypeEnum::getType).toArray();
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApiImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.api.brokerage;
  2 +
  3 +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserDTO;
  4 +import cn.iocoder.yudao.module.trade.convert.brokerage.user.BrokerageUserConvert;
  5 +import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService;
  6 +import org.springframework.stereotype.Service;
  7 +import org.springframework.validation.annotation.Validated;
  8 +
  9 +import javax.annotation.Resource;
  10 +
  11 +/**
  12 + * 分销 API 接口实现类
  13 + *
  14 + * @author owen
  15 + */
  16 +@Service
  17 +@Validated
  18 +public class BrokerageApiImpl implements BrokerageApi {
  19 +
  20 + @Resource
  21 + private BrokerageUserService brokerageUserService;
  22 +
  23 + public BrokerageUserDTO getBrokerageUser(Long userId) {
  24 + return BrokerageUserConvert.INSTANCE.convertDTO(brokerageUserService.getBrokerageUser(userId));
  25 + }
  26 +
  27 + @Override
  28 + public boolean bindUser(Long userId, Long bindUserId, Boolean isNewUser) {
  29 + return brokerageUserService.bindUser(userId, bindUserId, isNewUser);
  30 + }
  31 +
  32 +}
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/TradeBrokerageRecordController.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/BrokerageRecordController.java
... ... @@ -2,11 +2,11 @@ package cn.iocoder.yudao.module.trade.controller.admin.brokerage.record;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5   -import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.TradeBrokerageRecordPageReqVO;
6   -import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.TradeBrokerageRecordRespVO;
7   -import cn.iocoder.yudao.module.trade.convert.brokerage.record.TradeBrokerageRecordConvert;
8   -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.TradeBrokerageRecordDO;
9   -import cn.iocoder.yudao.module.trade.service.brokerage.record.TradeBrokerageRecordService;
  5 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordPageReqVO;
  6 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordRespVO;
  7 +import cn.iocoder.yudao.module.trade.convert.brokerage.record.BrokerageRecordConvert;
  8 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO;
  9 +import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService;
10 10 import io.swagger.v3.oas.annotations.Operation;
11 11 import io.swagger.v3.oas.annotations.Parameter;
12 12 import io.swagger.v3.oas.annotations.tags.Tag;
... ... @@ -26,26 +26,26 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
26 26 @RestController
27 27 @RequestMapping("/trade/brokerage-record")
28 28 @Validated
29   -public class TradeBrokerageRecordController {
  29 +public class BrokerageRecordController {
30 30  
31 31 @Resource
32   - private TradeBrokerageRecordService tradeBrokerageRecordService;
  32 + private BrokerageRecordService brokerageRecordService;
33 33  
34 34 @GetMapping("/get")
35 35 @Operation(summary = "获得佣金记录")
36 36 @Parameter(name = "id", description = "编号", required = true, example = "1024")
37 37 @PreAuthorize("@ss.hasPermission('trade:brokerage-record:query')")
38   - public CommonResult<TradeBrokerageRecordRespVO> getBrokerageRecord(@RequestParam("id") Integer id) {
39   - TradeBrokerageRecordDO tradeBrokerageRecord = tradeBrokerageRecordService.getBrokerageRecord(id);
40   - return success(TradeBrokerageRecordConvert.INSTANCE.convert(tradeBrokerageRecord));
  38 + public CommonResult<BrokerageRecordRespVO> getBrokerageRecord(@RequestParam("id") Integer id) {
  39 + BrokerageRecordDO brokerageRecord = brokerageRecordService.getBrokerageRecord(id);
  40 + return success(BrokerageRecordConvert.INSTANCE.convert(brokerageRecord));
41 41 }
42 42  
43 43 @GetMapping("/page")
44 44 @Operation(summary = "获得佣金记录分页")
45 45 @PreAuthorize("@ss.hasPermission('trade:brokerage-record:query')")
46   - public CommonResult<PageResult<TradeBrokerageRecordRespVO>> getBrokerageRecordPage(@Valid TradeBrokerageRecordPageReqVO pageVO) {
47   - PageResult<TradeBrokerageRecordDO> pageResult = tradeBrokerageRecordService.getBrokerageRecordPage(pageVO);
48   - return success(TradeBrokerageRecordConvert.INSTANCE.convertPage(pageResult));
  46 + public CommonResult<PageResult<BrokerageRecordRespVO>> getBrokerageRecordPage(@Valid BrokerageRecordPageReqVO pageVO) {
  47 + PageResult<BrokerageRecordDO> pageResult = brokerageRecordService.getBrokerageRecordPage(pageVO);
  48 + return success(BrokerageRecordConvert.INSTANCE.convertPage(pageResult));
49 49 }
50 50  
51 51 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/vo/TradeBrokerageRecordBaseVO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/vo/BrokerageRecordBaseVO.java
... ... @@ -15,7 +15,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
15 15 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
16 16 */
17 17 @Data
18   -public class TradeBrokerageRecordBaseVO {
  18 +public class BrokerageRecordBaseVO {
19 19  
20 20 @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25973")
21 21 @NotNull(message = "用户编号不能为空")
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/vo/TradeBrokerageRecordPageReqVO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/vo/BrokerageRecordPageReqVO.java
... ... @@ -15,7 +15,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
15 15 @Data
16 16 @EqualsAndHashCode(callSuper = true)
17 17 @ToString(callSuper = true)
18   -public class TradeBrokerageRecordPageReqVO extends PageParam {
  18 +public class BrokerageRecordPageReqVO extends PageParam {
19 19  
20 20 @Schema(description = "用户编号", example = "25973")
21 21 private Long userId;
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/vo/TradeBrokerageRecordRespVO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/vo/BrokerageRecordRespVO.java
... ... @@ -11,7 +11,7 @@ import java.time.LocalDateTime;
11 11 @Data
12 12 @EqualsAndHashCode(callSuper = true)
13 13 @ToString(callSuper = true)
14   -public class TradeBrokerageRecordRespVO extends TradeBrokerageRecordBaseVO {
  14 +public class BrokerageRecordRespVO extends BrokerageRecordBaseVO {
15 15  
16 16 @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28896")
17 17 private Integer id;
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/TradeBrokerageUserController.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/BrokerageUserController.java
... ... @@ -2,10 +2,16 @@ package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
  6 +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
5 7 import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.*;
6   -import cn.iocoder.yudao.module.trade.convert.brokerage.user.TradeBrokerageUserConvert;
7   -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.TradeBrokerageUserDO;
8   -import cn.iocoder.yudao.module.trade.service.brokerage.user.TradeBrokerageUserService;
  8 +import cn.iocoder.yudao.module.trade.convert.brokerage.user.BrokerageUserConvert;
  9 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
  10 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
  11 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
  12 +import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService;
  13 +import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
  14 +import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService;
9 15 import io.swagger.v3.oas.annotations.Operation;
10 16 import io.swagger.v3.oas.annotations.Parameter;
11 17 import io.swagger.v3.oas.annotations.tags.Tag;
... ... @@ -15,30 +21,39 @@ import org.springframework.web.bind.annotation.*;
15 21  
16 22 import javax.annotation.Resource;
17 23 import javax.validation.Valid;
  24 +import java.util.Map;
  25 +import java.util.Set;
18 26  
19 27 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  28 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  29 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
20 30  
21 31 @Tag(name = "管理后台 - 分销用户")
22 32 @RestController
23 33 @RequestMapping("/trade/brokerage-user")
24 34 @Validated
25   -public class TradeBrokerageUserController {
  35 +public class BrokerageUserController {
26 36  
27 37 @Resource
28   - private TradeBrokerageUserService brokerageUserService;
  38 + private BrokerageUserService brokerageUserService;
  39 + @Resource
  40 + private BrokerageRecordService brokerageRecordService;
  41 +
  42 + @Resource
  43 + private MemberUserApi memberUserApi;
29 44  
30 45 @PutMapping("/update-brokerage-user")
31 46 @Operation(summary = "修改推广员")
32 47 @PreAuthorize("@ss.hasPermission('trade:brokerage-user:update-brokerage-user')")
33   - public CommonResult<Boolean> updateBrokerageUser(@Valid @RequestBody TradeBrokerageUserUpdateBrokerageUserReqVO updateReqVO) {
34   - brokerageUserService.updateBrokerageUserId(updateReqVO.getId(), updateReqVO.getBrokerageUserId());
  48 + public CommonResult<Boolean> updateBrokerageUser(@Valid @RequestBody BrokerageUserUpdateBrokerageUserReqVO updateReqVO) {
  49 + brokerageUserService.updateBrokerageUserId(updateReqVO.getId(), updateReqVO.getBindUserId());
35 50 return success(true);
36 51 }
37 52  
38 53 @PutMapping("/clear-brokerage-user")
39 54 @Operation(summary = "清除推广员")
40 55 @PreAuthorize("@ss.hasPermission('trade:brokerage-user:clear-brokerage-user')")
41   - public CommonResult<Boolean> clearBrokerageUser(@Valid @RequestBody TradeBrokerageUserClearBrokerageUserReqVO updateReqVO) {
  56 + public CommonResult<Boolean> clearBrokerageUser(@Valid @RequestBody BrokerageUserClearBrokerageUserReqVO updateReqVO) {
42 57 brokerageUserService.updateBrokerageUserId(updateReqVO.getId(), null);
43 58 return success(true);
44 59 }
... ... @@ -46,8 +61,8 @@ public class TradeBrokerageUserController {
46 61 @PutMapping("/update-brokerage-enable")
47 62 @Operation(summary = "修改推广资格")
48 63 @PreAuthorize("@ss.hasPermission('trade:brokerage-user:update-brokerage-enable')")
49   - public CommonResult<Boolean> updateBrokerageEnabled(@Valid @RequestBody TradeBrokerageUserUpdateBrokerageEnabledReqVO updateReqVO) {
50   - brokerageUserService.updateBrokerageEnabled(updateReqVO.getId(), updateReqVO.getBrokerageEnabled());
  64 + public CommonResult<Boolean> updateBrokerageEnabled(@Valid @RequestBody BrokerageUserUpdateBrokerageEnabledReqVO updateReqVO) {
  65 + brokerageUserService.updateBrokerageEnabled(updateReqVO.getId(), updateReqVO.getEnabled());
51 66 return success(true);
52 67 }
53 68  
... ... @@ -55,17 +70,35 @@ public class TradeBrokerageUserController {
55 70 @Operation(summary = "获得分销用户")
56 71 @Parameter(name = "id", description = "编号", required = true, example = "1024")
57 72 @PreAuthorize("@ss.hasPermission('trade:brokerage-user:query')")
58   - public CommonResult<TradeBrokerageUserRespVO> getBrokerageUser(@RequestParam("id") Long id) {
59   - TradeBrokerageUserDO brokerageUser = brokerageUserService.getBrokerageUser(id);
60   - return success(TradeBrokerageUserConvert.INSTANCE.convert(brokerageUser));
  73 + public CommonResult<BrokerageUserRespVO> getBrokerageUser(@RequestParam("id") Long id) {
  74 + BrokerageUserDO brokerageUser = brokerageUserService.getBrokerageUser(id);
  75 + return success(BrokerageUserConvert.INSTANCE.convert(brokerageUser));
61 76 }
62 77  
63 78 @GetMapping("/page")
64 79 @Operation(summary = "获得分销用户分页")
65 80 @PreAuthorize("@ss.hasPermission('trade:brokerage-user:query')")
66   - public CommonResult<PageResult<TradeBrokerageUserRespVO>> getBrokerageUserPage(@Valid TradeBrokerageUserPageReqVO pageVO) {
67   - PageResult<TradeBrokerageUserDO> pageResult = brokerageUserService.getBrokerageUserPage(pageVO);
68   - return success(TradeBrokerageUserConvert.INSTANCE.convertPage(pageResult));
  81 + public CommonResult<PageResult<BrokerageUserRespVO>> getBrokerageUserPage(@Valid BrokerageUserPageReqVO pageVO) {
  82 + // 分页查询
  83 + PageResult<BrokerageUserDO> pageResult = brokerageUserService.getBrokerageUserPage(pageVO);
  84 +
  85 + // 涉及到的用户
  86 + Set<Long> userIds = convertSet(pageResult.getList(), BrokerageUserDO::getId);
  87 + // 查询用户信息
  88 + Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(userIds);
  89 + // 合计分佣订单
  90 + Map<Long, UserBrokerageSummaryBO> userOrderSummaryMap = convertMap(userIds,
  91 + userId -> userId,
  92 + userId -> brokerageRecordService.summaryByUserIdAndBizTypeAndStatus(userId,
  93 + BrokerageRecordBizTypeEnum.ORDER.getType(), BrokerageRecordStatusEnum.SETTLEMENT.getStatus()));
  94 + // 合计推广用户数量
  95 + Map<Long, Long> brokerageUserCountMap = convertMap(userIds,
  96 + userId -> userId,
  97 + userId -> brokerageUserService.getCountByBindUserId(userId));
  98 +
  99 + // todo 合计提现
  100 +
  101 + return success(BrokerageUserConvert.INSTANCE.convertPage(pageResult, userMap, brokerageUserCountMap, userOrderSummaryMap));
69 102 }
70 103  
71 104 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/TradeBrokerageUserBaseVO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserBaseVO.java
... ... @@ -14,15 +14,15 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
14 14 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
15 15 */
16 16 @Data
17   -public class TradeBrokerageUserBaseVO {
  17 +public class BrokerageUserBaseVO {
18 18  
19 19 @Schema(description = "推广员编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4587")
20 20 @NotNull(message = "推广员编号不能为空")
21   - private Long brokerageUserId;
  21 + private Long bindUserId;
22 22  
23 23 @Schema(description = "推广员绑定时间")
24 24 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
25   - private LocalDateTime brokerageBindTime;
  25 + private LocalDateTime bindUserTime;
26 26  
27 27 @Schema(description = "推广资格", requiredMode = Schema.RequiredMode.REQUIRED)
28 28 @NotNull(message = "推广资格不能为空")
... ... @@ -34,10 +34,10 @@ public class TradeBrokerageUserBaseVO {
34 34  
35 35 @Schema(description = "可用佣金", requiredMode = Schema.RequiredMode.REQUIRED, example = "11089")
36 36 @NotNull(message = "可用佣金不能为空")
37   - private Integer brokeragePrice;
  37 + private Integer price;
38 38  
39 39 @Schema(description = "冻结佣金", requiredMode = Schema.RequiredMode.REQUIRED, example = "30916")
40 40 @NotNull(message = "冻结佣金不能为空")
41   - private Integer frozenBrokeragePrice;
  41 + private Integer frozenPrice;
42 42  
43 43 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/TradeBrokerageUserClearBrokerageUserReqVO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserClearBrokerageUserReqVO.java
... ... @@ -9,7 +9,7 @@ import javax.validation.constraints.NotNull;
9 9 @Schema(description = "管理后台 - 分销用户 - 清除推广员 Request VO")
10 10 @Data
11 11 @ToString(callSuper = true)
12   -public class TradeBrokerageUserClearBrokerageUserReqVO {
  12 +public class BrokerageUserClearBrokerageUserReqVO {
13 13  
14 14 @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20019")
15 15 @NotNull(message = "用户编号不能为空")
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/TradeBrokerageUserPageReqVO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserPageReqVO.java
... ... @@ -15,10 +15,10 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
15 15 @Data
16 16 @EqualsAndHashCode(callSuper = true)
17 17 @ToString(callSuper = true)
18   -public class TradeBrokerageUserPageReqVO extends PageParam {
  18 +public class BrokerageUserPageReqVO extends PageParam {
19 19  
20 20 @Schema(description = "推广员编号", example = "4587")
21   - private Long brokerageUserId;
  21 + private Long bindUserId;
22 22  
23 23 @Schema(description = "推广资格")
24 24 private Boolean brokerageEnabled;
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/TradeBrokerageUserRespVO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserRespVO.java
... ... @@ -11,7 +11,7 @@ import java.time.LocalDateTime;
11 11 @Data
12 12 @EqualsAndHashCode(callSuper = true)
13 13 @ToString(callSuper = true)
14   -public class TradeBrokerageUserRespVO extends TradeBrokerageUserBaseVO {
  14 +public class BrokerageUserRespVO extends BrokerageUserBaseVO {
15 15  
16 16 @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20019")
17 17 private Long id;
... ... @@ -19,4 +19,30 @@ public class TradeBrokerageUserRespVO extends TradeBrokerageUserBaseVO {
19 19 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
20 20 private LocalDateTime createTime;
21 21  
  22 +
  23 + // ========== 用户信息 ==========
  24 +
  25 + @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png")
  26 + private String avatar;
  27 + @Schema(description = "用户昵称", example = "李四")
  28 + private String nickname;
  29 +
  30 +
  31 + // ========== 推广信息 ==========
  32 +
  33 + @Schema(description = "推广用户数量(一级)", example = "20019")
  34 + private Integer brokerageUserCount;
  35 + @Schema(description = "推广订单数量", example = "20019")
  36 + private Integer brokerageOrderCount;
  37 + @Schema(description = "推广订单金额", example = "20019")
  38 + private Integer brokerageOrderPrice;
  39 +
  40 +
  41 + // ========== 提现信息 ==========
  42 +
  43 + @Schema(description = "已提现金额", example = "20019")
  44 + private Integer withdrawPrice;
  45 + @Schema(description = "已提现次数", example = "20019")
  46 + private Integer withdrawCount;
  47 +
22 48 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/TradeBrokerageUserUpdateBrokerageEnabledReqVO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserUpdateBrokerageEnabledReqVO.java
... ... @@ -9,16 +9,14 @@ import javax.validation.constraints.NotNull;
9 9 @Schema(description = "管理后台 - 分销用户 - 修改推广员 Request VO")
10 10 @Data
11 11 @ToString(callSuper = true)
12   -public class TradeBrokerageUserUpdateBrokerageEnabledReqVO {
  12 +public class BrokerageUserUpdateBrokerageEnabledReqVO {
13 13  
14 14 @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20019")
15 15 @NotNull(message = "用户编号不能为空")
16 16 private Long id;
17 17  
18   - // TODO @疯狂:是不是这个字段,可以改成 enabled
19   -
20 18 @Schema(description = "推广资格", requiredMode = Schema.RequiredMode.REQUIRED)
21 19 @NotNull(message = "推广资格不能为空")
22   - private Boolean brokerageEnabled;
  20 + private Boolean enabled;
23 21  
24 22 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/TradeBrokerageUserUpdateBrokerageUserReqVO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserUpdateBrokerageUserReqVO.java
... ... @@ -9,7 +9,7 @@ import javax.validation.constraints.NotNull;
9 9 @Schema(description = "管理后台 - 分销用户 - 修改推广员 Request VO")
10 10 @Data
11 11 @ToString(callSuper = true)
12   -public class TradeBrokerageUserUpdateBrokerageUserReqVO {
  12 +public class BrokerageUserUpdateBrokerageUserReqVO {
13 13  
14 14 @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20019")
15 15 @NotNull(message = "用户编号不能为空")
... ... @@ -17,6 +17,6 @@ public class TradeBrokerageUserUpdateBrokerageUserReqVO {
17 17  
18 18 @Schema(description = "推广员编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4587")
19 19 @NotNull(message = "推广员编号不能为空")
20   - private Long brokerageUserId;
  20 + private Long bindUserId;
21 21  
22 22 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigBaseVO.java
... ... @@ -54,7 +54,6 @@ public class TradeConfigBaseVO {
54 54 @PositiveOrZero(message = "用户提现最低金额不能是负数")
55 55 private Integer brokerageWithdrawMinPrice;
56 56  
57   - // TODO @疯狂:要不要做成字典?按道理都可以体现对哇?感觉是全局的配置哈;
58 57 @Schema(description = "提现银行", requiredMode = Schema.RequiredMode.REQUIRED, example = "[0, 1]")
59 58 @NotEmpty(message = "提现银行不能为空")
60 59 private List<Integer> brokerageBankNames;
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageUserController.java
... ... @@ -4,21 +4,22 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
6 6 import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.*;
  7 +import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService;
7 8 import io.swagger.v3.oas.annotations.Operation;
8 9 import io.swagger.v3.oas.annotations.Parameter;
9 10 import io.swagger.v3.oas.annotations.tags.Tag;
10 11 import lombok.extern.slf4j.Slf4j;
11 12 import org.springframework.format.annotation.DateTimeFormat;
12 13 import org.springframework.validation.annotation.Validated;
13   -import org.springframework.web.bind.annotation.GetMapping;
14   -import org.springframework.web.bind.annotation.RequestMapping;
15   -import org.springframework.web.bind.annotation.RequestParam;
16   -import org.springframework.web.bind.annotation.RestController;
  14 +import org.springframework.web.bind.annotation.*;
17 15  
  16 +import javax.annotation.Resource;
  17 +import javax.validation.Valid;
18 18 import java.time.LocalDateTime;
19 19  
20 20 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
21 21 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  22 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
22 23 import static java.util.Arrays.asList;
23 24  
24 25 @Tag(name = "用户 APP - 分销用户")
... ... @@ -27,6 +28,8 @@ import static java.util.Arrays.asList;
27 28 @Validated
28 29 @Slf4j
29 30 public class AppBrokerageUserController {
  31 + @Resource
  32 + private BrokerageUserService brokerageUserService;
30 33  
31 34 // TODO 芋艿:临时 mock =>
32 35 @GetMapping("/get")
... ... @@ -34,8 +37,8 @@ public class AppBrokerageUserController {
34 37 @PreAuthenticated
35 38 public CommonResult<AppBrokerageUserRespVO> getBrokerageUser() {
36 39 AppBrokerageUserRespVO respVO = new AppBrokerageUserRespVO()
37   - .setBrokeragePrice(2000)
38   - .setFrozenBrokeragePrice(3000);
  40 + .setPrice(2000)
  41 + .setFrozenPrice(3000);
39 42 return success(respVO);
40 43 }
41 44  
... ... @@ -45,10 +48,10 @@ public class AppBrokerageUserController {
45 48 @PreAuthenticated
46 49 public CommonResult<AppBrokerageUserMySummaryRespVO> getBrokerageUserSummary() {
47 50 AppBrokerageUserMySummaryRespVO respVO = new AppBrokerageUserMySummaryRespVO()
48   - .setYesterdayBrokeragePrice(1)
49   - .setBrokeragePrice(2)
50   - .setFrozenBrokeragePrice(3)
51   - .setWithdrawBrokeragePrice(4)
  51 + .setYesterdayPrice(1)
  52 + .setPrice(2)
  53 + .setFrozenPrice(3)
  54 + .setWithdrawPrice(4)
52 55 .setFirstBrokerageUserCount(166)
53 56 .setSecondBrokerageUserCount(233);
54 57 return success(respVO);
... ... @@ -81,16 +84,16 @@ public class AppBrokerageUserController {
81 84 public CommonResult<PageResult<AppBrokerageUserRankByPriceRespVO>> getBrokerageUserChildSummaryPageByPrice(AppBrokerageUserRankPageReqVO pageReqVO) {
82 85 AppBrokerageUserRankByPriceRespVO vo1 = new AppBrokerageUserRankByPriceRespVO()
83 86 .setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
84   - .setBrokeragePrice(10);
  87 + .setPrice(10);
85 88 AppBrokerageUserRankByPriceRespVO vo2 = new AppBrokerageUserRankByPriceRespVO()
86 89 .setId(2L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
87   - .setBrokeragePrice(6);
  90 + .setPrice(6);
88 91 AppBrokerageUserRankByPriceRespVO vo3 = new AppBrokerageUserRankByPriceRespVO()
89 92 .setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
90   - .setBrokeragePrice(4);
  93 + .setPrice(4);
91 94 AppBrokerageUserRankByPriceRespVO vo4 = new AppBrokerageUserRankByPriceRespVO()
92 95 .setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
93   - .setBrokeragePrice(4);
  96 + .setPrice(4);
94 97 return success(new PageResult<>(asList(vo1, vo2, vo3, vo4), 10L));
95 98 }
96 99  
... ... @@ -102,11 +105,11 @@ public class AppBrokerageUserController {
102 105 AppBrokerageUserChildSummaryPageReqVO pageReqVO) {
103 106 AppBrokerageUserChildSummaryRespVO vo1 = new AppBrokerageUserChildSummaryRespVO()
104 107 .setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
105   - .setBrokeragePrice(10).setBrokeragePrice(20).setBrokerageOrderCount(30)
  108 + .setPrice(10).setPrice(20).setBrokerageOrderCount(30)
106 109 .setBrokerageTime(LocalDateTime.now());
107 110 AppBrokerageUserChildSummaryRespVO vo2 = new AppBrokerageUserChildSummaryRespVO()
108 111 .setId(1L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
109   - .setBrokeragePrice(20).setBrokeragePrice(30).setBrokerageOrderCount(40)
  112 + .setPrice(20).setPrice(30).setBrokerageOrderCount(40)
110 113 .setBrokerageTime(LocalDateTime.now());
111 114 return success(new PageResult<>(asList(vo1, vo2), 10L));
112 115 }
... ... @@ -120,4 +123,10 @@ public class AppBrokerageUserController {
120 123 return success(1);
121 124 }
122 125  
  126 + @PutMapping("/bind-user")
  127 + @Operation(summary = "绑定推广员")
  128 + public CommonResult<Boolean> getBrokerageUserRankByPrice(@Valid AppBrokerageUserBindReqVO reqVO) {
  129 + return success(brokerageUserService.bindUser(getLoginUserId(), reqVO.getBindUserId(), false));
  130 + }
  131 +
123 132 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/record/AppBrokerageRecordPageReqVO.java
1 1 package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
  6 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
4 7 import io.swagger.v3.oas.annotations.media.Schema;
5 8 import lombok.Data;
6 9  
... ... @@ -8,12 +11,12 @@ import lombok.Data;
8 11 @Data
9 12 public class AppBrokerageRecordPageReqVO extends PageParam {
10 13  
11   - // TODO @疯狂:要加下枚举校验
12   -
13 14 @Schema(description = "业务类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  15 + @InEnum(value = BrokerageRecordBizTypeEnum.class, message = "业务类型必须是 {value}")
14 16 private Integer bizType;
15 17  
16 18 @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  19 + @InEnum(value = BrokerageRecordStatusEnum.class, message = "状态必须是 {value}")
17 20 private Integer status;
18 21  
19 22 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserBindReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +
  7 +import javax.validation.constraints.NotNull;
  8 +
  9 +@Schema(description = "应用 App - 绑定推广员 Request VO")
  10 +@Data
  11 +public class AppBrokerageUserBindReqVO extends PageParam {
  12 +
  13 + @Schema(description = "推广员编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  14 + @NotNull(message = "推广员编号不能为空")
  15 + private Long bindUserId;
  16 +
  17 +}
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserChildSummaryRespVO.java
... ... @@ -19,7 +19,7 @@ public class AppBrokerageUserChildSummaryRespVO {
19 19 private String avatar;
20 20  
21 21 @Schema(description = "佣金金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
22   - private Integer brokeragePrice;
  22 + private Integer price;
23 23  
24 24 @Schema(description = "分销订单数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
25 25 private Integer brokerageOrderCount;
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserMySummaryRespVO.java
... ... @@ -8,16 +8,16 @@ import lombok.Data;
8 8 public class AppBrokerageUserMySummaryRespVO {
9 9  
10 10 @Schema(description = "昨天的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
11   - private Integer yesterdayBrokeragePrice;
  11 + private Integer yesterdayPrice;
12 12  
13 13 @Schema(description = "提现的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
14   - private Integer withdrawBrokeragePrice;
  14 + private Integer withdrawPrice;
15 15  
16 16 @Schema(description = "可用的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2408")
17   - private Integer brokeragePrice;
  17 + private Integer price;
18 18  
19 19 @Schema(description = "冻结的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "234")
20   - private Integer frozenBrokeragePrice;
  20 + private Integer frozenPrice;
21 21  
22 22 @Schema(description = "分销用户数量(一级)", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
23 23 private Integer firstBrokerageUserCount;
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRankByPriceRespVO.java
... ... @@ -17,6 +17,6 @@ public class AppBrokerageUserRankByPriceRespVO {
17 17 private String avatar;
18 18  
19 19 @Schema(description = "佣金金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
20   - private Integer brokeragePrice;
  20 + private Integer price;
21 21  
22 22 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRespVO.java
... ... @@ -8,9 +8,9 @@ import lombok.Data;
8 8 public class AppBrokerageUserRespVO {
9 9  
10 10 @Schema(description = "可用的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2408")
11   - private Integer brokeragePrice;
  11 + private Integer price;
12 12  
13 13 @Schema(description = "冻结的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "234")
14   - private Integer frozenBrokeragePrice;
  14 + private Integer frozenPrice;
15 15  
16 16 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java
1 1 package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw;
2 2  
  3 +import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum;
3 6 import io.swagger.v3.oas.annotations.media.Schema;
4 7 import lombok.Data;
5 8 import org.hibernate.validator.constraints.URL;
6 9  
  10 +import javax.validation.Validator;
7 11 import javax.validation.constraints.Min;
  12 +import javax.validation.constraints.NotBlank;
8 13  
9 14 @Schema(description = "用户 App - 分销提现创建 Request VO")
10 15 @Data
11 16 public class AppBrokerageWithdrawCreateReqVO {
12 17  
13   - // TODO @疯狂:参数校验逻辑,需要根据 type 进行不同的校验;感觉可以通过分组?
14   -
15 18 @Schema(description = "提现方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  19 + @InEnum(value = BrokerageWithdrawTypeEnum.class, message = "提现方式必须是 {value}")
16 20 private Integer type;
17 21  
18   - @Schema(description = "提现账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456789") // 银行卡号/微信账号/支付宝账号
  22 + @Schema(description = "提现金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
  23 + @Min(value = 1, message = "提现金额不能小于 1")
  24 + private Integer price;
  25 +
  26 +
  27 + // ========== 银行卡、微信、支付宝 提现相关字段 ==========
  28 +
  29 + @Schema(description = "提现账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456789")
  30 + @NotBlank(message = "提现账号不能为空", groups = {Bank.class, Wechat.class, Alipay.class})
19 31 private String accountNo;
20 32  
  33 +
  34 + // ========== 微信、支付宝 提现相关字段 ==========
  35 +
21 36 @Schema(description = "收款码的图片", example = "https://www.iocoder.cn/1.png")
22 37 @URL(message = "收款码的图片,必须是一个 URL")
23 38 private String accountQrCodeUrl;
24 39  
25   - @Schema(description = "提现金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
26   - @Min(value = 1, message = "提现金额必须大于 1")
27   - private Integer price;
  40 +
  41 + // ========== 银行卡 提现相关字段 ==========
  42 +
  43 + @Schema(description = "持卡人姓名", example = "张三")
  44 + @NotBlank(message = "持卡人姓名不能为空", groups = {Bank.class})
  45 + private String name;
  46 + @Schema(description = "提现银行", example = "1")
  47 + @NotBlank(message = "提现银行不能为空", groups = {Bank.class})
  48 + private Integer bankName;
  49 + @Schema(description = "开户地址", example = "海淀支行")
  50 + private String bankAddress;
  51 +
  52 + public interface Wallet {
  53 + }
  54 +
  55 + public interface Bank {
  56 + }
  57 +
  58 + public interface Wechat {
  59 + }
  60 +
  61 + public interface Alipay {
  62 + }
  63 +
  64 + public void validate(Validator validator) {
  65 + if (BrokerageWithdrawTypeEnum.WALLET.getType().equals(type)) {
  66 + ValidationUtils.validate(validator, this, Wallet.class);
  67 + } else if (BrokerageWithdrawTypeEnum.BANK.getType().equals(type)) {
  68 + ValidationUtils.validate(validator, this, Bank.class);
  69 + } else if (BrokerageWithdrawTypeEnum.WECHAT.getType().equals(type)) {
  70 + ValidationUtils.validate(validator, this, Wechat.class);
  71 + } else if (BrokerageWithdrawTypeEnum.ALIPAY.getType().equals(type)) {
  72 + ValidationUtils.validate(validator, this, Alipay.class);
  73 + }
  74 + }
28 75  
29 76 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/TradeBrokerageRecordConvert.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/BrokerageRecordConvert.java
1 1 package cn.iocoder.yudao.module.trade.convert.brokerage.record;
2 2  
  3 +import cn.hutool.core.util.ObjectUtil;
3 4 import cn.hutool.core.util.StrUtil;
4 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5   -import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.TradeBrokerageRecordRespVO;
6   -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.TradeBrokerageRecordDO;
7   -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.TradeBrokerageUserDO;
  6 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordRespVO;
  7 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO;
  8 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
8 9 import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
9 10 import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
10 11 import org.mapstruct.Mapper;
... ... @@ -19,29 +20,32 @@ import java.util.List;
19 20 * @author owen
20 21 */
21 22 @Mapper
22   -public interface TradeBrokerageRecordConvert {
  23 +public interface BrokerageRecordConvert {
23 24  
24   - TradeBrokerageRecordConvert INSTANCE = Mappers.getMapper(TradeBrokerageRecordConvert.class);
  25 + BrokerageRecordConvert INSTANCE = Mappers.getMapper(BrokerageRecordConvert.class);
25 26  
26   - TradeBrokerageRecordRespVO convert(TradeBrokerageRecordDO bean);
  27 + BrokerageRecordRespVO convert(BrokerageRecordDO bean);
27 28  
28   - List<TradeBrokerageRecordRespVO> convertList(List<TradeBrokerageRecordDO> list);
  29 + List<BrokerageRecordRespVO> convertList(List<BrokerageRecordDO> list);
29 30  
30   - PageResult<TradeBrokerageRecordRespVO> convertPage(PageResult<TradeBrokerageRecordDO> page);
  31 + PageResult<BrokerageRecordRespVO> convertPage(PageResult<BrokerageRecordDO> page);
31 32  
32   - default TradeBrokerageRecordDO convert(TradeBrokerageUserDO user, String bizId, int brokerageFrozenDays, int brokerage, LocalDateTime unfreezeTime) {
  33 + default BrokerageRecordDO convert(BrokerageUserDO user, BrokerageRecordBizTypeEnum bizType, String bizId,
  34 + Integer brokerageFrozenDays, int brokerage, LocalDateTime unfreezeTime,
  35 + String title) {
  36 + brokerageFrozenDays = ObjectUtil.defaultIfNull(brokerageFrozenDays, 0);
33 37 // 不冻结时,佣金直接就是结算状态
34 38 Integer status = brokerageFrozenDays > 0
35 39 ? BrokerageRecordStatusEnum.WAIT_SETTLEMENT.getStatus()
36 40 : BrokerageRecordStatusEnum.SETTLEMENT.getStatus();
37   - return new TradeBrokerageRecordDO()
  41 + return new BrokerageRecordDO()
38 42 .setUserId(user.getId())
39   - .setBizType(BrokerageRecordBizTypeEnum.ORDER.getType())
  43 + .setBizType(bizType.getType())
40 44 .setBizId(bizId)
41 45 .setPrice(brokerage)
42   - .setTotalPrice(user.getBrokeragePrice())
43   - .setTitle(BrokerageRecordBizTypeEnum.ORDER.getTitle()) // TODO @疯狂:可能 title 不是很固化,会存在类似:沐晴成功购买《XXX JVM 实战》
44   - .setDescription(StrUtil.format(BrokerageRecordBizTypeEnum.ORDER.getDescription(), String.valueOf(brokerage / 100.0)))
  46 + .setTotalPrice(user.getPrice())
  47 + .setTitle(title)
  48 + .setDescription(StrUtil.format(bizType.getDescription(), String.valueOf(brokerage / 100.0)))
45 49 .setStatus(status)
46 50 .setFrozenDays(brokerageFrozenDays)
47 51 .setUnfreezeTime(unfreezeTime);
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/user/BrokerageUserConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.convert.brokerage.user;
  2 +
  3 +import cn.hutool.core.map.MapUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
  6 +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserDTO;
  7 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserRespVO;
  8 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
  9 +import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
  10 +import org.mapstruct.Mapper;
  11 +import org.mapstruct.factory.Mappers;
  12 +
  13 +import java.util.List;
  14 +import java.util.Map;
  15 +import java.util.Optional;
  16 +
  17 +/**
  18 + * 分销用户 Convert
  19 + *
  20 + * @author owen
  21 + */
  22 +@Mapper
  23 +public interface BrokerageUserConvert {
  24 +
  25 + BrokerageUserConvert INSTANCE = Mappers.getMapper(BrokerageUserConvert.class);
  26 +
  27 + BrokerageUserRespVO convert(BrokerageUserDO bean);
  28 +
  29 + List<BrokerageUserRespVO> convertList(List<BrokerageUserDO> list);
  30 +
  31 + PageResult<BrokerageUserRespVO> convertPage(PageResult<BrokerageUserDO> page);
  32 +
  33 + default PageResult<BrokerageUserRespVO> convertPage(PageResult<BrokerageUserDO> pageResult,
  34 + Map<Long, MemberUserRespDTO> userMap,
  35 + Map<Long, Long> brokerageUserCountMap,
  36 + Map<Long, UserBrokerageSummaryBO> userOrderSummaryMap) {
  37 + PageResult<BrokerageUserRespVO> result = convertPage(pageResult);
  38 + for (BrokerageUserRespVO vo : result.getList()) {
  39 + // 用户信息
  40 + Optional.ofNullable(userMap.get(vo.getId()))
  41 + .ifPresent(user -> {
  42 + vo.setNickname(user.getNickname());
  43 + vo.setAvatar(user.getAvatar());
  44 + });
  45 +
  46 + // 推广用户数量(一级)
  47 + vo.setBrokerageUserCount(MapUtil.getInt(brokerageUserCountMap, vo.getId(), 0));
  48 +
  49 + Optional<UserBrokerageSummaryBO> orderSummaryOptional = Optional.ofNullable(userOrderSummaryMap.get(vo.getId()));
  50 + // 推广订单数量
  51 + vo.setBrokerageOrderCount(orderSummaryOptional.map(UserBrokerageSummaryBO::getCount).orElse(0));
  52 + // 推广订单金额
  53 + vo.setBrokerageOrderPrice(orderSummaryOptional.map(UserBrokerageSummaryBO::getPrice).orElse(0));
  54 +
  55 + // todo 已提现次数
  56 + vo.setWithdrawCount(0);
  57 + // todo 已提现金额
  58 + vo.setWithdrawPrice(0);
  59 + }
  60 + return result;
  61 + }
  62 +
  63 + BrokerageUserDTO convertDTO(BrokerageUserDO brokerageUser);
  64 +}
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/user/TradeBrokerageUserConvert.java deleted
1   -package cn.iocoder.yudao.module.trade.convert.brokerage.user;
2   -
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.TradeBrokerageUserRespVO;
5   -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.TradeBrokerageUserDO;
6   -import org.mapstruct.Mapper;
7   -import org.mapstruct.factory.Mappers;
8   -
9   -import java.util.List;
10   -
11   -/**
12   - * 分销用户 Convert
13   - *
14   - * @author owen
15   - */
16   -@Mapper
17   -public interface TradeBrokerageUserConvert {
18   -
19   - TradeBrokerageUserConvert INSTANCE = Mappers.getMapper(TradeBrokerageUserConvert.class);
20   -
21   - TradeBrokerageUserRespVO convert(TradeBrokerageUserDO bean);
22   -
23   - List<TradeBrokerageUserRespVO> convertList(List<TradeBrokerageUserDO> list);
24   -
25   - PageResult<TradeBrokerageUserRespVO> convertPage(PageResult<TradeBrokerageUserDO> page);
26   -
27   -}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
... ... @@ -7,7 +7,7 @@ import cn.iocoder.yudao.framework.common.util.string.StrUtils;
7 7 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
8 8 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
9 9 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
10   -import cn.iocoder.yudao.module.trade.service.brokerage.record.bo.BrokerageAddReqBO;
  10 +import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO;
11 11 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
12 12 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
13 13 import cn.iocoder.yudao.module.pay.enums.DictTypeConstants;
... ... @@ -279,8 +279,8 @@ public interface TradeOrderConvert {
279 279  
280 280 default BrokerageAddReqBO convert(TradeOrderItemDO item, ProductSkuRespDTO sku) {
281 281 return new BrokerageAddReqBO().setBizId(String.valueOf(item.getId()))
282   - .setPayPrice(item.getPayPrice()).setCount(item.getCount())
283   - .setSkuFirstBrokeragePrice(sku.getSubCommissionFirstPrice())
284   - .setSkuSecondBrokeragePrice(sku.getSubCommissionSecondPrice());
  282 + .setBasePrice(item.getPayPrice() * item.getCount())
  283 + .setFirstFixedPrice(sku.getSubCommissionFirstPrice())
  284 + .setSecondFixedPrice(sku.getSubCommissionSecondPrice());
285 285 }
286 286 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/record/TradeBrokerageRecordDO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/record/BrokerageRecordDO.java
... ... @@ -23,7 +23,7 @@ import java.time.LocalDateTime;
23 23 @Builder
24 24 @NoArgsConstructor
25 25 @AllArgsConstructor
26   -public class TradeBrokerageRecordDO extends BaseDO {
  26 +public class BrokerageRecordDO extends BaseDO {
27 27  
28 28 /**
29 29 * 编号
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/user/TradeBrokerageUserDO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/user/BrokerageUserDO.java
... ... @@ -8,7 +8,6 @@ import lombok.*;
8 8  
9 9 import java.time.LocalDateTime;
10 10  
11   -// TODO @疯狂:因为独立了表,是不是可以把字段的 brokerage 去掉了哈?
12 11 /**
13 12 * 分销用户 DO
14 13 *
... ... @@ -22,25 +21,26 @@ import java.time.LocalDateTime;
22 21 @Builder
23 22 @NoArgsConstructor
24 23 @AllArgsConstructor
25   -public class TradeBrokerageUserDO extends BaseDO {
  24 +public class BrokerageUserDO extends BaseDO {
26 25  
27 26 /**
28 27 * 用户编号
  28 + * <p>
  29 + * 对应 MemberUserDO 的 id 字段
29 30 */
30 31 @TableId
31 32 private Long id;
32 33  
33   - // TODO @疯狂:貌似改成 bindUserId,更明确?
34 34 /**
35 35 * 推广员编号
36   - *
  36 + * <p>
37 37 * 关联 MemberUserDO 的 id 字段
38 38 */
39   - private Long brokerageUserId;
  39 + private Long bindUserId;
40 40 /**
41 41 * 推广员绑定时间
42 42 */
43   - private LocalDateTime brokerageBindTime;
  43 + private LocalDateTime bindUserTime;
44 44  
45 45 /**
46 46 * 推广资格
... ... @@ -54,10 +54,10 @@ public class TradeBrokerageUserDO extends BaseDO {
54 54 /**
55 55 * 可用佣金
56 56 */
57   - private Integer brokeragePrice;
  57 + private Integer price;
58 58 /**
59 59 * 冻结佣金
60 60 */
61   - private Integer frozenBrokeragePrice;
  61 + private Integer frozenPrice;
62 62  
63 63 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/record/BrokerageRecordMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.dal.mysql.brokerage.record;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordPageReqVO;
  7 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO;
  8 +import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
  9 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  10 +import org.apache.ibatis.annotations.Mapper;
  11 +import org.apache.ibatis.annotations.Param;
  12 +import org.apache.ibatis.annotations.Select;
  13 +
  14 +import java.time.LocalDateTime;
  15 +import java.util.List;
  16 +
  17 +/**
  18 + * 佣金记录 Mapper
  19 + *
  20 + * @author owen
  21 + */
  22 +@Mapper
  23 +public interface BrokerageRecordMapper extends BaseMapperX<BrokerageRecordDO> {
  24 +
  25 + default PageResult<BrokerageRecordDO> selectPage(BrokerageRecordPageReqVO reqVO) {
  26 + return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageRecordDO>()
  27 + .eqIfPresent(BrokerageRecordDO::getUserId, reqVO.getUserId())
  28 + .eqIfPresent(BrokerageRecordDO::getBizType, reqVO.getBizType())
  29 + .eqIfPresent(BrokerageRecordDO::getStatus, reqVO.getStatus())
  30 + .betweenIfPresent(BrokerageRecordDO::getCreateTime, reqVO.getCreateTime())
  31 + .orderByDesc(BrokerageRecordDO::getId));
  32 + }
  33 +
  34 + default List<BrokerageRecordDO> selectListByStatusAndUnfreezeTimeLt(Integer status, LocalDateTime unfreezeTime) {
  35 + return selectList(new LambdaQueryWrapper<BrokerageRecordDO>()
  36 + .eq(BrokerageRecordDO::getStatus, status)
  37 + .lt(BrokerageRecordDO::getUnfreezeTime, unfreezeTime));
  38 + }
  39 +
  40 + default int updateByIdAndStatus(Integer id, Integer status, BrokerageRecordDO updateObj) {
  41 + return update(updateObj, new LambdaQueryWrapper<BrokerageRecordDO>()
  42 + .eq(BrokerageRecordDO::getId, id)
  43 + .eq(BrokerageRecordDO::getStatus, status));
  44 + }
  45 +
  46 + default BrokerageRecordDO selectByBizTypeAndBizId(Integer bizType, String bizId) {
  47 + return selectOne(BrokerageRecordDO::getBizType, bizType,
  48 + BrokerageRecordDO::getBizId, bizId);
  49 + }
  50 +
  51 + @Select("select count(1), sum(price) from trade_brokerage_record where user_id = #{userId} and biz_type = #{bizType} and status = #{status}")
  52 + UserBrokerageSummaryBO selectCountAndSumPriceByUserIdAndBizTypeAndStatus(@Param("userId") Long userId,
  53 + @Param("bizType") Integer bizType,
  54 + @Param("status") Integer status);
  55 +}
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/record/TradeBrokerageRecordMapper.java deleted
1   -package cn.iocoder.yudao.module.trade.dal.mysql.brokerage.record;
2   -
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5   -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
6   -import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.TradeBrokerageRecordPageReqVO;
7   -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.TradeBrokerageRecordDO;
8   -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
9   -import org.apache.ibatis.annotations.Mapper;
10   -
11   -import java.time.LocalDateTime;
12   -import java.util.List;
13   -
14   -/**
15   - * 佣金记录 Mapper
16   - *
17   - * @author owen
18   - */
19   -@Mapper
20   -public interface TradeBrokerageRecordMapper extends BaseMapperX<TradeBrokerageRecordDO> {
21   -
22   - default PageResult<TradeBrokerageRecordDO> selectPage(TradeBrokerageRecordPageReqVO reqVO) {
23   - return selectPage(reqVO, new LambdaQueryWrapperX<TradeBrokerageRecordDO>()
24   - .eqIfPresent(TradeBrokerageRecordDO::getUserId, reqVO.getUserId())
25   - .eqIfPresent(TradeBrokerageRecordDO::getBizType, reqVO.getBizType())
26   - .eqIfPresent(TradeBrokerageRecordDO::getStatus, reqVO.getStatus())
27   - .betweenIfPresent(TradeBrokerageRecordDO::getCreateTime, reqVO.getCreateTime())
28   - .orderByDesc(TradeBrokerageRecordDO::getId));
29   - }
30   -
31   - default List<TradeBrokerageRecordDO> selectListByStatusAndUnfreezeTimeLt(Integer status, LocalDateTime unfreezeTime) {
32   - return selectList(new LambdaQueryWrapper<TradeBrokerageRecordDO>()
33   - .eq(TradeBrokerageRecordDO::getStatus, status)
34   - .lt(TradeBrokerageRecordDO::getUnfreezeTime, unfreezeTime));
35   - }
36   -
37   - default int updateByIdAndStatus(Integer id, Integer status, TradeBrokerageRecordDO updateObj) {
38   - return update(updateObj, new LambdaQueryWrapper<TradeBrokerageRecordDO>()
39   - .eq(TradeBrokerageRecordDO::getId, id)
40   - .eq(TradeBrokerageRecordDO::getStatus, status));
41   - }
42   -
43   - // TODO @疯狂:userId???
44   - default TradeBrokerageRecordDO selectByUserIdAndBizTypeAndBizId(Integer bizType, String bizId) {
45   - return selectOne(TradeBrokerageRecordDO::getBizType, bizType,
46   - TradeBrokerageRecordDO::getBizId, bizId);
47   - }
48   -
49   -}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/user/TradeBrokerageUserMapper.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/user/BrokerageUserMapper.java
... ... @@ -4,8 +4,8 @@ import cn.hutool.core.lang.Assert;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
6 6 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
7   -import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.TradeBrokerageUserPageReqVO;
8   -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.TradeBrokerageUserDO;
  7 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO;
  8 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
9 9 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
10 10 import org.apache.ibatis.annotations.Mapper;
11 11  
... ... @@ -15,14 +15,14 @@ import org.apache.ibatis.annotations.Mapper;
15 15 * @author owen
16 16 */
17 17 @Mapper
18   -public interface TradeBrokerageUserMapper extends BaseMapperX<TradeBrokerageUserDO> {
  18 +public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
19 19  
20   - default PageResult<TradeBrokerageUserDO> selectPage(TradeBrokerageUserPageReqVO reqVO) {
21   - return selectPage(reqVO, new LambdaQueryWrapperX<TradeBrokerageUserDO>()
22   - .eqIfPresent(TradeBrokerageUserDO::getBrokerageUserId, reqVO.getBrokerageUserId())
23   - .eqIfPresent(TradeBrokerageUserDO::getBrokerageEnabled, reqVO.getBrokerageEnabled())
24   - .betweenIfPresent(TradeBrokerageUserDO::getCreateTime, reqVO.getCreateTime())
25   - .orderByDesc(TradeBrokerageUserDO::getId));
  20 + default PageResult<BrokerageUserDO> selectPage(BrokerageUserPageReqVO reqVO) {
  21 + return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageUserDO>()
  22 + .eqIfPresent(BrokerageUserDO::getBindUserId, reqVO.getBindUserId())
  23 + .eqIfPresent(BrokerageUserDO::getBrokerageEnabled, reqVO.getBrokerageEnabled())
  24 + .betweenIfPresent(BrokerageUserDO::getCreateTime, reqVO.getCreateTime())
  25 + .orderByDesc(BrokerageUserDO::getId));
26 26 }
27 27  
28 28 /**
... ... @@ -31,11 +31,11 @@ public interface TradeBrokerageUserMapper extends BaseMapperX&lt;TradeBrokerageUser
31 31 * @param id 用户编号
32 32 * @param incrCount 增加佣金(正数)
33 33 */
34   - default void updateBrokeragePriceIncr(Long id, int incrCount) {
  34 + default void updatePriceIncr(Long id, Integer incrCount) {
35 35 Assert.isTrue(incrCount > 0);
36   - LambdaUpdateWrapper<TradeBrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<TradeBrokerageUserDO>()
37   - .setSql(" brokerage_price = brokerage_price + " + incrCount)
38   - .eq(TradeBrokerageUserDO::getId, id);
  36 + LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>()
  37 + .setSql(" price = price + " + incrCount)
  38 + .eq(BrokerageUserDO::getId, id);
39 39 update(null, lambdaUpdateWrapper);
40 40 }
41 41  
... ... @@ -46,11 +46,11 @@ public interface TradeBrokerageUserMapper extends BaseMapperX&lt;TradeBrokerageUser
46 46 * @param id 用户编号
47 47 * @param incrCount 增加佣金(负数)
48 48 */
49   - default void updateBrokeragePriceDecr(Long id, int incrCount) {
  49 + default void updatePriceDecr(Long id, Integer incrCount) {
50 50 Assert.isTrue(incrCount < 0);
51   - LambdaUpdateWrapper<TradeBrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<TradeBrokerageUserDO>()
52   - .setSql(" brokerage_price = brokerage_price + " + incrCount) // 负数,所以使用 + 号
53   - .eq(TradeBrokerageUserDO::getId, id);
  51 + LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>()
  52 + .setSql(" price = price + " + incrCount) // 负数,所以使用 + 号
  53 + .eq(BrokerageUserDO::getId, id);
54 54 update(null, lambdaUpdateWrapper);
55 55 }
56 56  
... ... @@ -60,11 +60,11 @@ public interface TradeBrokerageUserMapper extends BaseMapperX&lt;TradeBrokerageUser
60 60 * @param id 用户编号
61 61 * @param incrCount 增加冻结佣金(正数)
62 62 */
63   - default void updateFrozenBrokeragePriceIncr(Long id, int incrCount) {
  63 + default void updateFrozenPriceIncr(Long id, Integer incrCount) {
64 64 Assert.isTrue(incrCount > 0);
65   - LambdaUpdateWrapper<TradeBrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<TradeBrokerageUserDO>()
66   - .setSql(" frozen_brokerage_price = frozen_brokerage_price + " + incrCount)
67   - .eq(TradeBrokerageUserDO::getId, id);
  65 + LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>()
  66 + .setSql(" frozen_price = frozen_price + " + incrCount)
  67 + .eq(BrokerageUserDO::getId, id);
68 68 update(null, lambdaUpdateWrapper);
69 69 }
70 70  
... ... @@ -75,11 +75,11 @@ public interface TradeBrokerageUserMapper extends BaseMapperX&lt;TradeBrokerageUser
75 75 * @param id 用户编号
76 76 * @param incrCount 减少冻结佣金(负数)
77 77 */
78   - default void updateFrozenBrokeragePriceDecr(Long id, int incrCount) {
  78 + default void updateFrozenPriceDecr(Long id, Integer incrCount) {
79 79 Assert.isTrue(incrCount < 0);
80   - LambdaUpdateWrapper<TradeBrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<TradeBrokerageUserDO>()
81   - .setSql(" frozen_brokerage_price = frozen_brokerage_price + " + incrCount) // 负数,所以使用 + 号
82   - .eq(TradeBrokerageUserDO::getId, id);
  80 + LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>()
  81 + .setSql(" frozen_price = frozen_price + " + incrCount) // 负数,所以使用 + 号
  82 + .eq(BrokerageUserDO::getId, id);
83 83 update(null, lambdaUpdateWrapper);
84 84 }
85 85  
... ... @@ -90,14 +90,25 @@ public interface TradeBrokerageUserMapper extends BaseMapperX&lt;TradeBrokerageUser
90 90 * @param incrCount 减少冻结佣金(负数)
91 91 * @return 更新条数
92 92 */
93   - default int updateFrozenBrokeragePriceDecrAndBrokeragePriceIncr(Long id, int incrCount) {
  93 + default int updateFrozenPriceDecrAndPriceIncr(Long id, Integer incrCount) {
94 94 Assert.isTrue(incrCount < 0);
95   - LambdaUpdateWrapper<TradeBrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<TradeBrokerageUserDO>()
96   - .setSql(" frozen_brokerage_price = frozen_brokerage_price + " + incrCount + // 负数,所以使用 + 号
97   - ", brokerage_price = brokerage_price + " + -incrCount) // 负数,所以使用 - 号
98   - .eq(TradeBrokerageUserDO::getId, id)
99   - .ge(TradeBrokerageUserDO::getFrozenBrokeragePrice, -incrCount); // cas 逻辑
  95 + LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>()
  96 + .setSql(" frozen_price = frozen_price + " + incrCount + // 负数,所以使用 + 号
  97 + ", price = price + " + -incrCount) // 负数,所以使用 - 号
  98 + .eq(BrokerageUserDO::getId, id)
  99 + .ge(BrokerageUserDO::getFrozenPrice, -incrCount); // cas 逻辑
100 100 return update(null, lambdaUpdateWrapper);
101 101 }
102 102  
  103 + default void updateBindUserIdAndBindUserTimeToNull(Long id) {
  104 + update(null, new LambdaUpdateWrapper<BrokerageUserDO>()
  105 + .eq(BrokerageUserDO::getId, id)
  106 + .set(BrokerageUserDO::getBindUserId, null).set(BrokerageUserDO::getBindUserTime, null));
  107 + }
  108 +
  109 + default void updateEnabledFalseAndBrokerageTimeToNull(Long id) {
  110 + update(null, new LambdaUpdateWrapper<BrokerageUserDO>()
  111 + .eq(BrokerageUserDO::getId, id)
  112 + .set(BrokerageUserDO::getBrokerageEnabled, false).set(BrokerageUserDO::getBrokerageTime, null));
  113 + }
103 114 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/job/brokerage/TradeBrokerageRecordUnfreezeJob.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/job/brokerage/BrokerageRecordUnfreezeJob.java
... ... @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.trade.job.brokerage;
3 3 import cn.hutool.core.util.StrUtil;
4 4 import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
5 5 import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
6   -import cn.iocoder.yudao.module.trade.service.brokerage.record.TradeBrokerageRecordService;
  6 +import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService;
7 7 import org.springframework.stereotype.Component;
8 8  
9 9 import javax.annotation.Resource;
... ... @@ -15,14 +15,14 @@ import javax.annotation.Resource;
15 15 */
16 16 @Component
17 17 @TenantJob
18   -public class TradeBrokerageRecordUnfreezeJob implements JobHandler {
  18 +public class BrokerageRecordUnfreezeJob implements JobHandler {
19 19  
20 20 @Resource
21   - private TradeBrokerageRecordService tradeBrokerageRecordService;
  21 + private BrokerageRecordService brokerageRecordService;
22 22  
23 23 @Override
24 24 public String execute(String param) {
25   - int count = tradeBrokerageRecordService.unfreezeRecord();
  25 + int count = brokerageRecordService.unfreezeRecord();
26 26 return StrUtil.format("解冻佣金 {} 个", count);
27 27 }
28 28  
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/bo/BrokerageAddReqBO.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/bo/BrokerageAddReqBO.java
1   -package cn.iocoder.yudao.module.trade.service.brokerage.record.bo;
  1 +package cn.iocoder.yudao.module.trade.service.brokerage.bo;
2 2  
3 3 import lombok.AllArgsConstructor;
4 4 import lombok.Data;
5 5 import lombok.NoArgsConstructor;
6 6  
7   -// TODO @疯狂:要不要 service 还是拍平;就是都放在 brokerage 包下,然后 bo 里面,稍微分分;
  7 +import javax.validation.constraints.NotBlank;
  8 +
8 9 /**
9 10 * 佣金 增加 Request BO
10 11 *
... ... @@ -15,29 +16,22 @@ import lombok.NoArgsConstructor;
15 16 @AllArgsConstructor
16 17 public class BrokerageAddReqBO {
17 18  
18   - // TODO @疯狂:bo 的话,也可以考虑加下 @Validated 注解,校验下参数;防御性下哈,虽然不一定用的到
19   -
20 19 /**
21   - * 业务ID
  20 + * 业务编号
22 21 */
  22 + @NotBlank(message = "业务编号不能为空")
23 23 private String bizId;
24   - // TODO @疯狂:不需要 payPrice 和 count,计算成 price 就好啦;
25   - /**
26   - * 商品支付价格
27   - */
28   - private Integer payPrice;
29   - // TODO @疯狂:可以去掉 sku 哈,更抽象一点;
30 24 /**
31   - * SKU 一级佣金
  25 + * 佣金基数
32 26 */
33   - private Integer skuFirstBrokeragePrice;
  27 + private Integer basePrice;
34 28 /**
35   - * SKU 二级佣金
  29 + * 一级佣金(固定)
36 30 */
37   - private Integer skuSecondBrokeragePrice;
  31 + private Integer firstFixedPrice;
38 32 /**
39   - * 购买数量
  33 + * 二级佣金(固定)
40 34 */
41   - private Integer count;
  35 + private Integer secondFixedPrice;
42 36  
43 37 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/bo/UserBrokerageSummaryBO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.service.brokerage.bo;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +
  7 +/**
  8 + * 用户佣金合计 BO
  9 + *
  10 + * @author owen
  11 + */
  12 +@Data
  13 +@NoArgsConstructor
  14 +@AllArgsConstructor
  15 +public class UserBrokerageSummaryBO {
  16 + /**
  17 + * 佣金数量
  18 + */
  19 + private Integer count;
  20 + /**
  21 + * 佣金总额
  22 + */
  23 + private Integer price;
  24 +}
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/TradeBrokerageRecordService.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/BrokerageRecordService.java
1 1 package cn.iocoder.yudao.module.trade.service.brokerage.record;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.TradeBrokerageRecordDO;
5   -import cn.iocoder.yudao.module.trade.service.brokerage.record.bo.BrokerageAddReqBO;
6   -import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.TradeBrokerageRecordPageReqVO;
  4 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordPageReqVO;
  5 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO;
  6 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
  7 +import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO;
  8 +import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
7 9  
  10 +import javax.validation.Valid;
8 11 import java.util.List;
9 12  
10 13 /**
... ... @@ -12,7 +15,7 @@ import java.util.List;
12 15 *
13 16 * @author owen
14 17 */
15   -public interface TradeBrokerageRecordService {
  18 +public interface BrokerageRecordService {
16 19  
17 20 /**
18 21 * 获得佣金记录
... ... @@ -20,7 +23,7 @@ public interface TradeBrokerageRecordService {
20 23 * @param id 编号
21 24 * @return 佣金记录
22 25 */
23   - TradeBrokerageRecordDO getBrokerageRecord(Integer id);
  26 + BrokerageRecordDO getBrokerageRecord(Integer id);
24 27  
25 28 /**
26 29 * 获得佣金记录分页
... ... @@ -28,25 +31,25 @@ public interface TradeBrokerageRecordService {
28 31 * @param pageReqVO 分页查询
29 32 * @return 佣金记录分页
30 33 */
31   - PageResult<TradeBrokerageRecordDO> getBrokerageRecordPage(TradeBrokerageRecordPageReqVO pageReqVO);
  34 + PageResult<BrokerageRecordDO> getBrokerageRecordPage(BrokerageRecordPageReqVO pageReqVO);
32 35  
33   - // TODO @疯狂:是不是 bizType 得加下?方便未来拓展哈;
34 36 /**
35 37 * 增加佣金
36 38 *
37   - * @param userId 会员编号
38   - * @param list 请求参数列表
  39 + * @param userId 会员编号
  40 + * @param bizType 业务类型
  41 + * @param list 请求参数列表
39 42 */
40   - void addBrokerage(Long userId, List<BrokerageAddReqBO> list);
  43 + void addBrokerage(Long userId, BrokerageRecordBizTypeEnum bizType, @Valid List<BrokerageAddReqBO> list);
41 44  
42   - // TODO @疯狂:是不是 bizType 得加下?方便未来拓展哈;
43 45 /**
44 46 * 取消佣金:将佣金记录,状态修改为已失效
45 47 *
46   - * @param userId 会员编号
47   - * @param bizId 业务编号
  48 + * @param userId 会员编号
  49 + * @param bizType 业务类型
  50 + * @param bizId 业务编号
48 51 */
49   - void cancelBrokerage(Long userId, String bizId);
  52 + void cancelBrokerage(Long userId, BrokerageRecordBizTypeEnum bizType, String bizId);
50 53  
51 54 /**
52 55 * 解冻佣金:将待结算的佣金记录,状态修改为已结算
... ... @@ -55,4 +58,13 @@ public interface TradeBrokerageRecordService {
55 58 */
56 59 int unfreezeRecord();
57 60  
  61 + /**
  62 + * 汇总用户佣金
  63 + *
  64 + * @param userId 用户编号
  65 + * @param bizType 业务类型
  66 + * @param status 佣金状态
  67 + * @return 用户佣金汇总
  68 + */
  69 + UserBrokerageSummaryBO summaryByUserIdAndBizTypeAndStatus(Long userId, Integer bizType, Integer status);
58 70 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/TradeBrokerageRecordServiceImpl.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/BrokerageRecordServiceImpl.java
... ... @@ -2,20 +2,21 @@ package cn.iocoder.yudao.module.trade.service.brokerage.record;
2 2  
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.util.BooleanUtil;
5   -import cn.hutool.core.util.NumberUtil;
6 5 import cn.hutool.core.util.ObjectUtil;
7 6 import cn.hutool.extra.spring.SpringUtil;
8 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
9   -import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.TradeBrokerageRecordPageReqVO;
10   -import cn.iocoder.yudao.module.trade.convert.brokerage.record.TradeBrokerageRecordConvert;
11   -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.TradeBrokerageRecordDO;
12   -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.TradeBrokerageUserDO;
  8 +import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
  9 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordPageReqVO;
  10 +import cn.iocoder.yudao.module.trade.convert.brokerage.record.BrokerageRecordConvert;
  11 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO;
  12 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
13 13 import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
14   -import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.record.TradeBrokerageRecordMapper;
  14 +import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.record.BrokerageRecordMapper;
15 15 import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
16 16 import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
17   -import cn.iocoder.yudao.module.trade.service.brokerage.record.bo.BrokerageAddReqBO;
18   -import cn.iocoder.yudao.module.trade.service.brokerage.user.TradeBrokerageUserService;
  17 +import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO;
  18 +import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
  19 +import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService;
19 20 import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
20 21 import lombok.extern.slf4j.Slf4j;
21 22 import org.springframework.stereotype.Service;
... ... @@ -23,7 +24,6 @@ import org.springframework.transaction.annotation.Transactional;
23 24 import org.springframework.validation.annotation.Validated;
24 25  
25 26 import javax.annotation.Resource;
26   -import java.math.RoundingMode;
27 27 import java.time.LocalDateTime;
28 28 import java.util.ArrayList;
29 29 import java.util.List;
... ... @@ -37,69 +37,67 @@ import java.util.function.Function;
37 37 @Slf4j
38 38 @Service
39 39 @Validated
40   -public class TradeBrokerageRecordServiceImpl implements TradeBrokerageRecordService {
  40 +public class BrokerageRecordServiceImpl implements BrokerageRecordService {
41 41  
42 42 @Resource
43   - private TradeBrokerageRecordMapper tradeBrokerageRecordMapper;
  43 + private BrokerageRecordMapper brokerageRecordMapper;
44 44 @Resource
45 45 private TradeConfigService tradeConfigService;
46 46 @Resource
47   - private TradeBrokerageUserService tradeBrokerageUserService;
  47 + private BrokerageUserService brokerageUserService;
48 48  
49 49 @Override
50   - public TradeBrokerageRecordDO getBrokerageRecord(Integer id) {
51   - return tradeBrokerageRecordMapper.selectById(id);
  50 + public BrokerageRecordDO getBrokerageRecord(Integer id) {
  51 + return brokerageRecordMapper.selectById(id);
52 52 }
53 53  
54 54 @Override
55   - public PageResult<TradeBrokerageRecordDO> getBrokerageRecordPage(TradeBrokerageRecordPageReqVO pageReqVO) {
56   - return tradeBrokerageRecordMapper.selectPage(pageReqVO);
  55 + public PageResult<BrokerageRecordDO> getBrokerageRecordPage(BrokerageRecordPageReqVO pageReqVO) {
  56 + return brokerageRecordMapper.selectPage(pageReqVO);
57 57 }
58 58  
59   - // TODO @疯狂:buyerId 要不要统一改成 userId 哈;
60 59 @Override
61 60 @Transactional(rollbackFor = Exception.class)
62   - public void addBrokerage(Long buyerId, List<BrokerageAddReqBO> list) {
  61 + public void addBrokerage(Long userId, BrokerageRecordBizTypeEnum bizType, List<BrokerageAddReqBO> list) {
63 62 TradeConfigDO memberConfig = tradeConfigService.getTradeConfig();
64 63 // 0 未启用分销功能
65   - // TODO @疯狂:BooleanUtil.isFalse();逻辑里,尽量不做 !取反,这样要多思考一层;
66 64 if (memberConfig == null || !BooleanUtil.isTrue(memberConfig.getBrokerageEnabled())) {
67   - log.warn("[addBrokerage][增加佣金失败:brokerageEnabled 未配置,buyerId({})", buyerId);
  65 + log.warn("[addBrokerage][增加佣金失败:brokerageEnabled 未配置,userId({})", userId);
68 66 return;
69 67 }
70 68  
71 69 // 1.1 获得一级推广人
72   - TradeBrokerageUserDO firstUser = tradeBrokerageUserService.getInviteBrokerageUser(buyerId);
  70 + BrokerageUserDO firstUser = brokerageUserService.getBindBrokerageUser(userId);
73 71 if (firstUser == null || !BooleanUtil.isTrue(firstUser.getBrokerageEnabled())) {
74 72 return;
75 73 }
76   -
77   - // 1.2 计算一级分佣 // TODO 疯狂:类似 1.1 和 1.2 的空行,可以去掉;一般在代码里的空行,是为了逻辑分块;但是分块如果太多,就会导致代码里都是空行哈;
78   - addBrokerage(firstUser, list, memberConfig.getBrokerageFrozenDays(), memberConfig.getBrokerageFirstPercent(), BrokerageAddReqBO::getSkuFirstBrokeragePrice);
  74 + // 1.2 计算一级分佣
  75 + addBrokerage(firstUser, list, memberConfig.getBrokerageFrozenDays(), memberConfig.getBrokerageFirstPercent(), BrokerageAddReqBO::getFirstFixedPrice, bizType);
79 76  
80 77 // 2.1 获得二级推广员
81   - // TODO @疯狂:这里可以加个 firstUser.getBrokerageUserId() 为空的判断 return
82   - TradeBrokerageUserDO secondUser = tradeBrokerageUserService.getBrokerageUser(firstUser.getBrokerageUserId());
  78 + if (firstUser.getBindUserId() == null) {
  79 + return;
  80 + }
  81 + BrokerageUserDO secondUser = brokerageUserService.getBrokerageUser(firstUser.getBindUserId());
83 82 if (secondUser == null || !BooleanUtil.isTrue(secondUser.getBrokerageEnabled())) {
84 83 return;
85 84 }
86   -
87 85 // 2.2 计算二级分佣
88   - addBrokerage(secondUser, list, memberConfig.getBrokerageFrozenDays(), memberConfig.getBrokerageSecondPercent(), BrokerageAddReqBO::getSkuSecondBrokeragePrice);
  86 + addBrokerage(secondUser, list, memberConfig.getBrokerageFrozenDays(), memberConfig.getBrokerageSecondPercent(), BrokerageAddReqBO::getSecondFixedPrice, bizType);
89 87 }
90 88  
91 89 @Override
92 90 @Transactional(rollbackFor = Exception.class)
93   - public void cancelBrokerage(Long userId, String bizId) {
94   - TradeBrokerageRecordDO record = tradeBrokerageRecordMapper.selectByUserIdAndBizTypeAndBizId(BrokerageRecordBizTypeEnum.ORDER.getType(), bizId);
  91 + public void cancelBrokerage(Long userId, BrokerageRecordBizTypeEnum bizType, String bizId) {
  92 + BrokerageRecordDO record = brokerageRecordMapper.selectByBizTypeAndBizId(bizType.getType(), bizId);
95 93 if (record == null || ObjectUtil.notEqual(record.getUserId(), userId)) {
96 94 log.error("[cancelBrokerage][userId({})][bizId({}) 更新为已失效失败:记录不存在]", userId, bizId);
97 95 return;
98 96 }
99 97  
100 98 // 1. 更新佣金记录为已失效
101   - TradeBrokerageRecordDO updateObj = new TradeBrokerageRecordDO().setStatus(BrokerageRecordStatusEnum.CANCEL.getStatus());
102   - int updateRows = tradeBrokerageRecordMapper.updateByIdAndStatus(record.getId(), record.getStatus(), updateObj);
  99 + BrokerageRecordDO updateObj = new BrokerageRecordDO().setStatus(BrokerageRecordStatusEnum.CANCEL.getStatus());
  100 + int updateRows = brokerageRecordMapper.updateByIdAndStatus(record.getId(), record.getStatus(), updateObj);
103 101 if (updateRows == 0) {
104 102 log.error("[cancelBrokerage][record({}) 更新为已失效失败]", record.getId());
105 103 return;
... ... @@ -107,30 +105,28 @@ public class TradeBrokerageRecordServiceImpl implements TradeBrokerageRecordServ
107 105  
108 106 // 2. 更新用户的佣金
109 107 if (BrokerageRecordStatusEnum.WAIT_SETTLEMENT.getStatus().equals(record.getStatus())) {
110   - tradeBrokerageUserService.updateUserFrozenBrokeragePrice(userId, -record.getPrice());
  108 + brokerageUserService.updateUserFrozenPrice(userId, -record.getPrice());
111 109 } else if (BrokerageRecordStatusEnum.SETTLEMENT.getStatus().equals(record.getStatus())) {
112   - tradeBrokerageUserService.updateUserBrokeragePrice(userId, -record.getPrice());
  110 + brokerageUserService.updateUserPrice(userId, -record.getPrice());
113 111 }
114 112 }
115 113  
116   - // TODO @疯狂:是不是 calculateBrokeragePrice
117 114 /**
118 115 * 计算佣金
119 116 *
120   - * @param payPrice 订单支付金额
121   - * @param percent 商品 SKU 设置的佣金
122   - * @param skuBrokeragePrice 商品的佣金
  117 + * @param basePrice 佣金基数
  118 + * @param percent 佣金比例
  119 + * @param fixedPrice 固定佣金
123 120 * @return 佣金
124 121 */
125   - int calculateBrokerage(Integer payPrice, Integer percent, Integer skuBrokeragePrice) {
126   - // 1. 优先使用商品 SKU 设置的佣金
127   - if (skuBrokeragePrice != null && skuBrokeragePrice > 0) {
128   - return ObjectUtil.defaultIfNull(skuBrokeragePrice, 0);
  122 + int calculatePrice(Integer basePrice, Integer percent, Integer fixedPrice) {
  123 + // 1. 优先使用固定佣金
  124 + if (fixedPrice != null && fixedPrice > 0) {
  125 + return ObjectUtil.defaultIfNull(fixedPrice, 0);
129 126 }
130   - // 2. 根据订单支付金额计算佣金
131   - // TODO @疯狂:要不要把 MoneyUtils 抽到 common 里,然后这里也使用这个类的方法;
132   - if (payPrice != null && payPrice > 0 && percent != null && percent > 0) {
133   - return NumberUtil.div(NumberUtil.mul(payPrice, percent), 100, 0, RoundingMode.DOWN).intValue();
  127 + // 2. 根据比例计算佣金
  128 + if (basePrice != null && basePrice > 0 && percent != null && percent > 0) {
  129 + return MoneyUtils.calculateRatePriceFloor(basePrice, Double.valueOf(percent));
134 130 }
135 131 return 0;
136 132 }
... ... @@ -138,51 +134,51 @@ public class TradeBrokerageRecordServiceImpl implements TradeBrokerageRecordServ
138 134 /**
139 135 * 增加用户佣金
140 136 *
141   - * @param user 用户
142   - * @param list 佣金增加参数列表
143   - * @param brokerageFrozenDays 冻结天数
144   - * @param brokeragePercent 佣金比例
145   - * @param skuBrokeragePriceFun 商品 SKU 设置的佣金
  137 + * @param user 用户
  138 + * @param list 佣金增加参数列表
  139 + * @param brokerageFrozenDays 冻结天数
  140 + * @param brokeragePercent 佣金比例
  141 + * @param fixedPriceFun 固定佣金
  142 + * @param bizType 业务类型
146 143 */
147   - private void addBrokerage(TradeBrokerageUserDO user, List<BrokerageAddReqBO> list, Integer brokerageFrozenDays,
148   - Integer brokeragePercent, Function<BrokerageAddReqBO, Integer> skuBrokeragePriceFun) {
  144 + private void addBrokerage(BrokerageUserDO user, List<BrokerageAddReqBO> list, Integer brokerageFrozenDays,
  145 + Integer brokeragePercent, Function<BrokerageAddReqBO, Integer> fixedPriceFun,
  146 + BrokerageRecordBizTypeEnum bizType) {
149 147 // 1.1 处理冻结时间
150   - // TODO @疯狂:是不是 brokerageFrozenDays != null && brokerageFrozenDays > 0 ?然后计算;更简洁一点;
151   - brokerageFrozenDays = ObjectUtil.defaultIfNull(brokerageFrozenDays, 0);
152 148 LocalDateTime unfreezeTime = null;
153   - if (brokerageFrozenDays > 0) {
  149 + if (brokerageFrozenDays != null && brokerageFrozenDays > 0) {
154 150 unfreezeTime = LocalDateTime.now().plusDays(brokerageFrozenDays);
155 151 }
156 152 // 1.2 计算分佣
157 153 int totalBrokerage = 0;
158   - List<TradeBrokerageRecordDO> records = new ArrayList<>();
  154 + List<BrokerageRecordDO> records = new ArrayList<>();
159 155 for (BrokerageAddReqBO item : list) {
160   - int brokeragePerItem = calculateBrokerage(item.getPayPrice(), brokeragePercent, skuBrokeragePriceFun.apply(item));
161   - // TODO @疯狂:其实可以 brokeragePerItem <= 0 ,continue;这样 { 层级更少;代码更简洁;}
162   - if (brokeragePerItem > 0) {
163   - int brokerage = brokeragePerItem * item.getCount();
164   - records.add(TradeBrokerageRecordConvert.INSTANCE.convert(user, item.getBizId(), brokerageFrozenDays, brokerage, unfreezeTime));
165   - totalBrokerage += brokerage;
  156 + int brokeragePerItem = calculatePrice(item.getBasePrice(), brokeragePercent, fixedPriceFun.apply(item));
  157 + if (brokeragePerItem <= 0) {
  158 + continue;
166 159 }
  160 + records.add(BrokerageRecordConvert.INSTANCE.convert(user, bizType, item.getBizId(),
  161 + brokerageFrozenDays, brokeragePerItem, unfreezeTime, bizType.getTitle()));
  162 + totalBrokerage += brokeragePerItem;
167 163 }
168 164 if (CollUtil.isEmpty(records)) {
169 165 return;
170 166 }
171 167 // 1.3 保存佣金记录
172   - tradeBrokerageRecordMapper.insertBatch(records);
  168 + brokerageRecordMapper.insertBatch(records);
173 169  
174 170 // 2. 更新用户佣金
175   - if (brokerageFrozenDays > 0) { // 更新用户冻结佣金
176   - tradeBrokerageUserService.updateUserFrozenBrokeragePrice(user.getId(), totalBrokerage);
  171 + if (brokerageFrozenDays != null && brokerageFrozenDays > 0) { // 更新用户冻结佣金
  172 + brokerageUserService.updateUserFrozenPrice(user.getId(), totalBrokerage);
177 173 } else { // 更新用户可用佣金
178   - tradeBrokerageUserService.updateUserBrokeragePrice(user.getId(), totalBrokerage);
  174 + brokerageUserService.updateUserPrice(user.getId(), totalBrokerage);
179 175 }
180 176 }
181 177  
182 178 @Override
183 179 public int unfreezeRecord() {
184 180 // 1. 查询待结算的佣金记录
185   - List<TradeBrokerageRecordDO> records = tradeBrokerageRecordMapper.selectListByStatusAndUnfreezeTimeLt(
  181 + List<BrokerageRecordDO> records = brokerageRecordMapper.selectListByStatusAndUnfreezeTimeLt(
186 182 BrokerageRecordStatusEnum.WAIT_SETTLEMENT.getStatus(), LocalDateTime.now());
187 183 if (CollUtil.isEmpty(records)) {
188 184 return 0;
... ... @@ -190,7 +186,7 @@ public class TradeBrokerageRecordServiceImpl implements TradeBrokerageRecordServ
190 186  
191 187 // 2. 遍历执行
192 188 int count = 0;
193   - for (TradeBrokerageRecordDO record : records) {
  189 + for (BrokerageRecordDO record : records) {
194 190 try {
195 191 boolean success = getSelf().unfreezeRecord(record);
196 192 if (success) {
... ... @@ -203,20 +199,26 @@ public class TradeBrokerageRecordServiceImpl implements TradeBrokerageRecordServ
203 199 return count;
204 200 }
205 201  
  202 + @Override
  203 + public UserBrokerageSummaryBO summaryByUserIdAndBizTypeAndStatus(Long userId, Integer bizType, Integer status) {
  204 + UserBrokerageSummaryBO summaryBO = brokerageRecordMapper.selectCountAndSumPriceByUserIdAndBizTypeAndStatus(userId, bizType, status);
  205 + return summaryBO == null ? new UserBrokerageSummaryBO(0, 0) : summaryBO;
  206 + }
  207 +
206 208 @Transactional(rollbackFor = Exception.class)
207   - public boolean unfreezeRecord(TradeBrokerageRecordDO record) {
  209 + public boolean unfreezeRecord(BrokerageRecordDO record) {
208 210 // 更新记录状态
209   - TradeBrokerageRecordDO updateObj = new TradeBrokerageRecordDO()
  211 + BrokerageRecordDO updateObj = new BrokerageRecordDO()
210 212 .setStatus(BrokerageRecordStatusEnum.SETTLEMENT.getStatus())
211 213 .setUnfreezeTime(LocalDateTime.now());
212   - int updateRows = tradeBrokerageRecordMapper.updateByIdAndStatus(record.getId(), record.getStatus(), updateObj);
  214 + int updateRows = brokerageRecordMapper.updateByIdAndStatus(record.getId(), record.getStatus(), updateObj);
213 215 if (updateRows == 0) {
214 216 log.error("[unfreezeRecord][record({}) 更新为已结算失败]", record.getId());
215 217 return false;
216 218 }
217 219  
218 220 // 更新用户冻结佣金
219   - tradeBrokerageUserService.updateFrozenBrokeragePriceDecrAndBrokeragePriceIncr(record.getUserId(), -record.getPrice());
  221 + brokerageUserService.updateFrozenPriceDecrAndPriceIncr(record.getUserId(), -record.getPrice());
220 222 log.info("[unfreezeRecord][record({}) 更新为已结算成功]", record.getId());
221 223 return true;
222 224 }
... ... @@ -226,7 +228,7 @@ public class TradeBrokerageRecordServiceImpl implements TradeBrokerageRecordServ
226 228 *
227 229 * @return 自己
228 230 */
229   - private TradeBrokerageRecordServiceImpl getSelf() {
  231 + private BrokerageRecordServiceImpl getSelf() {
230 232 return SpringUtil.getBean(getClass());
231 233 }
232 234  
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/TradeBrokerageUserService.java renamed to yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserService.java
1 1 package cn.iocoder.yudao.module.trade.service.brokerage.user;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.TradeBrokerageUserPageReqVO;
5   -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.TradeBrokerageUserDO;
  4 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO;
  5 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
6 6  
7 7 import java.util.Collection;
8 8 import java.util.List;
9 9  
10   -// TODO @疯狂:要不去掉 Trade 前缀哈;交易这块,我准备除了 tradeorder 保持下,类似 aftersale,都要取消前缀了;tradeorder 保持的原因,是避免 payorder 和它重复
11 10 /**
12 11 * 分销用户 Service 接口
13 12 *
14 13 * @author owen
15 14 */
16   -public interface TradeBrokerageUserService {
  15 +public interface BrokerageUserService {
17 16  
18 17 /**
19 18 * 获得分销用户
... ... @@ -21,7 +20,7 @@ public interface TradeBrokerageUserService {
21 20 * @param id 编号
22 21 * @return 分销用户
23 22 */
24   - TradeBrokerageUserDO getBrokerageUser(Long id);
  23 + BrokerageUserDO getBrokerageUser(Long id);
25 24  
26 25 /**
27 26 * 获得分销用户列表
... ... @@ -29,7 +28,7 @@ public interface TradeBrokerageUserService {
29 28 * @param ids 编号
30 29 * @return 分销用户列表
31 30 */
32   - List<TradeBrokerageUserDO> getBrokerageUserList(Collection<Long> ids);
  31 + List<BrokerageUserDO> getBrokerageUserList(Collection<Long> ids);
33 32  
34 33 /**
35 34 * 获得分销用户分页
... ... @@ -37,23 +36,23 @@ public interface TradeBrokerageUserService {
37 36 * @param pageReqVO 分页查询
38 37 * @return 分销用户分页
39 38 */
40   - PageResult<TradeBrokerageUserDO> getBrokerageUserPage(TradeBrokerageUserPageReqVO pageReqVO);
  39 + PageResult<BrokerageUserDO> getBrokerageUserPage(BrokerageUserPageReqVO pageReqVO);
41 40  
42 41 /**
43 42 * 修改推广员编号
44 43 *
45   - * @param id 用户编号
46   - * @param brokerageUserId 推广员编号
  44 + * @param id 用户编号
  45 + * @param bindUserId 推广员编号
47 46 */
48   - void updateBrokerageUserId(Long id, Long brokerageUserId);
  47 + void updateBrokerageUserId(Long id, Long bindUserId);
49 48  
50 49 /**
51 50 * 修改推广资格
52 51 *
53   - * @param id 用户编号
54   - * @param brokerageEnabled 推广资格
  52 + * @param id 用户编号
  53 + * @param enabled 推广资格
55 54 */
56   - void updateBrokerageEnabled(Long id, Boolean brokerageEnabled);
  55 + void updateBrokerageEnabled(Long id, Boolean enabled);
57 56  
58 57 /**
59 58 * 获得用户的推广人
... ... @@ -61,31 +60,47 @@ public interface TradeBrokerageUserService {
61 60 * @param id 用户编号
62 61 * @return 用户的推广人
63 62 */
64   - TradeBrokerageUserDO getInviteBrokerageUser(Long id);
  63 + BrokerageUserDO getBindBrokerageUser(Long id);
65 64  
66 65 /**
67 66 * 更新用户佣金
68 67 *
69   - * @param id 用户编号
70   - * @param brokeragePrice 用户可用佣金
  68 + * @param id 用户编号
  69 + * @param price 用户可用佣金
71 70 */
72   - void updateUserBrokeragePrice(Long id, int brokeragePrice);
  71 + void updateUserPrice(Long id, Integer price);
73 72  
74   - // TODO @疯狂:int 类型一般不用哈;尽量都用封装类型;不差这点内存哈;
75 73 /**
76 74 * 更新用户冻结佣金
77 75 *
78   - * @param id 用户编号
79   - * @param frozenBrokeragePrice 用户冻结佣金
  76 + * @param id 用户编号
  77 + * @param frozenPrice 用户冻结佣金
80 78 */
81   - void updateUserFrozenBrokeragePrice(Long id, int frozenBrokeragePrice);
  79 + void updateUserFrozenPrice(Long id, Integer frozenPrice);
82 80  
83 81 /**
84 82 * 更新用户冻结佣金(减少), 更新用户佣金(增加)
85 83 *
86   - * @param id 用户编号
87   - * @param frozenBrokeragePrice 减少冻结佣金(负数)
  84 + * @param id 用户编号
  85 + * @param frozenPrice 减少冻结佣金(负数)
88 86 */
89   - void updateFrozenBrokeragePriceDecrAndBrokeragePriceIncr(Long id, int frozenBrokeragePrice);
  87 + void updateFrozenPriceDecrAndPriceIncr(Long id, Integer frozenPrice);
90 88  
  89 + /**
  90 + * 获得推广用户数量(一级)
  91 + *
  92 + * @param bindUserId 绑定的推广员编号
  93 + * @return 推广用户数量
  94 + */
  95 + Long getCountByBindUserId(Long bindUserId);
  96 +
  97 + /**
  98 + * 【会员】绑定推广员
  99 + *
  100 + * @param userId 用户编号
  101 + * @param bindUserId 推广员编号
  102 + * @param isNewUser 是否为新用户
  103 + * @return 是否绑定
  104 + */
  105 + boolean bindUser(Long userId, Long bindUserId, Boolean isNewUser);
91 106 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.service.brokerage.user;
  2 +
  3 +import cn.hutool.core.lang.Assert;
  4 +import cn.hutool.core.util.BooleanUtil;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO;
  7 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
  8 +import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
  9 +import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.user.BrokerageUserMapper;
  10 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageBindModeEnum;
  11 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageEnabledConditionEnum;
  12 +import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
  13 +import org.springframework.stereotype.Service;
  14 +import org.springframework.validation.annotation.Validated;
  15 +
  16 +import javax.annotation.Resource;
  17 +import java.time.LocalDateTime;
  18 +import java.util.Collection;
  19 +import java.util.List;
  20 +import java.util.Objects;
  21 +import java.util.Optional;
  22 +
  23 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  24 +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
  25 +
  26 +/**
  27 + * 分销用户 Service 实现类
  28 + *
  29 + * @author owen
  30 + */
  31 +@Service
  32 +@Validated
  33 +public class BrokerageUserServiceImpl implements BrokerageUserService {
  34 +
  35 + @Resource
  36 + private BrokerageUserMapper brokerageUserMapper;
  37 +
  38 + @Resource
  39 + private TradeConfigService tradeConfigService;
  40 +
  41 + @Override
  42 + public BrokerageUserDO getBrokerageUser(Long id) {
  43 + return brokerageUserMapper.selectById(id);
  44 + }
  45 +
  46 + @Override
  47 + public List<BrokerageUserDO> getBrokerageUserList(Collection<Long> ids) {
  48 + return brokerageUserMapper.selectBatchIds(ids);
  49 + }
  50 +
  51 + @Override
  52 + public PageResult<BrokerageUserDO> getBrokerageUserPage(BrokerageUserPageReqVO pageReqVO) {
  53 + return brokerageUserMapper.selectPage(pageReqVO);
  54 + }
  55 +
  56 + @Override
  57 + public void updateBrokerageUserId(Long id, Long bindUserId) {
  58 + // 校验存在
  59 + validateBrokerageUserExists(id);
  60 + if (bindUserId == null) {
  61 + // 清除推广员
  62 + brokerageUserMapper.updateBindUserIdAndBindUserTimeToNull(id);
  63 + } else {
  64 + // 修改推广员
  65 + brokerageUserMapper.updateById(new BrokerageUserDO().setId(id)
  66 + .setBindUserId(bindUserId).setBindUserTime(LocalDateTime.now()));
  67 + }
  68 + }
  69 +
  70 + @Override
  71 + public void updateBrokerageEnabled(Long id, Boolean enabled) {
  72 + // 校验存在
  73 + validateBrokerageUserExists(id);
  74 + if (BooleanUtil.isTrue(enabled)) {
  75 + // 开通推广资格
  76 + brokerageUserMapper.updateById(new BrokerageUserDO().setId(id)
  77 + .setBrokerageEnabled(true).setBrokerageTime(LocalDateTime.now()));
  78 + } else {
  79 + // 取消推广资格
  80 + brokerageUserMapper.updateEnabledFalseAndBrokerageTimeToNull(id);
  81 + }
  82 + }
  83 +
  84 + private void validateBrokerageUserExists(Long id) {
  85 + if (brokerageUserMapper.selectById(id) == null) {
  86 + throw exception(BROKERAGE_USER_NOT_EXISTS);
  87 + }
  88 + }
  89 +
  90 + @Override
  91 + public BrokerageUserDO getBindBrokerageUser(Long id) {
  92 + return Optional.ofNullable(id)
  93 + .map(this::getBrokerageUser)
  94 + .map(BrokerageUserDO::getBindUserId)
  95 + .map(this::getBrokerageUser)
  96 + .orElse(null);
  97 + }
  98 +
  99 + @Override
  100 + public void updateUserPrice(Long id, Integer price) {
  101 + if (price > 0) {
  102 + brokerageUserMapper.updatePriceIncr(id, price);
  103 + } else if (price < 0) {
  104 + brokerageUserMapper.updatePriceDecr(id, price);
  105 + }
  106 + }
  107 +
  108 + @Override
  109 + public void updateUserFrozenPrice(Long id, Integer frozenPrice) {
  110 + if (frozenPrice > 0) {
  111 + brokerageUserMapper.updateFrozenPriceIncr(id, frozenPrice);
  112 + } else if (frozenPrice < 0) {
  113 + brokerageUserMapper.updateFrozenPriceDecr(id, frozenPrice);
  114 + }
  115 + }
  116 +
  117 + @Override
  118 + public void updateFrozenPriceDecrAndPriceIncr(Long id, Integer frozenPrice) {
  119 + Assert.isTrue(frozenPrice < 0);
  120 + int updateRows = brokerageUserMapper.updateFrozenPriceDecrAndPriceIncr(id, frozenPrice);
  121 + if (updateRows == 0) {
  122 + throw exception(BROKERAGE_USER_FROZEN_PRICE_NOT_ENOUGH);
  123 + }
  124 + }
  125 +
  126 + @Override
  127 + public Long getCountByBindUserId(Long bindUserId) {
  128 + return brokerageUserMapper.selectCount(BrokerageUserDO::getBindUserId, bindUserId);
  129 + }
  130 +
  131 + @Override
  132 + public boolean bindUser(Long userId, Long bindUserId, Boolean isNewUser) {
  133 + if (userId == null) {
  134 + throw exception(0);
  135 + }
  136 +
  137 + boolean isInsert = false;
  138 + BrokerageUserDO brokerageUser = brokerageUserMapper.selectById(userId);
  139 + // 分销用户不存在的情况:1.新注册 2.旧数据 3.分销功能关闭后又打开
  140 + if (brokerageUser == null) {
  141 + isInsert = true;
  142 + brokerageUser = new BrokerageUserDO().setId(userId).setBrokerageEnabled(false).setPrice(0).setFrozenPrice(0);
  143 + }
  144 +
  145 + // 校验能否绑定
  146 + boolean validated = validateCanBindUser(brokerageUser, bindUserId, isNewUser);
  147 + if (!validated) {
  148 + return false;
  149 + }
  150 +
  151 + if (isInsert) {
  152 + Integer enabledCondition = tradeConfigService.getTradeConfig().getBrokerageEnabledCondition();
  153 + if (BrokerageEnabledConditionEnum.ALL.getCondition().equals(enabledCondition)) {
  154 + // 人人分销:用户默认就有分销资格
  155 + brokerageUser.setBrokerageEnabled(true).setBindUserTime(LocalDateTime.now());
  156 + }
  157 + brokerageUserMapper.insert(brokerageUser);
  158 + } else {
  159 + brokerageUserMapper.updateById(new BrokerageUserDO().setId(userId)
  160 + .setBindUserId(bindUserId).setBindUserTime(LocalDateTime.now()));
  161 + }
  162 + return true;
  163 + }
  164 +
  165 + private boolean validateCanBindUser(BrokerageUserDO user, Long bindUserId, Boolean isNewUser) {
  166 + if (bindUserId == null) {
  167 + return false;
  168 + }
  169 +
  170 + // 校验分销功能是否启用
  171 + TradeConfigDO tradeConfig = tradeConfigService.getTradeConfig();
  172 + if (tradeConfig == null || !BooleanUtil.isTrue(tradeConfig.getBrokerageEnabled())) {
  173 + return false;
  174 + }
  175 +
  176 + // 校验绑定自己
  177 + if (Objects.equals(user.getId(), bindUserId)) {
  178 + throw exception(BROKERAGE_BIND_SELF);
  179 + }
  180 +
  181 + // 校验要绑定的用户有无推广资格
  182 + BrokerageUserDO bindUser = brokerageUserMapper.selectById(bindUserId);
  183 + if (bindUser == null || !BooleanUtil.isTrue(bindUser.getBrokerageEnabled())) {
  184 + throw exception(BROKERAGE_BIND_USER_NOT_ENABLED);
  185 + }
  186 +
  187 + // 校验分佣模式:仅可后台手动设置推广员
  188 + if (BrokerageEnabledConditionEnum.ADMIN.getCondition().equals(tradeConfig.getBrokerageEnabledCondition())) {
  189 + throw exception(BROKERAGE_BIND_CONDITION_ADMIN);
  190 + }
  191 +
  192 + // 校验分销关系绑定模式
  193 + if (BrokerageBindModeEnum.REGISTER.getMode().equals(tradeConfig.getBrokerageBindMode())) {
  194 + if (!BooleanUtil.isTrue(isNewUser)) {
  195 + throw exception(BROKERAGE_BIND_MODE_REGISTER); // 只有在注册时可以绑定
  196 + }
  197 + } else if (BrokerageBindModeEnum.ANYTIME.getMode().equals(tradeConfig.getBrokerageBindMode())) {
  198 + if (user.getBindUserId() != null) {
  199 + throw exception(BROKERAGE_BIND_OVERRIDE); // 已绑定了推广人
  200 + }
  201 + }
  202 +
  203 + // A->B->A:下级不能绑定自己的上级, A->B->C->A可以!!
  204 + if (Objects.equals(user.getId(), bindUser.getBindUserId())) {
  205 + throw exception(BROKERAGE_BIND_LOOP);
  206 + }
  207 + return true;
  208 + }
  209 +
  210 +}
... ...
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/TradeBrokerageUserServiceImpl.java deleted
1   -package cn.iocoder.yudao.module.trade.service.brokerage.user;
2   -
3   -import cn.hutool.core.lang.Assert;
4   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
5   -import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.TradeBrokerageUserPageReqVO;
6   -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.TradeBrokerageUserDO;
7   -import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.user.TradeBrokerageUserMapper;
8   -import org.springframework.stereotype.Service;
9   -import org.springframework.transaction.annotation.Transactional;
10   -import org.springframework.validation.annotation.Validated;
11   -
12   -import javax.annotation.Resource;
13   -import java.util.Collection;
14   -import java.util.List;
15   -import java.util.Optional;
16   -
17   -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
18   -import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.MEMBER_FROZEN_BROKERAGE_PRICE_NOT_ENOUGH;
19   -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.BROKERAGE_USER_NOT_EXISTS;
20   -
21   -/**
22   - * 分销用户 Service 实现类
23   - *
24   - * @author owen
25   - */
26   -@Service
27   -@Validated
28   -public class TradeBrokerageUserServiceImpl implements TradeBrokerageUserService {
29   -
30   - @Resource
31   - private TradeBrokerageUserMapper brokerageUserMapper;
32   -
33   - @Override
34   - public TradeBrokerageUserDO getBrokerageUser(Long id) {
35   - return brokerageUserMapper.selectById(id);
36   - }
37   -
38   - @Override
39   - public List<TradeBrokerageUserDO> getBrokerageUserList(Collection<Long> ids) {
40   - return brokerageUserMapper.selectBatchIds(ids);
41   - }
42   -
43   - @Override
44   - public PageResult<TradeBrokerageUserDO> getBrokerageUserPage(TradeBrokerageUserPageReqVO pageReqVO) {
45   - return brokerageUserMapper.selectPage(pageReqVO);
46   - }
47   -
48   - @Override
49   - public void updateBrokerageUserId(Long id, Long brokerageUserId) {
50   - // 校验存在
51   - validateBrokerageUserExists(id);
52   - // TODO @疯狂:貌似没实现完
53   - }
54   -
55   - @Override
56   - public void updateBrokerageEnabled(Long id, Boolean brokerageEnabled) {
57   - // 校验存在
58   - validateBrokerageUserExists(id);
59   - // TODO @疯狂:貌似没实现完
60   - }
61   -
62   - private void validateBrokerageUserExists(Long id) {
63   - if (brokerageUserMapper.selectById(id) == null) {
64   - throw exception(BROKERAGE_USER_NOT_EXISTS);
65   - }
66   - }
67   -
68   - // TODO @疯狂:getBindBrokerageUser 会不会好点,因为统一使用 Bind 替代了 Invite
69   - @Override
70   - public TradeBrokerageUserDO getInviteBrokerageUser(Long id) {
71   - return Optional.ofNullable(id)
72   - .map(this::getBrokerageUser)
73   - .map(TradeBrokerageUserDO::getBrokerageUserId)
74   - .map(this::getBrokerageUser)
75   - .orElse(null);
76   - }
77   -
78   - // TODO @疯狂:单个更新,不用事务哈;
79   - @Override
80   - @Transactional(rollbackFor = Exception.class)
81   - public void updateUserBrokeragePrice(Long id, int brokeragePrice) {
82   - if (brokeragePrice > 0) {
83   - brokerageUserMapper.updateBrokeragePriceIncr(id, brokeragePrice);
84   - } else if (brokeragePrice < 0) {
85   - brokerageUserMapper.updateBrokeragePriceDecr(id, brokeragePrice);
86   - }
87   - }
88   -
89   - // TODO @疯狂:单个更新,不用事务哈;
90   - @Override
91   - @Transactional(rollbackFor = Exception.class)
92   - public void updateUserFrozenBrokeragePrice(Long id, int frozenBrokeragePrice) {
93   - if (frozenBrokeragePrice > 0) {
94   - brokerageUserMapper.updateFrozenBrokeragePriceIncr(id, frozenBrokeragePrice);
95   - } else if (frozenBrokeragePrice < 0) {
96   - brokerageUserMapper.updateFrozenBrokeragePriceDecr(id, frozenBrokeragePrice);
97   - }
98   - }
99   -
100   - // TODO @疯狂:单个更新,不用事务哈;
101   - @Override
102   - @Transactional(rollbackFor = Exception.class)
103   - public void updateFrozenBrokeragePriceDecrAndBrokeragePriceIncr(Long id, int frozenBrokeragePrice) {
104   - Assert.isTrue(frozenBrokeragePrice < 0);
105   - int updateRows = brokerageUserMapper.updateFrozenBrokeragePriceDecrAndBrokeragePriceIncr(id, frozenBrokeragePrice);
106   - if (updateRows == 0) {
107   - // TODO @疯狂:挪到 trade 这变的错误码哈;
108   - throw exception(MEMBER_FROZEN_BROKERAGE_PRICE_NOT_ENOUGH);
109   - }
110   - }
111   -
112   -}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
... ... @@ -11,8 +11,6 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
11 11 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
12 12 import cn.iocoder.yudao.module.member.api.address.AddressApi;
13 13 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
14   -import cn.iocoder.yudao.module.trade.service.brokerage.record.TradeBrokerageRecordService;
15   -import cn.iocoder.yudao.module.trade.service.brokerage.record.bo.BrokerageAddReqBO;
16 14 import cn.iocoder.yudao.module.member.api.level.MemberLevelApi;
17 15 import cn.iocoder.yudao.module.member.api.point.MemberPointApi;
18 16 import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
... ... @@ -51,9 +49,12 @@ import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper;
51 49 import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper;
52 50 import cn.iocoder.yudao.module.trade.dal.redis.no.TradeOrderNoRedisDAO;
53 51 import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants;
  52 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
54 53 import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
55 54 import cn.iocoder.yudao.module.trade.enums.order.*;
56 55 import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
  56 +import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService;
  57 +import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO;
57 58 import cn.iocoder.yudao.module.trade.service.cart.CartService;
58 59 import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
59 60 import cn.iocoder.yudao.module.trade.service.message.TradeMessageService;
... ... @@ -128,7 +129,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
128 129 @Resource
129 130 private MemberPointApi memberPointApi;
130 131 @Resource
131   - private TradeBrokerageRecordService tradeBrokerageRecordService;
  132 + private BrokerageRecordService brokerageRecordService;
132 133 @Resource
133 134 private ProductCommentApi productCommentApi;
134 135  
... ... @@ -394,7 +395,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
394 395 // 增加用户经验
395 396 getSelf().addUserExperienceAsync(order.getUserId(), order.getPayPrice(), order.getId());
396 397 // 增加用户佣金
397   - getSelf().addBrokerageAsync(order.getUserId(), order.getId());
  398 + getSelf().addBrokerageAsync(order.getUserId(), BrokerageRecordBizTypeEnum.ORDER, order.getId());
398 399 }
399 400  
400 401 /**
... ... @@ -674,7 +675,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
674 675 // 扣减用户经验
675 676 getSelf().reduceUserExperienceAsync(order.getUserId(), orderRefundPrice, afterSaleId);
676 677 // 更新分佣记录为已失效
677   - getSelf().cancelBrokerageAsync(order.getUserId(), id);
  678 + getSelf().cancelBrokerageAsync(order.getUserId(), BrokerageRecordBizTypeEnum.ORDER, id);
678 679 }
679 680  
680 681 @Override
... ... @@ -784,16 +785,16 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
784 785  
785 786  
786 787 @Async
787   - protected void addBrokerageAsync(Long userId, Long orderId) {
  788 + protected void addBrokerageAsync(Long userId, BrokerageRecordBizTypeEnum bizType, Long orderId) {
788 789 List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(orderId);
789 790 List<BrokerageAddReqBO> list = convertList(orderItems,
790 791 item -> TradeOrderConvert.INSTANCE.convert(item, productSkuApi.getSku(item.getSkuId())));
791   - tradeBrokerageRecordService.addBrokerage(userId, list);
  792 + brokerageRecordService.addBrokerage(userId, bizType, list);
792 793 }
793 794  
794 795 @Async
795   - protected void cancelBrokerageAsync(Long userId, Long orderItemId) {
796   - tradeBrokerageRecordService.cancelBrokerage(userId, String.valueOf(orderItemId));
  796 + protected void cancelBrokerageAsync(Long userId, BrokerageRecordBizTypeEnum bizType, Long orderItemId) {
  797 + brokerageRecordService.cancelBrokerage(userId, bizType, String.valueOf(orderItemId));
797 798 }
798 799  
799 800 /**
... ...
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/brokerage/record/TradeBrokerageRecordServiceImplTest.java renamed to yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/brokerage/record/BrokerageRecordServiceImplTest.java
... ... @@ -3,10 +3,10 @@ package cn.iocoder.yudao.module.trade.service.brokerage.record;
3 3 import cn.hutool.core.util.NumberUtil;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
6   -import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.TradeBrokerageRecordPageReqVO;
7   -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.TradeBrokerageRecordDO;
8   -import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.record.TradeBrokerageRecordMapper;
9   -import cn.iocoder.yudao.module.trade.service.brokerage.user.TradeBrokerageUserService;
  6 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordPageReqVO;
  7 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO;
  8 +import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.record.BrokerageRecordMapper;
  9 +import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService;
10 10 import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
11 11 import org.junit.jupiter.api.Disabled;
12 12 import org.junit.jupiter.api.Test;
... ... @@ -27,51 +27,51 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
27 27  
28 28 // TODO @芋艿:单测后续看看
29 29 /**
30   - * {@link TradeBrokerageRecordServiceImpl} 的单元测试类
  30 + * {@link BrokerageRecordServiceImpl} 的单元测试类
31 31 *
32 32 * @author owen
33 33 */
34   -@Import(TradeBrokerageRecordServiceImpl.class)
35   -public class TradeBrokerageRecordServiceImplTest extends BaseDbUnitTest {
  34 +@Import(BrokerageRecordServiceImpl.class)
  35 +public class BrokerageRecordServiceImplTest extends BaseDbUnitTest {
36 36  
37 37 @Resource
38   - private TradeBrokerageRecordServiceImpl tradeBrokerageRecordService;
  38 + private BrokerageRecordServiceImpl brokerageRecordService;
39 39 @Resource
40   - private TradeBrokerageRecordMapper tradeBrokerageRecordMapper;
  40 + private BrokerageRecordMapper brokerageRecordMapper;
41 41  
42 42 @MockBean
43 43 private TradeConfigService tradeConfigService;
44 44 @MockBean
45   - private TradeBrokerageUserService tradeBrokerageUserService;
  45 + private BrokerageUserService brokerageUserService;
46 46  
47 47 @Test
48 48 @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
49 49 public void testGetBrokerageRecordPage() {
50 50 // mock 数据
51   - TradeBrokerageRecordDO dbBrokerageRecord = randomPojo(TradeBrokerageRecordDO.class, o -> { // 等会查询到
  51 + BrokerageRecordDO dbBrokerageRecord = randomPojo(BrokerageRecordDO.class, o -> { // 等会查询到
52 52 o.setUserId(null);
53 53 o.setBizType(null);
54 54 o.setStatus(null);
55 55 o.setCreateTime(null);
56 56 });
57   - tradeBrokerageRecordMapper.insert(dbBrokerageRecord);
  57 + brokerageRecordMapper.insert(dbBrokerageRecord);
58 58 // 测试 userId 不匹配
59   - tradeBrokerageRecordMapper.insert(cloneIgnoreId(dbBrokerageRecord, o -> o.setUserId(null)));
  59 + brokerageRecordMapper.insert(cloneIgnoreId(dbBrokerageRecord, o -> o.setUserId(null)));
60 60 // 测试 bizType 不匹配
61   - tradeBrokerageRecordMapper.insert(cloneIgnoreId(dbBrokerageRecord, o -> o.setBizType(null)));
  61 + brokerageRecordMapper.insert(cloneIgnoreId(dbBrokerageRecord, o -> o.setBizType(null)));
62 62 // 测试 status 不匹配
63   - tradeBrokerageRecordMapper.insert(cloneIgnoreId(dbBrokerageRecord, o -> o.setStatus(null)));
  63 + brokerageRecordMapper.insert(cloneIgnoreId(dbBrokerageRecord, o -> o.setStatus(null)));
64 64 // 测试 createTime 不匹配
65   - tradeBrokerageRecordMapper.insert(cloneIgnoreId(dbBrokerageRecord, o -> o.setCreateTime(null)));
  65 + brokerageRecordMapper.insert(cloneIgnoreId(dbBrokerageRecord, o -> o.setCreateTime(null)));
66 66 // 准备参数
67   - TradeBrokerageRecordPageReqVO reqVO = new TradeBrokerageRecordPageReqVO();
  67 + BrokerageRecordPageReqVO reqVO = new BrokerageRecordPageReqVO();
68 68 reqVO.setUserId(null);
69 69 reqVO.setBizType(null);
70 70 reqVO.setStatus(null);
71 71 reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
72 72  
73 73 // 调用
74   - PageResult<TradeBrokerageRecordDO> pageResult = tradeBrokerageRecordService.getBrokerageRecordPage(reqVO);
  74 + PageResult<BrokerageRecordDO> pageResult = brokerageRecordService.getBrokerageRecordPage(reqVO);
75 75 // 断言
76 76 assertEquals(1, pageResult.getTotal());
77 77 assertEquals(1, pageResult.getList().size());
... ... @@ -79,38 +79,38 @@ public class TradeBrokerageRecordServiceImplTest extends BaseDbUnitTest {
79 79 }
80 80  
81 81 @Test
82   - public void testCalculateBrokerage_useSkuBrokeragePrice() {
  82 + public void testCalculatePrice_useFixedPrice() {
83 83 // mock 数据
84 84 Integer payPrice = randomInteger();
85 85 Integer percent = randomInt(1, 101);
86   - Integer skuBrokeragePrice = randomInt();
  86 + Integer fixedPrice = randomInt();
87 87 // 调用
88   - int brokerage = tradeBrokerageRecordService.calculateBrokerage(payPrice, percent, skuBrokeragePrice);
  88 + int brokerage = brokerageRecordService.calculatePrice(payPrice, percent, fixedPrice);
89 89 // 断言
90   - assertEquals(brokerage, skuBrokeragePrice);
  90 + assertEquals(brokerage, fixedPrice);
91 91 }
92 92  
93 93 @Test
94   - public void testCalculateBrokerage_usePercent() {
  94 + public void testCalculatePrice_usePercent() {
95 95 // mock 数据
96 96 Integer payPrice = randomInteger();
97 97 Integer percent = randomInt(1, 101);
98   - Integer skuBrokeragePrice = randomEle(new Integer[]{0, null});
99   - System.out.println("skuBrokeragePrice=" + skuBrokeragePrice);
  98 + Integer fixedPrice = randomEle(new Integer[]{0, null});
  99 + System.out.println("fixedPrice=" + fixedPrice);
100 100 // 调用
101   - int brokerage = tradeBrokerageRecordService.calculateBrokerage(payPrice, percent, skuBrokeragePrice);
  101 + int brokerage = brokerageRecordService.calculatePrice(payPrice, percent, fixedPrice);
102 102 // 断言
103 103 assertEquals(brokerage, NumberUtil.div(NumberUtil.mul(payPrice, percent), 100, 0, RoundingMode.DOWN).intValue());
104 104 }
105 105  
106 106 @Test
107   - public void testCalculateBrokerage_equalsZero() {
  107 + public void testCalculatePrice_equalsZero() {
108 108 // mock 数据
109 109 Integer payPrice = null;
110 110 Integer percent = null;
111   - Integer skuBrokeragePrice = null;
  111 + Integer fixedPrice = null;
112 112 // 调用
113   - int brokerage = tradeBrokerageRecordService.calculateBrokerage(payPrice, percent, skuBrokeragePrice);
  113 + int brokerage = brokerageRecordService.calculatePrice(payPrice, percent, fixedPrice);
114 114 // 断言
115 115 assertEquals(brokerage, 0);
116 116 }
... ...
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/brokerage/user/TradeBrokerageUserServiceImplTest.java renamed to yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImplTest.java
... ... @@ -2,9 +2,9 @@ package cn.iocoder.yudao.module.trade.service.brokerage.user;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
5   -import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.TradeBrokerageUserPageReqVO;
6   -import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.TradeBrokerageUserDO;
7   -import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.user.TradeBrokerageUserMapper;
  5 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO;
  6 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
  7 +import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.user.BrokerageUserMapper;
8 8 import org.junit.jupiter.api.Disabled;
9 9 import org.junit.jupiter.api.Test;
10 10 import org.springframework.context.annotation.Import;
... ... @@ -19,43 +19,43 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
19 19  
20 20 // TODO @芋艿:单测后续看看
21 21 /**
22   - * {@link TradeBrokerageUserServiceImpl} 的单元测试类
  22 + * {@link BrokerageUserServiceImpl} 的单元测试类
23 23 *
24 24 * @author owen
25 25 */
26   -@Import(TradeBrokerageUserServiceImpl.class)
27   -public class TradeBrokerageUserServiceImplTest extends BaseDbUnitTest {
  26 +@Import(BrokerageUserServiceImpl.class)
  27 +public class BrokerageUserServiceImplTest extends BaseDbUnitTest {
28 28  
29 29 @Resource
30   - private TradeBrokerageUserServiceImpl brokerageUserService;
  30 + private BrokerageUserServiceImpl brokerageUserService;
31 31  
32 32 @Resource
33   - private TradeBrokerageUserMapper brokerageUserMapper;
  33 + private BrokerageUserMapper brokerageUserMapper;
34 34  
35 35 @Test
36 36 @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
37 37 public void testGetBrokerageUserPage() {
38 38 // mock 数据
39   - TradeBrokerageUserDO dbBrokerageUser = randomPojo(TradeBrokerageUserDO.class, o -> { // 等会查询到
40   - o.setBrokerageUserId(null);
  39 + BrokerageUserDO dbBrokerageUser = randomPojo(BrokerageUserDO.class, o -> { // 等会查询到
  40 + o.setBindUserId(null);
41 41 o.setBrokerageEnabled(null);
42 42 o.setCreateTime(null);
43 43 });
44 44 brokerageUserMapper.insert(dbBrokerageUser);
45 45 // 测试 brokerageUserId 不匹配
46   - brokerageUserMapper.insert(cloneIgnoreId(dbBrokerageUser, o -> o.setBrokerageUserId(null)));
  46 + brokerageUserMapper.insert(cloneIgnoreId(dbBrokerageUser, o -> o.setBindUserId(null)));
47 47 // 测试 brokerageEnabled 不匹配
48 48 brokerageUserMapper.insert(cloneIgnoreId(dbBrokerageUser, o -> o.setBrokerageEnabled(null)));
49 49 // 测试 createTime 不匹配
50 50 brokerageUserMapper.insert(cloneIgnoreId(dbBrokerageUser, o -> o.setCreateTime(null)));
51 51 // 准备参数
52   - TradeBrokerageUserPageReqVO reqVO = new TradeBrokerageUserPageReqVO();
53   - reqVO.setBrokerageUserId(null);
  52 + BrokerageUserPageReqVO reqVO = new BrokerageUserPageReqVO();
  53 + reqVO.setBindUserId(null);
54 54 reqVO.setBrokerageEnabled(null);
55 55 reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
56 56  
57 57 // 调用
58   - PageResult<TradeBrokerageUserDO> pageResult = brokerageUserService.getBrokerageUserPage(reqVO);
  58 + PageResult<BrokerageUserDO> pageResult = brokerageUserService.getBrokerageUserPage(reqVO);
59 59 // 断言
60 60 assertEquals(1, pageResult.getTotal());
61 61 assertEquals(1, pageResult.getList().size());
... ...
yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql
... ... @@ -128,19 +128,19 @@ CREATE TABLE IF NOT EXISTS &quot;trade_after_sale_log&quot; (
128 128  
129 129 CREATE TABLE IF NOT EXISTS "trade_brokerage_user"
130 130 (
131   - "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
132   - "brokerage_user_id" bigint NOT NULL,
133   - "brokerage_bind_time" varchar,
134   - "brokerage_enabled" bit NOT NULL,
135   - "brokerage_time" varchar,
136   - "brokerage_price" int NOT NULL,
137   - "frozen_brokerage_price" int NOT NULL,
138   - "creator" varchar DEFAULT '',
139   - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
140   - "updater" varchar DEFAULT '',
141   - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
142   - "deleted" bit NOT NULL DEFAULT FALSE,
143   - "tenant_id" bigint NOT NULL DEFAULT '0',
  131 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  132 + "bind_user_id" bigint NOT NULL,
  133 + "bind_user_time" varchar,
  134 + "brokerage_enabled" bit NOT NULL,
  135 + "brokerage_time" varchar,
  136 + "price" int NOT NULL,
  137 + "frozen_price" int NOT NULL,
  138 + "creator" varchar DEFAULT '',
  139 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  140 + "updater" varchar DEFAULT '',
  141 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  142 + "deleted" bit NOT NULL DEFAULT FALSE,
  143 + "tenant_id" bigint NOT NULL DEFAULT '0',
144 144 PRIMARY KEY ("id")
145 145 ) COMMENT '分销用户';
146 146 CREATE TABLE IF NOT EXISTS "trade_brokerage_record"
... ...
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java
... ... @@ -13,7 +13,6 @@ public interface ErrorCodeConstants {
13 13 ErrorCode USER_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在");
14 14 ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1004001001, "手机号未注册用户");
15 15 ErrorCode USER_MOBILE_USED = new ErrorCode(1004001002, "修改手机失败,该手机号({})已经被使用");
16   - ErrorCode MEMBER_FROZEN_BROKERAGE_PRICE_NOT_ENOUGH = new ErrorCode(1004001003, "用户冻结佣金({})数量不足");
17 16  
18 17 // ========== AUTH 模块 1004003000 ==========
19 18 ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1004003000, "登录失败,账号密码不正确");
... ...
yudao-module-member/yudao-module-member-biz/pom.xml
... ... @@ -33,6 +33,11 @@
33 33 <artifactId>yudao-module-infra-api</artifactId>
34 34 <version>${revision}</version>
35 35 </dependency>
  36 + <dependency>
  37 + <groupId>cn.iocoder.boot</groupId>
  38 + <artifactId>yudao-module-trade-api</artifactId>
  39 + <version>${revision}</version>
  40 + </dependency>
36 41  
37 42 <!-- 业务组件 -->
38 43 <dependency>
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java
... ... @@ -8,6 +8,8 @@ import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO;
8 8 import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
9 9 import cn.iocoder.yudao.module.member.service.level.MemberLevelService;
10 10 import cn.iocoder.yudao.module.member.service.user.MemberUserService;
  11 +import cn.iocoder.yudao.module.trade.api.brokerage.BrokerageApi;
  12 +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserDTO;
11 13 import io.swagger.v3.oas.annotations.Operation;
12 14 import io.swagger.v3.oas.annotations.tags.Tag;
13 15 import lombok.extern.slf4j.Slf4j;
... ... @@ -16,6 +18,7 @@ import org.springframework.web.bind.annotation.*;
16 18  
17 19 import javax.annotation.Resource;
18 20 import javax.validation.Valid;
  21 +import java.util.Optional;
19 22  
20 23 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
21 24 import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
... ... @@ -33,14 +36,18 @@ public class AppMemberUserController {
33 36 @Resource
34 37 private MemberLevelService levelService;
35 38  
  39 + @Resource
  40 + private BrokerageApi brokerageApi;
  41 +
36 42 @GetMapping("/get")
37 43 @Operation(summary = "获得基本信息")
38 44 @PreAuthenticated
39 45 public CommonResult<AppMemberUserInfoRespVO> getUserInfo() {
40 46 MemberUserDO user = userService.getUser(getLoginUserId());
41 47 MemberLevelDO level = levelService.getLevel(user.getLevelId());
  48 + BrokerageUserDTO brokerageUser = brokerageApi.getBrokerageUser(user.getId());
42 49 return success(MemberUserConvert.INSTANCE.convert(user, level)
43   - .setBrokerageEnabled(true) // TODO @疯狂:这里我先写死,后面改成 db 返回;
  50 + .setBrokerageEnabled(Optional.ofNullable(brokerageUser).map(BrokerageUserDTO::getBrokerageEnabled).orElse(false))
44 51 );
45 52 }
46 53  
... ...
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/user/MemberUserDO.java
... ... @@ -136,38 +136,4 @@ public class MemberUserDO extends TenantBaseDO {
136 136 */
137 137 private Long groupId;
138 138  
139   - // TODO @疯狂:看看要不要删除掉哈
140   - // ========== 分销相关 ==========
141   -
142   - /**
143   - * 推广员编号
144   - */
145   - @TableField(exist = false) // TODO 芋艿:避免报错
146   - private Long brokerageUserId;
147   - /**
148   - * 推广员绑定时间
149   - */
150   - @TableField(exist = false) // TODO 芋艿:避免报错
151   - private LocalDateTime brokerageBindTime;
152   - /**
153   - * 是否成为推广员
154   - */
155   - @TableField(exist = false) // TODO 芋艿:避免报错
156   - private Boolean brokerageEnabled;
157   - /**
158   - * 成为分销员时间
159   - */
160   - @TableField(exist = false) // TODO 芋艿:避免报错
161   - private LocalDateTime brokerageTime;
162   - /**
163   - * 可用佣金
164   - */
165   - @TableField(exist = false) // TODO 芋艿:避免报错
166   - private Integer brokeragePrice;
167   - /**
168   - * 冻结佣金
169   - */
170   - @TableField(exist = false) // TODO 芋艿:避免报错
171   - private Integer frozenBrokeragePrice;
172   -
173 139 }
... ...
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
... ... @@ -6,6 +6,7 @@ import cn.hutool.core.util.StrUtil;
6 6 import cn.hutool.extra.spring.SpringUtil;
7 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 8 import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
  9 +import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
9 10 import cn.iocoder.yudao.framework.pay.core.client.PayClient;
10 11 import cn.iocoder.yudao.framework.pay.core.client.PayClientFactory;
11 12 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
... ... @@ -31,7 +32,6 @@ import cn.iocoder.yudao.module.pay.framework.pay.config.PayProperties;
31 32 import cn.iocoder.yudao.module.pay.service.app.PayAppService;
32 33 import cn.iocoder.yudao.module.pay.service.channel.PayChannelService;
33 34 import cn.iocoder.yudao.module.pay.service.notify.PayNotifyService;
34   -import cn.iocoder.yudao.module.pay.util.MoneyUtils;
35 35 import com.google.common.annotations.VisibleForTesting;
36 36 import lombok.extern.slf4j.Slf4j;
37 37 import org.springframework.stereotype.Service;
... ...