Merge remote-tracking branch 'yudao/feature/mall_product' into feature/mall_product

# Conflicts:
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java
#	yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java
plp
puhui999 3 years ago
commit 52848d6341

@ -2,41 +2,50 @@
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 0 not null comment '1- 2-',
brokerage_bind_mode tinyint default 0 not null comment ': 1-广2-, 3-', brokerage_bind_mode tinyint default 0 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_bank_names varchar(200) default '' not null comment '=brokerage_bank_name',
brokerage_frozen_days int default 7 not null comment '()', brokerage_frozen_days int default 7 not null comment '()',
brokerage_withdraw_type varchar(32) default '1,2,3,4' not null comment '1-2-3-4-', brokerage_withdraw_type varchar(32) default '1,2,3,4' not null comment '1-2-3-4-',
creator varchar(64) collate utf8mb4_unicode_ci default '' null comment '', 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) collate utf8mb4_unicode_ci default '' null comment '', updater varchar(64) default '' null comment '',
update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '', update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '',
deleted bit default b'0' not null comment '', deleted bit default b'0' not null comment '',
tenant_id bigint default 0 not null comment '' tenant_id bigint default 0 not null comment ''
) comment ''; ) comment '';
# alter table trade_brokerage_user
# add level int not null default 1 comment '' after frozen_price;
# alter table trade_brokerage_user
# add path varchar(2000) null comment '' after level;
-- --
create table trade_brokerage_user create table trade_brokerage_user
( (
id bigint auto_increment comment '' primary key, id bigint auto_increment comment '' primary key,
bind_user_id bigint null comment '广', bind_user_id bigint null comment '广',
bind_user_time datetime null comment '广', bind_user_time datetime null comment '广',
brokerage_enabled bit default 1 not null comment '广', brokerage_enabled bit default 1 not null comment '广',
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 '',
creator varchar(64) collate utf8mb4_unicode_ci default '' null comment '', level int default 1 not null comment '',
create_time datetime default CURRENT_TIMESTAMP not null comment '', path varchar(2000) null comment '',
updater varchar(64) collate utf8mb4_unicode_ci default '' null comment '', creator varchar(64) default '' null comment '',
update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '', create_time datetime default CURRENT_TIMESTAMP not null comment '',
deleted bit default b'0' not null comment '', updater varchar(64) default '' null comment '',
tenant_id bigint default 0 not null comment '' update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '',
) comment ''; deleted bit default b'0' not null comment '',
tenant_id bigint default 0 not null comment ''
)
comment '';
create index idx_invite_user_id on trade_brokerage_user (bind_user_id) comment '广'; create index idx_invite_user_id on trade_brokerage_user (bind_user_id) comment '广';
create index idx_agent on trade_brokerage_user (brokerage_enabled) comment '广'; create index idx_agent on trade_brokerage_user (brokerage_enabled) comment '广';
@ -44,26 +53,26 @@ create index idx_agent on trade_brokerage_user (brokerage_enabled) comment '是
create table trade_brokerage_record create table trade_brokerage_record
( (
id int auto_increment comment '' id int auto_increment comment ''
primary key, primary key,
user_id bigint not null comment '', user_id bigint not null comment '',
biz_id varchar(64) default '' not null comment '', biz_id varchar(64) default '' not null comment '',
biz_type tinyint default 0 not null comment '1-2-', biz_type tinyint default 0 not null comment '1-2-',
title varchar(64) default '' not null comment '', title varchar(64) default '' not null comment '',
price int default 0 not null comment '', price int default 0 not null comment '',
total_price int default 0 not null comment '', total_price int default 0 not null comment '',
description varchar(500) default '' not null comment '', description varchar(500) default '' not null comment '',
status tinyint default 0 not null comment '0-1-2-', status tinyint default 0 not null comment '0-1-2-',
frozen_days int default 0 not null comment '', frozen_days int default 0 not null comment '',
unfreeze_time datetime null comment '', unfreeze_time datetime null comment '',
source_user_type tinyint not null comment '1-广2-广', source_user_level int not null comment '',
source_user_id bigint not null comment '', source_user_id bigint not null comment '',
creator varchar(64) collate utf8mb4_general_ci 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) collate utf8mb4_general_ci default '' null comment '', updater varchar(64) default '' null comment '',
update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '', update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '',
deleted bit default b'0' not null comment '', deleted bit default b'0' not null comment '',
tenant_id bigint default 0 not null comment '' tenant_id bigint default 0 not null comment ''
) )
comment ''; comment '';
@ -76,26 +85,26 @@ create table trade_brokerage_withdraw
( (
id int auto_increment comment '' id int 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 '',
fee_price int default 0 not null comment '', fee_price int default 0 not null comment '',
total_price int default 0 not null comment '', total_price int default 0 not null comment '',
type tinyint default 0 not null comment '1-2-3-4-', type tinyint default 0 not null comment '1-2-3-4-',
name varchar(64) null comment '', name varchar(64) null comment '',
account_no varchar(64) null comment '', account_no varchar(64) null comment '',
bank_name varchar(100) null comment '', bank_name varchar(100) null comment '',
bank_address varchar(200) null comment '', bank_address varchar(200) null comment '',
account_qr_code_url varchar(512) null comment '', account_qr_code_url varchar(512) null comment '',
status tinyint(2) default 0 not null comment '0-10- 20-11 - 21-', status tinyint(2) default 0 not null comment '0-10- 20-11 - 21-',
audit_reason varchar(128) null comment '', audit_reason varchar(128) null comment '',
audit_time datetime null comment '', audit_time datetime null comment '',
remark varchar(500) null comment '', remark varchar(500) null comment '',
creator varchar(64) collate utf8mb4_general_ci 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) collate utf8mb4_general_ci default '' null comment '', updater varchar(64) default '' null comment '',
update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '', update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '',
deleted bit default b'0' not null comment '', deleted bit default b'0' not null comment '',
tenant_id bigint default 0 not null comment '' tenant_id bigint default 0 not null comment ''
) )
comment ''; comment '';
@ -139,12 +148,12 @@ values ('brokerage_record_status', '待结算', 0, 0),
insert into system_dict_type(type, name) insert into system_dict_type(type, name)
values ('brokerage_withdraw_status', ''); values ('brokerage_withdraw_status', '');
insert into system_dict_data(dict_type, label, value, sort) insert into system_dict_data(dict_type, label, value, sort, color_type)
values ('brokerage_withdraw_status', '', 0, 0), values ('brokerage_withdraw_status', '', 0, 0, ''),
('brokerage_withdraw_status', '', 10, 10), ('brokerage_withdraw_status', '', 10, 10, 'success'),
('brokerage_withdraw_status', '', 11, 11), ('brokerage_withdraw_status', '', 11, 11, 'success'),
('brokerage_withdraw_status', '', 20, 20), ('brokerage_withdraw_status', '', 20, 20, 'danger'),
('brokerage_withdraw_status', '', 21, 21); ('brokerage_withdraw_status', '', 21, 21, 'danger');
insert into system_dict_type(type, name) insert into system_dict_type(type, name)
values ('brokerage_bank_name', ''); values ('brokerage_bank_name', '');
@ -221,3 +230,9 @@ INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, com
VALUES ('', 'trade:brokerage-withdraw:query', 3, 1, @parentId, '', '', '', 0); VALUES ('', 'trade:brokerage-withdraw:query', 3, 1, @parentId, '', '', '', 0);
INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
VALUES ('', 'trade:brokerage-withdraw:audit', 3, 2, @parentId, '', '', '', 0); VALUES ('', 'trade:brokerage-withdraw:audit', 3, 2, @parentId, '', '', '', 0);
--
INSERT INTO `ruoyi-vue-pro`.system_notify_template (name, code, nickname, content, type, params, status)
VALUES
('', 'brokerage_withdraw_audit_approve', 'system', '{createTime}{price}', 2, '["createTime","price"]', 0),
('', 'brokerage_withdraw_audit_reject', 'system', '{createTime}{price}{reason}', 2, '["createTime","price","reason"]', 0);

@ -50,6 +50,7 @@ public class LocalDateTimeUtils {
* @return * @return
*/ */
public static LocalDateTime buildTime(String timeStr) { public static LocalDateTime buildTime(String timeStr) {
// TODO @puhui999这个方法的实现和 LocalDateTimeUtil.parse() 的差异点是啥呀
return LocalDateTime.of(LocalDate.now(), LocalTime.parse(timeStr)); return LocalDateTime.of(LocalDate.now(), LocalTime.parse(timeStr));
} }

@ -100,6 +100,14 @@ 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

@ -64,14 +64,14 @@ public class ${table.className}ServiceImpl implements ${table.className}Service
@Override @Override
public ${table.className}DO get${simpleClassName}(${primaryColumn.javaType} id) { public ${table.className}DO get${simpleClassName}(${primaryColumn.javaType} id) {
if (CollUtil.isEmpty(ids)) {
return ListUtil.empty();
}
return ${classNameVar}Mapper.selectById(id); return ${classNameVar}Mapper.selectById(id);
} }
@Override @Override
public List<${table.className}DO> get${simpleClassName}List(Collection<${primaryColumn.javaType}> ids) { public List<${table.className}DO> get${simpleClassName}List(Collection<${primaryColumn.javaType}> ids) {
if (CollUtil.isEmpty(ids)) {
return ListUtil.empty();
}
return ${classNameVar}Mapper.selectBatchIds(ids); return ${classNameVar}Mapper.selectBatchIds(ids);
} }

@ -31,7 +31,7 @@ public interface CombinationRecordApi {
boolean isCombinationRecordSuccess(Long userId, Long orderId); boolean isCombinationRecordSuccess(Long userId, Long orderId);
/** /**
* *
* *
* @param userId * @param userId
* @param orderId * @param orderId
@ -39,7 +39,7 @@ public interface CombinationRecordApi {
void updateRecordStatusToSuccess(Long userId, Long orderId); void updateRecordStatusToSuccess(Long userId, Long orderId);
/** /**
* *
* *
* @param userId * @param userId
* @param orderId * @param orderId

@ -7,6 +7,7 @@ package cn.iocoder.yudao.module.promotion.api.seckill;
*/ */
public interface SeckillActivityApi { public interface SeckillActivityApi {
// TODO @puhui999activityId 改成 id 好点哈;
/** /**
* *
* *

@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.promotion.controller.admin.bargain;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
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.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityCreateReqVO; import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityCreateReqVO;
@ -25,6 +24,7 @@ import javax.validation.Valid;
import java.util.List; import java.util.List;
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.convertList;
@Tag(name = "管理后台 - 砍价活动") @Tag(name = "管理后台 - 砍价活动")
@RestController @RestController
@ -79,7 +79,9 @@ public class BargainActivityController {
if (CollUtil.isEmpty(pageResult.getList())) { if (CollUtil.isEmpty(pageResult.getList())) {
return success(PageResult.empty(pageResult.getTotal())); return success(PageResult.empty(pageResult.getTotal()));
} }
List<ProductSpuRespDTO> spuList = spuApi.getSpuList(CollectionUtils.convertList(pageResult.getList(), BargainActivityDO::getSpuId));
// 拼接数据
List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(pageResult.getList(), BargainActivityDO::getSpuId));
return success(BargainActivityConvert.INSTANCE.convertPage(pageResult, spuList)); return success(BargainActivityConvert.INSTANCE.convertPage(pageResult, spuList));
} }

@ -4,7 +4,6 @@ import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
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.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.activity.AppBargainActivityDetailRespVO; import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.activity.AppBargainActivityDetailRespVO;
@ -25,6 +24,7 @@ import javax.annotation.Resource;
import java.util.List; import java.util.List;
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.convertList;
@Tag(name = "用户 App - 砍价活动") @Tag(name = "用户 App - 砍价活动")
@RestController @RestController
@ -39,27 +39,27 @@ public class AppBargainActivityController {
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "获得砍价活动分页") @Operation(summary = "获得砍价活动分页")
public CommonResult<PageResult<AppBargainActivityRespVO>> getBargainActivityPage(PageParam pageReqVO) { public CommonResult<PageResult<AppBargainActivityRespVO>> getBargainActivityPage(PageParam pageReqVO) {
PageResult<BargainActivityDO> result = bargainActivityService.getBargainActivityAppPage(pageReqVO); PageResult<BargainActivityDO> result = bargainActivityService.getBargainActivityPageForApp(pageReqVO);
if (CollUtil.isEmpty(result.getList())) { if (CollUtil.isEmpty(result.getList())) {
return success(PageResult.empty(result.getTotal())); return success(PageResult.empty(result.getTotal()));
} }
// 拼接数据
List<ProductSpuRespDTO> spuList = spuApi.getSpuList(CollectionUtils.convertList(result.getList(), BargainActivityDO::getSpuId)); List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(result.getList(), BargainActivityDO::getSpuId));
return success(BargainActivityConvert.INSTANCE.convertAppPage(result, spuList)); return success(BargainActivityConvert.INSTANCE.convertAppPage(result, spuList));
} }
// TODO 芋艿:增加 Spring Cache
@GetMapping("/list") @GetMapping("/list")
@Operation(summary = "获得砍价活动列表", description = "用于小程序首页") @Operation(summary = "获得砍价活动列表", description = "用于小程序首页")
@Parameter(name = "count", description = "需要展示的数量", example = "6") @Parameter(name = "count", description = "需要展示的数量", example = "6")
public CommonResult<List<AppBargainActivityRespVO>> getBargainActivityList( public CommonResult<List<AppBargainActivityRespVO>> getBargainActivityList(
@RequestParam(name = "count", defaultValue = "6") Integer count) { @RequestParam(name = "count", defaultValue = "6") Integer count) {
List<BargainActivityDO> list = bargainActivityService.getBargainActivityAppList(count); List<BargainActivityDO> list = bargainActivityService.getBargainActivityListForApp(count);
if (CollUtil.isEmpty(list)) { if (CollUtil.isEmpty(list)) {
return success(BargainActivityConvert.INSTANCE.convertAppList(list)); return success(BargainActivityConvert.INSTANCE.convertAppList(list));
} }
// 拼接数据
List<ProductSpuRespDTO> spuList = spuApi.getSpuList(CollectionUtils.convertList(list, BargainActivityDO::getSpuId)); List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(list, BargainActivityDO::getSpuId));
// TODO 芋艿:增加 Spring Cache
return success(BargainActivityConvert.INSTANCE.convertAppList(list, spuList)); return success(BargainActivityConvert.INSTANCE.convertAppList(list, spuList));
} }
@ -71,9 +71,9 @@ public class AppBargainActivityController {
if (activity == null) { if (activity == null) {
return success(null); return success(null);
} }
// 拼接数据
ProductSpuRespDTO spu = spuApi.getSpu(activity.getSpuId()); ProductSpuRespDTO spu = spuApi.getSpu(activity.getSpuId());
return success(BargainActivityConvert.INSTANCE.convert1(activity, spu)); return success(BargainActivityConvert.INSTANCE.convert(activity, spu));
} }
} }

@ -53,19 +53,20 @@ public class AppSeckillActivityController {
@GetMapping("/get-now") @GetMapping("/get-now")
@Operation(summary = "获得当前秒杀活动", description = "获取当前正在进行的活动,提供给首页使用") @Operation(summary = "获得当前秒杀活动", description = "获取当前正在进行的活动,提供给首页使用")
public CommonResult<AppSeckillActivityNowRespVO> getNowSeckillActivity() { public CommonResult<AppSeckillActivityNowRespVO> getNowSeckillActivity() {
// 1、获取当前时间处在哪个秒杀阶段 // 1. 获取当前时间处在哪个秒杀阶段
// TODO @puhui999可以考虑在 service 写个方法;这样 controller 不用关注过多逻辑
List<SeckillConfigDO> configList = configService.getSeckillConfigList(); List<SeckillConfigDO> configList = configService.getSeckillConfigList();
SeckillConfigDO filteredConfig = findFirst(configList, config -> ObjectUtil.equal(config.getStatus(), SeckillConfigDO filteredConfig = findFirst(configList, config -> ObjectUtil.equal(config.getStatus(),
CommonStatusEnum.ENABLE.getStatus()) && isBetween(config.getStartTime(), config.getEndTime())); CommonStatusEnum.ENABLE.getStatus()) && isBetween(config.getStartTime(), config.getEndTime()));
// 1、1 时段不存在直接返回 null if (filteredConfig == null) { // 时段不存在直接返回 null
if (filteredConfig == null) {
return success(null); return success(null);
} }
// 2、查询满足当前阶段的活动 // 2. 查询满足当前阶段的活动
// TODO @puhui999最好直接返回开启的不多查询数据
List<SeckillActivityDO> activityList = activityService.getSeckillActivityListByConfigIds(Arrays.asList(filteredConfig.getId())); List<SeckillActivityDO> activityList = activityService.getSeckillActivityListByConfigIds(Arrays.asList(filteredConfig.getId()));
List<SeckillActivityDO> filteredList = filterList(activityList, item -> ObjectUtil.equal(item.getStatus(), CommonStatusEnum.ENABLE.getStatus())); List<SeckillActivityDO> filteredList = filterList(activityList, item -> ObjectUtil.equal(item.getStatus(), CommonStatusEnum.ENABLE.getStatus()));
// 2、1 获取 spu 信息 // 3 获取 spu 信息
List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(filteredList, SeckillActivityDO::getSpuId)); List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(filteredList, SeckillActivityDO::getSpuId));
// TODO 芋艿:需要增加 spring cache // TODO 芋艿:需要增加 spring cache
return success(SeckillActivityConvert.INSTANCE.convert(filteredConfig, filteredList, spuList)); return success(SeckillActivityConvert.INSTANCE.convert(filteredConfig, filteredList, spuList));
@ -74,9 +75,10 @@ public class AppSeckillActivityController {
@GetMapping("/page") @GetMapping("/page")
@Operation(summary = "获得秒杀活动分页") @Operation(summary = "获得秒杀活动分页")
public CommonResult<PageResult<AppSeckillActivityRespVO>> getSeckillActivityPage(AppSeckillActivityPageReqVO pageReqVO) { public CommonResult<PageResult<AppSeckillActivityRespVO>> getSeckillActivityPage(AppSeckillActivityPageReqVO pageReqVO) {
// 1查询满足当前阶段的活动 // 1. 查询满足当前阶段的活动
PageResult<SeckillActivityDO> pageResult = activityService.getSeckillActivityAppPageByConfigId(pageReqVO); PageResult<SeckillActivityDO> pageResult = activityService.getSeckillActivityAppPageByConfigId(pageReqVO);
// 1、1 获取 spu 信息
// 2. 拼接数据
List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(pageResult.getList(), SeckillActivityDO::getSpuId)); List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(pageResult.getList(), SeckillActivityDO::getSpuId));
return success(SeckillActivityConvert.INSTANCE.convertPage(pageResult, spuList)); return success(SeckillActivityConvert.INSTANCE.convertPage(pageResult, spuList));
} }
@ -86,15 +88,15 @@ public class AppSeckillActivityController {
@Parameter(name = "id", description = "活动编号", required = true, example = "1024") @Parameter(name = "id", description = "活动编号", required = true, example = "1024")
public CommonResult<AppSeckillActivityDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) { public CommonResult<AppSeckillActivityDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) {
// 1、获取当前时间处在哪个秒杀阶段 // 1、获取当前时间处在哪个秒杀阶段
// TODO puhui999这里和 58 行是雷同的
List<SeckillConfigDO> configList = configService.getSeckillConfigList(); List<SeckillConfigDO> configList = configService.getSeckillConfigList();
SeckillConfigDO filteredConfig = findFirst(configList, config -> ObjectUtil.equal(config.getStatus(), SeckillConfigDO filteredConfig = findFirst(configList, config -> ObjectUtil.equal(config.getStatus(),
CommonStatusEnum.ENABLE.getStatus()) && isBetween(config.getStartTime(), config.getEndTime())); CommonStatusEnum.ENABLE.getStatus()) && isBetween(config.getStartTime(), config.getEndTime()));
// 1、1 时段不存在直接返回 null if (filteredConfig == null) { // 时段不存在直接返回 null
if (filteredConfig == null) {
return success(null); return success(null);
} }
// 2获取活动 // 2. 获取活动
SeckillActivityDO seckillActivity = activityService.getSeckillActivity(id); SeckillActivityDO seckillActivity = activityService.getSeckillActivity(id);
if (seckillActivity == null) { if (seckillActivity == null) {
return success(null); return success(null);
@ -103,7 +105,7 @@ public class AppSeckillActivityController {
throw exception(SECKILL_ACTIVITY_APP_STATUS_CLOSED); throw exception(SECKILL_ACTIVITY_APP_STATUS_CLOSED);
} }
// 3、获取活动商品 // 3. 拼接数据
List<SeckillProductDO> products = activityService.getSeckillProductListByActivityId(seckillActivity.getId()); List<SeckillProductDO> products = activityService.getSeckillProductListByActivityId(seckillActivity.getId());
return success(SeckillActivityConvert.INSTANCE.convert3(seckillActivity, products, filteredConfig)); return success(SeckillActivityConvert.INSTANCE.convert3(seckillActivity, products, filteredConfig));
} }

@ -32,19 +32,12 @@ public class AppSeckillConfigController {
@Operation(summary = "获得秒杀时间段列表") @Operation(summary = "获得秒杀时间段列表")
public CommonResult<List<AppSeckillConfigRespVO>> getSeckillConfigList() { public CommonResult<List<AppSeckillConfigRespVO>> getSeckillConfigList() {
List<SeckillConfigDO> list = configService.getSeckillConfigListByStatus(CommonStatusEnum.ENABLE.getStatus()); List<SeckillConfigDO> list = configService.getSeckillConfigListByStatus(CommonStatusEnum.ENABLE.getStatus());
// TODO @puhui999如果这种不用判空也问题不大
if (CollectionUtil.isEmpty(list)) { if (CollectionUtil.isEmpty(list)) {
return success(Collections.emptyList()); return success(Collections.emptyList());
} }
return success(SeckillConfigConvert.INSTANCE.convertList2(list)); return success(SeckillConfigConvert.INSTANCE.convertList2(list));
//return success(Arrays.asList(
// new AppSeckillConfigRespVO().setId(1L).setStartTime("00:00").setEndTime("09:59")
// .setSliderPicUrls(Arrays.asList("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg",
// "https://static.iocoder.cn/mall/132.jpeg")),
// new AppSeckillConfigRespVO().setId(2L).setStartTime("10:00").setEndTime("12:59"),
// new AppSeckillConfigRespVO().setId(2L).setStartTime("13:00").setEndTime("22:59"),
// new AppSeckillConfigRespVO().setId(2L).setStartTime("23:00").setEndTime("23:59")
//));
} }
} }

@ -42,9 +42,11 @@ public interface BargainActivityConvert {
default PageResult<BargainActivityRespVO> convertPage(PageResult<BargainActivityDO> page, List<ProductSpuRespDTO> spuList) { default PageResult<BargainActivityRespVO> convertPage(PageResult<BargainActivityDO> page, List<ProductSpuRespDTO> spuList) {
PageResult<BargainActivityRespVO> result = convertPage(page); PageResult<BargainActivityRespVO> result = convertPage(page);
// 拼接关联属性
Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
List<BargainActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> { List<BargainActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> {
findAndThen(spuMap, item.getSpuId(), spu -> { findAndThen(spuMap, item.getSpuId(), spu -> {
// TODO @puhui999这里可以使用链式哈
item.setPicUrl(spu.getPicUrl()); item.setPicUrl(spu.getPicUrl());
item.setSpuName(spu.getName()); item.setSpuName(spu.getName());
}); });
@ -56,7 +58,7 @@ public interface BargainActivityConvert {
AppBargainActivityDetailRespVO convert1(BargainActivityDO bean); AppBargainActivityDetailRespVO convert1(BargainActivityDO bean);
default AppBargainActivityDetailRespVO convert1(BargainActivityDO bean, ProductSpuRespDTO spu) { default AppBargainActivityDetailRespVO convert(BargainActivityDO bean, ProductSpuRespDTO spu) {
AppBargainActivityDetailRespVO detail = convert1(bean); AppBargainActivityDetailRespVO detail = convert1(bean);
if (spu != null) { if (spu != null) {
detail.setPicUrl(spu.getPicUrl()); detail.setPicUrl(spu.getPicUrl());
@ -70,9 +72,11 @@ public interface BargainActivityConvert {
default PageResult<AppBargainActivityRespVO> convertAppPage(PageResult<BargainActivityDO> page, List<ProductSpuRespDTO> spuList) { default PageResult<AppBargainActivityRespVO> convertAppPage(PageResult<BargainActivityDO> page, List<ProductSpuRespDTO> spuList) {
PageResult<AppBargainActivityRespVO> result = convertAppPage(page); PageResult<AppBargainActivityRespVO> result = convertAppPage(page);
// 拼接关联属性
Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
List<AppBargainActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> { List<AppBargainActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> {
findAndThen(spuMap, item.getSpuId(), spu -> { findAndThen(spuMap, item.getSpuId(), spu -> {
// TODO @puhui999这里可以使用链式哈
item.setPicUrl(spu.getPicUrl()); item.setPicUrl(spu.getPicUrl());
item.setMarketPrice(spu.getMarketPrice()); item.setMarketPrice(spu.getMarketPrice());
}); });
@ -89,6 +93,7 @@ public interface BargainActivityConvert {
Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
return CollectionUtils.convertList(activityList, item -> { return CollectionUtils.convertList(activityList, item -> {
findAndThen(spuMap, item.getSpuId(), spu -> { findAndThen(spuMap, item.getSpuId(), spu -> {
// TODO @puhui999这里可以使用链式哈
item.setPicUrl(spu.getPicUrl()); item.setPicUrl(spu.getPicUrl());
item.setMarketPrice(spu.getMarketPrice()); item.setMarketPrice(spu.getMarketPrice());
}); });

@ -97,8 +97,10 @@ public interface CombinationActivityConvert {
CombinationRecordDO convert(CombinationRecordCreateReqDTO reqDTO); CombinationRecordDO convert(CombinationRecordCreateReqDTO reqDTO);
default CombinationRecordDO convert1(CombinationRecordCreateReqDTO reqDTO, CombinationActivityDO activity, MemberUserRespDTO user, default CombinationRecordDO convert(CombinationRecordCreateReqDTO reqDTO,
ProductSpuRespDTO spu, ProductSkuRespDTO sku) { CombinationActivityDO activity, MemberUserRespDTO user,
ProductSpuRespDTO spu, ProductSkuRespDTO sku) {
// TODO @puhui999搞成链式的 set这样会更规整一点
CombinationRecordDO record = convert(reqDTO); CombinationRecordDO record = convert(reqDTO);
record.setVirtualGroup(false); record.setVirtualGroup(false);
record.setExpireTime(record.getStartTime().plusHours(activity.getLimitDuration())); record.setExpireTime(record.getStartTime().plusHours(activity.getLimitDuration()));

@ -98,6 +98,7 @@ public interface SeckillActivityConvert {
Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
respVO.setActivities(CollectionUtils.convertList(convertList3(activityList), item -> { respVO.setActivities(CollectionUtils.convertList(convertList3(activityList), item -> {
findAndThen(spuMap, item.getSpuId(), spu -> { findAndThen(spuMap, item.getSpuId(), spu -> {
// TODO @puhui999可以尝试链式 set 哈;
item.setPicUrl(spu.getPicUrl()); item.setPicUrl(spu.getPicUrl());
item.setMarketPrice(spu.getMarketPrice()); item.setMarketPrice(spu.getMarketPrice());
item.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit())); item.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit()));
@ -114,6 +115,7 @@ public interface SeckillActivityConvert {
Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId);
List<AppSeckillActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> { List<AppSeckillActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> {
findAndThen(spuMap, item.getSpuId(), spu -> { findAndThen(spuMap, item.getSpuId(), spu -> {
// TODO @puhui999可以尝试链式 set 哈;
item.setPicUrl(spu.getPicUrl()); item.setPicUrl(spu.getPicUrl());
item.setMarketPrice(spu.getMarketPrice()); item.setMarketPrice(spu.getMarketPrice());
item.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit())); item.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit()));
@ -131,6 +133,7 @@ public interface SeckillActivityConvert {
default AppSeckillActivityDetailRespVO convert3(SeckillActivityDO seckillActivity, List<SeckillProductDO> products, SeckillConfigDO filteredConfig) { default AppSeckillActivityDetailRespVO convert3(SeckillActivityDO seckillActivity, List<SeckillProductDO> products, SeckillConfigDO filteredConfig) {
AppSeckillActivityDetailRespVO respVO = convert2(seckillActivity); AppSeckillActivityDetailRespVO respVO = convert2(seckillActivity);
respVO.setProducts(convertList1(products)); respVO.setProducts(convertList1(products));
// TODO @puhui999可以尝试链式 set 哈;
respVO.setStartTime(buildTime(filteredConfig.getStartTime())); respVO.setStartTime(buildTime(filteredConfig.getStartTime()));
respVO.setEndTime(buildTime(filteredConfig.getEndTime())); respVO.setEndTime(buildTime(filteredConfig.getEndTime()));
return respVO; return respVO;

@ -41,7 +41,7 @@ public interface BargainActivityMapper extends BaseMapperX<BargainActivityDO> {
default int updateActivityStock(Long id, int count) { default int updateActivityStock(Long id, int count) {
return update(null, new LambdaUpdateWrapper<BargainActivityDO>() return update(null, new LambdaUpdateWrapper<BargainActivityDO>()
.eq(BargainActivityDO::getId, id) .eq(BargainActivityDO::getId, id)
.gt(BargainActivityDO::getStock, count) .ge(BargainActivityDO::getStock, count)
.setSql("stock = stock - " + count)); .setSql("stock = stock - " + count));
} }

@ -52,6 +52,7 @@ public interface SeckillActivityMapper extends BaseMapperX<SeckillActivityDO> {
default PageResult<SeckillActivityDO> selectPage(AppSeckillActivityPageReqVO pageReqVO, Integer status) { default PageResult<SeckillActivityDO> selectPage(AppSeckillActivityPageReqVO pageReqVO, Integer status) {
return selectPage(pageReqVO, new LambdaQueryWrapperX<SeckillActivityDO>() return selectPage(pageReqVO, new LambdaQueryWrapperX<SeckillActivityDO>()
.eqIfPresent(SeckillActivityDO::getStatus, status) .eqIfPresent(SeckillActivityDO::getStatus, status)
// TODO 芋艿:对 find in set 的想法;
.apply(ObjectUtil.isNotNull(pageReqVO.getConfigId()), "FIND_IN_SET(" + pageReqVO.getConfigId() + ",config_ids) > 0")); .apply(ObjectUtil.isNotNull(pageReqVO.getConfigId()), "FIND_IN_SET(" + pageReqVO.getConfigId() + ",config_ids) > 0"));
} }

@ -63,20 +63,22 @@ public interface BargainActivityService {
*/ */
PageResult<BargainActivityDO> getBargainActivityPage(BargainActivityPageReqVO pageReqVO); PageResult<BargainActivityDO> getBargainActivityPage(BargainActivityPageReqVO pageReqVO);
// TODO @puhui999这里可以改成进行中的活动尽量避免专门为 app 定制或者类似的名字哈mapper 那也是
/** /**
* APP * APP
* *
* @param pageReqVO * @param pageReqVO
* @return * @return
*/ */
PageResult<BargainActivityDO> getBargainActivityAppPage(PageParam pageReqVO); PageResult<BargainActivityDO> getBargainActivityPageForApp(PageParam pageReqVO);
/** /**
* APP * APP
* *
* @param count * @param count
* @return * @return
*/ */
List<BargainActivityDO> getBargainActivityAppList(Integer count); List<BargainActivityDO> getBargainActivityListForApp(Integer count);
} }

@ -142,18 +142,20 @@ public class BargainActivityServiceImpl implements BargainActivityService {
} }
@Override @Override
public PageResult<BargainActivityDO> getBargainActivityAppPage(PageParam pageReqVO) { public PageResult<BargainActivityDO> getBargainActivityPageForApp(PageParam pageReqVO) {
// 只查询进行中,且在时间范围内的 // 只查询进行中,且在时间范围内的
return bargainActivityMapper.selectAppPage(pageReqVO, CommonStatusEnum.ENABLE.getStatus(), LocalDateTime.now()); return bargainActivityMapper.selectAppPage(pageReqVO, CommonStatusEnum.ENABLE.getStatus(), LocalDateTime.now());
} }
@Override @Override
public List<BargainActivityDO> getBargainActivityAppList(Integer count) { public List<BargainActivityDO> getBargainActivityListForApp(Integer count) {
// TODO @puhui999这种 default count 的逻辑,可以放到 controller 哈;然后可以使用 ObjectUtils.default 方法
if (count == null) { if (count == null) {
count = 6; count = 6;
} }
PageResult<BargainActivityDO> result = bargainActivityMapper.selectAppPage(new PageParam().setPageSize(count), CommonStatusEnum.ENABLE.getStatus(), LocalDateTime.now()); // TODO @puhui999这种不要用 page会浪费一次 count
PageResult<BargainActivityDO> result = bargainActivityMapper.selectAppPage(new PageParam().setPageSize(count),
CommonStatusEnum.ENABLE.getStatus(), LocalDateTime.now());
return result.getList(); return result.getList();
} }

@ -75,6 +75,7 @@ public interface CombinationActivityService {
/** /**
* *
*
* *
* @param activityId * @param activityId
* @param userId * @param userId

@ -224,6 +224,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
throw exception(COMBINATION_ACTIVITY_STATUS_DISABLE); throw exception(COMBINATION_ACTIVITY_STATUS_DISABLE);
} }
// 1.3 校验是否超出单次限购数量 // 1.3 校验是否超出单次限购数量
// TODO puhui999count > activity.getSingleLimitCount() 会更好理解点;
if (activity.getSingleLimitCount() < count) { if (activity.getSingleLimitCount() < count) {
throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED); throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED);
} }
@ -243,7 +244,6 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
if (activity.getTotalLimitCount() < countSum) { if (activity.getTotalLimitCount() < countSum) {
throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED); throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED);
} }
} }
@Override @Override

@ -132,7 +132,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
MemberUserRespDTO user = memberUserApi.getUser(reqDTO.getUserId()); MemberUserRespDTO user = memberUserApi.getUser(reqDTO.getUserId());
ProductSpuRespDTO spu = productSpuApi.getSpu(reqDTO.getSpuId()); ProductSpuRespDTO spu = productSpuApi.getSpu(reqDTO.getSpuId());
ProductSkuRespDTO sku = productSkuApi.getSku(reqDTO.getSkuId()); ProductSkuRespDTO sku = productSkuApi.getSku(reqDTO.getSkuId());
recordMapper.insert(CombinationActivityConvert.INSTANCE.convert1(reqDTO, activity, user, spu, sku)); recordMapper.insert(CombinationActivityConvert.INSTANCE.convert(reqDTO, activity, user, spu, sku));
} }
@Override @Override

@ -1,52 +0,0 @@
package cn.iocoder.yudao.module.trade.api.brokerage;
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserDTO;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
// TODO @疯狂:是不是不需要这个啦?
/**
* API
*
* @author owen
*/
public interface BrokerageApi {
/**
*
*
* @param userId
* @return
*/
BrokerageUserDTO getBrokerageUser(Long userId);
/**
* 广
*
* @param userId
* @param bindUserId 广
* @param registerTime
* @return
*/
default boolean bindUser(@NotNull Long userId, @NotNull Long bindUserId, @NotNull LocalDateTime registerTime) {
// 注册时间在30秒内的都算新用户
// TODO @疯狂:这个要不抽到 service 里哈?
boolean isNewUser = LocalDateTimeUtils.afterNow(registerTime.minusSeconds(30));
return bindUser(userId, bindUserId, isNewUser);
}
/**
* 广
*
* @param userId
* @param bindUserId 广
* @param isNewUser
* @return
*/
boolean bindUser(@NotNull(message = "用户编号不能为空") Long userId,
@NotNull(message = "推广员编号不能为空") Long bindUserId,
@NotNull Boolean isNewUser);
}

@ -1,51 +0,0 @@
package cn.iocoder.yudao.module.trade.api.brokerage.dto;
import lombok.Data;
import java.time.LocalDateTime;
/**
* DTO
*
* @author owen
*/
@Data
public class BrokerageUserDTO {
/**
*
* <p>
* MemberUserDO id
*/
private Long id;
/**
* 广
* <p>
* MemberUserDO id
*/
private Long bindUserId;
/**
* 广
*/
private LocalDateTime bindUserTime;
/**
* 广
*/
private Boolean brokerageEnabled;
/**
*
*/
private LocalDateTime brokerageTime;
/**
*
*/
private Integer price;
/**
*
*/
private Integer frozenPrice;
}

@ -88,4 +88,9 @@ public interface ErrorCodeConstants {
ErrorCode BROKERAGE_BIND_OVERRIDE = new ErrorCode(1011007006, "已绑定了推广人"); ErrorCode BROKERAGE_BIND_OVERRIDE = new ErrorCode(1011007006, "已绑定了推广人");
ErrorCode BROKERAGE_BIND_LOOP = new ErrorCode(1011007007, "下级不能绑定自己的上级"); ErrorCode BROKERAGE_BIND_LOOP = new ErrorCode(1011007007, "下级不能绑定自己的上级");
// ========== 分销提现 模块 1011008000 ==========
ErrorCode BROKERAGE_WITHDRAW_NOT_EXISTS = new ErrorCode(1011008000, "佣金提现记录不存在");
ErrorCode BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING = new ErrorCode(1011008001, "佣金提现记录状态不是审核中");
} }

@ -10,4 +10,7 @@ public interface MessageTemplateConstants {
String ORDER_DELIVERY = "order_delivery"; // 短信模版编号 String ORDER_DELIVERY = "order_delivery"; // 短信模版编号
String BROKERAGE_WITHDRAW_AUDIT_APPROVE = "brokerage_withdraw_audit_approve"; // 佣金提现(审核通过)
String BROKERAGE_WITHDRAW_AUDIT_REJECT = "brokerage_withdraw_audit_reject"; // 佣金提现(审核不通过)
} }

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

@ -1,33 +0,0 @@
package cn.iocoder.yudao.module.trade.api.brokerage;
import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserDTO;
import cn.iocoder.yudao.module.trade.convert.brokerage.user.BrokerageUserConvert;
import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
/**
* API
*
* @author owen
*/
@Service
@Validated
public class BrokerageApiImpl implements BrokerageApi {
@Resource
private BrokerageUserService brokerageUserService;
@Override
public BrokerageUserDTO getBrokerageUser(Long userId) {
return BrokerageUserConvert.INSTANCE.convertDTO(brokerageUserService.getBrokerageUser(userId));
}
@Override
public boolean bindUser(Long userId, Long bindUserId, Boolean isNewUser) {
return brokerageUserService.bindBrokerageUser(userId, bindUserId, isNewUser);
}
}

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

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

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

@ -1,8 +1,6 @@
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo; package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -22,18 +20,18 @@ public class BrokerageUserPageReqVO extends PageParam {
@Schema(description = "推广员编号", example = "4587") @Schema(description = "推广员编号", example = "4587")
private Long bindUserId; private Long bindUserId;
@Schema(description = "推广资格") @Schema(description = "推广资格", example = "true")
private Boolean brokerageEnabled; private Boolean brokerageEnabled;
@Schema(description = "创建时间") @Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime; private LocalDateTime[] createTime;
@Schema(description = "用户类型") @Schema(description = "用户等级", example = "1") // 注意,这了不是用户的会员等级,而是过滤推广的层级
@InEnum(value = BrokerageUserTypeEnum.class, message = "用户类型必须是 {value}") private Integer level;
private Integer userType;
@Schema(description = "绑定时间") @Schema(description = "绑定时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] bindUserTime; private LocalDateTime[] bindUserTime;
} }

@ -0,0 +1,78 @@
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawRejectReqVO;
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawPageReqVO;
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawRespVO;
import cn.iocoder.yudao.module.trade.convert.brokerage.withdraw.BrokerageWithdrawConvert;
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw.BrokerageWithdrawDO;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
import cn.iocoder.yudao.module.trade.service.brokerage.withdraw.BrokerageWithdrawService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
@Tag(name = "管理后台 - 佣金提现")
@RestController
@RequestMapping("/trade/brokerage-withdraw")
@Validated
public class BrokerageWithdrawController {
@Resource
private BrokerageWithdrawService brokerageWithdrawService;
@Resource
private MemberUserApi memberUserApi;
@PutMapping("/approve")
@Operation(summary = "通过申请")
@PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:audit')")
public CommonResult<Boolean> approveBrokerageWithdraw(@RequestParam("id") Integer id) {
brokerageWithdrawService.auditBrokerageWithdraw(id, BrokerageWithdrawStatusEnum.AUDIT_SUCCESS, "");
return success(true);
}
@PutMapping("/reject")
@Operation(summary = "驳回申请")
@PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:audit')")
public CommonResult<Boolean> rejectBrokerageWithdraw(@Valid @RequestBody BrokerageWithdrawRejectReqVO reqVO) {
brokerageWithdrawService.auditBrokerageWithdraw(reqVO.getId(), BrokerageWithdrawStatusEnum.AUDIT_FAIL, reqVO.getAuditReason());
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得佣金提现")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:query')")
public CommonResult<BrokerageWithdrawRespVO> getBrokerageWithdraw(@RequestParam("id") Integer id) {
BrokerageWithdrawDO brokerageWithdraw = brokerageWithdrawService.getBrokerageWithdraw(id);
return success(BrokerageWithdrawConvert.INSTANCE.convert(brokerageWithdraw));
}
@GetMapping("/page")
@Operation(summary = "获得佣金提现分页")
@PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:query')")
public CommonResult<PageResult<BrokerageWithdrawRespVO>> getBrokerageWithdrawPage(@Valid BrokerageWithdrawPageReqVO pageVO) {
// 分页查询
PageResult<BrokerageWithdrawDO> pageResult = brokerageWithdrawService.getBrokerageWithdrawPage(pageVO);
// 拼接信息
Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(
convertSet(pageResult.getList(), BrokerageWithdrawDO::getUserId));
return success(BrokerageWithdrawConvert.INSTANCE.convertPage(pageResult, userMap));
}
}

@ -0,0 +1,68 @@
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
/**
* Base VO VO 使
* VO Swagger
*/
@Data
public class BrokerageWithdrawBaseVO {
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11436")
@NotNull(message = "用户编号不能为空")
private Long userId;
@Schema(description = "提现金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "18781")
@NotNull(message = "提现金额不能为空")
private Integer price;
@Schema(description = "提现手续费", requiredMode = Schema.RequiredMode.REQUIRED, example = "11417")
@NotNull(message = "提现手续费不能为空")
private Integer feePrice;
@Schema(description = "当前总佣金", requiredMode = Schema.RequiredMode.REQUIRED, example = "18576")
@NotNull(message = "当前总佣金不能为空")
private Integer totalPrice;
@Schema(description = "提现类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "提现类型不能为空")
private Integer type;
@Schema(description = "真实姓名", example = "赵六")
private String name;
@Schema(description = "账号", example = "88677912132")
private String accountNo;
@Schema(description = "银行名称", example = "1")
private String bankName;
@Schema(description = "开户地址", example = "海淀支行")
private String bankAddress;
@Schema(description = "收款码", example = "https://www.iocoder.cn")
private String accountQrCodeUrl;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "状态不能为空")
private Integer status;
@Schema(description = "审核驳回原因", example = "不对")
private String auditReason;
@Schema(description = "审核时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime auditTime;
@Schema(description = "备注", example = "随便")
private String remark;
}

@ -0,0 +1,47 @@
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 佣金提现分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BrokerageWithdrawPageReqVO extends PageParam {
@Schema(description = "用户编号", example = "11436")
private Long userId;
@Schema(description = "提现类型", example = "1")
@InEnum(value = BrokerageWithdrawTypeEnum.class, message = "提现类型必须是 {value}")
private Integer type;
@Schema(description = "真实姓名", example = "赵六")
private String name;
@Schema(description = "账号", example = "886779132")
private String accountNo;
@Schema(description = "银行名称", example = "1")
private String bankName;
@Schema(description = "状态", example = "1")
@InEnum(value = BrokerageWithdrawStatusEnum.class, message = "状态必须是 {value}")
private Integer status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

@ -0,0 +1,23 @@
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - 驳回申请 Request VO")
@Data
@ToString(callSuper = true)
public class BrokerageWithdrawRejectReqVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7161")
@NotNull(message = "编号不能为空")
private Integer id;
@Schema(description = "审核驳回原因", example = "不对")
@NotEmpty(message = "审核驳回原因不能为空")
private String auditReason;
}

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 佣金提现 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class BrokerageWithdrawRespVO extends BrokerageWithdrawBaseVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7161")
private Integer id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
@Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
private String userNickname;
}

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

@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.convert.brokerage.user;
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.api.brokerage.dto.BrokerageUserDTO;
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserRespVO; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserRespVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO; import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO; import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO;
@ -56,6 +55,4 @@ public interface BrokerageUserConvert {
user -> target.setNickname(user.getNickname()).setAvatar(user.getAvatar())); user -> target.setNickname(user.getNickname()).setAvatar(user.getAvatar()));
return target; return target;
} }
BrokerageUserDTO convertDTO(BrokerageUserDO brokerageUser);
} }

@ -0,0 +1,41 @@
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;
}
}

@ -27,7 +27,6 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO;
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
@ -274,10 +273,10 @@ public interface TradeOrderConvert {
TradeOrderDO convert(TradeOrderRemarkReqVO reqVO); TradeOrderDO convert(TradeOrderRemarkReqVO reqVO);
default BrokerageAddReqBO convert(TradeOrderItemDO item, ProductSkuRespDTO sku) { default BrokerageAddReqBO convert(MemberUserRespDTO user, TradeOrderItemDO item, ProductSkuRespDTO sku) {
return new BrokerageAddReqBO().setBizId(String.valueOf(item.getId())).setSourceUserId(item.getUserId()) return new BrokerageAddReqBO().setBizId(String.valueOf(item.getId())).setSourceUserId(item.getUserId())
.setBasePrice(item.getPayPrice() * item.getCount()) .setBasePrice(item.getPayPrice() * item.getCount())
.setTitle(BrokerageRecordBizTypeEnum.ORDER.getTitle()) // TODO @疯狂标题类似木晴冰雪成功购买云时代的JVM原理与实战茫农成功购买深入拆解消息队列47讲 .setTitle(StrUtil.format("{}成功购买{}", user.getNickname(), item.getSpuName()))
.setFirstFixedPrice(sku.getFirstBrokeragePrice()).setSecondFixedPrice(sku.getSecondBrokeragePrice()); .setFirstFixedPrice(sku.getFirstBrokeragePrice()).setSecondFixedPrice(sku.getSecondBrokeragePrice());
} }
@ -292,6 +291,7 @@ public interface TradeOrderConvert {
@Mapping(target = "userId", source = "userId"), @Mapping(target = "userId", source = "userId"),
@Mapping(target = "payPrice", source = "tradeOrderDO.payPrice"), @Mapping(target = "payPrice", source = "tradeOrderDO.payPrice"),
}) })
TradeAfterOrderCreateReqBO convert(Long userId, AppTradeOrderCreateReqVO createReqVO, TradeOrderDO tradeOrderDO, TradeOrderItemDO orderItem); TradeAfterOrderCreateReqBO convert(Long userId, AppTradeOrderCreateReqVO createReqVO,
TradeOrderDO tradeOrderDO, TradeOrderItemDO orderItem);
} }

@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
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.enums.brokerage.BrokerageUserTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
@ -83,11 +82,11 @@ public class BrokerageRecordDO extends BaseDO {
private LocalDateTime unfreezeTime; private LocalDateTime unfreezeTime;
/** /**
* *
* <p> * <p>
* {@link BrokerageUserTypeEnum}广 {@link #userId} 广 * 广 {@link #userId} 广
*/ */
private Integer sourceUserType; private Integer sourceUserLevel;
/** /**
* *
* <p> * <p>

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

@ -0,0 +1,98 @@
package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw;
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.BrokerageWithdrawTypeEnum;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.time.LocalDateTime;
/**
* DO
*
* @author
*/
@TableName("trade_brokerage_withdraw")
@KeySequence("trade_brokerage_withdraw_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BrokerageWithdrawDO extends BaseDO {
/**
*
*/
@TableId
private Integer id;
/**
*
*
* MemberUserDO id
*/
private Long userId;
/**
*
*/
private Integer price;
/**
*
*/
private Integer feePrice;
/**
*
*/
private Integer totalPrice;
/**
*
* <p>
* {@link BrokerageWithdrawTypeEnum}
*/
private Integer type;
/**
*
*/
private String name;
/**
*
*/
private String accountNo;
/**
*
*/
private String bankName;
/**
*
*/
private String bankAddress;
/**
*
*/
private String accountQrCodeUrl;
/**
*
* <p>
* {@link BrokerageWithdrawStatusEnum}
*/
private Integer status;
/**
*
*/
private String auditReason;
/**
*
*/
private LocalDateTime auditTime;
/**
*
*/
private String remark;
}

@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.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.record.vo.BrokerageRecordPageReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO; import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum;
import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO; import 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 org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@ -24,14 +23,12 @@ import java.util.List;
public interface BrokerageRecordMapper extends BaseMapperX<BrokerageRecordDO> { public interface BrokerageRecordMapper extends BaseMapperX<BrokerageRecordDO> {
default PageResult<BrokerageRecordDO> selectPage(BrokerageRecordPageReqVO reqVO) { default PageResult<BrokerageRecordDO> selectPage(BrokerageRecordPageReqVO reqVO) {
boolean sourceUserTypeCondition = reqVO.getSourceUserType() != null &&
!BrokerageUserTypeEnum.ALL.getType().equals(reqVO.getSourceUserType());
// 分页查询 // 分页查询
return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageRecordDO>() return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageRecordDO>()
.eqIfPresent(BrokerageRecordDO::getUserId, reqVO.getUserId()) .eqIfPresent(BrokerageRecordDO::getUserId, reqVO.getUserId())
.eqIfPresent(BrokerageRecordDO::getBizType, reqVO.getBizType()) .eqIfPresent(BrokerageRecordDO::getBizType, reqVO.getBizType())
.eqIfPresent(BrokerageRecordDO::getStatus, reqVO.getStatus()) .eqIfPresent(BrokerageRecordDO::getStatus, reqVO.getStatus())
.eq(sourceUserTypeCondition, BrokerageRecordDO::getSourceUserType, reqVO.getSourceUserType()) .eqIfPresent(BrokerageRecordDO::getSourceUserLevel, reqVO.getSourceUserLevel())
.betweenIfPresent(BrokerageRecordDO::getCreateTime, reqVO.getCreateTime()) .betweenIfPresent(BrokerageRecordDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(BrokerageRecordDO::getId)); .orderByDesc(BrokerageRecordDO::getId));
} }
@ -59,4 +56,5 @@ public interface BrokerageRecordMapper extends BaseMapperX<BrokerageRecordDO> {
UserBrokerageSummaryBO selectCountAndSumPriceByUserIdAndBizTypeAndStatus(@Param("userId") Long userId, UserBrokerageSummaryBO selectCountAndSumPriceByUserIdAndBizTypeAndStatus(@Param("userId") Long userId,
@Param("bizType") Integer bizType, @Param("bizType") Integer bizType,
@Param("status") Integer status); @Param("status") Integer status);
} }

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

@ -0,0 +1,37 @@
package cn.iocoder.yudao.module.trade.dal.mysql.brokerage.withdraw;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawPageReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw.BrokerageWithdrawDO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
/**
* Mapper
*
* @author
*/
@Mapper
public interface BrokerageWithdrawMapper extends BaseMapperX<BrokerageWithdrawDO> {
default PageResult<BrokerageWithdrawDO> selectPage(BrokerageWithdrawPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageWithdrawDO>()
.eqIfPresent(BrokerageWithdrawDO::getUserId, reqVO.getUserId())
.eqIfPresent(BrokerageWithdrawDO::getType, reqVO.getType())
.likeIfPresent(BrokerageWithdrawDO::getName, reqVO.getName())
.eqIfPresent(BrokerageWithdrawDO::getAccountNo, reqVO.getAccountNo())
.likeIfPresent(BrokerageWithdrawDO::getBankName, reqVO.getBankName())
.eqIfPresent(BrokerageWithdrawDO::getStatus, reqVO.getStatus())
.betweenIfPresent(BrokerageWithdrawDO::getCreateTime, reqVO.getCreateTime())
.orderByAsc(BrokerageWithdrawDO::getStatus).orderByDesc(BrokerageWithdrawDO::getId));
}
default int updateByIdAndStatus(Integer id, Integer status, BrokerageWithdrawDO updateObj) {
return update(updateObj, new LambdaUpdateWrapper<BrokerageWithdrawDO>()
.eq(BrokerageWithdrawDO::getId, id)
.eq(BrokerageWithdrawDO::getStatus, status));
}
}

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

@ -1,10 +1,12 @@
package cn.iocoder.yudao.module.trade.service.brokerage.user; package cn.iocoder.yudao.module.trade.service.brokerage.user;
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.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO; import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO; import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
@ -91,10 +93,24 @@ public interface BrokerageUserService {
* 广 * 广
* *
* @param bindUserId 广 * @param bindUserId 广
* @param userType * @param level 广
* @return 广 * @return 广
*/ */
Long getBrokerageUserCountByBindUserId(Long bindUserId, BrokerageUserTypeEnum userType); Long getBrokerageUserCountByBindUserId(Long bindUserId, Integer level);
/**
* 广
*
* @param userId
* @param bindUserId 广
* @param registerTime
* @return
*/
default boolean bindBrokerageUser(@NotNull Long userId, @NotNull Long bindUserId, @NotNull LocalDateTime registerTime) {
// 注册时间在30秒内的都算新用户
boolean isNewUser = LocalDateTimeUtils.afterNow(registerTime.minusSeconds(30));
return bindBrokerageUser(userId, bindUserId, isNewUser);
}
/** /**
* 广 * 广

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

@ -0,0 +1,40 @@
package cn.iocoder.yudao.module.trade.service.brokerage.withdraw;
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.dal.dataobject.brokerage.withdraw.BrokerageWithdrawDO;
import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum;
/**
* Service
*
* @author
*/
public interface BrokerageWithdrawService {
/**
*
*
* @param id
* @param status
* @param auditReason
*/
void auditBrokerageWithdraw(Integer id, BrokerageWithdrawStatusEnum status, String auditReason);
/**
*
*
* @param id
* @return
*/
BrokerageWithdrawDO getBrokerageWithdraw(Integer id);
/**
*
*
* @param pageReqVO
* @return
*/
PageResult<BrokerageWithdrawDO> getBrokerageWithdrawPage(BrokerageWithdrawPageReqVO pageReqVO);
}

@ -0,0 +1,104 @@
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);
}
}

@ -12,6 +12,8 @@ import cn.iocoder.yudao.module.member.api.address.AddressApi;
import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
import cn.iocoder.yudao.module.member.api.level.MemberLevelApi; import cn.iocoder.yudao.module.member.api.level.MemberLevelApi;
import cn.iocoder.yudao.module.member.api.point.MemberPointApi; import cn.iocoder.yudao.module.member.api.point.MemberPointApi;
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.enums.MemberExperienceBizTypeEnum; import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum;
import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum;
import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
@ -115,6 +117,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
@Resource @Resource
private BargainRecordApi bargainRecordApi; private BargainRecordApi bargainRecordApi;
@Resource @Resource
private MemberUserApi memberUserApi;
@Resource
private MemberLevelApi memberLevelApi; private MemberLevelApi memberLevelApi;
@Resource @Resource
private MemberPointApi memberPointApi; private MemberPointApi memberPointApi;
@ -782,9 +786,12 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
@Async @Async
protected void addBrokerageAsync(Long userId, Long orderId) { protected void addBrokerageAsync(Long userId, Long orderId) {
MemberUserRespDTO user = memberUserApi.getUser(userId);
Assert.notNull(user);
List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(orderId); List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(orderId);
List<BrokerageAddReqBO> list = convertList(orderItems, List<BrokerageAddReqBO> list = convertList(orderItems,
item -> TradeOrderConvert.INSTANCE.convert(item, productSkuApi.getSku(item.getSkuId()))); item -> TradeOrderConvert.INSTANCE.convert(user, item, productSkuApi.getSku(item.getSkuId())));
brokerageRecordService.addBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, list); brokerageRecordService.addBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, list);
} }

@ -14,6 +14,8 @@ import javax.validation.constraints.NotNull;
@Data @Data
public class TradeBeforeOrderCreateReqBO { public class TradeBeforeOrderCreateReqBO {
// TODO @puhui999注释也写下哈bo 还是写注释噢
@NotNull(message = "订单类型不能为空") @NotNull(message = "订单类型不能为空")
private Integer orderType; private Integer orderType;

@ -0,0 +1,88 @@
package cn.iocoder.yudao.module.trade.service.withdraw;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
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.trade.dal.dataobject.brokerage.withdraw.BrokerageWithdrawDO;
import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.withdraw.BrokerageWithdrawMapper;
import cn.iocoder.yudao.module.trade.service.brokerage.withdraw.BrokerageWithdrawServiceImpl;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;
import javax.annotation.Resource;
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.test.core.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
import static org.junit.jupiter.api.Assertions.assertEquals;
// TODO 芋艿:后续 review
/**
* {@link BrokerageWithdrawServiceImpl}
*
* @author
*/
@Import(BrokerageWithdrawServiceImpl.class)
public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest {
@Resource
private BrokerageWithdrawServiceImpl brokerageWithdrawService;
@Resource
private BrokerageWithdrawMapper brokerageWithdrawMapper;
@Test
@Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
public void testGetBrokerageWithdrawPage() {
// mock 数据
BrokerageWithdrawDO dbBrokerageWithdraw = randomPojo(BrokerageWithdrawDO.class, o -> { // 等会查询到
o.setUserId(null);
o.setType(null);
o.setName(null);
o.setAccountNo(null);
o.setBankName(null);
o.setStatus(null);
o.setCreateTime(null);
});
brokerageWithdrawMapper.insert(dbBrokerageWithdraw);
// 测试 userId 不匹配
brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setUserId(null)));
// 测试 type 不匹配
brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setType(null)));
// 测试 name 不匹配
brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setName(null)));
// 测试 accountNo 不匹配
brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setAccountNo(null)));
// 测试 bankName 不匹配
brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setBankName(null)));
// 测试 status 不匹配
brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setStatus(null)));
// 测试 auditReason 不匹配
brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setAuditReason(null)));
// 测试 auditTime 不匹配
brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setAuditTime(null)));
// 测试 remark 不匹配
brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setRemark(null)));
// 测试 createTime 不匹配
brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setCreateTime(null)));
// 准备参数
BrokerageWithdrawPageReqVO reqVO = new BrokerageWithdrawPageReqVO();
reqVO.setUserId(null);
reqVO.setType(null);
reqVO.setName(null);
reqVO.setAccountNo(null);
reqVO.setBankName(null);
reqVO.setStatus(null);
reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
// 调用
PageResult<BrokerageWithdrawDO> pageResult = brokerageWithdrawService.getBrokerageWithdrawPage(reqVO);
// 断言
assertEquals(1, pageResult.getTotal());
assertEquals(1, pageResult.getList().size());
assertPojoEquals(dbBrokerageWithdraw, pageResult.getList().get(0));
}
}

@ -4,3 +4,4 @@ DELETE FROM trade_after_sale;
DELETE FROM trade_after_sale_log; DELETE FROM trade_after_sale_log;
DELETE FROM trade_brokerage_user; DELETE FROM trade_brokerage_user;
DELETE FROM trade_brokerage_record; DELETE FROM trade_brokerage_record;
DELETE FROM "trade_brokerage_withdraw";

@ -164,3 +164,28 @@ CREATE TABLE IF NOT EXISTS "trade_brokerage_record"
"tenant_id" bigint not null default '0', "tenant_id" bigint not null default '0',
PRIMARY KEY ("id") PRIMARY KEY ("id")
) COMMENT ''; ) COMMENT '';
CREATE TABLE IF NOT EXISTS "trade_brokerage_withdraw"
(
"id" int NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"user_id" bigint NOT NULL,
"price" int NOT NULL,
"fee_price" int NOT NULL,
"total_price" int NOT NULL,
"type" varchar NOT NULL,
"name" varchar,
"account_no" varchar,
"bank_name" varchar,
"bank_address" varchar,
"account_qr_code_url" varchar,
"status" varchar NOT NULL,
"audit_reason" varchar,
"audit_time" varchar,
"remark" varchar,
"creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0',
PRIMARY KEY ("id")
) COMMENT '';

@ -44,31 +44,31 @@ spring:
primary: master primary: master
datasource: datasource:
master: master:
name: mall name: ruoyi-vue-pro
url: jdbc:mysql://10.211.55.5:3308/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
# url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例 # url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
# url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.master.name} # PostgreSQL 连接的示例 # url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.master.name} # PostgreSQL 连接的示例
# url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
# url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.master.name} # SQLServer 连接的示例 # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.master.name} # SQLServer 连接的示例
username: root username: root
password: 1qaz!QAZ password: 123456
# username: sa # username: sa
# password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W # password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W
slave: # 模拟从库,可根据自己需要修改 slave: # 模拟从库,可根据自己需要修改
name: mall name: ruoyi-vue-pro
url: jdbc:mysql://10.211.55.5:3308/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例
# url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例 # url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例
# url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例 # url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例
# url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
# url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.slave.name} # SQLServer 连接的示例 # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=${spring.datasource.dynamic.datasource.slave.name} # SQLServer 连接的示例
username: root username: root
password: 1qaz!QAZ password: 123456
# username: sa # username: sa
# password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W # password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
redis: redis:
host: 10.211.55.5 # 地址 host: 127.0.0.1 # 地址
port: 6379 # 端口 port: 6379 # 端口
database: 0 # 数据库索引 database: 0 # 数据库索引
# password: dev # 密码,建议生产环境开启 # password: dev # 密码,建议生产环境开启

Loading…
Cancel
Save