Commit a7de955926c9c6fb45adbad2bf8daa68967cd551

Authored by owen
1 parent 5ed99a91

trade: 分销业务 - 提现申请

Showing 20 changed files with 216 additions and 46 deletions
sql/mysql/brokerage.sql
1 -- 增加配置表 1 -- 增加配置表
2 create table trade_config 2 create table trade_config
3 ( 3 (
4 - id bigint auto_increment comment '自增主键' primary key,  
5 - brokerage_enabled bit default 1 not null comment '是否启用分佣',  
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 - brokerage_post_urls varchar(2000) default '' null comment '分销海报图地址数组',  
9 - brokerage_first_percent int default 0 not null comment '一级返佣比例',  
10 - brokerage_second_percent int default 0 not null comment '二级返佣比例',  
11 - brokerage_withdraw_min_price int default 0 not null comment '用户提现最低金额',  
12 - brokerage_bank_names varchar(200) default '' not null comment '提现银行(字典类型=brokerage_bank_name)',  
13 - brokerage_frozen_days int default 7 not null comment '佣金冻结时间(天)',  
14 - brokerage_withdraw_type varchar(32) default '1,2,3,4' not null comment '提现方式:1-钱包;2-银行卡;3-微信;4-支付宝',  
15 - creator varchar(64) default '' null comment '创建者',  
16 - create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',  
17 - updater varchar(64) default '' null comment '更新者',  
18 - update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',  
19 - deleted bit default b'0' not null comment '是否删除',  
20 - tenant_id bigint default 0 not null comment '租户编号' 4 + id bigint auto_increment comment '自增主键' primary key,
  5 + brokerage_enabled bit default 1 not null comment '是否启用分佣',
  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 + brokerage_post_urls varchar(2000) default '' null comment '分销海报图地址数组',
  9 + brokerage_first_percent int default 0 not null comment '一级返佣比例',
  10 + brokerage_second_percent int default 0 not null comment '二级返佣比例',
  11 + brokerage_withdraw_min_price int default 0 not null comment '用户提现最低金额',
  12 + brokerage_withdraw_fee_percent int default 0 not null comment '提现手续费百分比',
  13 + brokerage_bank_names varchar(200) default '' not null comment '提现银行(字典类型=brokerage_bank_name)',
  14 + brokerage_frozen_days int default 7 not null comment '佣金冻结时间(天)',
  15 + brokerage_withdraw_type varchar(32) default '1,2,3,4' not null comment '提现方式:1-钱包;2-银行卡;3-微信;4-支付宝',
  16 + creator varchar(64) default '' null comment '创建者',
  17 + create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
  18 + updater varchar(64) default '' null comment '更新者',
  19 + update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
  20 + deleted bit default b'0' not null comment '是否删除',
  21 + tenant_id bigint default 0 not null comment '租户编号'
21 ) comment '交易中心配置'; 22 ) comment '交易中心配置';
22 23
  24 +# alter table trade_config
  25 +# add brokerage_withdraw_fee_percent int default 0 not null comment '提现手续费百分比' after brokerage_withdraw_min_price;
  26 +
23 # alter table trade_brokerage_user 27 # alter table trade_brokerage_user
24 # add level int not null default 1 comment '等级' after frozen_price; 28 # add level int not null default 1 comment '等级' after frozen_price;
25 # alter table trade_brokerage_user 29 # alter table trade_brokerage_user
@@ -83,7 +87,7 @@ create index idx_status on trade_brokerage_record (status) comment '状态'; @@ -83,7 +87,7 @@ create index idx_status on trade_brokerage_record (status) comment '状态';
83 87
84 create table trade_brokerage_withdraw 88 create table trade_brokerage_withdraw
85 ( 89 (
86 - id int auto_increment comment '编号' 90 + id bigint auto_increment comment '编号'
87 primary key, 91 primary key,
88 user_id bigint not null comment '用户编号', 92 user_id bigint not null comment '用户编号',
89 price int default 0 not null comment '提现金额', 93 price int default 0 not null comment '提现金额',
@@ -137,7 +141,8 @@ insert into system_dict_type(type, name) @@ -137,7 +141,8 @@ insert into system_dict_type(type, name)
137 values ('brokerage_record_biz_type', '佣金记录业务类型'); 141 values ('brokerage_record_biz_type', '佣金记录业务类型');
138 insert into system_dict_data(dict_type, label, value, sort) 142 insert into system_dict_data(dict_type, label, value, sort)
139 values ('brokerage_record_biz_type', '订单返佣', 1, 1), 143 values ('brokerage_record_biz_type', '订单返佣', 1, 1),
140 - ('brokerage_record_biz_type', '申请提现', 2, 2); 144 + ('brokerage_record_biz_type', '申请提现', 2, 2),
  145 + ('brokerage_record_biz_type', '申请提现驳回', 3, 3);
141 146
142 insert into system_dict_type(type, name) 147 insert into system_dict_type(type, name)
143 values ('brokerage_record_status', '佣金记录状态'); 148 values ('brokerage_record_status', '佣金记录状态');
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
@@ -93,5 +93,7 @@ public interface ErrorCodeConstants { @@ -93,5 +93,7 @@ public interface ErrorCodeConstants {
93 // ========== 分销提现 模块 1011008000 ========== 93 // ========== 分销提现 模块 1011008000 ==========
94 ErrorCode BROKERAGE_WITHDRAW_NOT_EXISTS = new ErrorCode(1011008000, "佣金提现记录不存在"); 94 ErrorCode BROKERAGE_WITHDRAW_NOT_EXISTS = new ErrorCode(1011008000, "佣金提现记录不存在");
95 ErrorCode BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING = new ErrorCode(1011008001, "佣金提现记录状态不是审核中"); 95 ErrorCode BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING = new ErrorCode(1011008001, "佣金提现记录状态不是审核中");
  96 + ErrorCode BROKERAGE_WITHDRAW_MIN_PRICE = new ErrorCode(1011008002, "提现金额不能低于{}元");
  97 + ErrorCode BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH = new ErrorCode(1011008003, "您当前最多可提现{}元");
96 98
97 } 99 }
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageRecordBizTypeEnum.java
@@ -17,6 +17,7 @@ public enum BrokerageRecordBizTypeEnum implements IntArrayValuable { @@ -17,6 +17,7 @@ public enum BrokerageRecordBizTypeEnum implements IntArrayValuable {
17 17
18 ORDER(1, "获得推广佣金", "获得推广佣金 {}", true), 18 ORDER(1, "获得推广佣金", "获得推广佣金 {}", true),
19 WITHDRAW(2, "提现申请", "提现申请扣除佣金 {}", false), 19 WITHDRAW(2, "提现申请", "提现申请扣除佣金 {}", false),
  20 + WITHDRAW_REJECT(3, "提现申请驳回", "提现申请驳回返还佣金 {}", true),
20 ; 21 ;
21 22
22 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageRecordBizTypeEnum::getType).toArray(); 23 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/controller/app/brokerage/AppBrokerageUserController.java
@@ -38,7 +38,7 @@ public class AppBrokerageUserController { @@ -38,7 +38,7 @@ public class AppBrokerageUserController {
38 public CommonResult<AppBrokerageUserRespVO> getBrokerageUser() { 38 public CommonResult<AppBrokerageUserRespVO> getBrokerageUser() {
39 AppBrokerageUserRespVO respVO = new AppBrokerageUserRespVO() 39 AppBrokerageUserRespVO respVO = new AppBrokerageUserRespVO()
40 .setBrokerageEnabled(true) 40 .setBrokerageEnabled(true)
41 - .setPrice(2000) 41 + .setBrokeragePrice(2000)
42 .setFrozenPrice(3000); 42 .setFrozenPrice(3000);
43 return success(respVO); 43 return success(respVO);
44 } 44 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageWithdrawController.java
@@ -5,16 +5,19 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -5,16 +5,19 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; 5 import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
6 import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO; 6 import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO;
7 import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawRespVO; 7 import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawRespVO;
  8 +import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageWithdrawService;
8 import io.swagger.v3.oas.annotations.Operation; 9 import io.swagger.v3.oas.annotations.Operation;
9 import io.swagger.v3.oas.annotations.tags.Tag; 10 import io.swagger.v3.oas.annotations.tags.Tag;
10 import lombok.extern.slf4j.Slf4j; 11 import lombok.extern.slf4j.Slf4j;
11 import org.springframework.validation.annotation.Validated; 12 import org.springframework.validation.annotation.Validated;
12 import org.springframework.web.bind.annotation.*; 13 import org.springframework.web.bind.annotation.*;
13 14
  15 +import javax.annotation.Resource;
14 import javax.validation.Valid; 16 import javax.validation.Valid;
15 import java.time.LocalDateTime; 17 import java.time.LocalDateTime;
16 18
17 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 19 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  20 +import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
18 import static java.util.Arrays.asList; 21 import static java.util.Arrays.asList;
19 22
20 @Tag(name = "用户 APP - 分销提现") 23 @Tag(name = "用户 APP - 分销提现")
@@ -23,6 +26,8 @@ import static java.util.Arrays.asList; @@ -23,6 +26,8 @@ import static java.util.Arrays.asList;
23 @Validated 26 @Validated
24 @Slf4j 27 @Slf4j
25 public class AppBrokerageWithdrawController { 28 public class AppBrokerageWithdrawController {
  29 + @Resource
  30 + private BrokerageWithdrawService brokerageWithdrawService;
26 31
27 // TODO 芋艿:临时 mock => 32 // TODO 芋艿:临时 mock =>
28 @GetMapping("/page") 33 @GetMapping("/page")
@@ -36,12 +41,11 @@ public class AppBrokerageWithdrawController { @@ -36,12 +41,11 @@ public class AppBrokerageWithdrawController {
36 return success(new PageResult<>(asList(vo1, vo2), 10L)); 41 return success(new PageResult<>(asList(vo1, vo2), 10L));
37 } 42 }
38 43
39 - // TODO 芋艿:临时 mock =>  
40 @PostMapping("/create") 44 @PostMapping("/create")
41 @Operation(summary = "创建分销提现") 45 @Operation(summary = "创建分销提现")
42 @PreAuthenticated 46 @PreAuthenticated
43 public CommonResult<Long> createBrokerageWithdraw(@RequestBody @Valid AppBrokerageWithdrawCreateReqVO createReqVO) { 47 public CommonResult<Long> createBrokerageWithdraw(@RequestBody @Valid AppBrokerageWithdrawCreateReqVO createReqVO) {
44 - return success(1L); 48 + return success(brokerageWithdrawService.createBrokerageWithdraw(createReqVO, getLoginUserId()));
45 } 49 }
46 50
47 } 51 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRespVO.java
@@ -11,7 +11,7 @@ public class AppBrokerageUserRespVO { @@ -11,7 +11,7 @@ public class AppBrokerageUserRespVO {
11 private Boolean brokerageEnabled; 11 private Boolean brokerageEnabled;
12 12
13 @Schema(description = "可用的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2408") 13 @Schema(description = "可用的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2408")
14 - private Integer price; 14 + private Integer brokeragePrice;
15 15
16 @Schema(description = "冻结的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "234") 16 @Schema(description = "冻结的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "234")
17 private Integer frozenPrice; 17 private Integer frozenPrice;
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java
@@ -8,8 +8,9 @@ import lombok.Data; @@ -8,8 +8,9 @@ import lombok.Data;
8 import org.hibernate.validator.constraints.URL; 8 import org.hibernate.validator.constraints.URL;
9 9
10 import javax.validation.Validator; 10 import javax.validation.Validator;
11 -import javax.validation.constraints.Min;  
12 import javax.validation.constraints.NotBlank; 11 import javax.validation.constraints.NotBlank;
  12 +import javax.validation.constraints.NotNull;
  13 +import javax.validation.constraints.PositiveOrZero;
13 14
14 @Schema(description = "用户 App - 分销提现创建 Request VO") 15 @Schema(description = "用户 App - 分销提现创建 Request VO")
15 @Data 16 @Data
@@ -20,7 +21,8 @@ public class AppBrokerageWithdrawCreateReqVO { @@ -20,7 +21,8 @@ public class AppBrokerageWithdrawCreateReqVO {
20 private Integer type; 21 private Integer type;
21 22
22 @Schema(description = "提现金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") 23 @Schema(description = "提现金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
23 - @Min(value = 1, message = "提现金额不能小于 1") 24 + @PositiveOrZero(message = "提现金额不能小于 0")
  25 + @NotNull(message = "提现金额不能为空")
24 private Integer price; 26 private Integer price;
25 27
26 // ========== 银行卡、微信、支付宝 提现相关字段 ========== 28 // ========== 银行卡、微信、支付宝 提现相关字段 ==========
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageRecordConvert.java
1 package cn.iocoder.yudao.module.trade.convert.brokerage; 1 package cn.iocoder.yudao.module.trade.convert.brokerage;
2 2
  3 +import cn.hutool.core.math.Money;
3 import cn.hutool.core.util.ObjectUtil; 4 import cn.hutool.core.util.ObjectUtil;
4 import cn.hutool.core.util.StrUtil; 5 import cn.hutool.core.util.StrUtil;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
@@ -45,7 +46,7 @@ public interface BrokerageRecordConvert { @@ -45,7 +46,7 @@ public interface BrokerageRecordConvert {
45 .setBizType(bizType.getType()).setBizId(bizId) 46 .setBizType(bizType.getType()).setBizId(bizId)
46 .setPrice(brokeragePrice).setTotalPrice(user.getBrokeragePrice()) 47 .setPrice(brokeragePrice).setTotalPrice(user.getBrokeragePrice())
47 .setTitle(title) 48 .setTitle(title)
48 - .setDescription(StrUtil.format(bizType.getDescription(), String.format("¥%.2f", brokeragePrice / 100d))) 49 + .setDescription(StrUtil.format(bizType.getDescription(), new Money(0, Math.abs(brokeragePrice))))
49 .setStatus(status).setFrozenDays(brokerageFrozenDays).setUnfreezeTime(unfreezeTime) 50 .setStatus(status).setFrozenDays(brokerageFrozenDays).setUnfreezeTime(unfreezeTime)
50 .setSourceUserLevel(sourceUserLevel).setSourceUserId(sourceUserId); 51 .setSourceUserLevel(sourceUserLevel).setSourceUserId(sourceUserId);
51 } 52 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageWithdrawConvert.java
@@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.trade.convert.brokerage; @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.trade.convert.brokerage;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; 4 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
5 -import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawRejectReqVO;  
6 import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawRespVO; 5 import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawRespVO;
  6 +import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO;
7 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO; 7 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO;
8 import org.mapstruct.Mapper; 8 import org.mapstruct.Mapper;
9 import org.mapstruct.factory.Mappers; 9 import org.mapstruct.factory.Mappers;
@@ -22,7 +22,7 @@ public interface BrokerageWithdrawConvert { @@ -22,7 +22,7 @@ public interface BrokerageWithdrawConvert {
22 22
23 BrokerageWithdrawConvert INSTANCE = Mappers.getMapper(BrokerageWithdrawConvert.class); 23 BrokerageWithdrawConvert INSTANCE = Mappers.getMapper(BrokerageWithdrawConvert.class);
24 24
25 - BrokerageWithdrawDO convert(BrokerageWithdrawRejectReqVO bean); 25 + BrokerageWithdrawDO convert(AppBrokerageWithdrawCreateReqVO createReqVO, Long userId, Integer feePrice);
26 26
27 BrokerageWithdrawRespVO convert(BrokerageWithdrawDO bean); 27 BrokerageWithdrawRespVO convert(BrokerageWithdrawDO bean);
28 28
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/BrokerageWithdrawDO.java
@@ -29,7 +29,7 @@ public class BrokerageWithdrawDO extends BaseDO { @@ -29,7 +29,7 @@ public class BrokerageWithdrawDO extends BaseDO {
29 * 编号 29 * 编号
30 */ 30 */
31 @TableId 31 @TableId
32 - private Integer id; 32 + private Long id;
33 /** 33 /**
34 * 用户编号 34 * 用户编号
35 * 35 *
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/config/TradeConfigDO.java
@@ -82,6 +82,10 @@ public class TradeConfigDO extends BaseDO { @@ -82,6 +82,10 @@ public class TradeConfigDO extends BaseDO {
82 */ 82 */
83 private Integer brokerageWithdrawMinPrice; 83 private Integer brokerageWithdrawMinPrice;
84 /** 84 /**
  85 + * 用户提现手续费百分比
  86 + */
  87 + private Integer brokerageWithdrawFeePercent;
  88 + /**
85 * 提现银行 89 * 提现银行
86 */ 90 */
87 @TableField(typeHandler = IntegerListTypeHandler.class) 91 @TableField(typeHandler = IntegerListTypeHandler.class)
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageUserMapper.java
@@ -38,7 +38,7 @@ public interface BrokerageUserMapper extends BaseMapperX&lt;BrokerageUserDO&gt; { @@ -38,7 +38,7 @@ public interface BrokerageUserMapper extends BaseMapperX&lt;BrokerageUserDO&gt; {
38 default void updatePriceIncr(Long id, Integer incrCount) { 38 default void updatePriceIncr(Long id, Integer incrCount) {
39 Assert.isTrue(incrCount > 0); 39 Assert.isTrue(incrCount > 0);
40 LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>() 40 LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>()
41 - .setSql(" price = price + " + incrCount) 41 + .setSql(" brokerage_price = brokerage_price + " + incrCount)
42 .eq(BrokerageUserDO::getId, id); 42 .eq(BrokerageUserDO::getId, id);
43 update(null, lambdaUpdateWrapper); 43 update(null, lambdaUpdateWrapper);
44 } 44 }
@@ -49,13 +49,14 @@ public interface BrokerageUserMapper extends BaseMapperX&lt;BrokerageUserDO&gt; { @@ -49,13 +49,14 @@ public interface BrokerageUserMapper extends BaseMapperX&lt;BrokerageUserDO&gt; {
49 * 49 *
50 * @param id 用户编号 50 * @param id 用户编号
51 * @param incrCount 增加佣金(负数) 51 * @param incrCount 增加佣金(负数)
  52 + * @return 更新行数
52 */ 53 */
53 - default void updatePriceDecr(Long id, Integer incrCount) { 54 + default int updatePriceDecr(Long id, Integer incrCount) {
54 Assert.isTrue(incrCount < 0); 55 Assert.isTrue(incrCount < 0);
55 LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>() 56 LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>()
56 - .setSql(" price = price + " + incrCount) // 负数,所以使用 + 号 57 + .setSql(" brokerage_price = brokerage_price + " + incrCount) // 负数,所以使用 + 号
57 .eq(BrokerageUserDO::getId, id); 58 .eq(BrokerageUserDO::getId, id);
58 - update(null, lambdaUpdateWrapper); 59 + return update(null, lambdaUpdateWrapper);
59 } 60 }
60 61
61 /** 62 /**
@@ -98,7 +99,7 @@ public interface BrokerageUserMapper extends BaseMapperX&lt;BrokerageUserDO&gt; { @@ -98,7 +99,7 @@ public interface BrokerageUserMapper extends BaseMapperX&lt;BrokerageUserDO&gt; {
98 Assert.isTrue(incrCount < 0); 99 Assert.isTrue(incrCount < 0);
99 LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>() 100 LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>()
100 .setSql(" frozen_price = frozen_price + " + incrCount + // 负数,所以使用 + 号 101 .setSql(" frozen_price = frozen_price + " + incrCount + // 负数,所以使用 + 号
101 - ", price = price + " + -incrCount) // 负数,所以使用 - 号 102 + ", brokerage_price = brokerage_price + " + -incrCount) // 负数,所以使用 - 号
102 .eq(BrokerageUserDO::getId, id) 103 .eq(BrokerageUserDO::getId, id)
103 .ge(BrokerageUserDO::getFrozenPrice, -incrCount); // cas 逻辑 104 .ge(BrokerageUserDO::getFrozenPrice, -incrCount); // cas 逻辑
104 return update(null, lambdaUpdateWrapper); 105 return update(null, lambdaUpdateWrapper);
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordService.java
@@ -43,6 +43,17 @@ public interface BrokerageRecordService { @@ -43,6 +43,17 @@ public interface BrokerageRecordService {
43 void addBrokerage(Long userId, BrokerageRecordBizTypeEnum bizType, @Valid List<BrokerageAddReqBO> list); 43 void addBrokerage(Long userId, BrokerageRecordBizTypeEnum bizType, @Valid List<BrokerageAddReqBO> list);
44 44
45 /** 45 /**
  46 + * 增加佣金
  47 + *
  48 + * @param userId 会员编号
  49 + * @param bizType 业务类型
  50 + * @param bizId 业务编号
  51 + * @param brokeragePrice 佣金
  52 + * @param title 标题
  53 + */
  54 + void addBrokerage(Long userId, BrokerageRecordBizTypeEnum bizType, String bizId, int brokeragePrice, String title);
  55 +
  56 + /**
46 * 取消佣金:将佣金记录,状态修改为已失效 57 * 取消佣金:将佣金记录,状态修改为已失效
47 * 58 *
48 * @param userId 会员编号 59 * @param userId 会员编号
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageRecordServiceImpl.java
1 package cn.iocoder.yudao.module.trade.service.brokerage; 1 package cn.iocoder.yudao.module.trade.service.brokerage;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.math.Money;
4 import cn.hutool.core.util.BooleanUtil; 5 import cn.hutool.core.util.BooleanUtil;
5 import cn.hutool.core.util.ObjectUtil; 6 import cn.hutool.core.util.ObjectUtil;
6 import cn.hutool.core.util.StrUtil; 7 import cn.hutool.core.util.StrUtil;
@@ -28,6 +29,10 @@ import java.time.LocalDateTime; @@ -28,6 +29,10 @@ import java.time.LocalDateTime;
28 import java.util.ArrayList; 29 import java.util.ArrayList;
29 import java.util.List; 30 import java.util.List;
30 import java.util.Objects; 31 import java.util.Objects;
  32 +import java.util.Optional;
  33 +
  34 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  35 +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH;
31 36
32 /** 37 /**
33 * 佣金记录 Service 实现类 38 * 佣金记录 Service 实现类
@@ -217,6 +222,29 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { @@ -217,6 +222,29 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
217 return summaryBO != null ? summaryBO : new UserBrokerageSummaryBO(0, 0); 222 return summaryBO != null ? summaryBO : new UserBrokerageSummaryBO(0, 0);
218 } 223 }
219 224
  225 + @Override
  226 + @Transactional(rollbackFor = Exception.class)
  227 + public void addBrokerage(Long userId, BrokerageRecordBizTypeEnum bizType, String bizId, int brokeragePrice, String title) {
  228 + // 校验佣金余额
  229 + BrokerageUserDO user = brokerageUserService.getBrokerageUser(userId);
  230 + int balance = Optional.of(user)
  231 + .map(BrokerageUserDO::getBrokeragePrice).orElse(0);
  232 + if (balance < brokeragePrice) {
  233 + throw exception(BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH, new Money(0, balance));
  234 + }
  235 +
  236 + // 扣减佣金余额
  237 + boolean success = brokerageUserService.updateUserPrice(userId, brokeragePrice);
  238 + if (!success) {
  239 + throw exception(BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH, new Money(0, balance));
  240 + }
  241 +
  242 + // 新增记录
  243 + BrokerageRecordDO record = BrokerageRecordConvert.INSTANCE.convert(user, bizType, bizId, 0, brokeragePrice,
  244 + null, title, null, null);
  245 + brokerageRecordMapper.insert(record);
  246 + }
  247 +
220 @Transactional(rollbackFor = Exception.class) 248 @Transactional(rollbackFor = Exception.class)
221 public boolean unfreezeRecord(BrokerageRecordDO record) { 249 public boolean unfreezeRecord(BrokerageRecordDO record) {
222 // 更新记录状态 250 // 更新记录状态
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserService.java
@@ -70,8 +70,9 @@ public interface BrokerageUserService { @@ -70,8 +70,9 @@ public interface BrokerageUserService {
70 * 70 *
71 * @param id 用户编号 71 * @param id 用户编号
72 * @param price 用户可用佣金 72 * @param price 用户可用佣金
  73 + * @return 更新结果
73 */ 74 */
74 - void updateUserPrice(Long id, Integer price); 75 + boolean updateUserPrice(Long id, Integer price);
75 76
76 /** 77 /**
77 * 更新用户冻结佣金 78 * 更新用户冻结佣金
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java
@@ -110,12 +110,13 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { @@ -110,12 +110,13 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
110 } 110 }
111 111
112 @Override 112 @Override
113 - public void updateUserPrice(Long id, Integer price) { 113 + public boolean updateUserPrice(Long id, Integer price) {
114 if (price > 0) { 114 if (price > 0) {
115 brokerageUserMapper.updatePriceIncr(id, price); 115 brokerageUserMapper.updatePriceIncr(id, price);
116 } else if (price < 0) { 116 } else if (price < 0) {
117 - brokerageUserMapper.updatePriceDecr(id, price); 117 + return brokerageUserMapper.updatePriceDecr(id, price) > 0;
118 } 118 }
  119 + return true;
119 } 120 }
120 121
121 @Override 122 @Override
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawService.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.service.brokerage; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.service.brokerage;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO; 4 import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO;
  5 +import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO;
5 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO; 6 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO;
6 import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum; 7 import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
7 8
@@ -13,7 +14,7 @@ import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum @@ -13,7 +14,7 @@ import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum
13 public interface BrokerageWithdrawService { 14 public interface BrokerageWithdrawService {
14 15
15 /** 16 /**
16 - * 审核佣金提现 17 + * 【管理员】审核佣金提现
17 * 18 *
18 * @param id 佣金编号 19 * @param id 佣金编号
19 * @param status 审核状态 20 * @param status 审核状态
@@ -37,4 +38,13 @@ public interface BrokerageWithdrawService { @@ -37,4 +38,13 @@ public interface BrokerageWithdrawService {
37 * @return 佣金提现分页 38 * @return 佣金提现分页
38 */ 39 */
39 PageResult<BrokerageWithdrawDO> getBrokerageWithdrawPage(BrokerageWithdrawPageReqVO pageReqVO); 40 PageResult<BrokerageWithdrawDO> getBrokerageWithdrawPage(BrokerageWithdrawPageReqVO pageReqVO);
  41 +
  42 + /**
  43 + * 【会员】创建佣金提现
  44 + *
  45 + * @param createReqVO 创建信息
  46 + * @param userId 会员用户编号
  47 + * @return 佣金提现编号
  48 + */
  49 + Long createBrokerageWithdraw(AppBrokerageWithdrawCreateReqVO createReqVO, Long userId);
40 } 50 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImpl.java
@@ -2,26 +2,34 @@ package cn.iocoder.yudao.module.trade.service.brokerage; @@ -2,26 +2,34 @@ package cn.iocoder.yudao.module.trade.service.brokerage;
2 2
3 import cn.hutool.core.date.LocalDateTimeUtil; 3 import cn.hutool.core.date.LocalDateTimeUtil;
4 import cn.hutool.core.map.MapUtil; 4 import cn.hutool.core.map.MapUtil;
  5 +import cn.hutool.core.math.Money;
5 import cn.hutool.core.util.ObjectUtil; 6 import cn.hutool.core.util.ObjectUtil;
6 import cn.iocoder.yudao.framework.common.pojo.PageResult; 7 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  8 +import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
7 import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi; 9 import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
8 import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO; 10 import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
9 import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO; 11 import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO;
  12 +import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO;
  13 +import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageWithdrawConvert;
10 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO; 14 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO;
  15 +import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
11 import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageWithdrawMapper; 16 import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageWithdrawMapper;
12 import cn.iocoder.yudao.module.trade.enums.MessageTemplateConstants; 17 import cn.iocoder.yudao.module.trade.enums.MessageTemplateConstants;
  18 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
13 import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum; 19 import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
  20 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum;
  21 +import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
14 import org.springframework.stereotype.Service; 22 import org.springframework.stereotype.Service;
15 import org.springframework.transaction.annotation.Transactional; 23 import org.springframework.transaction.annotation.Transactional;
16 import org.springframework.validation.annotation.Validated; 24 import org.springframework.validation.annotation.Validated;
17 25
18 import javax.annotation.Resource; 26 import javax.annotation.Resource;
  27 +import javax.validation.Validator;
19 import java.time.LocalDateTime; 28 import java.time.LocalDateTime;
20 import java.util.Map; 29 import java.util.Map;
21 30
22 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 31 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
23 -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.BROKERAGE_WITHDRAW_NOT_EXISTS;  
24 -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING; 32 +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
25 33
26 /** 34 /**
27 * 佣金提现 Service 实现类 35 * 佣金提现 Service 实现类
@@ -37,10 +45,15 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @@ -37,10 +45,15 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
37 45
38 @Resource 46 @Resource
39 private BrokerageRecordService brokerageRecordService; 47 private BrokerageRecordService brokerageRecordService;
  48 + @Resource
  49 + private TradeConfigService tradeConfigService;
40 50
41 @Resource 51 @Resource
42 private NotifyMessageSendApi notifyMessageSendApi; 52 private NotifyMessageSendApi notifyMessageSendApi;
43 53
  54 + @Resource
  55 + private Validator validator;
  56 +
44 @Override 57 @Override
45 @Transactional(rollbackFor = Exception.class) 58 @Transactional(rollbackFor = Exception.class)
46 public void auditBrokerageWithdraw(Integer id, BrokerageWithdrawStatusEnum status, String auditReason) { 59 public void auditBrokerageWithdraw(Integer id, BrokerageWithdrawStatusEnum status, String auditReason) {
@@ -61,19 +74,26 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @@ -61,19 +74,26 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
61 throw exception(BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING); 74 throw exception(BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING);
62 } 75 }
63 76
64 - // 3. 驳回时需要退还用户佣金  
65 String templateCode = MessageTemplateConstants.BROKERAGE_WITHDRAW_AUDIT_APPROVE; 77 String templateCode = MessageTemplateConstants.BROKERAGE_WITHDRAW_AUDIT_APPROVE;
66 - if (BrokerageWithdrawStatusEnum.AUDIT_FAIL.equals(status)) { 78 + if (BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.equals(status)) {
  79 + // 3.1 通过时佣金转余额
  80 + if (BrokerageWithdrawTypeEnum.WALLET.getType().equals(withdraw.getType())) {
  81 + // todo
  82 + }
  83 + } else if (BrokerageWithdrawStatusEnum.AUDIT_FAIL.equals(status)) {
67 templateCode = MessageTemplateConstants.BROKERAGE_WITHDRAW_AUDIT_REJECT; 84 templateCode = MessageTemplateConstants.BROKERAGE_WITHDRAW_AUDIT_REJECT;
68 85
69 - // todo @owen  
70 -// brokerageRecordService.addBrokerage(withdraw.getUserId(), BrokerageRecordBizTypeEnum.WITHDRAW, withdraw.getPrice(), ""); 86 + // 3.2 驳回时需要退还用户佣金
  87 + brokerageRecordService.addBrokerage(withdraw.getUserId(), BrokerageRecordBizTypeEnum.WITHDRAW_REJECT,
  88 + String.valueOf(withdraw.getId()), withdraw.getPrice(), BrokerageRecordBizTypeEnum.WITHDRAW_REJECT.getTitle());
  89 + } else {
  90 + throw new IllegalArgumentException("不支持的提现状态");
71 } 91 }
72 92
73 // 4. 通知用户 93 // 4. 通知用户
74 Map<String, Object> templateParams = MapUtil.<String, Object>builder() 94 Map<String, Object> templateParams = MapUtil.<String, Object>builder()
75 .put("createTime", LocalDateTimeUtil.formatNormal(withdraw.getCreateTime())) 95 .put("createTime", LocalDateTimeUtil.formatNormal(withdraw.getCreateTime()))
76 - .put("price", String.format("%.2f", withdraw.getPrice() / 100d)) 96 + .put("price", new Money(0, withdraw.getPrice()).toString())
77 .put("reason", withdraw.getAuditReason()) 97 .put("reason", withdraw.getAuditReason())
78 .build(); 98 .build();
79 NotifySendSingleToUserReqDTO reqDTO = new NotifySendSingleToUserReqDTO() 99 NotifySendSingleToUserReqDTO reqDTO = new NotifySendSingleToUserReqDTO()
@@ -100,4 +120,53 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { @@ -100,4 +120,53 @@ public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
100 return brokerageWithdrawMapper.selectPage(pageReqVO); 120 return brokerageWithdrawMapper.selectPage(pageReqVO);
101 } 121 }
102 122
  123 + @Override
  124 + @Transactional(rollbackFor = Exception.class)
  125 + public Long createBrokerageWithdraw(AppBrokerageWithdrawCreateReqVO createReqVO, Long userId) {
  126 + // 校验提现金额
  127 + TradeConfigDO tradeConfig = validateWithdrawPrice(createReqVO.getPrice());
  128 + // 校验提现参数
  129 + createReqVO.validate(validator);
  130 +
  131 + // 计算手续费
  132 + Integer feePrice = calculateFeePrice(createReqVO.getPrice(), tradeConfig.getBrokerageWithdrawFeePercent());
  133 + // 创建佣金提现记录
  134 + BrokerageWithdrawDO withdraw = BrokerageWithdrawConvert.INSTANCE.convert(createReqVO, userId, feePrice);
  135 + brokerageWithdrawMapper.insert(withdraw);
  136 +
  137 + // 创建用户佣金记录
  138 + brokerageRecordService.addBrokerage(userId, BrokerageRecordBizTypeEnum.WITHDRAW, String.valueOf(withdraw.getId()),
  139 + -createReqVO.getPrice(), BrokerageRecordBizTypeEnum.WITHDRAW.getTitle());
  140 +
  141 + return withdraw.getId();
  142 + }
  143 +
  144 + /**
  145 + * 计算提现手续费
  146 + *
  147 + * @param withdrawPrice 提现金额
  148 + * @param percent 手续费百分比
  149 + * @return 提现手续费
  150 + */
  151 + Integer calculateFeePrice(Integer withdrawPrice, Integer percent) {
  152 + Integer feePrice = 0;
  153 + if (percent != null && percent > 0) {
  154 + feePrice = MoneyUtils.calculateRatePrice(withdrawPrice, Double.valueOf(percent));
  155 + }
  156 + return feePrice;
  157 + }
  158 +
  159 + /**
  160 + * 校验提现金额要求
  161 + *
  162 + * @param withdrawPrice 提现金额
  163 + * @return 分销配置
  164 + */
  165 + TradeConfigDO validateWithdrawPrice(Integer withdrawPrice) {
  166 + TradeConfigDO tradeConfig = tradeConfigService.getTradeConfig();
  167 + if (tradeConfig.getBrokerageWithdrawMinPrice() != null && withdrawPrice < tradeConfig.getBrokerageWithdrawMinPrice()) {
  168 + throw exception(BROKERAGE_WITHDRAW_MIN_PRICE, new Money(0, tradeConfig.getBrokerageWithdrawMinPrice()));
  169 + }
  170 + return tradeConfig;
  171 + }
103 } 172 }
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageWithdrawServiceImplTest.java
@@ -2,14 +2,18 @@ package cn.iocoder.yudao.module.trade.service.brokerage; @@ -2,14 +2,18 @@ package cn.iocoder.yudao.module.trade.service.brokerage;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; 4 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  5 +import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
5 import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO; 6 import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO;
6 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO; 7 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO;
7 import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageWithdrawMapper; 8 import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageWithdrawMapper;
  9 +import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
8 import org.junit.jupiter.api.Disabled; 10 import org.junit.jupiter.api.Disabled;
9 import org.junit.jupiter.api.Test; 11 import org.junit.jupiter.api.Test;
  12 +import org.springframework.boot.test.mock.mockito.MockBean;
10 import org.springframework.context.annotation.Import; 13 import org.springframework.context.annotation.Import;
11 14
12 import javax.annotation.Resource; 15 import javax.annotation.Resource;
  16 +import javax.validation.Validator;
13 17
14 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; 18 import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
15 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; 19 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
@@ -32,6 +36,19 @@ public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest { @@ -32,6 +36,19 @@ public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest {
32 @Resource 36 @Resource
33 private BrokerageWithdrawMapper brokerageWithdrawMapper; 37 private BrokerageWithdrawMapper brokerageWithdrawMapper;
34 38
  39 + @MockBean
  40 + private BrokerageRecordService brokerageRecordService;
  41 + @MockBean
  42 + private BrokerageUserService brokerageUserService;
  43 + @MockBean
  44 + private TradeConfigService tradeConfigService;
  45 +
  46 + @MockBean
  47 + private NotifyMessageSendApi notifyMessageSendApi;
  48 +
  49 + @Resource
  50 + private Validator validator;
  51 +
35 @Test 52 @Test
36 @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 53 @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
37 public void testGetBrokerageWithdrawPage() { 54 public void testGetBrokerageWithdrawPage() {
@@ -84,4 +101,17 @@ public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest { @@ -84,4 +101,17 @@ public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest {
84 assertPojoEquals(dbBrokerageWithdraw, pageResult.getList().get(0)); 101 assertPojoEquals(dbBrokerageWithdraw, pageResult.getList().get(0));
85 } 102 }
86 103
  104 + @Test
  105 + public void testCalculateFeePrice() {
  106 + Integer withdrawPrice = 100;
  107 + // 测试手续费比例未设置
  108 + Integer percent = null;
  109 + assertEquals(brokerageWithdrawService.calculateFeePrice(withdrawPrice, percent), 0);
  110 + // 测试手续费给为0
  111 + percent = 0;
  112 + assertEquals(brokerageWithdrawService.calculateFeePrice(withdrawPrice, percent), 0);
  113 + // 测试手续费
  114 + percent = 1;
  115 + assertEquals(brokerageWithdrawService.calculateFeePrice(withdrawPrice, percent), 1);
  116 + }
87 } 117 }
yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql
@@ -186,6 +186,6 @@ CREATE TABLE IF NOT EXISTS &quot;trade_brokerage_withdraw&quot; @@ -186,6 +186,6 @@ CREATE TABLE IF NOT EXISTS &quot;trade_brokerage_withdraw&quot;
186 "updater" varchar DEFAULT '', 186 "updater" varchar DEFAULT '',
187 "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 187 "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
188 "deleted" bit NOT NULL DEFAULT FALSE, 188 "deleted" bit NOT NULL DEFAULT FALSE,
189 - "tenant_id" bigint not null default '0',目 189 + "tenant_id" bigint not null default '0',
190 PRIMARY KEY ("id") 190 PRIMARY KEY ("id")
191 ) COMMENT '佣金提现'; 191 ) COMMENT '佣金提现';
192 \ No newline at end of file 192 \ No newline at end of file