commit
51899c4c13
|
@ -1,25 +1,29 @@
|
||||||
-- 增加配置表
|
-- 增加配置表
|
||||||
create table trade_config
|
create table trade_config
|
||||||
(
|
(
|
||||||
id bigint auto_increment comment '自增主键' primary key,
|
id bigint auto_increment comment '自增主键' primary key,
|
||||||
brokerage_enabled bit default 1 not null comment '是否启用分佣',
|
brokerage_enabled bit default 1 not null comment '是否启用分佣',
|
||||||
brokerage_enabled_condition tinyint default 0 not null comment '分佣模式:1-人人分销 2-指定分销',
|
brokerage_enabled_condition tinyint default 1 not null comment '分佣模式:1-人人分销 2-指定分销',
|
||||||
brokerage_bind_mode tinyint default 0 not null comment '分销关系绑定模式: 1-没有推广人,2-新用户, 3-扫码覆盖',
|
brokerage_bind_mode tinyint default 1 not null comment '分销关系绑定模式: 1-没有推广人,2-新用户, 3-扫码覆盖',
|
||||||
brokerage_post_urls varchar(2000) default '' null comment '分销海报图地址数组',
|
brokerage_post_urls varchar(2000) default '' null comment '分销海报图地址数组',
|
||||||
brokerage_first_percent int default 0 not null comment '一级返佣比例',
|
brokerage_first_percent int default 0 not null comment '一级返佣比例',
|
||||||
brokerage_second_percent int default 0 not null comment '二级返佣比例',
|
brokerage_second_percent int default 0 not null comment '二级返佣比例',
|
||||||
brokerage_withdraw_min_price int default 0 not null comment '用户提现最低金额',
|
brokerage_withdraw_min_price int default 0 not null comment '用户提现最低金额',
|
||||||
brokerage_bank_names varchar(200) default '' not null comment '提现银行(字典类型=brokerage_bank_name)',
|
brokerage_withdraw_fee_percent int default 0 not null comment '提现手续费百分比',
|
||||||
brokerage_frozen_days int default 7 not null comment '佣金冻结时间(天)',
|
brokerage_bank_names varchar(200) default '' not null comment '提现银行(字典类型=brokerage_bank_name)',
|
||||||
brokerage_withdraw_type varchar(32) default '1,2,3,4' not null comment '提现方式:1-钱包;2-银行卡;3-微信;4-支付宝',
|
brokerage_frozen_days int default 7 not null comment '佣金冻结时间(天)',
|
||||||
creator varchar(64) default '' null comment '创建者',
|
brokerage_withdraw_type varchar(32) default '1,2,3,4' not null comment '提现方式:1-钱包;2-银行卡;3-微信;4-支付宝',
|
||||||
create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
|
creator varchar(64) default '' null comment '创建者',
|
||||||
updater varchar(64) default '' null comment '更新者',
|
create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
|
||||||
update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
|
updater varchar(64) default '' null comment '更新者',
|
||||||
deleted bit default b'0' not null comment '是否删除',
|
update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
|
||||||
tenant_id bigint default 0 not null comment '租户编号'
|
deleted bit default b'0' not null comment '是否删除',
|
||||||
|
tenant_id bigint default 0 not null comment '租户编号'
|
||||||
) comment '交易中心配置';
|
) comment '交易中心配置';
|
||||||
|
|
||||||
|
# alter table trade_config
|
||||||
|
# add brokerage_withdraw_fee_percent int default 0 not null comment '提现手续费百分比' after brokerage_withdraw_min_price;
|
||||||
|
|
||||||
# alter table trade_brokerage_user
|
# alter table trade_brokerage_user
|
||||||
# add level int not null default 1 comment '等级' after frozen_price;
|
# add level int not null default 1 comment '等级' after frozen_price;
|
||||||
# alter table trade_brokerage_user
|
# alter table trade_brokerage_user
|
||||||
|
@ -36,8 +40,6 @@ create table trade_brokerage_user
|
||||||
brokerage_time datetime null comment '成为分销员时间',
|
brokerage_time datetime null comment '成为分销员时间',
|
||||||
price int default 0 not null comment '可用佣金',
|
price int default 0 not null comment '可用佣金',
|
||||||
frozen_price int default 0 not null comment '冻结佣金',
|
frozen_price int default 0 not null comment '冻结佣金',
|
||||||
level int default 1 not null comment '等级',
|
|
||||||
path varchar(2000) null comment '路径',
|
|
||||||
creator varchar(64) default '' null comment '创建者',
|
creator varchar(64) default '' null comment '创建者',
|
||||||
create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
|
create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
|
||||||
updater varchar(64) default '' null comment '更新者',
|
updater varchar(64) default '' null comment '更新者',
|
||||||
|
@ -83,7 +85,7 @@ create index idx_status on trade_brokerage_record (status) comment '状态';
|
||||||
|
|
||||||
create table trade_brokerage_withdraw
|
create table trade_brokerage_withdraw
|
||||||
(
|
(
|
||||||
id int auto_increment comment '编号'
|
id bigint auto_increment comment '编号'
|
||||||
primary key,
|
primary key,
|
||||||
user_id bigint not null comment '用户编号',
|
user_id bigint not null comment '用户编号',
|
||||||
price int default 0 not null comment '提现金额',
|
price int default 0 not null comment '提现金额',
|
||||||
|
@ -137,7 +139,8 @@ insert into system_dict_type(type, name)
|
||||||
values ('brokerage_record_biz_type', '佣金记录业务类型');
|
values ('brokerage_record_biz_type', '佣金记录业务类型');
|
||||||
insert into system_dict_data(dict_type, label, value, sort)
|
insert into system_dict_data(dict_type, label, value, sort)
|
||||||
values ('brokerage_record_biz_type', '订单返佣', 1, 1),
|
values ('brokerage_record_biz_type', '订单返佣', 1, 1),
|
||||||
('brokerage_record_biz_type', '申请提现', 2, 2);
|
('brokerage_record_biz_type', '申请提现', 2, 2),
|
||||||
|
('brokerage_record_biz_type', '申请提现驳回', 3, 3);
|
||||||
|
|
||||||
insert into system_dict_type(type, name)
|
insert into system_dict_type(type, name)
|
||||||
values ('brokerage_record_status', '佣金记录状态');
|
values ('brokerage_record_status', '佣金记录状态');
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
ALTER TABLE trade_order ADD COLUMN use_point int NOT NULL DEFAULT 0 COMMENT '使用的积分' AFTER point_price;
|
||||||
|
ALTER TABLE trade_order ADD COLUMN refund_point int NOT NULL DEFAULT 0 COMMENT '退还的使用积分' AFTER use_point;
|
||||||
|
ALTER TABLE trade_order ADD COLUMN give_point int NOT NULL DEFAULT 0 COMMENT '赠送的积分' AFTER refund_point;
|
||||||
|
|
||||||
|
ALTER TABLE trade_order_item ADD COLUMN use_point int NOT NULL DEFAULT 0 COMMENT '使用的积分' AFTER point_price;
|
||||||
|
ALTER TABLE trade_order_item ADD COLUMN give_point int NOT NULL DEFAULT 0 COMMENT '赠送的积分' AFTER use_point;
|
|
@ -100,14 +100,6 @@ public class LambdaQueryWrapperX<T> extends LambdaQueryWrapper<T> {
|
||||||
return betweenIfPresent(column, val1, val2);
|
return betweenIfPresent(column, val1, val2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @疯狂:这个是 mysql 独有的,不好做成通用的哈。如果多层级,有没可能先查询一个层级,再查询一个层级;形成 set 后,直接去 in?
|
|
||||||
public LambdaQueryWrapperX<T> findInSetIfPresent(SFunction<T, ?> column, Object val) {
|
|
||||||
if (val != null) {
|
|
||||||
return (LambdaQueryWrapperX<T>) super.apply("FIND_IN_SET({0}, " + columnToString(column) + ")", val);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== 重写父类方法,方便链式调用 ==========
|
// ========== 重写父类方法,方便链式调用 ==========
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,18 +1,24 @@
|
||||||
package cn.iocoder.yudao.framework.jackson.config;
|
package cn.iocoder.yudao.framework.jackson.config;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.jackson.core.databind.NumberSerializer;
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
import cn.iocoder.yudao.framework.jackson.core.databind.LocalDateTimeDeserializer;
|
import cn.iocoder.yudao.framework.jackson.core.databind.LocalDateTimeDeserializer;
|
||||||
import cn.iocoder.yudao.framework.jackson.core.databind.LocalDateTimeSerializer;
|
import cn.iocoder.yudao.framework.jackson.core.databind.LocalDateTimeSerializer;
|
||||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
import cn.iocoder.yudao.framework.jackson.core.databind.NumberSerializer;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
|
||||||
@AutoConfiguration
|
@AutoConfiguration
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -36,6 +42,10 @@ public class YudaoJacksonAutoConfiguration {
|
||||||
simpleModule
|
simpleModule
|
||||||
.addSerializer(Long.class, NumberSerializer.INSTANCE)
|
.addSerializer(Long.class, NumberSerializer.INSTANCE)
|
||||||
.addSerializer(Long.TYPE, NumberSerializer.INSTANCE)
|
.addSerializer(Long.TYPE, NumberSerializer.INSTANCE)
|
||||||
|
.addSerializer(LocalDate.class, LocalDateSerializer.INSTANCE)
|
||||||
|
.addDeserializer(LocalDate.class, LocalDateDeserializer.INSTANCE)
|
||||||
|
.addSerializer(LocalTime.class, LocalTimeSerializer.INSTANCE)
|
||||||
|
.addDeserializer(LocalTime.class, LocalTimeDeserializer.INSTANCE)
|
||||||
.addSerializer(LocalDateTime.class, LocalDateTimeSerializer.INSTANCE)
|
.addSerializer(LocalDateTime.class, LocalDateTimeSerializer.INSTANCE)
|
||||||
.addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);
|
.addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);
|
||||||
|
|
||||||
|
|
|
@ -110,6 +110,11 @@ public class ProductSpuRespDTO {
|
||||||
|
|
||||||
// ========== 物流相关字段 =========
|
// ========== 物流相关字段 =========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 赠送积分
|
||||||
|
*/
|
||||||
|
private Integer giveIntegral;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 物流配置模板编号
|
* 物流配置模板编号
|
||||||
*
|
*
|
||||||
|
|
|
@ -23,7 +23,8 @@ public enum PromotionTypeEnum implements IntArrayValuable {
|
||||||
REWARD_ACTIVITY(5, "满减送"),
|
REWARD_ACTIVITY(5, "满减送"),
|
||||||
|
|
||||||
MEMBER_LEVEL(6, "会员折扣"),
|
MEMBER_LEVEL(6, "会员折扣"),
|
||||||
COUPON(7, "优惠劵")
|
COUPON(7, "优惠劵"),
|
||||||
|
POINT(8, "积分")
|
||||||
;
|
;
|
||||||
|
|
||||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionTypeEnum::getType).toArray();
|
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionTypeEnum::getType).toArray();
|
||||||
|
|
|
@ -87,5 +87,7 @@ public interface ErrorCodeConstants {
|
||||||
// ========== 分销提现 模块 1011008000 ==========
|
// ========== 分销提现 模块 1011008000 ==========
|
||||||
ErrorCode BROKERAGE_WITHDRAW_NOT_EXISTS = new ErrorCode(1011008000, "佣金提现记录不存在");
|
ErrorCode BROKERAGE_WITHDRAW_NOT_EXISTS = new ErrorCode(1011008000, "佣金提现记录不存在");
|
||||||
ErrorCode BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING = new ErrorCode(1011008001, "佣金提现记录状态不是审核中");
|
ErrorCode BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING = new ErrorCode(1011008001, "佣金提现记录状态不是审核中");
|
||||||
|
ErrorCode BROKERAGE_WITHDRAW_MIN_PRICE = new ErrorCode(1011008002, "提现金额不能低于{}元");
|
||||||
|
ErrorCode BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH = new ErrorCode(1011008003, "您当前最多可提现{}元");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ public enum BrokerageRecordBizTypeEnum implements IntArrayValuable {
|
||||||
|
|
||||||
ORDER(1, "获得推广佣金", "获得推广佣金 {}", true),
|
ORDER(1, "获得推广佣金", "获得推广佣金 {}", true),
|
||||||
WITHDRAW(2, "提现申请", "提现申请扣除佣金 {}", false),
|
WITHDRAW(2, "提现申请", "提现申请扣除佣金 {}", false),
|
||||||
|
WITHDRAW_REJECT(3, "提现申请驳回", "提现申请驳回返还佣金 {}", true),
|
||||||
;
|
;
|
||||||
|
|
||||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageRecordBizTypeEnum::getType).toArray();
|
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageRecordBizTypeEnum::getType).toArray();
|
||||||
|
|
|
@ -22,6 +22,7 @@ public enum BrokerageWithdrawStatusEnum implements IntArrayValuable {
|
||||||
WITHDRAW_FAIL(21, "提现失败"),
|
WITHDRAW_FAIL(21, "提现失败"),
|
||||||
;
|
;
|
||||||
|
|
||||||
|
public static final String DICT_TYPE = "BROKERAGE_WITHDRAW_STATUS";
|
||||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageWithdrawStatusEnum::getStatus).toArray();
|
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageWithdrawStatusEnum::getStatus).toArray();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.record;
|
package cn.iocoder.yudao.module.trade.controller.admin.brokerage;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
|
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
|
||||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordPageReqVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordRespVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordRespVO;
|
||||||
import cn.iocoder.yudao.module.trade.convert.brokerage.record.BrokerageRecordConvert;
|
import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService;
|
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
@ -1,17 +1,17 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user;
|
package cn.iocoder.yudao.module.trade.controller.admin.brokerage;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
|
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
|
||||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.*;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.*;
|
||||||
import cn.iocoder.yudao.module.trade.convert.brokerage.user.BrokerageUserConvert;
|
import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageUserConvert;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
|
||||||
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
|
||||||
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
|
import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService;
|
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService;
|
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
@ -1,16 +1,16 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw;
|
package cn.iocoder.yudao.module.trade.controller.admin.brokerage;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
|
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
|
||||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawRejectReqVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawRejectReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawPageReqVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawRespVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawRespVO;
|
||||||
import cn.iocoder.yudao.module.trade.convert.brokerage.withdraw.BrokerageWithdrawConvert;
|
import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageWithdrawConvert;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw.BrokerageWithdrawDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO;
|
||||||
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.withdraw.BrokerageWithdrawService;
|
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageWithdrawService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo;
|
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo;
|
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo;
|
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo;
|
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo;
|
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo;
|
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo;
|
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo;
|
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo;
|
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo;
|
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo;
|
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo;
|
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo;
|
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
|
@ -19,6 +19,17 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class TradeConfigBaseVO {
|
public class TradeConfigBaseVO {
|
||||||
|
/**
|
||||||
|
* 是否启用全场包邮
|
||||||
|
*/
|
||||||
|
@Schema(description = "是否启用全场包邮", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
||||||
|
@NotNull(message = "是否启用全场包邮不能为空")
|
||||||
|
private Boolean deliveryExpressFreeEnabled;
|
||||||
|
|
||||||
|
@Schema(description = "全场包邮的最小金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
|
||||||
|
@NotNull(message = "全场包邮的最小金额不能为空")
|
||||||
|
@PositiveOrZero(message = "全场包邮的最小金额不能是负数")
|
||||||
|
private Integer deliveryExpressFreePrice;
|
||||||
|
|
||||||
// ========== 分销相关 ==========
|
// ========== 分销相关 ==========
|
||||||
|
|
||||||
|
@ -54,6 +65,11 @@ public class TradeConfigBaseVO {
|
||||||
@PositiveOrZero(message = "用户提现最低金额不能是负数")
|
@PositiveOrZero(message = "用户提现最低金额不能是负数")
|
||||||
private Integer brokerageWithdrawMinPrice;
|
private Integer brokerageWithdrawMinPrice;
|
||||||
|
|
||||||
|
@Schema(description = "用户提现手续费百分比", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
|
||||||
|
@NotNull(message = "用户提现手续费百分比不能为空")
|
||||||
|
@PositiveOrZero(message = "用户提现手续费百分比不能是负数")
|
||||||
|
private Integer brokerageWithdrawFeePercent;
|
||||||
|
|
||||||
@Schema(description = "提现银行", requiredMode = Schema.RequiredMode.REQUIRED, example = "[0, 1]")
|
@Schema(description = "提现银行", requiredMode = Schema.RequiredMode.REQUIRED, example = "[0, 1]")
|
||||||
@NotEmpty(message = "提现银行不能为空")
|
@NotEmpty(message = "提现银行不能为空")
|
||||||
private List<Integer> brokerageBankNames;
|
private List<Integer> brokerageBankNames;
|
||||||
|
|
|
@ -6,7 +6,10 @@ import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
|
||||||
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageProductPriceRespVO;
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageProductPriceRespVO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordPageReqVO;
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordPageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordRespVO;
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordRespVO;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService;
|
import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
@ -18,11 +21,9 @@ import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
|
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
|
|
||||||
@Tag(name = "用户 APP - 分销用户")
|
@Tag(name = "用户 APP - 分销用户")
|
||||||
@RestController
|
@RestController
|
||||||
|
@ -32,19 +33,16 @@ import static java.util.Arrays.asList;
|
||||||
public class AppBrokerageRecordController {
|
public class AppBrokerageRecordController {
|
||||||
@Resource
|
@Resource
|
||||||
private BrokerageUserService brokerageUserService;
|
private BrokerageUserService brokerageUserService;
|
||||||
|
@Resource
|
||||||
|
private BrokerageRecordService brokerageRecordService;
|
||||||
|
|
||||||
// TODO 芋艿:临时 mock =>
|
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
@Operation(summary = "获得分销记录分页")
|
@Operation(summary = "获得分销记录分页")
|
||||||
@PreAuthenticated
|
@PreAuthenticated
|
||||||
public CommonResult<PageResult<AppBrokerageRecordRespVO>> getBrokerageRecordPage(@Valid AppBrokerageRecordPageReqVO pageReqVO) {
|
public CommonResult<PageResult<AppBrokerageRecordRespVO>> getBrokerageRecordPage(@Valid AppBrokerageRecordPageReqVO pageReqVO) {
|
||||||
AppBrokerageRecordRespVO vo1 = new AppBrokerageRecordRespVO()
|
PageResult<BrokerageRecordDO> pageResult = brokerageRecordService.getBrokerageRecordPage(
|
||||||
.setId(1L).setPrice(10).setTitle("收到钱").setCreateTime(LocalDateTime.now())
|
BrokerageRecordConvert.INSTANCE.convert(pageReqVO, getLoginUserId()));
|
||||||
.setFinishTime(LocalDateTime.now());
|
return success(BrokerageRecordConvert.INSTANCE.convertPage02(pageResult));
|
||||||
AppBrokerageRecordRespVO vo2 = new AppBrokerageRecordRespVO()
|
|
||||||
.setId(2L).setPrice(-20).setTitle("提现钱").setCreateTime(LocalDateTime.now())
|
|
||||||
.setFinishTime(LocalDateTime.now());
|
|
||||||
return success(new PageResult<>(asList(vo1, vo2), 10L));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/get-product-brokerage-price")
|
@GetMapping("/get-product-brokerage-price")
|
||||||
|
|
|
@ -1,10 +1,20 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.app.brokerage;
|
package cn.iocoder.yudao.module.trade.controller.app.brokerage;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
|
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
|
||||||
|
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
|
||||||
|
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.*;
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.*;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService;
|
import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert;
|
||||||
|
import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageUserConvert;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
|
||||||
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageWithdrawService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
@ -16,11 +26,13 @@ import org.springframework.web.bind.annotation.*;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
|
|
||||||
@Tag(name = "用户 APP - 分销用户")
|
@Tag(name = "用户 APP - 分销用户")
|
||||||
@RestController
|
@RestController
|
||||||
|
@ -30,16 +42,23 @@ import static java.util.Arrays.asList;
|
||||||
public class AppBrokerageUserController {
|
public class AppBrokerageUserController {
|
||||||
@Resource
|
@Resource
|
||||||
private BrokerageUserService brokerageUserService;
|
private BrokerageUserService brokerageUserService;
|
||||||
|
@Resource
|
||||||
|
private BrokerageRecordService brokerageRecordService;
|
||||||
|
@Resource
|
||||||
|
private BrokerageWithdrawService brokerageWithdrawService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MemberUserApi memberUserApi;
|
||||||
|
|
||||||
// TODO 芋艿:临时 mock =>
|
|
||||||
@GetMapping("/get")
|
@GetMapping("/get")
|
||||||
@Operation(summary = "获得个人分销信息")
|
@Operation(summary = "获得个人分销信息")
|
||||||
@PreAuthenticated
|
@PreAuthenticated
|
||||||
public CommonResult<AppBrokerageUserRespVO> getBrokerageUser() {
|
public CommonResult<AppBrokerageUserRespVO> getBrokerageUser() {
|
||||||
|
Optional<BrokerageUserDO> user = Optional.ofNullable(brokerageUserService.getBrokerageUser(getLoginUserId()));
|
||||||
AppBrokerageUserRespVO respVO = new AppBrokerageUserRespVO()
|
AppBrokerageUserRespVO respVO = new AppBrokerageUserRespVO()
|
||||||
.setBrokerageEnabled(true)
|
.setBrokerageEnabled(user.map(BrokerageUserDO::getBrokerageEnabled).orElse(false))
|
||||||
.setPrice(2000)
|
.setBrokeragePrice(user.map(BrokerageUserDO::getBrokeragePrice).orElse(0))
|
||||||
.setFrozenPrice(3000);
|
.setFrozenPrice(user.map(BrokerageUserDO::getFrozenPrice).orElse(0));
|
||||||
return success(respVO);
|
return success(respVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,85 +69,65 @@ public class AppBrokerageUserController {
|
||||||
return success(brokerageUserService.bindBrokerageUser(getLoginUserId(), reqVO.getBindUserId(), false));
|
return success(brokerageUserService.bindBrokerageUser(getLoginUserId(), reqVO.getBindUserId(), false));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO 芋艿:临时 mock =>
|
|
||||||
@GetMapping("/get-summary")
|
@GetMapping("/get-summary")
|
||||||
@Operation(summary = "获得个人分销统计")
|
@Operation(summary = "获得个人分销统计")
|
||||||
@PreAuthenticated
|
@PreAuthenticated
|
||||||
public CommonResult<AppBrokerageUserMySummaryRespVO> getBrokerageUserSummary() {
|
public CommonResult<AppBrokerageUserMySummaryRespVO> getBrokerageUserSummary() {
|
||||||
|
Long userId = getLoginUserId();
|
||||||
|
LocalDateTime yesterday = LocalDateTime.now().minusDays(1);
|
||||||
|
LocalDateTime beginTime = LocalDateTimeUtil.beginOfDay(yesterday);
|
||||||
|
LocalDateTime endTime = LocalDateTimeUtil.endOfDay(yesterday);
|
||||||
|
|
||||||
AppBrokerageUserMySummaryRespVO respVO = new AppBrokerageUserMySummaryRespVO()
|
AppBrokerageUserMySummaryRespVO respVO = new AppBrokerageUserMySummaryRespVO()
|
||||||
.setYesterdayPrice(1)
|
.setYesterdayPrice(brokerageRecordService.getSummaryPriceByUserId(userId, BrokerageRecordBizTypeEnum.ORDER.getType(), beginTime, endTime))
|
||||||
.setBrokeragePrice(2)
|
.setWithdrawPrice(brokerageWithdrawService.getSummaryPriceByUserIdAndStatus(userId, BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.getStatus()))
|
||||||
.setFrozenPrice(3)
|
.setBrokeragePrice(0)
|
||||||
.setWithdrawPrice(4)
|
.setFrozenPrice(0)
|
||||||
.setFirstBrokerageUserCount(166)
|
.setFirstBrokerageUserCount(brokerageUserService.getBrokerageUserCountByBindUserId(userId, 1))
|
||||||
.setSecondBrokerageUserCount(233);
|
.setSecondBrokerageUserCount(brokerageUserService.getBrokerageUserCountByBindUserId(userId, 2));
|
||||||
|
Optional.ofNullable(brokerageUserService.getBrokerageUser(userId))
|
||||||
|
.ifPresent(user -> respVO.setBrokeragePrice(user.getBrokeragePrice()).setFrozenPrice(user.getFrozenPrice()));
|
||||||
return success(respVO);
|
return success(respVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO 芋艿:临时 mock =>
|
|
||||||
@GetMapping("/rank-page-by-user-count")
|
@GetMapping("/rank-page-by-user-count")
|
||||||
@Operation(summary = "获得分销用户排行分页(基于用户量)")
|
@Operation(summary = "获得分销用户排行分页(基于用户量)")
|
||||||
@PreAuthenticated
|
@PreAuthenticated
|
||||||
public CommonResult<PageResult<AppBrokerageUserRankByUserCountRespVO>> getBrokerageUserRankPageByUserCount(AppBrokerageUserRankPageReqVO pageReqVO) {
|
public CommonResult<PageResult<AppBrokerageUserRankByUserCountRespVO>> getBrokerageUserRankPageByUserCount(AppBrokerageUserRankPageReqVO pageReqVO) {
|
||||||
AppBrokerageUserRankByUserCountRespVO vo1 = new AppBrokerageUserRankByUserCountRespVO()
|
// 分页查询
|
||||||
.setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
|
PageResult<AppBrokerageUserRankByUserCountRespVO> pageResult = brokerageUserService.getBrokerageUserRankPageByUserCount(pageReqVO);
|
||||||
.setBrokerageUserCount(10);
|
// 拼接数据
|
||||||
AppBrokerageUserRankByUserCountRespVO vo2 = new AppBrokerageUserRankByUserCountRespVO()
|
Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(convertSet(pageResult.getList(), AppBrokerageUserRankByUserCountRespVO::getId));
|
||||||
.setId(2L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
|
return success(BrokerageUserConvert.INSTANCE.convertPage03(pageResult, userMap));
|
||||||
.setBrokerageUserCount(6);
|
|
||||||
AppBrokerageUserRankByUserCountRespVO vo3 = new AppBrokerageUserRankByUserCountRespVO()
|
|
||||||
.setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
|
|
||||||
.setBrokerageUserCount(4);
|
|
||||||
AppBrokerageUserRankByUserCountRespVO vo4 = new AppBrokerageUserRankByUserCountRespVO()
|
|
||||||
.setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
|
|
||||||
.setBrokerageUserCount(4);
|
|
||||||
return success(new PageResult<>(asList(vo1, vo2, vo3, vo4), 10L));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO 芋艿:临时 mock =>
|
|
||||||
@GetMapping("/rank-page-by-price")
|
@GetMapping("/rank-page-by-price")
|
||||||
@Operation(summary = "获得分销用户排行分页(基于佣金)")
|
@Operation(summary = "获得分销用户排行分页(基于佣金)")
|
||||||
@PreAuthenticated
|
@PreAuthenticated
|
||||||
public CommonResult<PageResult<AppBrokerageUserRankByPriceRespVO>> getBrokerageUserChildSummaryPageByPrice(AppBrokerageUserRankPageReqVO pageReqVO) {
|
public CommonResult<PageResult<AppBrokerageUserRankByPriceRespVO>> getBrokerageUserChildSummaryPageByPrice(AppBrokerageUserRankPageReqVO pageReqVO) {
|
||||||
AppBrokerageUserRankByPriceRespVO vo1 = new AppBrokerageUserRankByPriceRespVO()
|
// 分页查询
|
||||||
.setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
|
PageResult<AppBrokerageUserRankByPriceRespVO> pageResult = brokerageRecordService.getBrokerageUserChildSummaryPageByPrice(pageReqVO);
|
||||||
.setBrokeragePrice(10);
|
// 拼接数据
|
||||||
AppBrokerageUserRankByPriceRespVO vo2 = new AppBrokerageUserRankByPriceRespVO()
|
Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(convertSet(pageResult.getList(), AppBrokerageUserRankByPriceRespVO::getId));
|
||||||
.setId(2L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
|
return success(BrokerageRecordConvert.INSTANCE.convertPage03(pageResult, userMap));
|
||||||
.setBrokeragePrice(6);
|
|
||||||
AppBrokerageUserRankByPriceRespVO vo3 = new AppBrokerageUserRankByPriceRespVO()
|
|
||||||
.setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
|
|
||||||
.setBrokeragePrice(4);
|
|
||||||
AppBrokerageUserRankByPriceRespVO vo4 = new AppBrokerageUserRankByPriceRespVO()
|
|
||||||
.setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
|
|
||||||
.setBrokeragePrice(4);
|
|
||||||
return success(new PageResult<>(asList(vo1, vo2, vo3, vo4), 10L));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO 芋艿:临时 mock =>
|
|
||||||
@GetMapping("/child-summary-page")
|
@GetMapping("/child-summary-page")
|
||||||
@Operation(summary = "获得下级分销统计分页")
|
@Operation(summary = "获得下级分销统计分页")
|
||||||
@PreAuthenticated
|
@PreAuthenticated
|
||||||
public CommonResult<PageResult<AppBrokerageUserChildSummaryRespVO>> getBrokerageUserChildSummaryPage(
|
public CommonResult<PageResult<AppBrokerageUserChildSummaryRespVO>> getBrokerageUserChildSummaryPage(
|
||||||
AppBrokerageUserChildSummaryPageReqVO pageReqVO) {
|
AppBrokerageUserChildSummaryPageReqVO pageReqVO) {
|
||||||
AppBrokerageUserChildSummaryRespVO vo1 = new AppBrokerageUserChildSummaryRespVO()
|
// 分页查询
|
||||||
.setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
|
PageResult<AppBrokerageUserChildSummaryRespVO> pageResult = brokerageUserService.getBrokerageUserChildSummaryPage(pageReqVO, getLoginUserId());
|
||||||
.setBrokeragePrice(10).setBrokeragePrice(20).setBrokerageOrderCount(30)
|
return success(pageResult);
|
||||||
.setBrokerageTime(LocalDateTime.now());
|
|
||||||
AppBrokerageUserChildSummaryRespVO vo2 = new AppBrokerageUserChildSummaryRespVO()
|
|
||||||
.setId(1L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
|
|
||||||
.setBrokeragePrice(20).setBrokeragePrice(30).setBrokerageOrderCount(40)
|
|
||||||
.setBrokerageTime(LocalDateTime.now());
|
|
||||||
return success(new PageResult<>(asList(vo1, vo2), 10L));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO 芋艿:临时 mock =>
|
|
||||||
@GetMapping("/get-rank-by-price")
|
@GetMapping("/get-rank-by-price")
|
||||||
@Operation(summary = "获得分销用户排行(基于佣金)")
|
@Operation(summary = "获得分销用户排行(基于佣金)")
|
||||||
@Parameter(name = "times", description = "时间段", required = true)
|
@Parameter(name = "times", description = "时间段", required = true)
|
||||||
public CommonResult<Integer> bindBrokerageUser(
|
public CommonResult<Integer> getRankByPrice(
|
||||||
@RequestParam("times") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) LocalDateTime[] times) {
|
@RequestParam("times") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) LocalDateTime[] times) {
|
||||||
return success(1);
|
return success(brokerageRecordService.getUserRankByPrice(getLoginUserId(), times));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,19 +3,26 @@ package cn.iocoder.yudao.module.trade.controller.app.brokerage;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
|
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
|
||||||
|
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
|
||||||
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO;
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawPageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawRespVO;
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageWithdrawConvert;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO;
|
||||||
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageWithdrawService;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.time.LocalDateTime;
|
import java.util.Map;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
import static java.util.Arrays.asList;
|
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
|
||||||
|
|
||||||
@Tag(name = "用户 APP - 分销提现")
|
@Tag(name = "用户 APP - 分销提现")
|
||||||
@RestController
|
@RestController
|
||||||
|
@ -23,25 +30,29 @@ import static java.util.Arrays.asList;
|
||||||
@Validated
|
@Validated
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class AppBrokerageWithdrawController {
|
public class AppBrokerageWithdrawController {
|
||||||
|
@Resource
|
||||||
|
private BrokerageWithdrawService brokerageWithdrawService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private DictDataApi dictDataApi;
|
||||||
|
|
||||||
// TODO 芋艿:临时 mock =>
|
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
@Operation(summary = "获得分销提现分页")
|
@Operation(summary = "获得分销提现分页")
|
||||||
@PreAuthenticated
|
@PreAuthenticated
|
||||||
public CommonResult<PageResult<AppBrokerageWithdrawRespVO>> getBrokerageWithdrawPage() {
|
public CommonResult<PageResult<AppBrokerageWithdrawRespVO>> getBrokerageWithdrawPage(AppBrokerageWithdrawPageReqVO pageReqVO) {
|
||||||
AppBrokerageWithdrawRespVO vo1 = new AppBrokerageWithdrawRespVO()
|
// 分页查询
|
||||||
.setId(1L).setStatus(10).setPrice(10).setStatusName("审批通过").setCreateTime(LocalDateTime.now());
|
PageResult<BrokerageWithdrawDO> pageResult = brokerageWithdrawService.getBrokerageWithdrawPage(
|
||||||
AppBrokerageWithdrawRespVO vo2 = new AppBrokerageWithdrawRespVO()
|
BrokerageWithdrawConvert.INSTANCE.convert(pageReqVO, getLoginUserId()));
|
||||||
.setId(2L).setStatus(0).setPrice(20).setStatusName("审批中").setCreateTime(LocalDateTime.now());
|
// 拼接信息
|
||||||
return success(new PageResult<>(asList(vo1, vo2), 10L));
|
Map<String, String> statusNameMap = dictDataApi.getDictDataLabelMap(BrokerageWithdrawStatusEnum.DICT_TYPE);
|
||||||
|
return success(BrokerageWithdrawConvert.INSTANCE.convertPage02(pageResult, statusNameMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO 芋艿:临时 mock =>
|
|
||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
@Operation(summary = "创建分销提现")
|
@Operation(summary = "创建分销提现")
|
||||||
@PreAuthenticated
|
@PreAuthenticated
|
||||||
public CommonResult<Long> createBrokerageWithdraw(@RequestBody @Valid AppBrokerageWithdrawCreateReqVO createReqVO) {
|
public CommonResult<Long> createBrokerageWithdraw(@RequestBody @Valid AppBrokerageWithdrawCreateReqVO createReqVO) {
|
||||||
return success(1L);
|
return success(brokerageWithdrawService.createBrokerageWithdraw(createReqVO, getLoginUserId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ public class AppBrokerageUserChildSummaryRespVO {
|
||||||
@Schema(description = "分销用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "30")
|
@Schema(description = "分销用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "30")
|
||||||
private Integer brokerageUserCount;
|
private Integer brokerageUserCount;
|
||||||
|
|
||||||
@Schema(description = "成为分销员时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "绑定推广员的时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
private LocalDateTime brokerageTime;
|
private LocalDateTime brokerageTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,9 @@ public class AppBrokerageUserMySummaryRespVO {
|
||||||
private Integer frozenPrice;
|
private Integer frozenPrice;
|
||||||
|
|
||||||
@Schema(description = "分销用户数量(一级)", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
@Schema(description = "分销用户数量(一级)", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||||
private Integer firstBrokerageUserCount;
|
private Long firstBrokerageUserCount;
|
||||||
|
|
||||||
@Schema(description = "分销用户数量(二级)", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
@Schema(description = "分销用户数量(二级)", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
|
||||||
private Integer secondBrokerageUserCount;
|
private Long secondBrokerageUserCount;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ public class AppBrokerageUserRespVO {
|
||||||
private Boolean brokerageEnabled;
|
private Boolean brokerageEnabled;
|
||||||
|
|
||||||
@Schema(description = "可用的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2408")
|
@Schema(description = "可用的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2408")
|
||||||
private Integer price;
|
private Integer brokeragePrice;
|
||||||
|
|
||||||
@Schema(description = "冻结的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "234")
|
@Schema(description = "冻结的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "234")
|
||||||
private Integer frozenPrice;
|
private Integer frozenPrice;
|
||||||
|
|
|
@ -8,8 +8,9 @@ import lombok.Data;
|
||||||
import org.hibernate.validator.constraints.URL;
|
import org.hibernate.validator.constraints.URL;
|
||||||
|
|
||||||
import javax.validation.Validator;
|
import javax.validation.Validator;
|
||||||
import javax.validation.constraints.Min;
|
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import javax.validation.constraints.PositiveOrZero;
|
||||||
|
|
||||||
@Schema(description = "用户 App - 分销提现创建 Request VO")
|
@Schema(description = "用户 App - 分销提现创建 Request VO")
|
||||||
@Data
|
@Data
|
||||||
|
@ -20,7 +21,8 @@ public class AppBrokerageWithdrawCreateReqVO {
|
||||||
private Integer type;
|
private Integer type;
|
||||||
|
|
||||||
@Schema(description = "提现金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
|
@Schema(description = "提现金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
|
||||||
@Min(value = 1, message = "提现金额不能小于 1")
|
@PositiveOrZero(message = "提现金额不能小于 0")
|
||||||
|
@NotNull(message = "提现金额不能为空")
|
||||||
private Integer price;
|
private Integer price;
|
||||||
|
|
||||||
// ========== 银行卡、微信、支付宝 提现相关字段 ==========
|
// ========== 银行卡、微信、支付宝 提现相关字段 ==========
|
||||||
|
@ -41,7 +43,7 @@ public class AppBrokerageWithdrawCreateReqVO {
|
||||||
@NotBlank(message = "持卡人姓名不能为空", groups = {Bank.class})
|
@NotBlank(message = "持卡人姓名不能为空", groups = {Bank.class})
|
||||||
private String name;
|
private String name;
|
||||||
@Schema(description = "提现银行", example = "1")
|
@Schema(description = "提现银行", example = "1")
|
||||||
@NotBlank(message = "提现银行不能为空", groups = {Bank.class})
|
@NotNull(message = "提现银行不能为空", groups = {Bank.class})
|
||||||
private Integer bankName;
|
private Integer bankName;
|
||||||
@Schema(description = "开户地址", example = "海淀支行")
|
@Schema(description = "开户地址", example = "海淀支行")
|
||||||
private String bankAddress;
|
private String bankAddress;
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||||
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
|
||||||
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Schema(description = "应用 App - 分销提现分页 Request VO")
|
||||||
|
@Data
|
||||||
|
public class AppBrokerageWithdrawPageReqVO extends PageParam {
|
||||||
|
|
||||||
|
@Schema(description = "类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@InEnum(value = BrokerageWithdrawTypeEnum.class, message = "类型必须是 {value}")
|
||||||
|
private Integer type;
|
||||||
|
|
||||||
|
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@InEnum(value = BrokerageWithdrawStatusEnum.class, message = "状态必须是 {value}")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,10 @@
|
||||||
package cn.iocoder.yudao.module.trade.controller.app.config;
|
package cn.iocoder.yudao.module.trade.controller.app.config;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.module.trade.controller.app.config.vo.AppTradeConfigRespVO;
|
import cn.iocoder.yudao.module.trade.controller.app.config.vo.AppTradeConfigRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
@ -10,8 +13,9 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
import static java.util.Arrays.asList;
|
|
||||||
|
|
||||||
@Tag(name = "用户 App - 交易配置")
|
@Tag(name = "用户 App - 交易配置")
|
||||||
@RestController
|
@RestController
|
||||||
|
@ -20,17 +24,18 @@ import static java.util.Arrays.asList;
|
||||||
@Validated
|
@Validated
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class AppTradeConfigController {
|
public class AppTradeConfigController {
|
||||||
|
@Resource
|
||||||
|
private TradeConfigService tradeConfigService;
|
||||||
|
|
||||||
@GetMapping("/get")
|
@GetMapping("/get")
|
||||||
public CommonResult<AppTradeConfigRespVO> getTradeConfig() {
|
public CommonResult<AppTradeConfigRespVO> getTradeConfig() {
|
||||||
AppTradeConfigRespVO respVO = new AppTradeConfigRespVO();
|
TradeConfigDO tradeConfig = ObjUtil.defaultIfNull(tradeConfigService.getTradeConfig(), new TradeConfigDO());
|
||||||
respVO.setBrokeragePosterUrls(asList(
|
|
||||||
"https://api.java.crmeb.net/crmebimage/product/2020/08/03/755bf516b1ca4b6db3bfeaa4dd5901cdh71kob20re.jpg",
|
AppTradeConfigRespVO respVO = new AppTradeConfigRespVO()
|
||||||
"https://api.java.crmeb.net/crmebimage/maintain/2021/03/01/406d729b84ed4ec9a2171bfcf6fd0634ughzbz9kfi.jpg",
|
.setBrokeragePosterUrls(tradeConfig.getBrokeragePostUrls())
|
||||||
"https://api.java.crmeb.net/crmebimage/maintain/2021/03/01/efb1e4e7fe604fe1988b4213ce08cb11tdsyijtd2r.jpg"
|
.setBrokerageFrozenDays(tradeConfig.getBrokerageFrozenDays())
|
||||||
));
|
.setBrokerageWithdrawMinPrice(tradeConfig.getBrokerageWithdrawMinPrice())
|
||||||
respVO.setBrokerageFrozenDays(10);
|
.setBrokerageWithdrawType(tradeConfig.getBrokerageWithdrawType());
|
||||||
respVO.setBrokerageWithdrawMinPrice(100);
|
|
||||||
return success(respVO);
|
return success(respVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,4 +18,7 @@ public class AppTradeConfigRespVO {
|
||||||
@Schema(description = "佣金提现最小金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
@Schema(description = "佣金提现最小金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
||||||
private Integer brokerageWithdrawMinPrice;
|
private Integer brokerageWithdrawMinPrice;
|
||||||
|
|
||||||
|
@Schema(description = "提现方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "[1, 2]")
|
||||||
|
private List<Integer> brokerageWithdrawType;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
package cn.iocoder.yudao.module.trade.convert.brokerage.record;
|
package cn.iocoder.yudao.module.trade.convert.brokerage;
|
||||||
|
|
||||||
|
import cn.hutool.core.math.Money;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordRespVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordRespVO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
|
||||||
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
|
||||||
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.MappingTarget;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
@ -45,7 +51,7 @@ public interface BrokerageRecordConvert {
|
||||||
.setBizType(bizType.getType()).setBizId(bizId)
|
.setBizType(bizType.getType()).setBizId(bizId)
|
||||||
.setPrice(brokeragePrice).setTotalPrice(user.getBrokeragePrice())
|
.setPrice(brokeragePrice).setTotalPrice(user.getBrokeragePrice())
|
||||||
.setTitle(title)
|
.setTitle(title)
|
||||||
.setDescription(StrUtil.format(bizType.getDescription(), String.format("¥%.2f", brokeragePrice / 100d)))
|
.setDescription(StrUtil.format(bizType.getDescription(), new Money(0, Math.abs(brokeragePrice))))
|
||||||
.setStatus(status).setFrozenDays(brokerageFrozenDays).setUnfreezeTime(unfreezeTime)
|
.setStatus(status).setFrozenDays(brokerageFrozenDays).setUnfreezeTime(unfreezeTime)
|
||||||
.setSourceUserLevel(sourceUserLevel).setSourceUserId(sourceUserId);
|
.setSourceUserLevel(sourceUserLevel).setSourceUserId(sourceUserId);
|
||||||
}
|
}
|
||||||
|
@ -60,4 +66,17 @@ public interface BrokerageRecordConvert {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BrokerageRecordPageReqVO convert(AppBrokerageRecordPageReqVO pageReqVO, Long userId);
|
||||||
|
|
||||||
|
PageResult<AppBrokerageRecordRespVO> convertPage02(PageResult<BrokerageRecordDO> pageResult);
|
||||||
|
|
||||||
|
default PageResult<AppBrokerageUserRankByPriceRespVO> convertPage03(PageResult<AppBrokerageUserRankByPriceRespVO> pageResult, Map<Long, MemberUserRespDTO> userMap) {
|
||||||
|
for (AppBrokerageUserRankByPriceRespVO vo : pageResult.getList()) {
|
||||||
|
copyTo(userMap.get(vo.getId()), vo);
|
||||||
|
}
|
||||||
|
return pageResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copyTo(MemberUserRespDTO from, @MappingTarget AppBrokerageUserRankByPriceRespVO to);
|
||||||
}
|
}
|
|
@ -1,12 +1,14 @@
|
||||||
package cn.iocoder.yudao.module.trade.convert.brokerage.user;
|
package cn.iocoder.yudao.module.trade.convert.brokerage;
|
||||||
|
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserRespVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.BrokerageUserRespVO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByUserCountRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
|
import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.MappingTarget;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -55,4 +57,13 @@ public interface BrokerageUserConvert {
|
||||||
user -> target.setNickname(user.getNickname()).setAvatar(user.getAvatar()));
|
user -> target.setNickname(user.getNickname()).setAvatar(user.getAvatar()));
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default PageResult<AppBrokerageUserRankByUserCountRespVO> convertPage03(PageResult<AppBrokerageUserRankByUserCountRespVO> pageResult, Map<Long, MemberUserRespDTO> userMap) {
|
||||||
|
for (AppBrokerageUserRankByUserCountRespVO vo : pageResult.getList()) {
|
||||||
|
copyTo(userMap.get(vo.getId()), vo);
|
||||||
|
}
|
||||||
|
return pageResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copyTo(MemberUserRespDTO from, @MappingTarget AppBrokerageUserRankByUserCountRespVO to);
|
||||||
}
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package cn.iocoder.yudao.module.trade.convert.brokerage;
|
||||||
|
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 佣金提现 Convert
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface BrokerageWithdrawConvert {
|
||||||
|
|
||||||
|
BrokerageWithdrawConvert INSTANCE = Mappers.getMapper(BrokerageWithdrawConvert.class);
|
||||||
|
|
||||||
|
BrokerageWithdrawDO convert(AppBrokerageWithdrawCreateReqVO createReqVO, Long userId, Integer feePrice);
|
||||||
|
|
||||||
|
BrokerageWithdrawRespVO convert(BrokerageWithdrawDO bean);
|
||||||
|
|
||||||
|
List<BrokerageWithdrawRespVO> convertList(List<BrokerageWithdrawDO> list);
|
||||||
|
|
||||||
|
PageResult<BrokerageWithdrawRespVO> convertPage(PageResult<BrokerageWithdrawDO> page);
|
||||||
|
|
||||||
|
default PageResult<BrokerageWithdrawRespVO> convertPage(PageResult<BrokerageWithdrawDO> pageResult, Map<Long, MemberUserRespDTO> userMap) {
|
||||||
|
PageResult<BrokerageWithdrawRespVO> result = convertPage(pageResult);
|
||||||
|
for (BrokerageWithdrawRespVO vo : result.getList()) {
|
||||||
|
vo.setUserNickname(Optional.ofNullable(userMap.get(vo.getUserId())).map(MemberUserRespDTO::getNickname).orElse(null));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
PageResult<AppBrokerageWithdrawRespVO> convertPage02(PageResult<BrokerageWithdrawDO> pageResult);
|
||||||
|
|
||||||
|
default PageResult<AppBrokerageWithdrawRespVO> convertPage02(PageResult<BrokerageWithdrawDO> pageResult, Map<String, String> statusNameMap) {
|
||||||
|
PageResult<AppBrokerageWithdrawRespVO> result = convertPage02(pageResult);
|
||||||
|
for (AppBrokerageWithdrawRespVO vo : result.getList()) {
|
||||||
|
vo.setStatusName(MapUtil.getStr(statusNameMap, String.valueOf(vo.getStatus()), ""));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
BrokerageWithdrawPageReqVO convert(AppBrokerageWithdrawPageReqVO pageReqVO, Long userId);
|
||||||
|
}
|
|
@ -1,41 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.trade.convert.brokerage.withdraw;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawRejectReqVO;
|
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawRespVO;
|
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw.BrokerageWithdrawDO;
|
|
||||||
import org.mapstruct.Mapper;
|
|
||||||
import org.mapstruct.factory.Mappers;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 佣金提现 Convert
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface BrokerageWithdrawConvert {
|
|
||||||
|
|
||||||
BrokerageWithdrawConvert INSTANCE = Mappers.getMapper(BrokerageWithdrawConvert.class);
|
|
||||||
|
|
||||||
BrokerageWithdrawDO convert(BrokerageWithdrawRejectReqVO bean);
|
|
||||||
|
|
||||||
BrokerageWithdrawRespVO convert(BrokerageWithdrawDO bean);
|
|
||||||
|
|
||||||
List<BrokerageWithdrawRespVO> convertList(List<BrokerageWithdrawDO> list);
|
|
||||||
|
|
||||||
PageResult<BrokerageWithdrawRespVO> convertPage(PageResult<BrokerageWithdrawDO> page);
|
|
||||||
|
|
||||||
default PageResult<BrokerageWithdrawRespVO> convertPage(PageResult<BrokerageWithdrawDO> pageResult, Map<Long, MemberUserRespDTO> userMap) {
|
|
||||||
PageResult<BrokerageWithdrawRespVO> result = convertPage(pageResult);
|
|
||||||
for (BrokerageWithdrawRespVO vo : result.getList()) {
|
|
||||||
vo.setUserNickname(Optional.ofNullable(userMap.get(vo.getUserId())).map(MemberUserRespDTO::getNickname).orElse(null));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record;
|
package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user;
|
package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
|
@ -59,13 +59,4 @@ public class BrokerageUserDO extends BaseDO {
|
||||||
* 冻结佣金
|
* 冻结佣金
|
||||||
*/
|
*/
|
||||||
private Integer frozenPrice;
|
private Integer frozenPrice;
|
||||||
|
|
||||||
/**
|
|
||||||
* 等级
|
|
||||||
*/
|
|
||||||
private Integer level;
|
|
||||||
/**
|
|
||||||
* 路径
|
|
||||||
*/
|
|
||||||
private String path;
|
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw;
|
package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
|
||||||
|
@ -29,7 +29,7 @@ public class BrokerageWithdrawDO extends BaseDO {
|
||||||
* 编号
|
* 编号
|
||||||
*/
|
*/
|
||||||
@TableId
|
@TableId
|
||||||
private Integer id;
|
private Long id;
|
||||||
/**
|
/**
|
||||||
* 用户编号
|
* 用户编号
|
||||||
*
|
*
|
|
@ -36,7 +36,7 @@ public class TradeConfigDO extends BaseDO {
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
// ========== 配送相关 ==========
|
// ========== 配送相关 ==========
|
||||||
// TODO 芋艿:未配置
|
|
||||||
/**
|
/**
|
||||||
* 是否启用全场包邮
|
* 是否启用全场包邮
|
||||||
*/
|
*/
|
||||||
|
@ -81,6 +81,10 @@ public class TradeConfigDO extends BaseDO {
|
||||||
* 用户提现最低金额
|
* 用户提现最低金额
|
||||||
*/
|
*/
|
||||||
private Integer brokerageWithdrawMinPrice;
|
private Integer brokerageWithdrawMinPrice;
|
||||||
|
/**
|
||||||
|
* 用户提现手续费百分比
|
||||||
|
*/
|
||||||
|
private Integer brokerageWithdrawFeePercent;
|
||||||
/**
|
/**
|
||||||
* 提现银行
|
* 提现银行
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -266,10 +266,14 @@ public class TradeOrderDO extends BaseDO {
|
||||||
* 对应 taobao 的 trade.point_fee 字段
|
* 对应 taobao 的 trade.point_fee 字段
|
||||||
*/
|
*/
|
||||||
private Integer pointPrice;
|
private Integer pointPrice;
|
||||||
// /**
|
/**
|
||||||
// * 奖励的积分 TODO 疯狂:可以使用这个字段哈;
|
* 赠送的积分
|
||||||
// */
|
*/
|
||||||
// private Integer rewardPoint;
|
private Integer givePoint;
|
||||||
|
/**
|
||||||
|
* 退还的使用的积分
|
||||||
|
*/
|
||||||
|
private Integer refundPoint;
|
||||||
/**
|
/**
|
||||||
* VIP 减免金额,单位:分
|
* VIP 减免金额,单位:分
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -144,6 +144,14 @@ public class TradeOrderItemDO extends BaseDO {
|
||||||
* 对应 taobao 的 trade.point_fee 字段
|
* 对应 taobao 的 trade.point_fee 字段
|
||||||
*/
|
*/
|
||||||
private Integer pointPrice;
|
private Integer pointPrice;
|
||||||
|
/**
|
||||||
|
* 使用的积分
|
||||||
|
*/
|
||||||
|
private Integer usePoint;
|
||||||
|
/**
|
||||||
|
* 赠送的积分
|
||||||
|
*/
|
||||||
|
private Integer givePoint;
|
||||||
/**
|
/**
|
||||||
* VIP 减免金额,单位:分
|
* VIP 减免金额,单位:分
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package cn.iocoder.yudao.module.trade.dal.mysql.brokerage.record;
|
package cn.iocoder.yudao.module.trade.dal.mysql.brokerage;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordPageReqVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO;
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
|
import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import org.apache.ibatis.annotations.Select;
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
@ -57,4 +59,21 @@ public interface BrokerageRecordMapper extends BaseMapperX<BrokerageRecordDO> {
|
||||||
@Param("bizType") Integer bizType,
|
@Param("bizType") Integer bizType,
|
||||||
@Param("status") Integer status);
|
@Param("status") Integer status);
|
||||||
|
|
||||||
|
@Select("SELECT SUM(price) FROM trade_brokerage_record WHERE user_id = #{userId} AND biz_type = #{bizType} " +
|
||||||
|
"AND create_time BETWEEN #{beginTime} AND #{endTime}")
|
||||||
|
Integer selectSummaryPriceByUserIdAndBizTypeAndCreateTimeBetween(@Param("userId") Long userId,
|
||||||
|
@Param("bizType") Integer bizType,
|
||||||
|
@Param("beginTime") LocalDateTime beginTime,
|
||||||
|
@Param("endTime") LocalDateTime endTime);
|
||||||
|
|
||||||
|
@Select("SELECT user_id AS id, SUM(price) AS brokeragePrice FROM trade_brokerage_record " +
|
||||||
|
"WHERE biz_type = #{bizType} AND status = #{status} AND deleted = FALSE " +
|
||||||
|
"AND unfreeze_time BETWEEN #{beginTime} AND #{endTime} " +
|
||||||
|
"GROUP BY user_id " +
|
||||||
|
"ORDER BY brokeragePrice DESC")
|
||||||
|
IPage<AppBrokerageUserRankByPriceRespVO> selectSummaryPricePageGroupByUserId(IPage<?> page,
|
||||||
|
@Param("bizType") Integer bizType,
|
||||||
|
@Param("status") Integer status,
|
||||||
|
@Param("beginTime") LocalDateTime beginTime,
|
||||||
|
@Param("endTime") LocalDateTime endTime);
|
||||||
}
|
}
|
|
@ -1,14 +1,22 @@
|
||||||
package cn.iocoder.yudao.module.trade.dal.mysql.brokerage.user;
|
package cn.iocoder.yudao.module.trade.dal.mysql.brokerage;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.BrokerageUserPageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByUserCountRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,13 +27,12 @@ import java.util.List;
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
|
public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
|
||||||
|
|
||||||
default PageResult<BrokerageUserDO> selectPage(BrokerageUserPageReqVO reqVO, List<Integer> levels) {
|
default PageResult<BrokerageUserDO> selectPage(BrokerageUserPageReqVO reqVO, List<Long> bindUserIds) {
|
||||||
return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageUserDO>()
|
return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageUserDO>()
|
||||||
.eqIfPresent(BrokerageUserDO::getBrokerageEnabled, reqVO.getBrokerageEnabled())
|
.eqIfPresent(BrokerageUserDO::getBrokerageEnabled, reqVO.getBrokerageEnabled())
|
||||||
.betweenIfPresent(BrokerageUserDO::getCreateTime, reqVO.getCreateTime())
|
.betweenIfPresent(BrokerageUserDO::getCreateTime, reqVO.getCreateTime())
|
||||||
.betweenIfPresent(BrokerageUserDO::getBindUserTime, reqVO.getBindUserTime())
|
.betweenIfPresent(BrokerageUserDO::getBindUserTime, reqVO.getBindUserTime())
|
||||||
.findInSetIfPresent(BrokerageUserDO::getPath, reqVO.getBindUserId())
|
.inIfPresent(BrokerageUserDO::getBindUserId, bindUserIds)
|
||||||
.inIfPresent(BrokerageUserDO::getLevel, levels)
|
|
||||||
.orderByDesc(BrokerageUserDO::getId));
|
.orderByDesc(BrokerageUserDO::getId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +45,7 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
|
||||||
default void updatePriceIncr(Long id, Integer incrCount) {
|
default void updatePriceIncr(Long id, Integer incrCount) {
|
||||||
Assert.isTrue(incrCount > 0);
|
Assert.isTrue(incrCount > 0);
|
||||||
LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>()
|
LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>()
|
||||||
.setSql(" price = price + " + incrCount)
|
.setSql(" brokerage_price = brokerage_price + " + incrCount)
|
||||||
.eq(BrokerageUserDO::getId, id);
|
.eq(BrokerageUserDO::getId, id);
|
||||||
update(null, lambdaUpdateWrapper);
|
update(null, lambdaUpdateWrapper);
|
||||||
}
|
}
|
||||||
|
@ -49,13 +56,14 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
|
||||||
*
|
*
|
||||||
* @param id 用户编号
|
* @param id 用户编号
|
||||||
* @param incrCount 增加佣金(负数)
|
* @param incrCount 增加佣金(负数)
|
||||||
|
* @return 更新行数
|
||||||
*/
|
*/
|
||||||
default void updatePriceDecr(Long id, Integer incrCount) {
|
default int updatePriceDecr(Long id, Integer incrCount) {
|
||||||
Assert.isTrue(incrCount < 0);
|
Assert.isTrue(incrCount < 0);
|
||||||
LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>()
|
LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>()
|
||||||
.setSql(" price = price + " + incrCount) // 负数,所以使用 + 号
|
.setSql(" brokerage_price = brokerage_price + " + incrCount) // 负数,所以使用 + 号
|
||||||
.eq(BrokerageUserDO::getId, id);
|
.eq(BrokerageUserDO::getId, id);
|
||||||
update(null, lambdaUpdateWrapper);
|
return update(null, lambdaUpdateWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,7 +106,7 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
|
||||||
Assert.isTrue(incrCount < 0);
|
Assert.isTrue(incrCount < 0);
|
||||||
LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>()
|
LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>()
|
||||||
.setSql(" frozen_price = frozen_price + " + incrCount + // 负数,所以使用 + 号
|
.setSql(" frozen_price = frozen_price + " + incrCount + // 负数,所以使用 + 号
|
||||||
", price = price + " + -incrCount) // 负数,所以使用 - 号
|
", brokerage_price = brokerage_price + " + -incrCount) // 负数,所以使用 - 号
|
||||||
.eq(BrokerageUserDO::getId, id)
|
.eq(BrokerageUserDO::getId, id)
|
||||||
.ge(BrokerageUserDO::getFrozenPrice, -incrCount); // cas 逻辑
|
.ge(BrokerageUserDO::getFrozenPrice, -incrCount); // cas 逻辑
|
||||||
return update(null, lambdaUpdateWrapper);
|
return update(null, lambdaUpdateWrapper);
|
||||||
|
@ -107,8 +115,7 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
|
||||||
default void updateBindUserIdAndBindUserTimeToNull(Long id) {
|
default void updateBindUserIdAndBindUserTimeToNull(Long id) {
|
||||||
update(null, new LambdaUpdateWrapper<BrokerageUserDO>()
|
update(null, new LambdaUpdateWrapper<BrokerageUserDO>()
|
||||||
.eq(BrokerageUserDO::getId, id)
|
.eq(BrokerageUserDO::getId, id)
|
||||||
.set(BrokerageUserDO::getBindUserId, null).set(BrokerageUserDO::getBindUserTime, null)
|
.set(BrokerageUserDO::getBindUserId, null).set(BrokerageUserDO::getBindUserTime, null));
|
||||||
.set(BrokerageUserDO::getLevel, 1).set(BrokerageUserDO::getPath, ""));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void updateEnabledFalseAndBrokerageTimeToNull(Long id) {
|
default void updateEnabledFalseAndBrokerageTimeToNull(Long id) {
|
||||||
|
@ -117,10 +124,25 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
|
||||||
.set(BrokerageUserDO::getBrokerageEnabled, false).set(BrokerageUserDO::getBrokerageTime, null));
|
.set(BrokerageUserDO::getBrokerageEnabled, false).set(BrokerageUserDO::getBrokerageTime, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
default Long selectCountByBindUserIdAndLevelIn(Long bindUserId, List<Integer> levels) {
|
default Long selectCountByBindUserIdIn(List<Long> bindUserIds) {
|
||||||
return selectCount(new LambdaQueryWrapperX<BrokerageUserDO>()
|
return selectCount(new LambdaQueryWrapperX<BrokerageUserDO>()
|
||||||
.findInSetIfPresent(BrokerageUserDO::getPath, bindUserId)
|
.inIfPresent(BrokerageUserDO::getBindUserId, bindUserIds));
|
||||||
.inIfPresent(BrokerageUserDO::getLevel, levels));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Select("SELECT bind_user_id AS id, COUNT(1) AS brokerageUserCount FROM trade_brokerage_user " +
|
||||||
|
"WHERE bind_user_id IS NOT NULL AND deleted = FALSE " +
|
||||||
|
"AND bind_user_time BETWEEN #{beginTime} AND #{endTime} " +
|
||||||
|
"GROUP BY bind_user_id " +
|
||||||
|
"ORDER BY brokerageUserCount DESC")
|
||||||
|
IPage<AppBrokerageUserRankByUserCountRespVO> selectCountPageGroupByBindUserId(Page<?> page,
|
||||||
|
@Param("beginTime") LocalDateTime beginTime,
|
||||||
|
@Param("endTime") LocalDateTime endTime);
|
||||||
|
|
||||||
|
IPage<AppBrokerageUserChildSummaryRespVO> selectSummaryPageByUserId(Page<?> page,
|
||||||
|
@Param("param") AppBrokerageUserChildSummaryPageReqVO param,
|
||||||
|
@Param("userId") Long userId);
|
||||||
|
|
||||||
|
default List<BrokerageUserDO> selectListByBindUserId(Long bindUserId) {
|
||||||
|
return selectList(BrokerageUserDO::getBindUserId, bindUserId);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,12 +1,14 @@
|
||||||
package cn.iocoder.yudao.module.trade.dal.mysql.brokerage.withdraw;
|
package cn.iocoder.yudao.module.trade.dal.mysql.brokerage;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawPageReqVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw.BrokerageWithdrawDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 佣金提现 Mapper
|
* 佣金提现 Mapper
|
||||||
|
@ -34,4 +36,6 @@ public interface BrokerageWithdrawMapper extends BaseMapperX<BrokerageWithdrawDO
|
||||||
.eq(BrokerageWithdrawDO::getStatus, status));
|
.eq(BrokerageWithdrawDO::getStatus, status));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Select("SELECT SUM(price) FROM trade_brokerage_withdraw WHERE user_id = #{userId} AND status = #{status}")
|
||||||
|
Integer selectSummaryPriceByUserIdAndStatus(@Param("userId") Long userId, @Param("status") Integer status);
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.trade.job.brokerage;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
|
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
|
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService;
|
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.brokerage.record;
|
package cn.iocoder.yudao.module.trade.service.brokerage;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordPageReqVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO;
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO;
|
||||||
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO;
|
import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
|
import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,6 +45,17 @@ public interface BrokerageRecordService {
|
||||||
*/
|
*/
|
||||||
void addBrokerage(Long userId, BrokerageRecordBizTypeEnum bizType, @Valid List<BrokerageAddReqBO> list);
|
void addBrokerage(Long userId, BrokerageRecordBizTypeEnum bizType, @Valid List<BrokerageAddReqBO> list);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 增加佣金
|
||||||
|
*
|
||||||
|
* @param userId 会员编号
|
||||||
|
* @param bizType 业务类型
|
||||||
|
* @param bizId 业务编号
|
||||||
|
* @param brokeragePrice 佣金
|
||||||
|
* @param title 标题
|
||||||
|
*/
|
||||||
|
void addBrokerage(Long userId, BrokerageRecordBizTypeEnum bizType, String bizId, Integer brokeragePrice, String title);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 取消佣金:将佣金记录,状态修改为已失效
|
* 取消佣金:将佣金记录,状态修改为已失效
|
||||||
*
|
*
|
||||||
|
@ -67,4 +81,31 @@ public interface BrokerageRecordService {
|
||||||
* @return 用户佣金汇总
|
* @return 用户佣金汇总
|
||||||
*/
|
*/
|
||||||
UserBrokerageSummaryBO getUserBrokerageSummaryByUserId(Long userId, Integer bizType, Integer status);
|
UserBrokerageSummaryBO getUserBrokerageSummaryByUserId(Long userId, Integer bizType, Integer status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得用户佣金合计
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param bizType 业务类型
|
||||||
|
* @param beginTime 开始时间
|
||||||
|
* @param endTime 截止时间
|
||||||
|
* @return 用户佣金合计
|
||||||
|
*/
|
||||||
|
Integer getSummaryPriceByUserId(Long userId, Integer bizType, LocalDateTime beginTime, LocalDateTime endTime);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得用户佣金排行分页列表(基于佣金总数)
|
||||||
|
* @param pageReqVO 分页查询
|
||||||
|
* @return 排行榜分页
|
||||||
|
*/
|
||||||
|
PageResult<AppBrokerageUserRankByPriceRespVO> getBrokerageUserChildSummaryPageByPrice(AppBrokerageUserRankPageReqVO pageReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户的排名(基于佣金总数)
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param times 时间范围
|
||||||
|
* @return 用户的排名
|
||||||
|
*/
|
||||||
|
Integer getUserRankByPrice(Long userId, LocalDateTime[] times);
|
||||||
}
|
}
|
|
@ -1,24 +1,29 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.brokerage.record;
|
package cn.iocoder.yudao.module.trade.service.brokerage;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.math.Money;
|
||||||
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.BooleanUtil;
|
import cn.hutool.core.util.BooleanUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
|
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordPageReqVO;
|
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
|
||||||
import cn.iocoder.yudao.module.trade.convert.brokerage.record.BrokerageRecordConvert;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO;
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByPriceRespVO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageRecordConvert;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.record.BrokerageRecordMapper;
|
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageRecordMapper;
|
||||||
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
|
||||||
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO;
|
import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
|
import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService;
|
|
||||||
import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
|
import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
@ -29,6 +34,10 @@ import java.time.LocalDateTime;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 佣金记录 Service 实现类
|
* 佣金记录 Service 实现类
|
||||||
|
@ -218,6 +227,54 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService {
|
||||||
return summaryBO != null ? summaryBO : new UserBrokerageSummaryBO(0, 0);
|
return summaryBO != null ? summaryBO : new UserBrokerageSummaryBO(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getSummaryPriceByUserId(Long userId, Integer bizType, LocalDateTime beginTime, LocalDateTime endTime) {
|
||||||
|
return brokerageRecordMapper.selectSummaryPriceByUserIdAndBizTypeAndCreateTimeBetween(userId, bizType, beginTime, endTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<AppBrokerageUserRankByPriceRespVO> getBrokerageUserChildSummaryPageByPrice(AppBrokerageUserRankPageReqVO pageReqVO) {
|
||||||
|
IPage<AppBrokerageUserRankByPriceRespVO> pageResult = brokerageRecordMapper.selectSummaryPricePageGroupByUserId(MyBatisUtils.buildPage(pageReqVO),
|
||||||
|
BrokerageRecordBizTypeEnum.ORDER.getType(), BrokerageRecordStatusEnum.SETTLEMENT.getStatus(),
|
||||||
|
ArrayUtil.get(pageReqVO.getTimes(), 0), ArrayUtil.get(pageReqVO.getTimes(), 1));
|
||||||
|
return new PageResult<>(pageResult.getRecords(), pageResult.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getUserRankByPrice(Long userId, LocalDateTime[] times) {
|
||||||
|
AppBrokerageUserRankPageReqVO pageParam = new AppBrokerageUserRankPageReqVO().setTimes(times);
|
||||||
|
// 取前100名
|
||||||
|
pageParam.setPageSize(100);
|
||||||
|
PageResult<AppBrokerageUserRankByPriceRespVO> pageResult = getBrokerageUserChildSummaryPageByPrice(pageParam);
|
||||||
|
// 获得索引
|
||||||
|
int index = CollUtil.indexOf(pageResult.getList(), user -> Objects.equals(userId, user.getId()));
|
||||||
|
// 获得排名
|
||||||
|
return index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void addBrokerage(Long userId, BrokerageRecordBizTypeEnum bizType, String bizId, Integer brokeragePrice, String title) {
|
||||||
|
// 校验佣金余额
|
||||||
|
BrokerageUserDO user = brokerageUserService.getBrokerageUser(userId);
|
||||||
|
int balance = Optional.of(user)
|
||||||
|
.map(BrokerageUserDO::getBrokeragePrice).orElse(0);
|
||||||
|
if (balance + brokeragePrice < 0) {
|
||||||
|
throw exception(BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH, new Money(0, balance));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 扣减佣金余额
|
||||||
|
boolean success = brokerageUserService.updateUserPrice(userId, brokeragePrice);
|
||||||
|
if (!success) {
|
||||||
|
throw exception(BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH, new Money(0, balance));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增记录
|
||||||
|
BrokerageRecordDO record = BrokerageRecordConvert.INSTANCE.convert(user, bizType, bizId, 0, brokeragePrice,
|
||||||
|
null, title, null, null);
|
||||||
|
brokerageRecordMapper.insert(record);
|
||||||
|
}
|
||||||
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public boolean unfreezeRecord(BrokerageRecordDO record) {
|
public boolean unfreezeRecord(BrokerageRecordDO record) {
|
||||||
// 更新记录状态
|
// 更新记录状态
|
|
@ -1,9 +1,13 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.brokerage.user;
|
package cn.iocoder.yudao.module.trade.service.brokerage;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.BrokerageUserPageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByUserCountRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
|
||||||
|
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
@ -70,8 +74,9 @@ public interface BrokerageUserService {
|
||||||
*
|
*
|
||||||
* @param id 用户编号
|
* @param id 用户编号
|
||||||
* @param price 用户可用佣金
|
* @param price 用户可用佣金
|
||||||
|
* @return 更新结果
|
||||||
*/
|
*/
|
||||||
void updateUserPrice(Long id, Integer price);
|
boolean updateUserPrice(Long id, Integer price);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新用户冻结佣金
|
* 更新用户冻结佣金
|
||||||
|
@ -129,4 +134,21 @@ public interface BrokerageUserService {
|
||||||
* @return 是否有分销资格
|
* @return 是否有分销资格
|
||||||
*/
|
*/
|
||||||
Boolean getUserBrokerageEnabled(Long userId);
|
Boolean getUserBrokerageEnabled(Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得推广人排行
|
||||||
|
*
|
||||||
|
* @param pageReqVO 分页查询
|
||||||
|
* @return 推广人排行
|
||||||
|
*/
|
||||||
|
PageResult<AppBrokerageUserRankByUserCountRespVO> getBrokerageUserRankPageByUserCount(AppBrokerageUserRankPageReqVO pageReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得下级分销统计分页
|
||||||
|
*
|
||||||
|
* @param pageReqVO 分页查询
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @return 下级分销统计分页
|
||||||
|
*/
|
||||||
|
PageResult<AppBrokerageUserChildSummaryRespVO> getBrokerageUserChildSummaryPage(AppBrokerageUserChildSummaryPageReqVO pageReqVO, Long userId);
|
||||||
}
|
}
|
|
@ -1,26 +1,35 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.brokerage.user;
|
package cn.iocoder.yudao.module.trade.service.brokerage;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.BooleanUtil;
|
import cn.hutool.core.util.BooleanUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO;
|
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.BrokerageUserPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankByUserCountRespVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserRankPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.user.BrokerageUserMapper;
|
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageUserMapper;
|
||||||
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageBindModeEnum;
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageBindModeEnum;
|
||||||
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageEnabledConditionEnum;
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageEnabledConditionEnum;
|
||||||
import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
|
import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||||
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
|
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,8 +59,8 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageResult<BrokerageUserDO> getBrokerageUserPage(BrokerageUserPageReqVO pageReqVO) {
|
public PageResult<BrokerageUserDO> getBrokerageUserPage(BrokerageUserPageReqVO pageReqVO) {
|
||||||
List<Integer> levels = buildUserQueryLevels(pageReqVO.getBindUserId(), pageReqVO.getLevel());
|
List<Long> bindUserIds = buildBindUserIdsByLevel(pageReqVO.getBindUserId(), pageReqVO.getLevel());
|
||||||
return brokerageUserMapper.selectPage(pageReqVO, levels);
|
return brokerageUserMapper.selectPage(pageReqVO, bindUserIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -59,6 +68,11 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
|
||||||
// 校验存在
|
// 校验存在
|
||||||
BrokerageUserDO brokerageUser = validateBrokerageUserExists(id);
|
BrokerageUserDO brokerageUser = validateBrokerageUserExists(id);
|
||||||
|
|
||||||
|
// 绑定关系未发生变化
|
||||||
|
if (Objects.equals(brokerageUser.getBindUserId(), bindUserId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 情况一:清除推广员
|
// 情况一:清除推广员
|
||||||
if (bindUserId == null) {
|
if (bindUserId == null) {
|
||||||
// 清除推广员
|
// 清除推广员
|
||||||
|
@ -66,12 +80,6 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 绑定关系未发生变化
|
|
||||||
// TODO @疯狂:这个放到“情况一”之前,貌似也没关系?
|
|
||||||
if (Objects.equals(brokerageUser.getBindUserId(), bindUserId)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 情况二:修改推广员
|
// 情况二:修改推广员
|
||||||
validateCanBindUser(brokerageUser, bindUserId);
|
validateCanBindUser(brokerageUser, bindUserId);
|
||||||
brokerageUserMapper.updateById(fillBindUserData(bindUserId, new BrokerageUserDO().setId(id)));
|
brokerageUserMapper.updateById(fillBindUserData(bindUserId, new BrokerageUserDO().setId(id)));
|
||||||
|
@ -110,12 +118,13 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateUserPrice(Long id, Integer price) {
|
public boolean updateUserPrice(Long id, Integer price) {
|
||||||
if (price > 0) {
|
if (price > 0) {
|
||||||
brokerageUserMapper.updatePriceIncr(id, price);
|
brokerageUserMapper.updatePriceIncr(id, price);
|
||||||
} else if (price < 0) {
|
} else if (price < 0) {
|
||||||
brokerageUserMapper.updatePriceDecr(id, price);
|
return brokerageUserMapper.updatePriceDecr(id, price) > 0;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -138,11 +147,11 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long getBrokerageUserCountByBindUserId(Long bindUserId, Integer level) {
|
public Long getBrokerageUserCountByBindUserId(Long bindUserId, Integer level) {
|
||||||
List<Integer> levels = buildUserQueryLevels(bindUserId, level);
|
List<Long> bindUserIds = buildBindUserIdsByLevel(bindUserId, level);
|
||||||
if (CollUtil.isEmpty(levels)) {
|
if (CollUtil.isEmpty(bindUserIds)) {
|
||||||
return 0L;
|
return 0L;
|
||||||
}
|
}
|
||||||
return brokerageUserMapper.selectCountByBindUserIdAndLevelIn(bindUserId, levels);
|
return brokerageUserMapper.selectCountByBindUserIdIn(bindUserIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -177,20 +186,7 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private BrokerageUserDO fillBindUserData(Long bindUserId, BrokerageUserDO brokerageUser) {
|
private BrokerageUserDO fillBindUserData(Long bindUserId, BrokerageUserDO brokerageUser) {
|
||||||
BrokerageUserDO bindUser = getBrokerageUser(bindUserId);
|
return brokerageUser.setBindUserId(bindUserId).setBindUserTime(LocalDateTime.now());
|
||||||
|
|
||||||
Integer bindUserLevel = 0;
|
|
||||||
String bindUserPath = "";
|
|
||||||
if (bindUser != null) {
|
|
||||||
bindUserLevel = ObjectUtil.defaultIfNull(bindUser.getLevel(), 0);
|
|
||||||
bindUserPath = bindUser.getPath();
|
|
||||||
}
|
|
||||||
|
|
||||||
String path = StrUtil.isEmpty(bindUserPath)
|
|
||||||
? String.valueOf(bindUserId)
|
|
||||||
: String.format("%s,%s", bindUserPath, bindUserId);
|
|
||||||
return brokerageUser.setBindUserId(bindUserId).setBindUserTime(LocalDateTime.now())
|
|
||||||
.setLevel(bindUserLevel + 1).setPath(path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -207,6 +203,19 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
|
||||||
.orElse(false);
|
.orElse(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<AppBrokerageUserRankByUserCountRespVO> getBrokerageUserRankPageByUserCount(AppBrokerageUserRankPageReqVO pageReqVO) {
|
||||||
|
IPage<AppBrokerageUserRankByUserCountRespVO> pageResult = brokerageUserMapper.selectCountPageGroupByBindUserId(MyBatisUtils.buildPage(pageReqVO),
|
||||||
|
ArrayUtil.get(pageReqVO.getTimes(), 0), ArrayUtil.get(pageReqVO.getTimes(), 1));
|
||||||
|
return new PageResult<>(pageResult.getRecords(), pageResult.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<AppBrokerageUserChildSummaryRespVO> getBrokerageUserChildSummaryPage(AppBrokerageUserChildSummaryPageReqVO pageReqVO, Long userId) {
|
||||||
|
IPage<AppBrokerageUserChildSummaryRespVO> pageResult = brokerageUserMapper.selectSummaryPageByUserId(MyBatisUtils.buildPage(pageReqVO), pageReqVO, userId);
|
||||||
|
return new PageResult<>(pageResult.getRecords(), pageResult.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isUserCanBind(BrokerageUserDO user, Boolean isNewUser) {
|
private boolean isUserCanBind(BrokerageUserDO user, Boolean isNewUser) {
|
||||||
// 校验分销功能是否启用
|
// 校验分销功能是否启用
|
||||||
TradeConfigDO tradeConfig = tradeConfigService.getTradeConfig();
|
TradeConfigDO tradeConfig = tradeConfigService.getTradeConfig();
|
||||||
|
@ -246,28 +255,25 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 下级不能绑定自己的上级
|
// 下级不能绑定自己的上级
|
||||||
if (StrUtil.split(bindUser.getPath(), ",").contains(String.valueOf(user.getId()))) {
|
for (int i = 0; i <= Short.MAX_VALUE; i++) {
|
||||||
throw exception(BROKERAGE_BIND_LOOP);
|
if (Objects.equals(bindUser.getBindUserId(), user.getId())) {
|
||||||
|
throw exception(BROKERAGE_BIND_LOOP);
|
||||||
|
}
|
||||||
|
bindUser = getBrokerageUser(bindUser.getBindUserId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO @芋艿:这个层级,要微信讨论下;
|
private List<Long> buildBindUserIdsByLevel(Long bindUserId, Integer level) {
|
||||||
private List<Integer> buildUserQueryLevels(Long bindUserId, Integer level) {
|
List<Long> bindUserIds = CollUtil.newArrayList();
|
||||||
List<Integer> levels = new ArrayList<>(2);
|
if (level == null || level == 1) {
|
||||||
|
bindUserIds.add(bindUserId);
|
||||||
BrokerageUserDO bindUser = getBrokerageUser(bindUserId);
|
}
|
||||||
if (bindUser == null) {
|
if (level == null || level == 2) {
|
||||||
return levels;
|
List<Long> firstUserIds = convertList(brokerageUserMapper.selectListByBindUserId(bindUserId), BrokerageUserDO::getId);
|
||||||
|
bindUserIds.addAll(firstUserIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (level == null) {
|
return bindUserIds;
|
||||||
// 默认查两层
|
|
||||||
levels.add(bindUser.getLevel() + 1);
|
|
||||||
levels.add(bindUser.getLevel() + 2);
|
|
||||||
} else {
|
|
||||||
levels.add(bindUser.getLevel() + level);
|
|
||||||
}
|
|
||||||
return levels;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.brokerage.withdraw;
|
package cn.iocoder.yudao.module.trade.service.brokerage;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawPageReqVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw.BrokerageWithdrawDO;
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO;
|
||||||
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,7 +14,7 @@ import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum
|
||||||
public interface BrokerageWithdrawService {
|
public interface BrokerageWithdrawService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 审核佣金提现
|
* 【管理员】审核佣金提现
|
||||||
*
|
*
|
||||||
* @param id 佣金编号
|
* @param id 佣金编号
|
||||||
* @param status 审核状态
|
* @param status 审核状态
|
||||||
|
@ -37,4 +38,23 @@ public interface BrokerageWithdrawService {
|
||||||
* @return 佣金提现分页
|
* @return 佣金提现分页
|
||||||
*/
|
*/
|
||||||
PageResult<BrokerageWithdrawDO> getBrokerageWithdrawPage(BrokerageWithdrawPageReqVO pageReqVO);
|
PageResult<BrokerageWithdrawDO> getBrokerageWithdrawPage(BrokerageWithdrawPageReqVO pageReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 【会员】创建佣金提现
|
||||||
|
*
|
||||||
|
* @param createReqVO 创建信息
|
||||||
|
* @param userId 会员用户编号
|
||||||
|
* @return 佣金提现编号
|
||||||
|
*/
|
||||||
|
Long createBrokerageWithdraw(AppBrokerageWithdrawCreateReqVO createReqVO, Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得用户已提现金额
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param status 状态
|
||||||
|
* @return 用户已提现金额
|
||||||
|
*/
|
||||||
|
Integer getSummaryPriceByUserIdAndStatus(Long userId, Integer status);
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,177 @@
|
||||||
|
package cn.iocoder.yudao.module.trade.service.brokerage;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.hutool.core.math.Money;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
|
||||||
|
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
|
||||||
|
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.trade.convert.brokerage.BrokerageWithdrawConvert;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageWithdrawMapper;
|
||||||
|
import cn.iocoder.yudao.module.trade.enums.MessageTemplateConstants;
|
||||||
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
|
||||||
|
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.validation.Validator;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 佣金提现 Service 实现类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private BrokerageWithdrawMapper brokerageWithdrawMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private BrokerageRecordService brokerageRecordService;
|
||||||
|
@Resource
|
||||||
|
private TradeConfigService tradeConfigService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private NotifyMessageSendApi notifyMessageSendApi;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private Validator validator;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void auditBrokerageWithdraw(Integer id, BrokerageWithdrawStatusEnum status, String auditReason) {
|
||||||
|
// 1.1 校验存在
|
||||||
|
BrokerageWithdrawDO withdraw = validateBrokerageWithdrawExists(id);
|
||||||
|
// 1.2 校验状态为审核中
|
||||||
|
if (ObjectUtil.notEqual(BrokerageWithdrawStatusEnum.AUDITING.getStatus(), withdraw.getStatus())) {
|
||||||
|
throw exception(BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 更新
|
||||||
|
BrokerageWithdrawDO updateObj = new BrokerageWithdrawDO()
|
||||||
|
.setStatus(status.getStatus())
|
||||||
|
.setAuditReason(auditReason)
|
||||||
|
.setAuditTime(LocalDateTime.now());
|
||||||
|
int rows = brokerageWithdrawMapper.updateByIdAndStatus(id, BrokerageWithdrawStatusEnum.AUDITING.getStatus(), updateObj);
|
||||||
|
if (rows == 0) {
|
||||||
|
throw exception(BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING);
|
||||||
|
}
|
||||||
|
|
||||||
|
String templateCode = MessageTemplateConstants.BROKERAGE_WITHDRAW_AUDIT_APPROVE;
|
||||||
|
if (BrokerageWithdrawStatusEnum.AUDIT_SUCCESS.equals(status)) {
|
||||||
|
// 3.1 通过时佣金转余额
|
||||||
|
if (BrokerageWithdrawTypeEnum.WALLET.getType().equals(withdraw.getType())) {
|
||||||
|
// todo
|
||||||
|
}
|
||||||
|
} else if (BrokerageWithdrawStatusEnum.AUDIT_FAIL.equals(status)) {
|
||||||
|
templateCode = MessageTemplateConstants.BROKERAGE_WITHDRAW_AUDIT_REJECT;
|
||||||
|
|
||||||
|
// 3.2 驳回时需要退还用户佣金
|
||||||
|
brokerageRecordService.addBrokerage(withdraw.getUserId(), BrokerageRecordBizTypeEnum.WITHDRAW_REJECT,
|
||||||
|
String.valueOf(withdraw.getId()), withdraw.getPrice(), BrokerageRecordBizTypeEnum.WITHDRAW_REJECT.getTitle());
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("不支持的提现状态");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 通知用户
|
||||||
|
Map<String, Object> templateParams = MapUtil.<String, Object>builder()
|
||||||
|
.put("createTime", LocalDateTimeUtil.formatNormal(withdraw.getCreateTime()))
|
||||||
|
.put("price", new Money(0, withdraw.getPrice()).toString())
|
||||||
|
.put("reason", withdraw.getAuditReason())
|
||||||
|
.build();
|
||||||
|
NotifySendSingleToUserReqDTO reqDTO = new NotifySendSingleToUserReqDTO()
|
||||||
|
.setUserId(withdraw.getUserId())
|
||||||
|
.setTemplateCode(templateCode).setTemplateParams(templateParams);
|
||||||
|
notifyMessageSendApi.sendSingleMessageToMember(reqDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BrokerageWithdrawDO validateBrokerageWithdrawExists(Integer id) {
|
||||||
|
BrokerageWithdrawDO withdraw = brokerageWithdrawMapper.selectById(id);
|
||||||
|
if (withdraw == null) {
|
||||||
|
throw exception(BROKERAGE_WITHDRAW_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
return withdraw;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BrokerageWithdrawDO getBrokerageWithdraw(Integer id) {
|
||||||
|
return brokerageWithdrawMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<BrokerageWithdrawDO> getBrokerageWithdrawPage(BrokerageWithdrawPageReqVO pageReqVO) {
|
||||||
|
return brokerageWithdrawMapper.selectPage(pageReqVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Long createBrokerageWithdraw(AppBrokerageWithdrawCreateReqVO createReqVO, Long userId) {
|
||||||
|
// 校验提现金额
|
||||||
|
TradeConfigDO tradeConfig = validateWithdrawPrice(createReqVO.getPrice());
|
||||||
|
// 校验提现参数
|
||||||
|
createReqVO.validate(validator);
|
||||||
|
|
||||||
|
// 计算手续费
|
||||||
|
Integer feePrice = calculateFeePrice(createReqVO.getPrice(), tradeConfig.getBrokerageWithdrawFeePercent());
|
||||||
|
// 创建佣金提现记录
|
||||||
|
BrokerageWithdrawDO withdraw = BrokerageWithdrawConvert.INSTANCE.convert(createReqVO, userId, feePrice);
|
||||||
|
brokerageWithdrawMapper.insert(withdraw);
|
||||||
|
|
||||||
|
// 创建用户佣金记录
|
||||||
|
brokerageRecordService.addBrokerage(userId, BrokerageRecordBizTypeEnum.WITHDRAW, String.valueOf(withdraw.getId()),
|
||||||
|
-createReqVO.getPrice(), BrokerageRecordBizTypeEnum.WITHDRAW.getTitle());
|
||||||
|
|
||||||
|
return withdraw.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer getSummaryPriceByUserIdAndStatus(Long userId, Integer status) {
|
||||||
|
return brokerageWithdrawMapper.selectSummaryPriceByUserIdAndStatus(userId, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算提现手续费
|
||||||
|
*
|
||||||
|
* @param withdrawPrice 提现金额
|
||||||
|
* @param percent 手续费百分比
|
||||||
|
* @return 提现手续费
|
||||||
|
*/
|
||||||
|
Integer calculateFeePrice(Integer withdrawPrice, Integer percent) {
|
||||||
|
Integer feePrice = 0;
|
||||||
|
if (percent != null && percent > 0) {
|
||||||
|
feePrice = MoneyUtils.calculateRatePrice(withdrawPrice, Double.valueOf(percent));
|
||||||
|
}
|
||||||
|
return feePrice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验提现金额要求
|
||||||
|
*
|
||||||
|
* @param withdrawPrice 提现金额
|
||||||
|
* @return 分销配置
|
||||||
|
*/
|
||||||
|
TradeConfigDO validateWithdrawPrice(Integer withdrawPrice) {
|
||||||
|
TradeConfigDO tradeConfig = tradeConfigService.getTradeConfig();
|
||||||
|
if (tradeConfig.getBrokerageWithdrawMinPrice() != null && withdrawPrice < tradeConfig.getBrokerageWithdrawMinPrice()) {
|
||||||
|
throw exception(BROKERAGE_WITHDRAW_MIN_PRICE, new Money(0, tradeConfig.getBrokerageWithdrawMinPrice()));
|
||||||
|
}
|
||||||
|
return tradeConfig;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,104 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.brokerage.withdraw;
|
|
||||||
|
|
||||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
|
||||||
import cn.hutool.core.map.MapUtil;
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
|
|
||||||
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
|
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw.BrokerageWithdrawDO;
|
|
||||||
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.withdraw.BrokerageWithdrawMapper;
|
|
||||||
import cn.iocoder.yudao.module.trade.enums.MessageTemplateConstants;
|
|
||||||
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
|
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
||||||
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.BROKERAGE_WITHDRAW_NOT_EXISTS;
|
|
||||||
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 佣金提现 Service 实现类
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@Validated
|
|
||||||
public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private BrokerageWithdrawMapper brokerageWithdrawMapper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private BrokerageRecordService brokerageRecordService;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private NotifyMessageSendApi notifyMessageSendApi;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void auditBrokerageWithdraw(Integer id, BrokerageWithdrawStatusEnum status, String auditReason) {
|
|
||||||
// 1.1 校验存在
|
|
||||||
BrokerageWithdrawDO withdraw = validateBrokerageWithdrawExists(id);
|
|
||||||
// 1.2 校验状态为审核中
|
|
||||||
if (ObjectUtil.notEqual(BrokerageWithdrawStatusEnum.AUDITING.getStatus(), withdraw.getStatus())) {
|
|
||||||
throw exception(BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 更新
|
|
||||||
BrokerageWithdrawDO updateObj = new BrokerageWithdrawDO()
|
|
||||||
.setStatus(status.getStatus())
|
|
||||||
.setAuditReason(auditReason)
|
|
||||||
.setAuditTime(LocalDateTime.now());
|
|
||||||
int rows = brokerageWithdrawMapper.updateByIdAndStatus(id, BrokerageWithdrawStatusEnum.AUDITING.getStatus(), updateObj);
|
|
||||||
if (rows == 0) {
|
|
||||||
throw exception(BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 驳回时需要退还用户佣金
|
|
||||||
String templateCode = MessageTemplateConstants.BROKERAGE_WITHDRAW_AUDIT_APPROVE;
|
|
||||||
if (BrokerageWithdrawStatusEnum.AUDIT_FAIL.equals(status)) {
|
|
||||||
templateCode = MessageTemplateConstants.BROKERAGE_WITHDRAW_AUDIT_REJECT;
|
|
||||||
|
|
||||||
// todo @owen
|
|
||||||
// brokerageRecordService.addBrokerage(withdraw.getUserId(), BrokerageRecordBizTypeEnum.WITHDRAW, withdraw.getPrice(), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 通知用户
|
|
||||||
Map<String, Object> templateParams = MapUtil.<String, Object>builder()
|
|
||||||
.put("createTime", LocalDateTimeUtil.formatNormal(withdraw.getCreateTime()))
|
|
||||||
.put("price", String.format("%.2f", withdraw.getPrice() / 100d))
|
|
||||||
.put("reason", withdraw.getAuditReason())
|
|
||||||
.build();
|
|
||||||
NotifySendSingleToUserReqDTO reqDTO = new NotifySendSingleToUserReqDTO()
|
|
||||||
.setUserId(withdraw.getUserId())
|
|
||||||
.setTemplateCode(templateCode).setTemplateParams(templateParams);
|
|
||||||
notifyMessageSendApi.sendSingleMessageToMember(reqDTO);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BrokerageWithdrawDO validateBrokerageWithdrawExists(Integer id) {
|
|
||||||
BrokerageWithdrawDO withdraw = brokerageWithdrawMapper.selectById(id);
|
|
||||||
if (withdraw == null) {
|
|
||||||
throw exception(BROKERAGE_WITHDRAW_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
return withdraw;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BrokerageWithdrawDO getBrokerageWithdraw(Integer id) {
|
|
||||||
return brokerageWithdrawMapper.selectById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PageResult<BrokerageWithdrawDO> getBrokerageWithdrawPage(BrokerageWithdrawPageReqVO pageReqVO) {
|
|
||||||
return brokerageWithdrawMapper.selectPage(pageReqVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -24,6 +24,7 @@ import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
|
||||||
import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
|
import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
|
||||||
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
|
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
||||||
|
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
|
||||||
import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi;
|
import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi;
|
||||||
import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
|
import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
|
||||||
import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
|
import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
|
||||||
|
@ -49,8 +50,8 @@ import cn.iocoder.yudao.module.trade.enums.order.*;
|
||||||
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
|
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
|
||||||
import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog;
|
import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog;
|
||||||
import cn.iocoder.yudao.module.trade.framework.order.core.utils.TradeOrderLogUtils;
|
import cn.iocoder.yudao.module.trade.framework.order.core.utils.TradeOrderLogUtils;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordService;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO;
|
import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService;
|
|
||||||
import cn.iocoder.yudao.module.trade.service.cart.CartService;
|
import cn.iocoder.yudao.module.trade.service.cart.CartService;
|
||||||
import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
|
import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
|
||||||
import cn.iocoder.yudao.module.trade.service.message.TradeMessageService;
|
import cn.iocoder.yudao.module.trade.service.message.TradeMessageService;
|
||||||
|
@ -106,6 +107,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
@Resource
|
@Resource
|
||||||
private TradeMessageService tradeMessageService;
|
private TradeMessageService tradeMessageService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ProductSpuApi productSpuApi;
|
||||||
@Resource
|
@Resource
|
||||||
private ProductSkuApi productSkuApi;
|
private ProductSkuApi productSkuApi;
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -241,8 +244,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
/**
|
/**
|
||||||
* 订单创建前,执行前置逻辑
|
* 订单创建前,执行前置逻辑
|
||||||
*
|
*
|
||||||
* @param userId 用户编号
|
* @param userId 用户编号
|
||||||
* @param createReqVO 创建订单请求
|
* @param createReqVO 创建订单请求
|
||||||
* @param calculateRespBO 订单价格计算结果
|
* @param calculateRespBO 订单价格计算结果
|
||||||
*/
|
*/
|
||||||
private void beforeCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
|
private void beforeCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
|
||||||
|
@ -261,12 +264,12 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单创建后,执行后置逻辑
|
* 订单创建后,执行后置逻辑
|
||||||
*
|
* <p>
|
||||||
* 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等
|
* 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等
|
||||||
*
|
*
|
||||||
* @param userId 用户编号
|
* @param userId 用户编号
|
||||||
* @param createReqVO 创建订单请求
|
* @param createReqVO 创建订单请求
|
||||||
* @param order 交易订单
|
* @param order 交易订单
|
||||||
* @param calculateRespBO 订单价格计算结果
|
* @param calculateRespBO 订单价格计算结果
|
||||||
*/
|
*/
|
||||||
private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
|
private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
|
||||||
|
@ -284,12 +287,9 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
.setOrderId(order.getId()));
|
.setOrderId(order.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 扣减积分
|
// 3. 扣减积分(抵扣)
|
||||||
// 不在前置扣减的原因,是因为积分扣减时,需要记录关联业务
|
// 不在前置扣减的原因,是因为积分扣减时,需要记录关联业务
|
||||||
if (order.getUsePoint() != null && order.getUsePoint() > 0) {
|
reduceUserPoint(order.getUserId(), order.getUsePoint(), MemberPointBizTypeEnum.ORDER_USE, order.getId());
|
||||||
memberPointApi.reducePoint(userId, calculateRespBO.getUsePoint(),
|
|
||||||
MemberPointBizTypeEnum.ORDER_USE.getType(), String.valueOf(order.getId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 删除购物车商品
|
// 4. 删除购物车商品
|
||||||
Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId);
|
Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId);
|
||||||
|
@ -346,8 +346,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
|
|
||||||
// TODO 芋艿:OrderLog
|
// TODO 芋艿:OrderLog
|
||||||
|
|
||||||
// 增加用户积分
|
// 增加用户积分(赠送)
|
||||||
getSelf().addMemberPointAsync(order.getUserId(), order.getPayPrice(), order.getId());
|
addUserPoint(order.getUserId(), order.getGivePoint(), MemberPointBizTypeEnum.ORDER_REWARD, order.getId());
|
||||||
// 增加用户经验
|
// 增加用户经验
|
||||||
getSelf().addUserExperienceAsync(order.getUserId(), order.getPayPrice(), order.getId());
|
getSelf().addUserExperienceAsync(order.getUserId(), order.getPayPrice(), order.getId());
|
||||||
// 增加用户佣金
|
// 增加用户佣金
|
||||||
|
@ -653,11 +653,12 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 计算总的退款金额
|
// 计算总的退款金额
|
||||||
TradeOrderDO order = tradeOrderMapper.selectById(tradeOrderItemMapper.selectById(id).getOrderId());
|
TradeOrderItemDO orderItem = tradeOrderItemMapper.selectById(id);
|
||||||
|
TradeOrderDO order = tradeOrderMapper.selectById(orderItem.getOrderId());
|
||||||
Integer orderRefundPrice = order.getRefundPrice() + refundPrice;
|
Integer orderRefundPrice = order.getRefundPrice() + refundPrice;
|
||||||
if (isAllOrderItemAfterSaleSuccess(order.getId())) { // 如果都售后成功,则需要取消订单
|
if (isAllOrderItemAfterSaleSuccess(order.getId())) { // 如果都售后成功,则需要取消订单
|
||||||
tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId())
|
tradeOrderMapper.updateById(new TradeOrderDO().setId(order.getId())
|
||||||
.setRefundStatus(TradeOrderRefundStatusEnum.ALL.getStatus()).setRefundPrice(orderRefundPrice)
|
.setRefundStatus(TradeOrderRefundStatusEnum.ALL.getStatus()).setRefundPrice(orderRefundPrice).setRefundPoint(order.getRefundPoint() + orderItem.getUsePoint())
|
||||||
.setCancelType(TradeOrderCancelTypeEnum.AFTER_SALE_CLOSE.getType()).setCancelTime(LocalDateTime.now()));
|
.setCancelType(TradeOrderCancelTypeEnum.AFTER_SALE_CLOSE.getType()).setCancelTime(LocalDateTime.now()));
|
||||||
|
|
||||||
// TODO 芋艿:记录订单日志
|
// TODO 芋艿:记录订单日志
|
||||||
|
@ -668,12 +669,17 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
.setRefundStatus(TradeOrderRefundStatusEnum.PART.getStatus()).setRefundPrice(orderRefundPrice));
|
.setRefundStatus(TradeOrderRefundStatusEnum.PART.getStatus()).setRefundPrice(orderRefundPrice));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 扣减用户积分
|
// 售后成功后,执行数据回滚逻辑
|
||||||
getSelf().reduceMemberPointAsync(order.getUserId(), orderRefundPrice, afterSaleId);
|
if (Objects.equals(newAfterSaleStatus, TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus())) {
|
||||||
// 扣减用户经验
|
// 扣减用户积分(赠送的)
|
||||||
getSelf().reduceUserExperienceAsync(order.getUserId(), orderRefundPrice, afterSaleId);
|
reduceUserPoint(order.getUserId(), orderItem.getGivePoint(), MemberPointBizTypeEnum.AFTER_SALE_DEDUCT_GIVE, afterSaleId);
|
||||||
// 更新分佣记录为已失效
|
// 增加用户积分(返还抵扣)
|
||||||
getSelf().cancelBrokerageAsync(order.getUserId(), id);
|
addUserPoint(order.getUserId(), orderItem.getUsePoint(), MemberPointBizTypeEnum.AFTER_SALE_REFUND_USED, afterSaleId);
|
||||||
|
// 扣减用户经验
|
||||||
|
getSelf().reduceUserExperienceAsync(order.getUserId(), orderRefundPrice, afterSaleId);
|
||||||
|
// 更新分佣记录为已失效
|
||||||
|
getSelf().cancelBrokerageAsync(order.getUserId(), id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -747,8 +753,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
couponApi.returnUsedCoupon(order.getCouponId());
|
couponApi.returnUsedCoupon(order.getCouponId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. 回滚积分:积分是支付成功后才增加的吧? 回复:每个项目不同,目前看下来,确认收货貌似更合适,我再看看其它项目的业务选择;
|
// 6. 回滚积分(抵扣的)
|
||||||
// TODO @疯狂:有赞是可配置(支付 or 确认收货),我们按照支付好列;然后这里的退积分,指的是下单时的积分抵扣。
|
addUserPoint(order.getUserId(), order.getUsePoint(), MemberPointBizTypeEnum.ORDER_CANCEL, order.getId());
|
||||||
|
|
||||||
// 7. 增加订单日志
|
// 7. 增加订单日志
|
||||||
TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.CANCELED.getStatus());
|
TradeOrderLogUtils.setOrderInfo(order.getId(), order.getStatus(), TradeOrderStatusEnum.CANCELED.getStatus());
|
||||||
|
@ -767,7 +773,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.CANCELED.getStatus())) {
|
if (ObjectUtil.notEqual(order.getStatus(), TradeOrderStatusEnum.CANCELED.getStatus())) {
|
||||||
throw exception(ORDER_DELETE_FAIL_STATUS_NOT_CANCEL);
|
throw exception(ORDER_DELETE_FAIL_STATUS_NOT_CANCEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 删除订单
|
// 2. 删除订单
|
||||||
tradeOrderMapper.deleteById(id);
|
tradeOrderMapper.deleteById(id);
|
||||||
|
|
||||||
|
@ -801,29 +806,28 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加用户积分
|
* 添加用户积分
|
||||||
*
|
* <p>
|
||||||
* 目前是支付成功后,就会创建积分记录。
|
* 目前是支付成功后,就会创建积分记录。
|
||||||
*
|
* <p>
|
||||||
* 业内还有两种做法,可以根据自己的业务调整:
|
* 业内还有两种做法,可以根据自己的业务调整:
|
||||||
* 1. 确认收货后,才创建积分记录
|
* 1. 确认收货后,才创建积分记录
|
||||||
* 2. 支付 or 下单成功时,创建积分记录(冻结),确认收货解冻或者 n 天后解冻
|
* 2. 支付 or 下单成功时,创建积分记录(冻结),确认收货解冻或者 n 天后解冻
|
||||||
*
|
*
|
||||||
* @param userId 用户编号
|
* @param userId 用户编号
|
||||||
* @param payPrice 支付金额
|
* @param point 增加积分数量
|
||||||
* @param orderId 订单编号
|
* @param bizType 业务编号
|
||||||
|
* @param bizId 业务编号
|
||||||
*/
|
*/
|
||||||
@Async
|
protected void addUserPoint(Long userId, Integer point, MemberPointBizTypeEnum bizType, Long bizId) {
|
||||||
protected void addMemberPointAsync(Long userId, Integer payPrice, Long orderId) {
|
if (point != null && point > 0) {
|
||||||
// TODO @疯狂:具体多少积分,需要分成 2 不分:1. 支付金额;2. 商品金额
|
memberPointApi.addPoint(userId, point, bizType.getType(), String.valueOf(bizId));
|
||||||
int bizType = MemberPointBizTypeEnum.ORDER_REWARD.getType();
|
}
|
||||||
memberPointApi.addPoint(userId, payPrice, bizType, String.valueOf(orderId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Async
|
protected void reduceUserPoint(Long userId, Integer point, MemberPointBizTypeEnum bizType, Long bizId) {
|
||||||
protected void reduceMemberPointAsync(Long userId, Integer refundPrice, Long afterSaleId) {
|
if (point != null && point > 0) {
|
||||||
// TODO @疯狂:退款时,按照金额比例,退还积分;https://help.youzan.com/displaylist/detail_4_4-1-49185
|
memberPointApi.reducePoint(userId, point, bizType.getType(), String.valueOf(bizId));
|
||||||
int bizType = MemberPointBizTypeEnum.ORDER_CANCEL.getType();
|
}
|
||||||
memberPointApi.addPoint(userId, -refundPrice, bizType, String.valueOf(afterSaleId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -41,7 +41,6 @@ public class TradePriceServiceImpl implements TradePriceService {
|
||||||
@Resource
|
@Resource
|
||||||
private List<TradePriceCalculator> priceCalculators;
|
private List<TradePriceCalculator> priceCalculators;
|
||||||
|
|
||||||
// TODO @疯狂:需要搞个 TradePriceCalculator,计算赠送积分;
|
|
||||||
@Override
|
@Override
|
||||||
public TradePriceCalculateRespBO calculatePrice(TradePriceCalculateReqBO calculateReqBO) {
|
public TradePriceCalculateRespBO calculatePrice(TradePriceCalculateReqBO calculateReqBO) {
|
||||||
// 1.1 获得商品 SKU 数组
|
// 1.1 获得商品 SKU 数组
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class TradePriceCalculateReqBO {
|
||||||
* 对应 CouponDO 的 id 编号
|
* 对应 CouponDO 的 id 编号
|
||||||
*/
|
*/
|
||||||
private Long couponId;
|
private Long couponId;
|
||||||
// TODO @疯狂:需要增加一个 PriceCalculator 实现积分扣减的计算;写回到 TradePriceCalculateRespBO 的 usePoint
|
|
||||||
/**
|
/**
|
||||||
* 是否使用积分
|
* 是否使用积分
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -53,6 +53,11 @@ public class TradePriceCalculateRespBO {
|
||||||
*/
|
*/
|
||||||
private Integer usePoint;
|
private Integer usePoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用的积分
|
||||||
|
*/
|
||||||
|
private Integer givePoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单价格
|
* 订单价格
|
||||||
*/
|
*/
|
||||||
|
@ -163,6 +168,10 @@ public class TradePriceCalculateRespBO {
|
||||||
* 对应 taobao 的 trade.point_fee 字段
|
* 对应 taobao 的 trade.point_fee 字段
|
||||||
*/
|
*/
|
||||||
private Integer pointPrice;
|
private Integer pointPrice;
|
||||||
|
/**
|
||||||
|
* 使用的积分
|
||||||
|
*/
|
||||||
|
private Integer usePoint;
|
||||||
/**
|
/**
|
||||||
* VIP 减免金额,单位:分
|
* VIP 减免金额,单位:分
|
||||||
*/
|
*/
|
||||||
|
@ -215,6 +224,11 @@ public class TradePriceCalculateRespBO {
|
||||||
*/
|
*/
|
||||||
private List<ProductPropertyValueDetailRespDTO> properties;
|
private List<ProductPropertyValueDetailRespDTO> properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用的积分
|
||||||
|
*/
|
||||||
|
private Integer givePoint;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package cn.iocoder.yudao.module.trade.service.price.calculator;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.BooleanUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
|
||||||
|
import cn.iocoder.yudao.module.member.api.point.MemberPointApi;
|
||||||
|
import cn.iocoder.yudao.module.member.api.point.dto.MemberPointConfigRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 赠送积分的 {@link TradePriceCalculator} 实现类
|
||||||
|
*
|
||||||
|
* @author owen
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@Order(TradePriceCalculator.ORDER_POINT_GIVE)
|
||||||
|
@Slf4j
|
||||||
|
public class TradePointGiveCalculator implements TradePriceCalculator {
|
||||||
|
@Resource
|
||||||
|
private MemberPointApi memberPointApi;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
|
||||||
|
// 1.1 校验积分功能是否开启
|
||||||
|
int givePointPerYuan = Optional.ofNullable(memberPointApi.getConfig())
|
||||||
|
.filter(config -> BooleanUtil.isTrue(config.getTradeDeductEnable()))
|
||||||
|
.map(MemberPointConfigRespDTO::getTradeGivePoint)
|
||||||
|
.orElse(0);
|
||||||
|
if (givePointPerYuan <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 1.2 校验支付金额
|
||||||
|
if (result.getPrice().getPayPrice() <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.1 计算赠送积分
|
||||||
|
int givePoint = MoneyUtils.calculateRatePriceFloor(result.getPrice().getPayPrice(), (double) givePointPerYuan);
|
||||||
|
// 2.2 计算分摊的赠送积分
|
||||||
|
List<TradePriceCalculateRespBO.OrderItem> orderItems = filterList(result.getItems(), TradePriceCalculateRespBO.OrderItem::getSelected);
|
||||||
|
List<Integer> dividePoints = TradePriceCalculatorHelper.dividePrice(orderItems, givePoint);
|
||||||
|
|
||||||
|
// 3.2 更新 SKU 赠送积分
|
||||||
|
for (int i = 0; i < orderItems.size(); i++) {
|
||||||
|
TradePriceCalculateRespBO.OrderItem orderItem = orderItems.get(i);
|
||||||
|
// 商品可能赠送了积分,所以这里要加上
|
||||||
|
orderItem.setGivePoint(orderItem.getGivePoint() + dividePoints.get(i));
|
||||||
|
TradePriceCalculatorHelper.recountPayPrice(orderItem);
|
||||||
|
}
|
||||||
|
// 3.3 更新订单赠送积分
|
||||||
|
TradePriceCalculatorHelper.recountAllGivePoint(result);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,25 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.price.calculator;
|
package cn.iocoder.yudao.module.trade.service.price.calculator;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.BooleanUtil;
|
||||||
|
import cn.hutool.core.util.NumberUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.iocoder.yudao.module.member.api.point.MemberPointApi;
|
||||||
|
import cn.iocoder.yudao.module.member.api.point.dto.MemberPointConfigRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
|
||||||
|
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum;
|
||||||
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
|
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
|
||||||
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
|
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.math.RoundingMode;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用积分的 {@link TradePriceCalculator} 实现类
|
* 使用积分的 {@link TradePriceCalculator} 实现类
|
||||||
*
|
*
|
||||||
|
@ -15,15 +29,81 @@ import org.springframework.stereotype.Component;
|
||||||
@Order(TradePriceCalculator.ORDER_POINT_USE)
|
@Order(TradePriceCalculator.ORDER_POINT_USE)
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class TradePointUsePriceCalculator implements TradePriceCalculator {
|
public class TradePointUsePriceCalculator implements TradePriceCalculator {
|
||||||
|
@Resource
|
||||||
|
private MemberPointApi memberPointApi;
|
||||||
|
@Resource
|
||||||
|
private MemberUserApi memberUserApi;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
|
public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) {
|
||||||
// TODO 疯狂:待实现,嘿嘿;
|
// 1.1 校验是否使用积分
|
||||||
if (param.getPointStatus()) {
|
if (!BooleanUtil.isTrue(param.getPointStatus())) {
|
||||||
result.setUsePoint(10);
|
|
||||||
} else {
|
|
||||||
result.setUsePoint(0);
|
result.setUsePoint(0);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
// 1.2 校验积分抵扣是否开启
|
||||||
|
MemberPointConfigRespDTO config = memberPointApi.getConfig();
|
||||||
|
if (!checkDeductPointEnable(config)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 1.3 校验用户积分余额
|
||||||
|
MemberUserRespDTO user = memberUserApi.getUser(param.getUserId());
|
||||||
|
if (user.getPoint() == null || user.getPoint() < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.1 计算积分优惠金额
|
||||||
|
int pointPrice = calculatePointPrice(config, user.getPoint(), result);
|
||||||
|
// 2.1 计算分摊的积分、抵扣金额
|
||||||
|
List<TradePriceCalculateRespBO.OrderItem> orderItems = filterList(result.getItems(), TradePriceCalculateRespBO.OrderItem::getSelected);
|
||||||
|
List<Integer> dividePointPrices = TradePriceCalculatorHelper.dividePrice(orderItems, pointPrice);
|
||||||
|
List<Integer> divideUsePoints = TradePriceCalculatorHelper.dividePrice(orderItems, result.getUsePoint());
|
||||||
|
|
||||||
|
// 3.1 记录优惠明细
|
||||||
|
TradePriceCalculatorHelper.addPromotion(result, orderItems,
|
||||||
|
param.getUserId(), "积分抵扣", PromotionTypeEnum.POINT.getType(),
|
||||||
|
StrUtil.format("积分抵扣:省 {} 元", TradePriceCalculatorHelper.formatPrice(pointPrice)),
|
||||||
|
dividePointPrices);
|
||||||
|
// 3.2 更新 SKU 优惠金额
|
||||||
|
for (int i = 0; i < orderItems.size(); i++) {
|
||||||
|
TradePriceCalculateRespBO.OrderItem orderItem = orderItems.get(i);
|
||||||
|
orderItem.setPointPrice(dividePointPrices.get(i));
|
||||||
|
orderItem.setUsePoint(divideUsePoints.get(i));
|
||||||
|
TradePriceCalculatorHelper.recountPayPrice(orderItem);
|
||||||
|
}
|
||||||
|
TradePriceCalculatorHelper.recountAllPrice(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean checkDeductPointEnable(MemberPointConfigRespDTO config) {
|
||||||
|
if (config == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!BooleanUtil.isTrue(config.getTradeDeductEnable())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 有没有配置:1 积分抵扣多少分
|
||||||
|
return config.getTradeDeductUnitPrice() != null && config.getTradeDeductUnitPrice() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Integer calculatePointPrice(MemberPointConfigRespDTO config, Integer usePoint, TradePriceCalculateRespBO result) {
|
||||||
|
// 每个订单最多可以使用的积分数量
|
||||||
|
if (config.getTradeDeductMaxPrice() != null && config.getTradeDeductMaxPrice() > 0) {
|
||||||
|
usePoint = Math.min(usePoint, config.getTradeDeductMaxPrice());
|
||||||
|
}
|
||||||
|
// 积分优惠金额(分)
|
||||||
|
int pointPrice = usePoint * config.getTradeDeductUnitPrice();
|
||||||
|
// 0元购!!!:用户积分比较多时,积分可以抵扣的金额要大于支付金额, 这时需要根据支付金额反推使用多少积分
|
||||||
|
if (result.getPrice().getPayPrice() < pointPrice) {
|
||||||
|
pointPrice = result.getPrice().getPayPrice();
|
||||||
|
// 反推需要扣除的积分
|
||||||
|
usePoint = NumberUtil.toBigDecimal(pointPrice)
|
||||||
|
.divide(NumberUtil.toBigDecimal(config.getTradeDeductUnitPrice()), 0, RoundingMode.HALF_UP)
|
||||||
|
.intValue();
|
||||||
|
}
|
||||||
|
// 记录使用的积分
|
||||||
|
result.setUsePoint(usePoint);
|
||||||
|
|
||||||
|
return pointPrice;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,10 @@ public interface TradePriceCalculator {
|
||||||
* 放在各种营销活动、优惠劵后面 TODO
|
* 放在各种营销活动、优惠劵后面 TODO
|
||||||
*/
|
*/
|
||||||
int ORDER_DELIVERY = 50;
|
int ORDER_DELIVERY = 50;
|
||||||
|
/**
|
||||||
|
* 赠送积分,放最后
|
||||||
|
*/
|
||||||
|
int ORDER_POINT_GIVE = 999;
|
||||||
|
|
||||||
void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result);
|
void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result);
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,8 @@ public class TradePriceCalculatorHelper {
|
||||||
.setWeight(sku.getWeight()).setVolume(sku.getVolume());
|
.setWeight(sku.getWeight()).setVolume(sku.getVolume());
|
||||||
// spu 信息
|
// spu 信息
|
||||||
orderItem.setSpuName(spu.getName()).setCategoryId(spu.getCategoryId())
|
orderItem.setSpuName(spu.getName()).setCategoryId(spu.getCategoryId())
|
||||||
.setDeliveryTemplateId(spu.getDeliveryTemplateId());
|
.setDeliveryTemplateId(spu.getDeliveryTemplateId())
|
||||||
|
.setGivePoint(spu.getGiveIntegral()).setUsePoint(0);
|
||||||
if (orderItem.getPicUrl() == null) {
|
if (orderItem.getPicUrl() == null) {
|
||||||
orderItem.setPicUrl(spu.getPicUrl());
|
orderItem.setPicUrl(spu.getPicUrl());
|
||||||
}
|
}
|
||||||
|
@ -67,6 +68,7 @@ public class TradePriceCalculatorHelper {
|
||||||
// 创建它的 Price 属性
|
// 创建它的 Price 属性
|
||||||
result.setPrice(new TradePriceCalculateRespBO.Price());
|
result.setPrice(new TradePriceCalculateRespBO.Price());
|
||||||
recountAllPrice(result);
|
recountAllPrice(result);
|
||||||
|
recountAllGivePoint(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,13 +114,22 @@ public class TradePriceCalculatorHelper {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基于订单项,重新计算赠送积分
|
||||||
|
*
|
||||||
|
* @param result 计算结果
|
||||||
|
*/
|
||||||
|
public static void recountAllGivePoint(TradePriceCalculateRespBO result) {
|
||||||
|
result.setGivePoint(getSumValue(result.getItems(), item -> item.getSelected() ? item.getGivePoint() : 0, Integer::sum));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重新计算单个订单项的支付金额
|
* 重新计算单个订单项的支付金额
|
||||||
*
|
*
|
||||||
* @param orderItem 订单项
|
* @param orderItem 订单项
|
||||||
*/
|
*/
|
||||||
public static void recountPayPrice(TradePriceCalculateRespBO.OrderItem orderItem) {
|
public static void recountPayPrice(TradePriceCalculateRespBO.OrderItem orderItem) {
|
||||||
orderItem.setPayPrice(orderItem.getPrice()* orderItem.getCount()
|
orderItem.setPayPrice(orderItem.getPrice() * orderItem.getCount()
|
||||||
- orderItem.getDiscountPrice()
|
- orderItem.getDiscountPrice()
|
||||||
+ orderItem.getDeliveryPrice()
|
+ orderItem.getDeliveryPrice()
|
||||||
- orderItem.getCouponPrice()
|
- orderItem.getCouponPrice()
|
||||||
|
@ -148,6 +159,12 @@ public class TradePriceCalculatorHelper {
|
||||||
if (orderItem.getPointPrice() == null) {
|
if (orderItem.getPointPrice() == null) {
|
||||||
orderItem.setPointPrice(0);
|
orderItem.setPointPrice(0);
|
||||||
}
|
}
|
||||||
|
if (orderItem.getUsePoint() == null) {
|
||||||
|
orderItem.setUsePoint(0);
|
||||||
|
}
|
||||||
|
if (orderItem.getGivePoint() == null) {
|
||||||
|
orderItem.setGivePoint(0);
|
||||||
|
}
|
||||||
if (orderItem.getVipPrice() == null) {
|
if (orderItem.getVipPrice() == null) {
|
||||||
orderItem.setVipPrice(0);
|
orderItem.setVipPrice(0);
|
||||||
}
|
}
|
||||||
|
@ -175,7 +192,7 @@ public class TradePriceCalculatorHelper {
|
||||||
*/
|
*/
|
||||||
public static Integer calculateTotalCount(List<TradePriceCalculateRespBO.OrderItem> orderItems) {
|
public static Integer calculateTotalCount(List<TradePriceCalculateRespBO.OrderItem> orderItems) {
|
||||||
return getSumValue(orderItems,
|
return getSumValue(orderItems,
|
||||||
orderItem -> orderItem.getSelected() ? orderItem.getCount() : 0, // 未选中的情况下,不计算数量
|
orderItem -> orderItem.getSelected() ? orderItem.getCount() : 0, // 未选中的情况下,不计算数量
|
||||||
Integer::sum);
|
Integer::sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +200,7 @@ public class TradePriceCalculatorHelper {
|
||||||
* 按照支付金额,返回每个订单项的分摊金额数组
|
* 按照支付金额,返回每个订单项的分摊金额数组
|
||||||
*
|
*
|
||||||
* @param orderItems 订单项数组
|
* @param orderItems 订单项数组
|
||||||
* @param price 金额
|
* @param price 金额
|
||||||
* @return 分摊金额数组,和传入的 orderItems 一一对应
|
* @return 分摊金额数组,和传入的 orderItems 一一对应
|
||||||
*/
|
*/
|
||||||
public static List<Integer> dividePrice(List<TradePriceCalculateRespBO.OrderItem> orderItems, Integer price) {
|
public static List<Integer> dividePrice(List<TradePriceCalculateRespBO.OrderItem> orderItems, Integer price) {
|
||||||
|
@ -216,12 +233,12 @@ public class TradePriceCalculatorHelper {
|
||||||
/**
|
/**
|
||||||
* 添加【匹配】单个 OrderItem 的营销明细
|
* 添加【匹配】单个 OrderItem 的营销明细
|
||||||
*
|
*
|
||||||
* @param result 价格计算结果
|
* @param result 价格计算结果
|
||||||
* @param orderItem 单个订单商品 SKU
|
* @param orderItem 单个订单商品 SKU
|
||||||
* @param id 营销编号
|
* @param id 营销编号
|
||||||
* @param name 营销名字
|
* @param name 营销名字
|
||||||
* @param description 满足条件的提示
|
* @param description 满足条件的提示
|
||||||
* @param type 营销类型
|
* @param type 营销类型
|
||||||
* @param discountPrice 单个订单商品 SKU 的优惠价格(总)
|
* @param discountPrice 单个订单商品 SKU 的优惠价格(总)
|
||||||
*/
|
*/
|
||||||
public static void addPromotion(TradePriceCalculateRespBO result, TradePriceCalculateRespBO.OrderItem orderItem,
|
public static void addPromotion(TradePriceCalculateRespBO result, TradePriceCalculateRespBO.OrderItem orderItem,
|
||||||
|
@ -232,7 +249,7 @@ public class TradePriceCalculatorHelper {
|
||||||
/**
|
/**
|
||||||
* 添加【匹配】多个 OrderItem 的营销明细
|
* 添加【匹配】多个 OrderItem 的营销明细
|
||||||
*
|
*
|
||||||
* @param result 价格计算结果
|
* @param result 价格计算结果
|
||||||
* @param orderItems 多个订单商品 SKU
|
* @param orderItems 多个订单商品 SKU
|
||||||
* @param id 营销编号
|
* @param id 营销编号
|
||||||
* @param name 营销名字
|
* @param name 营销名字
|
||||||
|
@ -241,7 +258,7 @@ public class TradePriceCalculatorHelper {
|
||||||
* @param discountPrices 多个订单商品 SKU 的优惠价格(总),和 orderItems 一一对应
|
* @param discountPrices 多个订单商品 SKU 的优惠价格(总),和 orderItems 一一对应
|
||||||
*/
|
*/
|
||||||
public static void addPromotion(TradePriceCalculateRespBO result, List<TradePriceCalculateRespBO.OrderItem> orderItems,
|
public static void addPromotion(TradePriceCalculateRespBO result, List<TradePriceCalculateRespBO.OrderItem> orderItems,
|
||||||
Long id, String name, Integer type, String description, List<Integer> discountPrices) {
|
Long id, String name, Integer type, String description, List<Integer> discountPrices) {
|
||||||
// 创建营销明细 Item
|
// 创建营销明细 Item
|
||||||
List<TradePriceCalculateRespBO.PromotionItem> promotionItems = new ArrayList<>(discountPrices.size());
|
List<TradePriceCalculateRespBO.PromotionItem> promotionItems = new ArrayList<>(discountPrices.size());
|
||||||
for (int i = 0; i < orderItems.size(); i++) {
|
for (int i = 0; i < orderItems.size(); i++) {
|
||||||
|
@ -261,12 +278,12 @@ public class TradePriceCalculatorHelper {
|
||||||
/**
|
/**
|
||||||
* 添加【不匹配】多个 OrderItem 的营销明细
|
* 添加【不匹配】多个 OrderItem 的营销明细
|
||||||
*
|
*
|
||||||
* @param result 价格计算结果
|
* @param result 价格计算结果
|
||||||
* @param orderItems 多个订单商品 SKU
|
* @param orderItems 多个订单商品 SKU
|
||||||
* @param id 营销编号
|
* @param id 营销编号
|
||||||
* @param name 营销名字
|
* @param name 营销名字
|
||||||
* @param description 满足条件的提示
|
* @param description 满足条件的提示
|
||||||
* @param type 营销类型
|
* @param type 营销类型
|
||||||
*/
|
*/
|
||||||
public static void addNotMatchPromotion(TradePriceCalculateRespBO result, List<TradePriceCalculateRespBO.OrderItem> orderItems,
|
public static void addNotMatchPromotion(TradePriceCalculateRespBO result, List<TradePriceCalculateRespBO.OrderItem> orderItems,
|
||||||
Long id, String name, Integer type, String description) {
|
Long id, String name, Integer type, String description) {
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageUserMapper">
|
||||||
|
|
||||||
|
<select id="selectSummaryPageByUserId"
|
||||||
|
resultType="cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO">
|
||||||
|
SELECT bu.id, bu.bind_user_time AS brokerageTime,
|
||||||
|
u.nickname, u.avatar,
|
||||||
|
(SELECT SUM(price) FROM trade_brokerage_record r
|
||||||
|
WHERE r.user_id = u.id AND biz_type = 1 AND r.status = 1 AND r.deleted = FALSE) AS brokeragePrice,
|
||||||
|
(SELECT COUNT(1) FROM trade_brokerage_record r
|
||||||
|
WHERE r.user_id = u.id AND biz_type = 1 AND r.status = 1 AND r.deleted = FALSE) AS brokerageOrderCount,
|
||||||
|
(SELECT COUNT(1) FROM trade_brokerage_user c
|
||||||
|
WHERE c.bind_user_id = u.id AND c.deleted = FALSE) AS brokerageUserCount
|
||||||
|
FROM member_user AS u
|
||||||
|
JOIN trade_brokerage_user AS bu ON bu.id = u.id
|
||||||
|
<where>
|
||||||
|
<if test="param.nickname != null and param.nickname != ''">
|
||||||
|
AND u.nickname LIKE concat('', #{param.nickname}, '')
|
||||||
|
</if>
|
||||||
|
<if test="param.level == 1">
|
||||||
|
AND bu.bind_user_id = #{userId}
|
||||||
|
</if>
|
||||||
|
<if test="param.level == 2">
|
||||||
|
AND bu.bind_user_id = (SELECT id FROM trade_brokerage_user c WHERE c.bind_user_id =
|
||||||
|
#{userId})
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
<choose>
|
||||||
|
<when test="param.sortingField.field == 'userCount'">
|
||||||
|
ORDER BY brokerageUserCount ${param.sortingField.order}
|
||||||
|
</when>
|
||||||
|
<when test="param.sortingField.field == 'orderCount'">
|
||||||
|
ORDER BY brokerageOrderCount ${param.sortingField.order}
|
||||||
|
</when>
|
||||||
|
<when test="param.sortingField.field == 'price'">
|
||||||
|
ORDER BY brokeragePrice ${param.sortingField.order}
|
||||||
|
</when>
|
||||||
|
<otherwise>
|
||||||
|
ORDER BY bu.bind_user_time DESC
|
||||||
|
</otherwise>
|
||||||
|
</choose>
|
||||||
|
</select>
|
||||||
|
</mapper>
|
|
@ -1,12 +1,13 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.brokerage.record;
|
package cn.iocoder.yudao.module.trade.service.brokerage;
|
||||||
|
|
||||||
import cn.hutool.core.util.NumberUtil;
|
import cn.hutool.core.util.NumberUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordPageReqVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.record.BrokerageRecordPageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageRecordDO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.record.BrokerageRecordMapper;
|
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageRecordMapper;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService;
|
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageRecordServiceImpl;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserService;
|
||||||
import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
|
import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
|
@ -1,10 +1,11 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.brokerage.user;
|
package cn.iocoder.yudao.module.trade.service.brokerage;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.user.BrokerageUserPageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.user.BrokerageUserMapper;
|
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageUserMapper;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.brokerage.BrokerageUserServiceImpl;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
|
@ -1,16 +1,19 @@
|
||||||
package cn.iocoder.yudao.module.trade.service.withdraw;
|
package cn.iocoder.yudao.module.trade.service.brokerage;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawPageReqVO;
|
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw.BrokerageWithdrawDO;
|
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.vo.withdraw.BrokerageWithdrawPageReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.withdraw.BrokerageWithdrawMapper;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageWithdrawDO;
|
||||||
import cn.iocoder.yudao.module.trade.service.brokerage.withdraw.BrokerageWithdrawServiceImpl;
|
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageWithdrawMapper;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import javax.validation.Validator;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||||
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||||
|
@ -33,6 +36,19 @@ public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest {
|
||||||
@Resource
|
@Resource
|
||||||
private BrokerageWithdrawMapper brokerageWithdrawMapper;
|
private BrokerageWithdrawMapper brokerageWithdrawMapper;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private BrokerageRecordService brokerageRecordService;
|
||||||
|
@MockBean
|
||||||
|
private BrokerageUserService brokerageUserService;
|
||||||
|
@MockBean
|
||||||
|
private TradeConfigService tradeConfigService;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private NotifyMessageSendApi notifyMessageSendApi;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private Validator validator;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
|
||||||
public void testGetBrokerageWithdrawPage() {
|
public void testGetBrokerageWithdrawPage() {
|
||||||
|
@ -85,4 +101,17 @@ public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest {
|
||||||
assertPojoEquals(dbBrokerageWithdraw, pageResult.getList().get(0));
|
assertPojoEquals(dbBrokerageWithdraw, pageResult.getList().get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCalculateFeePrice() {
|
||||||
|
Integer withdrawPrice = 100;
|
||||||
|
// 测试手续费比例未设置
|
||||||
|
Integer percent = null;
|
||||||
|
assertEquals(brokerageWithdrawService.calculateFeePrice(withdrawPrice, percent), 0);
|
||||||
|
// 测试手续费给为0
|
||||||
|
percent = 0;
|
||||||
|
assertEquals(brokerageWithdrawService.calculateFeePrice(withdrawPrice, percent), 0);
|
||||||
|
// 测试手续费
|
||||||
|
percent = 1;
|
||||||
|
assertEquals(brokerageWithdrawService.calculateFeePrice(withdrawPrice, percent), 1);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -186,6 +186,6 @@ CREATE TABLE IF NOT EXISTS "trade_brokerage_withdraw"
|
||||||
"updater" varchar DEFAULT '',
|
"updater" varchar DEFAULT '',
|
||||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||||
"tenant_id" bigint not null default '0',目
|
"tenant_id" bigint not null default '0',
|
||||||
PRIMARY KEY ("id")
|
PRIMARY KEY ("id")
|
||||||
) COMMENT '佣金提现';
|
) COMMENT '佣金提现';
|
|
@ -1,5 +1,6 @@
|
||||||
package cn.iocoder.yudao.module.member.api.point;
|
package cn.iocoder.yudao.module.member.api.point;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.member.api.point.dto.MemberPointConfigRespDTO;
|
||||||
import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
|
import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
|
||||||
|
|
||||||
import javax.validation.constraints.Min;
|
import javax.validation.constraints.Min;
|
||||||
|
@ -11,6 +12,13 @@ import javax.validation.constraints.Min;
|
||||||
*/
|
*/
|
||||||
public interface MemberPointApi {
|
public interface MemberPointApi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得积分配置
|
||||||
|
*
|
||||||
|
* @return 积分配置
|
||||||
|
*/
|
||||||
|
MemberPointConfigRespDTO getConfig();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 增加用户积分
|
* 增加用户积分
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package cn.iocoder.yudao.module.member.api.point.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户信息 Response DTO
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class MemberPointConfigRespDTO {
|
||||||
|
/**
|
||||||
|
* 积分抵扣开关
|
||||||
|
*/
|
||||||
|
private Boolean tradeDeductEnable;
|
||||||
|
/**
|
||||||
|
* 积分抵扣,单位:分
|
||||||
|
* <p>
|
||||||
|
* 1 积分抵扣多少分
|
||||||
|
*/
|
||||||
|
private Integer tradeDeductUnitPrice;
|
||||||
|
/**
|
||||||
|
* 积分抵扣最大值
|
||||||
|
*/
|
||||||
|
private Integer tradeDeductMaxPrice;
|
||||||
|
/**
|
||||||
|
* 1 元赠送多少分
|
||||||
|
*/
|
||||||
|
private Integer tradeGivePoint;
|
||||||
|
}
|
|
@ -41,4 +41,8 @@ public class MemberUserRespDTO {
|
||||||
*/
|
*/
|
||||||
private Long levelId;
|
private Long levelId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 积分
|
||||||
|
*/
|
||||||
|
private Integer point;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ public interface ErrorCodeConstants {
|
||||||
ErrorCode USER_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在");
|
ErrorCode USER_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在");
|
||||||
ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1004001001, "手机号未注册用户");
|
ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1004001001, "手机号未注册用户");
|
||||||
ErrorCode USER_MOBILE_USED = new ErrorCode(1004001002, "修改手机失败,该手机号({})已经被使用");
|
ErrorCode USER_MOBILE_USED = new ErrorCode(1004001002, "修改手机失败,该手机号({})已经被使用");
|
||||||
|
ErrorCode USER_POINT_NOT_ENOUGH = new ErrorCode(1004001003, "用户积分余额不足");
|
||||||
|
|
||||||
// ========== AUTH 模块 1004003000 ==========
|
// ========== AUTH 模块 1004003000 ==========
|
||||||
ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1004003000, "登录失败,账号密码不正确");
|
ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1004003000, "登录失败,账号密码不正确");
|
||||||
|
|
|
@ -18,8 +18,10 @@ public enum MemberPointBizTypeEnum implements IntArrayValuable {
|
||||||
|
|
||||||
SIGN(1, "签到", "签到获得 {} 积分", true),
|
SIGN(1, "签到", "签到获得 {} 积分", true),
|
||||||
ORDER_REWARD(10, "订单奖励", "下单获得 {} 积分", true),
|
ORDER_REWARD(10, "订单奖励", "下单获得 {} 积分", true),
|
||||||
ORDER_CANCEL(11, "订单取消", "退单获得 {} 积分", false), // 退回积分
|
ORDER_CANCEL(11, "订单取消", "订单取消,退还 {} 积分", true), // 退回积分
|
||||||
ORDER_USE(12, "订单使用", "下单使用 {} 积分", false), // 扣减积分
|
ORDER_USE(12, "订单使用", "下单使用 {} 积分", false), // 扣减积分
|
||||||
|
AFTER_SALE_REFUND_USED(13, "订单退款", "订单退款,退还 {} 积分", true), // 退回积分
|
||||||
|
AFTER_SALE_DEDUCT_GIVE(14, "订单退款", "订单退款,扣除赠送的 {} 积分", false), // 扣减积分
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package cn.iocoder.yudao.module.member.api.point;
|
package cn.iocoder.yudao.module.member.api.point;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.iocoder.yudao.module.member.api.point.dto.MemberPointConfigRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.member.convert.point.MemberPointConfigConvert;
|
||||||
import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
|
import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.member.service.point.MemberPointConfigService;
|
||||||
import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService;
|
import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
@ -21,9 +25,17 @@ public class MemberPointApiImpl implements MemberPointApi {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private MemberPointRecordService memberPointRecordService;
|
private MemberPointRecordService memberPointRecordService;
|
||||||
|
@Resource
|
||||||
|
private MemberPointConfigService memberPointConfigService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MemberPointConfigRespDTO getConfig() {
|
||||||
|
return MemberPointConfigConvert.INSTANCE.convert01(memberPointConfigService.getPointConfig());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addPoint(Long userId, Integer point, Integer bizType, String bizId) {
|
public void addPoint(Long userId, Integer point, Integer bizType, String bizId) {
|
||||||
|
Assert.isTrue(point > 0);
|
||||||
MemberPointBizTypeEnum bizTypeEnum = MemberPointBizTypeEnum.getByType(bizType);
|
MemberPointBizTypeEnum bizTypeEnum = MemberPointBizTypeEnum.getByType(bizType);
|
||||||
if (bizTypeEnum == null) {
|
if (bizTypeEnum == null) {
|
||||||
throw exception(POINT_RECORD_BIZ_NOT_SUPPORT);
|
throw exception(POINT_RECORD_BIZ_NOT_SUPPORT);
|
||||||
|
@ -33,11 +45,12 @@ public class MemberPointApiImpl implements MemberPointApi {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reducePoint(Long userId, Integer point, Integer bizType, String bizId) {
|
public void reducePoint(Long userId, Integer point, Integer bizType, String bizId) {
|
||||||
|
Assert.isTrue(point > 0);
|
||||||
MemberPointBizTypeEnum bizTypeEnum = MemberPointBizTypeEnum.getByType(bizType);
|
MemberPointBizTypeEnum bizTypeEnum = MemberPointBizTypeEnum.getByType(bizType);
|
||||||
if (bizTypeEnum == null) {
|
if (bizTypeEnum == null) {
|
||||||
throw exception(POINT_RECORD_BIZ_NOT_SUPPORT);
|
throw exception(POINT_RECORD_BIZ_NOT_SUPPORT);
|
||||||
}
|
}
|
||||||
memberPointRecordService.createPointRecord(userId, point, bizTypeEnum, bizId);
|
memberPointRecordService.createPointRecord(userId, -point, bizTypeEnum, bizId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package cn.iocoder.yudao.module.member.convert.point;
|
package cn.iocoder.yudao.module.member.convert.point;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.member.api.point.dto.MemberPointConfigRespDTO;
|
||||||
import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigRespVO;
|
import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigRespVO;
|
||||||
import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigSaveReqVO;
|
import cn.iocoder.yudao.module.member.controller.admin.point.vo.config.MemberPointConfigSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO;
|
import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO;
|
||||||
|
@ -20,4 +21,5 @@ public interface MemberPointConfigConvert {
|
||||||
|
|
||||||
MemberPointConfigDO convert(MemberPointConfigSaveReqVO bean);
|
MemberPointConfigDO convert(MemberPointConfigSaveReqVO bean);
|
||||||
|
|
||||||
|
MemberPointConfigRespDTO convert01(MemberPointConfigDO pointConfig);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package cn.iocoder.yudao.module.member.dal.mysql.user;
|
package cn.iocoder.yudao.module.member.dal.mysql.user;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
|
import cn.iocoder.yudao.module.member.controller.admin.user.vo.MemberUserPageReqVO;
|
||||||
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -62,4 +64,33 @@ public interface MemberUserMapper extends BaseMapperX<MemberUserDO> {
|
||||||
.apply("FIND_IN_SET({0}, tag_ids)", tagId));
|
.apply("FIND_IN_SET({0}, tag_ids)", tagId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户积分(增加)
|
||||||
|
*
|
||||||
|
* @param id 用户编号
|
||||||
|
* @param incrCount 增加积分(正数)
|
||||||
|
*/
|
||||||
|
default void updatePointIncr(Long id, Integer incrCount) {
|
||||||
|
Assert.isTrue(incrCount > 0);
|
||||||
|
LambdaUpdateWrapper<MemberUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<MemberUserDO>()
|
||||||
|
.setSql(" point = point + " + incrCount)
|
||||||
|
.eq(MemberUserDO::getId, id);
|
||||||
|
update(null, lambdaUpdateWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户积分(减少)
|
||||||
|
*
|
||||||
|
* @param id 用户编号
|
||||||
|
* @param incrCount 增加积分(负数)
|
||||||
|
* @return 更新行数
|
||||||
|
*/
|
||||||
|
default int updatePointDecr(Long id, Integer incrCount) {
|
||||||
|
Assert.isTrue(incrCount < 0);
|
||||||
|
LambdaUpdateWrapper<MemberUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<MemberUserDO>()
|
||||||
|
.setSql(" point = point + " + incrCount) // 负数,所以使用 + 号
|
||||||
|
.eq(MemberUserDO::getId, id);
|
||||||
|
return update(null, lambdaUpdateWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod.MemberPointRecordPageReqVO;
|
import cn.iocoder.yudao.module.member.controller.admin.point.vo.recrod.MemberPointRecordPageReqVO;
|
||||||
import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointConfigDO;
|
|
||||||
import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointRecordDO;
|
import cn.iocoder.yudao.module.member.dal.dataobject.point.MemberPointRecordDO;
|
||||||
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
||||||
import cn.iocoder.yudao.module.member.dal.mysql.point.MemberPointRecordMapper;
|
import cn.iocoder.yudao.module.member.dal.mysql.point.MemberPointRecordMapper;
|
||||||
|
@ -14,6 +13,7 @@ import cn.iocoder.yudao.module.member.service.user.MemberUserService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
@ -21,7 +21,9 @@ import javax.annotation.Resource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||||
|
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.USER_POINT_NOT_ENOUGH;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,8 +38,6 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private MemberPointRecordMapper memberPointRecordMapper;
|
private MemberPointRecordMapper memberPointRecordMapper;
|
||||||
@Resource
|
|
||||||
private MemberPointConfigService memberPointConfigService;
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private MemberUserService memberUserService;
|
private MemberUserService memberUserService;
|
||||||
|
@ -64,32 +64,28 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void createPointRecord(Long userId, Integer point, MemberPointBizTypeEnum bizType, String bizId) {
|
public void createPointRecord(Long userId, Integer point, MemberPointBizTypeEnum bizType, String bizId) {
|
||||||
MemberPointConfigDO pointConfig = memberPointConfigService.getPointConfig();
|
// 1. 校验用户积分余额
|
||||||
if (pointConfig == null || pointConfig.getTradeGivePoint() == null) {
|
|
||||||
log.error("[createPointRecord][增加积分失败:tradeGivePoint 未配置,userId({}) point({}) bizType({}) bizId({})]",
|
|
||||||
userId, point, bizType.getType(), bizId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. 根据配置的比例,换算实际的积分
|
|
||||||
point = point * pointConfig.getTradeGivePoint();
|
|
||||||
if (!bizType.isAdd() && point > 0) {
|
|
||||||
point = -point;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. 增加积分记录
|
|
||||||
MemberUserDO user = memberUserService.getUser(userId);
|
MemberUserDO user = memberUserService.getUser(userId);
|
||||||
Integer userPoint = ObjectUtil.defaultIfNull(user.getPoint(), 0);
|
Integer userPoint = ObjectUtil.defaultIfNull(user.getPoint(), 0);
|
||||||
Integer totalPoint = userPoint + point; // 用户变动后的积分
|
int totalPoint = userPoint + point; // 用户变动后的积分
|
||||||
|
if (totalPoint < 0) {
|
||||||
|
throw exception(USER_POINT_NOT_ENOUGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 更新用户积分
|
||||||
|
boolean success = memberUserService.updateUserPoint(userId, point);
|
||||||
|
if (!success) {
|
||||||
|
throw exception(USER_POINT_NOT_ENOUGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 增加积分记录
|
||||||
MemberPointRecordDO record = new MemberPointRecordDO()
|
MemberPointRecordDO record = new MemberPointRecordDO()
|
||||||
.setUserId(userId).setBizId(bizId).setBizType(bizType.getType())
|
.setUserId(userId).setBizId(bizId).setBizType(bizType.getType())
|
||||||
.setTitle(bizType.getName()).setDescription(StrUtil.format(bizType.getDescription(), point))
|
.setTitle(bizType.getName()).setDescription(StrUtil.format(bizType.getDescription(), point))
|
||||||
.setPoint(point).setTotalPoint(totalPoint);
|
.setPoint(point).setTotalPoint(totalPoint);
|
||||||
memberPointRecordMapper.insert(record);
|
memberPointRecordMapper.insert(record);
|
||||||
|
|
||||||
// 3. 更新用户积分
|
|
||||||
memberUserService.updateUserPoint(userId, totalPoint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,6 +164,7 @@ public interface MemberUserService {
|
||||||
*
|
*
|
||||||
* @param userId 用户编号
|
* @param userId 用户编号
|
||||||
* @param point 积分数量
|
* @param point 积分数量
|
||||||
|
* @return 更新结果
|
||||||
*/
|
*/
|
||||||
void updateUserPoint(Long userId, Integer point);
|
boolean updateUserPoint(Long userId, Integer point);
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,8 +260,13 @@ public class MemberUserServiceImpl implements MemberUserService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateUserPoint(Long userId, Integer point) {
|
public boolean updateUserPoint(Long id, Integer point) {
|
||||||
memberUserMapper.updateById(new MemberUserDO().setId(userId).setPoint(point));
|
if (point > 0) {
|
||||||
|
memberUserMapper.updatePointIncr(id, point);
|
||||||
|
} else if (point < 0) {
|
||||||
|
return memberUserMapper.updatePointDecr(id, point) > 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.system.api.dict;
|
||||||
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
|
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字典数据 API 接口
|
* 字典数据 API 接口
|
||||||
|
@ -30,6 +32,23 @@ public interface DictDataApi {
|
||||||
*/
|
*/
|
||||||
DictDataRespDTO getDictData(String type, String value);
|
DictDataRespDTO getDictData(String type, String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得指定类型的字典数据,从缓存中
|
||||||
|
*
|
||||||
|
* @param type 字典类型
|
||||||
|
* @return 字典数据
|
||||||
|
*/
|
||||||
|
List<DictDataRespDTO> getDictDataList(String type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得指定类型的字典数据 标签字典,从缓存中
|
||||||
|
* key:value, value: label
|
||||||
|
*
|
||||||
|
* @param type 字典类型
|
||||||
|
* @return 字典数据
|
||||||
|
*/
|
||||||
|
Map<String, String> getDictDataLabelMap(String type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析获得指定的字典数据,从缓存中
|
* 解析获得指定的字典数据,从缓存中
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package cn.iocoder.yudao.module.system.api.dict;
|
package cn.iocoder.yudao.module.system.api.dict;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
|
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataExportReqVO;
|
||||||
import cn.iocoder.yudao.module.system.convert.dict.DictDataConvert;
|
import cn.iocoder.yudao.module.system.convert.dict.DictDataConvert;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
|
||||||
import cn.iocoder.yudao.module.system.service.dict.DictDataService;
|
import cn.iocoder.yudao.module.system.service.dict.DictDataService;
|
||||||
|
@ -8,6 +9,10 @@ import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 字典数据 API 实现类
|
* 字典数据 API 实现类
|
||||||
|
@ -31,6 +36,18 @@ public class DictDataApiImpl implements DictDataApi {
|
||||||
return DictDataConvert.INSTANCE.convert02(dictData);
|
return DictDataConvert.INSTANCE.convert02(dictData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<DictDataRespDTO> getDictDataList(String type) {
|
||||||
|
List<DictDataDO> list = dictDataService.getDictDataList(new DictDataExportReqVO().setDictType(type));
|
||||||
|
return DictDataConvert.INSTANCE.convertList04(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> getDictDataLabelMap(String type) {
|
||||||
|
List<DictDataDO> list = dictDataService.getDictDataList(new DictDataExportReqVO().setDictType(type));
|
||||||
|
return convertMap(list, DictDataDO::getValue, DictDataDO::getLabel);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DictDataRespDTO parseDictData(String dictType, String label) {
|
public DictDataRespDTO parseDictData(String dictType, String label) {
|
||||||
DictDataDO dictData = dictDataService.parseDictData(dictType, label);
|
DictDataDO dictData = dictDataService.parseDictData(dictType, label);
|
||||||
|
|
|
@ -1,4 +1,37 @@
|
||||||
package cn.iocoder.yudao.module.system.controller.app.dict;
|
package cn.iocoder.yudao.module.system.controller.app.dict;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataExportReqVO;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.app.dict.vo.AppDictDataRespVO;
|
||||||
|
import cn.iocoder.yudao.module.system.convert.dict.DictDataConvert;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
|
||||||
|
import cn.iocoder.yudao.module.system.service.dict.DictDataService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
|
@Tag(name = "用户 App - 字典数据")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/system/dict-data")
|
||||||
|
@Validated
|
||||||
public class AppDictDataController {
|
public class AppDictDataController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private DictDataService dictDataService;
|
||||||
|
|
||||||
|
@GetMapping("/type/{dictType}")
|
||||||
|
@Operation(summary = "根据字典类型查询字典数据信息")
|
||||||
|
public CommonResult<List<AppDictDataRespVO>> getDicts(@PathVariable String dictType) {
|
||||||
|
List<DictDataDO> list = dictDataService.getDictDataList(new DictDataExportReqVO().setDictType(dictType));
|
||||||
|
return success(DictDataConvert.INSTANCE.convertList03(list));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package cn.iocoder.yudao.module.system.controller.app.dict.vo;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.DictDataBaseVO;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Schema(description = "用户 App - 字典数据信息 Response VO")
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class AppDictDataRespVO extends DictDataBaseVO {
|
||||||
|
|
||||||
|
@Schema(description = "字典数据编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
}
|
|
@ -3,11 +3,11 @@ package cn.iocoder.yudao.module.system.convert.dict;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
|
import cn.iocoder.yudao.module.system.api.dict.dto.DictDataRespDTO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.*;
|
import cn.iocoder.yudao.module.system.controller.admin.dict.vo.data.*;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.app.dict.vo.AppDictDataRespVO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
import org.mapstruct.factory.Mappers;
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
|
@ -29,4 +29,7 @@ public interface DictDataConvert {
|
||||||
|
|
||||||
DictDataRespDTO convert02(DictDataDO bean);
|
DictDataRespDTO convert02(DictDataDO bean);
|
||||||
|
|
||||||
|
List<AppDictDataRespVO> convertList03(List<DictDataDO> list);
|
||||||
|
|
||||||
|
List<DictDataRespDTO> convertList04(List<DictDataDO> list);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class DictDataServiceImpl implements DictDataService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<DictDataDO> getDictDataList() {
|
public List<DictDataDO> getDictDataList() {
|
||||||
List<DictDataDO> list = dictDataMapper.selectList();
|
List<DictDataDO> list = dictDataMapper.selectList(DictDataDO::getStatus, CommonStatusEnum.ENABLE.getStatus());
|
||||||
list.sort(COMPARATOR_TYPE_AND_SORT);
|
list.sort(COMPARATOR_TYPE_AND_SORT);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,10 +43,15 @@ public class DictDataServiceImplTest extends BaseDbUnitTest {
|
||||||
@Test
|
@Test
|
||||||
public void testGetDictDataList() {
|
public void testGetDictDataList() {
|
||||||
// mock 数据
|
// mock 数据
|
||||||
DictDataDO dictDataDO01 = randomDictDataDO().setDictType("yunai").setSort(2);
|
DictDataDO dictDataDO01 = randomDictDataDO().setDictType("yunai").setSort(2)
|
||||||
|
.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
dictDataMapper.insert(dictDataDO01);
|
dictDataMapper.insert(dictDataDO01);
|
||||||
DictDataDO dictDataDO02 = randomDictDataDO().setDictType("yunai").setSort(1);
|
DictDataDO dictDataDO02 = randomDictDataDO().setDictType("yunai").setSort(1)
|
||||||
|
.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
dictDataMapper.insert(dictDataDO02);
|
dictDataMapper.insert(dictDataDO02);
|
||||||
|
DictDataDO dictDataDO03 = randomDictDataDO().setDictType("yunai").setSort(3)
|
||||||
|
.setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||||
|
dictDataMapper.insert(dictDataDO03);
|
||||||
// 准备参数
|
// 准备参数
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
|
|
Loading…
Reference in New Issue