mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-27 09:41:58 +08:00
!649 Review代码修改
Merge pull request !649 from 疯狂的世界/feature/mall_product
This commit is contained in:
commit
d874346d42
@ -78,6 +78,13 @@ public class CollectionUtils {
|
|||||||
return from.stream().filter(filter).map(func).filter(Objects::nonNull).collect(Collectors.toSet());
|
return from.stream().filter(filter).map(func).filter(Objects::nonNull).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T, K> Map<K, T> convertMapByFilter(Collection<T> from, Predicate<T> filter, Function<T, K> keyFunc) {
|
||||||
|
if (CollUtil.isEmpty(from)) {
|
||||||
|
return new HashMap<>();
|
||||||
|
}
|
||||||
|
return from.stream().filter(filter).collect(Collectors.toMap(keyFunc, v -> v));
|
||||||
|
}
|
||||||
|
|
||||||
public static <T, K> Map<K, T> convertMap(Collection<T> from, Function<T, K> keyFunc) {
|
public static <T, K> Map<K, T> convertMap(Collection<T> from, Function<T, K> keyFunc) {
|
||||||
if (CollUtil.isEmpty(from)) {
|
if (CollUtil.isEmpty(from)) {
|
||||||
return new HashMap<>();
|
return new HashMap<>();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.promotion.mq.consumer.coupon;
|
package cn.iocoder.yudao.module.promotion.mq.consumer.coupon;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener;
|
import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessageListener;
|
||||||
import cn.iocoder.yudao.module.member.mq.message.user.RegisterCouponSendMessage;
|
import cn.iocoder.yudao.module.promotion.mq.message.coupon.UserCreateMessage;
|
||||||
import cn.iocoder.yudao.module.promotion.service.coupon.CouponService;
|
import cn.iocoder.yudao.module.promotion.service.coupon.CouponService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -9,19 +9,19 @@ import org.springframework.stereotype.Component;
|
|||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 针对 {@link RegisterCouponSendMessage} 的消费者
|
* 针对 {@link UserCreateMessage} 的消费者
|
||||||
*
|
*
|
||||||
* @author owen
|
* @author owen
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class RegisterCouponSendConsumer extends AbstractStreamMessageListener<RegisterCouponSendMessage> {
|
public class UserCreateConsumer extends AbstractStreamMessageListener<UserCreateMessage> {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private CouponService couponService;
|
private CouponService couponService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessage(RegisterCouponSendMessage message) {
|
public void onMessage(UserCreateMessage message) {
|
||||||
log.info("[onMessage][消息内容({})]", message);
|
log.info("[onMessage][消息内容({})]", message);
|
||||||
couponService.takeCouponByRegister(message.getUserId());
|
couponService.takeCouponByRegister(message.getUserId());
|
||||||
}
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package cn.iocoder.yudao.module.promotion.mq.message.coupon;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.mq.core.stream.AbstractStreamMessage;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员用户创建消息
|
||||||
|
*
|
||||||
|
* @author owen
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class UserCreateMessage extends AbstractStreamMessage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户编号
|
||||||
|
*/
|
||||||
|
@NotNull(message = "用户编号不能为空")
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStreamKey() {
|
||||||
|
return "member.create.send";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -178,7 +178,7 @@ public class CouponServiceImpl implements CouponService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
// TODO @疯狂:搞个事务;
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void takeCouponByRegister(Long userId) {
|
public void takeCouponByRegister(Long userId) {
|
||||||
List<CouponTemplateDO> templates = couponTemplateService.getCouponTemplateListByTakeType(CouponTakeTypeEnum.REGISTER);
|
List<CouponTemplateDO> templates = couponTemplateService.getCouponTemplateListByTakeType(CouponTakeTypeEnum.REGISTER);
|
||||||
for (CouponTemplateDO template : templates) {
|
for (CouponTemplateDO template : templates) {
|
||||||
|
@ -81,6 +81,7 @@ public interface ErrorCodeConstants {
|
|||||||
ErrorCode BROKERAGE_BIND_MODE_REGISTER = new ErrorCode(1_011_007_005, "只有在注册时可以绑定");
|
ErrorCode BROKERAGE_BIND_MODE_REGISTER = new ErrorCode(1_011_007_005, "只有在注册时可以绑定");
|
||||||
ErrorCode BROKERAGE_BIND_OVERRIDE = new ErrorCode(1_011_007_006, "已绑定了推广人");
|
ErrorCode BROKERAGE_BIND_OVERRIDE = new ErrorCode(1_011_007_006, "已绑定了推广人");
|
||||||
ErrorCode BROKERAGE_BIND_LOOP = new ErrorCode(1_011_007_007, "下级不能绑定自己的上级");
|
ErrorCode BROKERAGE_BIND_LOOP = new ErrorCode(1_011_007_007, "下级不能绑定自己的上级");
|
||||||
|
ErrorCode BROKERAGE_USER_LEVEL_NOT_SUPPORT = new ErrorCode(1_011_007_008, "目前只支持 level 小于等于 2");
|
||||||
|
|
||||||
|
|
||||||
// ========== 分销提现 模块 1-011-008-000 ==========
|
// ========== 分销提现 模块 1-011-008-000 ==========
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.trade.dal.mysql.brokerage;
|
package cn.iocoder.yudao.module.trade.dal.mysql.brokerage;
|
||||||
|
|
||||||
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.SortingField;
|
import cn.iocoder.yudao.framework.common.pojo.SortingField;
|
||||||
@ -17,6 +18,8 @@ import org.apache.ibatis.annotations.Param;
|
|||||||
import org.apache.ibatis.annotations.Select;
|
import org.apache.ibatis.annotations.Select;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,12 +30,12 @@ import java.util.List;
|
|||||||
@Mapper
|
@Mapper
|
||||||
public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
|
public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
|
||||||
|
|
||||||
default PageResult<BrokerageUserDO> selectPage(BrokerageUserPageReqVO reqVO, List<Long> bindUserIds) {
|
default PageResult<BrokerageUserDO> selectPage(BrokerageUserPageReqVO reqVO, List<Long> ids) {
|
||||||
return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageUserDO>()
|
return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageUserDO>()
|
||||||
|
.inIfPresent(BrokerageUserDO::getId, ids)
|
||||||
.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())
|
||||||
.inIfPresent(BrokerageUserDO::getBindUserId, bindUserIds)
|
|
||||||
.orderByDesc(BrokerageUserDO::getId));
|
.orderByDesc(BrokerageUserDO::getId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,11 +127,6 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
|
|||||||
.set(BrokerageUserDO::getBrokerageEnabled, false).set(BrokerageUserDO::getBrokerageTime, null));
|
.set(BrokerageUserDO::getBrokerageEnabled, false).set(BrokerageUserDO::getBrokerageTime, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
default Long selectCountByBindUserIdIn(List<Long> bindUserIds) {
|
|
||||||
return selectCount(new LambdaQueryWrapperX<BrokerageUserDO>()
|
|
||||||
.inIfPresent(BrokerageUserDO::getBindUserId, bindUserIds));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Select("SELECT bind_user_id AS id, COUNT(1) AS brokerageUserCount FROM trade_brokerage_user " +
|
@Select("SELECT bind_user_id AS id, COUNT(1) AS brokerageUserCount FROM trade_brokerage_user " +
|
||||||
"WHERE bind_user_id IS NOT NULL AND deleted = FALSE " +
|
"WHERE bind_user_id IS NOT NULL AND deleted = FALSE " +
|
||||||
"AND bind_user_time BETWEEN #{beginTime} AND #{endTime} " +
|
"AND bind_user_time BETWEEN #{beginTime} AND #{endTime} " +
|
||||||
@ -143,32 +141,21 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> {
|
|||||||
*
|
*
|
||||||
* @param bizType 业务类型
|
* @param bizType 业务类型
|
||||||
* @param status 状态
|
* @param status 状态
|
||||||
* @param bindUserIds 绑定用户编号列表
|
* @param ids 用户编号列表
|
||||||
* @param sortingField 排序字段
|
* @param sortingField 排序字段
|
||||||
* @return 下级分销统计分页列表
|
* @return 下级分销统计分页列表
|
||||||
*/
|
*/
|
||||||
IPage<AppBrokerageUserChildSummaryRespVO> selectSummaryPageByUserId(Page<?> page,
|
IPage<AppBrokerageUserChildSummaryRespVO> selectSummaryPageByUserId(Page<?> page,
|
||||||
@Param("bizType") Integer bizType,
|
@Param("bizType") Integer bizType,
|
||||||
@Param("status") Integer status,
|
@Param("status") Integer status,
|
||||||
@Param("bindUserIds") List<Long> bindUserIds,
|
@Param("ids") Collection<Long> ids,
|
||||||
@Param("sortingField") SortingField sortingField);
|
@Param("sortingField") SortingField sortingField);
|
||||||
|
|
||||||
/**
|
default List<Long> selectIdListByBindUserIdIn(Collection<Long> bindUserIds) {
|
||||||
* 下级分销统计(不分页)
|
return Convert.toList(Long.class,
|
||||||
*
|
selectObjs(new LambdaQueryWrapperX<BrokerageUserDO>()
|
||||||
* @param bizType 业务类型
|
.select(Collections.singletonList(BrokerageUserDO::getId))
|
||||||
* @param status 状态
|
.in(BrokerageUserDO::getBindUserId, bindUserIds)));
|
||||||
* @param bindUserIds 绑定用户编号列表
|
|
||||||
* @param sortingField 排序字段
|
|
||||||
* @return 下级分销统计列表
|
|
||||||
*/
|
|
||||||
List<AppBrokerageUserChildSummaryRespVO> selectSummaryListByUserId(@Param("bizType") Integer bizType,
|
|
||||||
@Param("status") Integer status,
|
|
||||||
@Param("bindUserIds") List<Long> bindUserIds,
|
|
||||||
@Param("sortingField") SortingField sortingField);
|
|
||||||
|
|
||||||
default List<BrokerageUserDO> selectListByBindUserId(Long bindUserId) {
|
|
||||||
return selectList(BrokerageUserDO::getBindUserId, bindUserId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,10 +31,9 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMapByFilter;
|
||||||
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
|
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,8 +66,12 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageResult<BrokerageUserDO> getBrokerageUserPage(BrokerageUserPageReqVO pageReqVO) {
|
public PageResult<BrokerageUserDO> getBrokerageUserPage(BrokerageUserPageReqVO pageReqVO) {
|
||||||
List<Long> bindUserIds = buildBindUserIdsByLevel(pageReqVO.getBindUserId(), pageReqVO.getLevel());
|
List<Long> childIds = getChildUserIdsByLevel(pageReqVO.getBindUserId(), pageReqVO.getLevel());
|
||||||
return brokerageUserMapper.selectPage(pageReqVO, bindUserIds);
|
// 有”绑定用户编号“查询条件时,没有查到下级会员,直接返回空
|
||||||
|
if (pageReqVO.getBindUserId() != null && CollUtil.isEmpty(childIds)) {
|
||||||
|
return PageResult.empty();
|
||||||
|
}
|
||||||
|
return brokerageUserMapper.selectPage(pageReqVO, childIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -154,11 +157,8 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long getBrokerageUserCountByBindUserId(Long bindUserId, Integer level) {
|
public Long getBrokerageUserCountByBindUserId(Long bindUserId, Integer level) {
|
||||||
List<Long> bindUserIds = buildBindUserIdsByLevel(bindUserId, level);
|
List<Long> childIds = getChildUserIdsByLevel(bindUserId, level);
|
||||||
if (CollUtil.isEmpty(bindUserIds)) {
|
return (long) CollUtil.size(childIds);
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
return brokerageUserMapper.selectCountByBindUserIdIn(bindUserIds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -226,70 +226,29 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageResult<AppBrokerageUserChildSummaryRespVO> getBrokerageUserChildSummaryPage(AppBrokerageUserChildSummaryPageReqVO pageReqVO, Long userId) {
|
public PageResult<AppBrokerageUserChildSummaryRespVO> getBrokerageUserChildSummaryPage(AppBrokerageUserChildSummaryPageReqVO pageReqVO, Long userId) {
|
||||||
// 生成推广员编号列表
|
// 1.1 查询下级用户编号列表
|
||||||
List<Long> bindUserIds = buildBindUserIdsByLevel(userId, pageReqVO.getLevel());
|
List<Long> childIds = getChildUserIdsByLevel(userId, pageReqVO.getLevel());
|
||||||
|
if (CollUtil.isEmpty(childIds)) {
|
||||||
// TODO @疯狂:情况一和情况二,可以合并哈;
|
|
||||||
// 如果有 nickname 的时候,相当于提前查询 users,然后 nickname 过滤掉 bindUserIds;
|
|
||||||
// 之后,继续使用 selectSummaryPageByUserId 里面 in bindUserIds 查询;
|
|
||||||
|
|
||||||
// 情况一:没有昵称过滤条件时,直接使用数据库的分页查询
|
|
||||||
if (StrUtil.isBlank(pageReqVO.getNickname())) {
|
|
||||||
// 1.1 分页查询
|
|
||||||
IPage<AppBrokerageUserChildSummaryRespVO> pageResult = brokerageUserMapper.selectSummaryPageByUserId(
|
|
||||||
MyBatisUtils.buildPage(pageReqVO), BrokerageRecordBizTypeEnum.ORDER.getType(),
|
|
||||||
BrokerageRecordStatusEnum.SETTLEMENT.getStatus(), bindUserIds, pageReqVO.getSortingField()
|
|
||||||
);
|
|
||||||
|
|
||||||
// 1.2 拼接数据并返回
|
|
||||||
List<Long> userIds = convertList(pageResult.getRecords(), AppBrokerageUserChildSummaryRespVO::getId);
|
|
||||||
Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(userIds);
|
|
||||||
BrokerageUserConvert.INSTANCE.copyTo(pageResult.getRecords(), userMap);
|
|
||||||
return new PageResult<>(pageResult.getRecords(), pageResult.getTotal());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 情况二:有昵称过滤条件时,需要跨模块(Member)过滤
|
|
||||||
// 2.1 查询所有匹配的分销用户
|
|
||||||
List<AppBrokerageUserChildSummaryRespVO> list = brokerageUserMapper.selectSummaryListByUserId(
|
|
||||||
BrokerageRecordBizTypeEnum.ORDER.getType(), BrokerageRecordStatusEnum.SETTLEMENT.getStatus(),
|
|
||||||
bindUserIds, pageReqVO.getSortingField()
|
|
||||||
);
|
|
||||||
if (CollUtil.isEmpty(list)) {
|
|
||||||
return PageResult.empty();
|
return PageResult.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2.2 查出对应的用户信息
|
// 1.2 根据昵称过滤下级用户
|
||||||
List<MemberUserRespDTO> users = memberUserApi.getUserList(convertList(list, AppBrokerageUserChildSummaryRespVO::getId));
|
Map<Long, MemberUserRespDTO> userMap = convertMapByFilter(memberUserApi.getUserList(childIds),
|
||||||
if (CollUtil.isEmpty(users)) {
|
user -> StrUtil.contains(user.getNickname(), pageReqVO.getNickname()),
|
||||||
return PageResult.empty();
|
MemberUserRespDTO::getId);
|
||||||
}
|
|
||||||
|
|
||||||
// 2.3 根据昵称过滤出用户编号
|
|
||||||
Map<Long, MemberUserRespDTO> userMap = users.stream()
|
|
||||||
.filter(user -> StrUtil.contains(user.getNickname(), pageReqVO.getNickname()))
|
|
||||||
.collect(Collectors.toMap(MemberUserRespDTO::getId, dto -> dto));
|
|
||||||
if (CollUtil.isEmpty(userMap)) {
|
if (CollUtil.isEmpty(userMap)) {
|
||||||
return PageResult.empty();
|
return PageResult.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2.4 根据用户编号过滤结果
|
// 2 分页查询
|
||||||
list.removeIf(vo -> !userMap.containsKey(vo.getId()));
|
IPage<AppBrokerageUserChildSummaryRespVO> pageResult = brokerageUserMapper.selectSummaryPageByUserId(
|
||||||
if (CollUtil.isEmpty(list)) {
|
MyBatisUtils.buildPage(pageReqVO), BrokerageRecordBizTypeEnum.ORDER.getType(),
|
||||||
return PageResult.empty();
|
BrokerageRecordStatusEnum.SETTLEMENT.getStatus(), userMap.keySet(), pageReqVO.getSortingField()
|
||||||
}
|
);
|
||||||
|
|
||||||
// 2.5 处理分页
|
// 3 拼接数据并返回
|
||||||
List<AppBrokerageUserChildSummaryRespVO> result = list.stream()
|
BrokerageUserConvert.INSTANCE.copyTo(pageResult.getRecords(), userMap);
|
||||||
.skip((long) (pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize())
|
return new PageResult<>(pageResult.getRecords(), pageResult.getTotal());
|
||||||
.limit(pageReqVO.getPageSize())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
if (CollUtil.isEmpty(result)) {
|
|
||||||
return PageResult.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2.6 拼接数据并返回
|
|
||||||
BrokerageUserConvert.INSTANCE.copyTo(result, userMap);
|
|
||||||
return new PageResult<>(result, (long) list.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isUserCanBind(BrokerageUserDO user) {
|
private boolean isUserCanBind(BrokerageUserDO user) {
|
||||||
@ -360,24 +319,35 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据绑定用户编号,获得绑定用户编号列表
|
* 根据绑定用户编号,获得下级用户编号列表
|
||||||
*
|
*
|
||||||
* @param bindUserId 绑定用户编号
|
* @param bindUserId 绑定用户编号
|
||||||
* @param level 绑定用户的层级。
|
* @param level 下级用户的层级。
|
||||||
* 如果 level 为空,则查询 1+2 两个层级
|
* 如果 level 为空,则查询 1+2 两个层级
|
||||||
* @return 绑定用户编号列表
|
* @return 下级用户编号列表
|
||||||
*/
|
*/
|
||||||
private List<Long> buildBindUserIdsByLevel(Long bindUserId, Integer level) {
|
private List<Long> getChildUserIdsByLevel(Long bindUserId, Integer level) {
|
||||||
if (bindUserId == null) {
|
if (bindUserId == null) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
Assert.isTrue(level == null || level <= 2, "目前只支持 level 小于等于 2");
|
|
||||||
List<Long> bindUserIds = CollUtil.newArrayList();
|
// 先查第 1 级
|
||||||
if (level == null || level == 1) {
|
List<Long> bindUserIds = brokerageUserMapper.selectIdListByBindUserIdIn(Collections.singleton(bindUserId));
|
||||||
bindUserIds.add(bindUserId);
|
if (CollUtil.isEmpty(bindUserIds)) {
|
||||||
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
if (level == null || level == 2) {
|
|
||||||
bindUserIds.addAll(convertList(brokerageUserMapper.selectListByBindUserId(bindUserId), BrokerageUserDO::getId));
|
if (level == null) {
|
||||||
|
// level 为空,再查第 2 级,并合并结果
|
||||||
|
bindUserIds.addAll(brokerageUserMapper.selectIdListByBindUserIdIn(bindUserIds));
|
||||||
|
} else if (level == 2) {
|
||||||
|
// 只查第 2 级
|
||||||
|
bindUserIds = brokerageUserMapper.selectIdListByBindUserIdIn(bindUserIds);
|
||||||
|
} else if (level == 1) {
|
||||||
|
// 只查第 1 级
|
||||||
|
return bindUserIds;
|
||||||
|
} else {
|
||||||
|
throw exception(BROKERAGE_USER_LEVEL_NOT_SUPPORT);
|
||||||
}
|
}
|
||||||
return bindUserIds;
|
return bindUserIds;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,9 @@
|
|||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageUserMapper">
|
<mapper namespace="cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageUserMapper">
|
||||||
|
|
||||||
<sql id="selectSummaryListByUserId">
|
<select id="selectSummaryPageByUserId"
|
||||||
|
resultType="cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO">
|
||||||
|
|
||||||
SELECT bu.id, bu.bind_user_time AS brokerageTime,
|
SELECT bu.id, bu.bind_user_time AS brokerageTime,
|
||||||
(SELECT SUM(price) FROM trade_brokerage_record r
|
(SELECT SUM(price) FROM trade_brokerage_record r
|
||||||
WHERE r.user_id = bu.id AND biz_type = #{bizType} AND r.status = #{status} AND r.deleted = FALSE) AS brokeragePrice,
|
WHERE r.user_id = bu.id AND biz_type = #{bizType} AND r.status = #{status} AND r.deleted = FALSE) AS brokeragePrice,
|
||||||
@ -13,10 +15,10 @@
|
|||||||
FROM trade_brokerage_user AS bu
|
FROM trade_brokerage_user AS bu
|
||||||
<where>
|
<where>
|
||||||
bu.deleted = false
|
bu.deleted = false
|
||||||
<if test="bindUserIds != null and bindUserIds.size() > 0">
|
<if test="ids != null and ids.size() > 0">
|
||||||
and bu.bind_user_id in
|
and bu.id in
|
||||||
<foreach collection="bindUserIds" open="(" item="bindUserId" separator="," close=")">
|
<foreach collection="ids" open="(" item="id" separator="," close=")">
|
||||||
#{bindUserId}
|
#{id}
|
||||||
</foreach>
|
</foreach>
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
@ -34,15 +36,6 @@
|
|||||||
ORDER BY bu.bind_user_time DESC
|
ORDER BY bu.bind_user_time DESC
|
||||||
</otherwise>
|
</otherwise>
|
||||||
</choose>
|
</choose>
|
||||||
</sql>
|
|
||||||
|
|
||||||
<select id="selectSummaryPageByUserId"
|
|
||||||
resultType="cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO">
|
|
||||||
<include refid="selectSummaryListByUserId" />
|
|
||||||
</select>
|
|
||||||
<select id="selectSummaryListByUserId"
|
|
||||||
resultType="cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO">
|
|
||||||
<include refid="selectSummaryListByUserId" />
|
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
@ -22,13 +22,6 @@
|
|||||||
<artifactId>yudao-common</artifactId>
|
<artifactId>yudao-common</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- TODO @疯狂:biz 引入哈;api 保持低依赖 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
|
||||||
<artifactId>yudao-spring-boot-starter-mq</artifactId>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- 参数校验 -->
|
<!-- 参数校验 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
@ -38,11 +38,9 @@ public interface ErrorCodeConstants {
|
|||||||
//========== 签到配置 1-004-009-000 ==========
|
//========== 签到配置 1-004-009-000 ==========
|
||||||
ErrorCode SIGN_IN_CONFIG_NOT_EXISTS = new ErrorCode(1_004_009_000, "签到天数规则不存在");
|
ErrorCode SIGN_IN_CONFIG_NOT_EXISTS = new ErrorCode(1_004_009_000, "签到天数规则不存在");
|
||||||
ErrorCode SIGN_IN_CONFIG_EXISTS = new ErrorCode(1_004_009_001, "签到天数规则已存在");
|
ErrorCode SIGN_IN_CONFIG_EXISTS = new ErrorCode(1_004_009_001, "签到天数规则已存在");
|
||||||
// TODO @疯狂:这个可以用 validator 去做;通过在 BaseVO 里,增加一个 @AssertTrue 注解的方式
|
|
||||||
ErrorCode SIGN_IN_CONFIG_AWARD_EMPTY = new ErrorCode(1_004_009_002, "签到奖励积分和经验不能同时为空");
|
|
||||||
|
|
||||||
//========== 签到配置 1-004-010-000 ==========
|
//========== 签到配置 1-004-010-000 ==========
|
||||||
ErrorCode SIGN_IN_RECORD_TODAY_EXISTS = new ErrorCode(1_004_010_000,"今日已签到,请勿重复签到");
|
ErrorCode SIGN_IN_RECORD_TODAY_EXISTS = new ErrorCode(1_004_010_000, "今日已签到,请勿重复签到");
|
||||||
|
|
||||||
//========== 用户等级 1-004-011-000 ==========
|
//========== 用户等级 1-004-011-000 ==========
|
||||||
ErrorCode LEVEL_NOT_EXISTS = new ErrorCode(1_004_011_000, "用户等级不存在");
|
ErrorCode LEVEL_NOT_EXISTS = new ErrorCode(1_004_011_000, "用户等级不存在");
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package cn.iocoder.yudao.module.member.controller.admin.signin.vo.config;
|
package cn.iocoder.yudao.module.member.controller.admin.signin.vo.config;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.AssertTrue;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import javax.validation.constraints.PositiveOrZero;
|
import javax.validation.constraints.PositiveOrZero;
|
||||||
|
|
||||||
@ -34,4 +37,9 @@ public class MemberSignInConfigBaseVO {
|
|||||||
@InEnum(CommonStatusEnum.class)
|
@InEnum(CommonStatusEnum.class)
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
|
@AssertTrue(message = "签到奖励积分和经验不能同时为空")
|
||||||
|
@JsonIgnore
|
||||||
|
public boolean isConfigAward() {
|
||||||
|
return ObjUtil.notEqual(point, 0) || ObjUtil.notEqual(experience, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,13 @@ import lombok.EqualsAndHashCode;
|
|||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新人券发放消息
|
* 会员用户创建消息
|
||||||
*
|
*
|
||||||
* @author owen
|
* @author owen
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
public class RegisterCouponSendMessage extends AbstractStreamMessage {
|
public class UserCreateMessage extends AbstractStreamMessage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户编号
|
* 用户编号
|
||||||
@ -23,7 +23,7 @@ public class RegisterCouponSendMessage extends AbstractStreamMessage {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getStreamKey() {
|
public String getStreamKey() {
|
||||||
return "member.register-coupon.send";
|
return "member.create.send";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,32 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.member.mq.producer.user;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
|
|
||||||
import cn.iocoder.yudao.module.member.mq.message.user.RegisterCouponSendMessage;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
// TODO @疯狂:发 UserCreateMessage;解耦,然后优惠劵监听到,去发卷;
|
|
||||||
/**
|
|
||||||
* 新人券发放 Producer
|
|
||||||
*
|
|
||||||
* @author owen
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
public class RegisterCouponProducer {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private RedisMQTemplate redisMQTemplate;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送 {@link RegisterCouponSendMessage} 消息
|
|
||||||
*
|
|
||||||
* @param userId 用户编号
|
|
||||||
*/
|
|
||||||
public void sendMailSendMessage(Long userId) {
|
|
||||||
redisMQTemplate.send(new RegisterCouponSendMessage().setUserId(userId));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,31 @@
|
|||||||
|
package cn.iocoder.yudao.module.member.mq.producer.user;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
|
||||||
|
import cn.iocoder.yudao.module.member.mq.message.user.UserCreateMessage;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员用户创建 Producer
|
||||||
|
*
|
||||||
|
* @author owen
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class UserCreateProducer {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RedisMQTemplate redisMQTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送 {@link UserCreateMessage} 消息
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
*/
|
||||||
|
public void sendUserCreateMessage(Long userId) {
|
||||||
|
redisMQTemplate.send(new UserCreateMessage().setUserId(userId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -11,10 +11,10 @@ import org.springframework.validation.annotation.Validated;
|
|||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
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.member.enums.ErrorCodeConstants.*;
|
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.SIGN_IN_CONFIG_EXISTS;
|
||||||
|
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.SIGN_IN_CONFIG_NOT_EXISTS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 签到规则 Service 实现类
|
* 签到规则 Service 实现类
|
||||||
@ -30,8 +30,6 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long createSignInConfig(MemberSignInConfigCreateReqVO createReqVO) {
|
public Long createSignInConfig(MemberSignInConfigCreateReqVO createReqVO) {
|
||||||
// 校验奖励积分、奖励经验
|
|
||||||
validatePointAndExperience(createReqVO.getPoint(), createReqVO.getExperience());
|
|
||||||
// 判断是否重复插入签到天数
|
// 判断是否重复插入签到天数
|
||||||
validateSignInConfigDayDuplicate(createReqVO.getDay(), null);
|
validateSignInConfigDayDuplicate(createReqVO.getDay(), null);
|
||||||
|
|
||||||
@ -44,8 +42,6 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateSignInConfig(MemberSignInConfigUpdateReqVO updateReqVO) {
|
public void updateSignInConfig(MemberSignInConfigUpdateReqVO updateReqVO) {
|
||||||
// 校验奖励积分、奖励经验
|
|
||||||
validatePointAndExperience(updateReqVO.getPoint(), updateReqVO.getExperience());
|
|
||||||
// 校验存在
|
// 校验存在
|
||||||
validateSignInConfigExists(updateReqVO.getId());
|
validateSignInConfigExists(updateReqVO.getId());
|
||||||
// 判断是否重复插入签到天数
|
// 判断是否重复插入签到天数
|
||||||
@ -88,13 +84,6 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validatePointAndExperience(Integer point, Integer experience) {
|
|
||||||
// 奖励积分、经验 至少要配置一个,否则没有意义
|
|
||||||
if (Objects.equals(point, 0) && Objects.equals(experience, 0)) {
|
|
||||||
throw exception(SIGN_IN_CONFIG_AWARD_EMPTY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MemberSignInConfigDO getSignInConfig(Long id) {
|
public MemberSignInConfigDO getSignInConfig(Long id) {
|
||||||
return memberSignInConfigMapper.selectById(id);
|
return memberSignInConfigMapper.selectById(id);
|
||||||
|
@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.member.service.user;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.collection.ListUtil;
|
import cn.hutool.core.collection.ListUtil;
|
||||||
|
import cn.hutool.core.util.BooleanUtil;
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
@ -18,7 +19,7 @@ import cn.iocoder.yudao.module.member.convert.auth.AuthConvert;
|
|||||||
import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert;
|
import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert;
|
||||||
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
|
||||||
import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
|
import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
|
||||||
import cn.iocoder.yudao.module.member.mq.producer.user.RegisterCouponProducer;
|
import cn.iocoder.yudao.module.member.mq.producer.user.UserCreateProducer;
|
||||||
import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
|
import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
|
||||||
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
|
import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
|
||||||
import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
|
import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
|
||||||
@ -27,6 +28,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
@ -60,7 +62,10 @@ public class MemberUserServiceImpl implements MemberUserService {
|
|||||||
private PasswordEncoder passwordEncoder;
|
private PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private RegisterCouponProducer registerCouponProducer;
|
private UserCreateProducer registerCouponProducer;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private TransactionTemplate transactionTemplate;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MemberUserDO getUserByMobile(String mobile) {
|
public MemberUserDO getUserByMobile(String mobile) {
|
||||||
@ -92,11 +97,13 @@ public class MemberUserServiceImpl implements MemberUserService {
|
|||||||
user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启
|
user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启
|
||||||
user.setPassword(encodePassword(password)); // 加密密码
|
user.setPassword(encodePassword(password)); // 加密密码
|
||||||
user.setRegisterIp(registerIp);
|
user.setRegisterIp(registerIp);
|
||||||
memberUserMapper.insert(user);
|
|
||||||
|
|
||||||
// 发送 MQ 消息,发放新人券
|
Boolean success = transactionTemplate.execute(status -> memberUserMapper.insert(user) > 0);
|
||||||
// TODO @疯狂:事务结束后,在发送 MQ 消息;避免出现消息已经发了,事务没提交,或者回滚了
|
if (BooleanUtil.isTrue(success)) {
|
||||||
registerCouponProducer.sendMailSendMessage(user.getId());
|
// 发送 MQ 消息:用户创建
|
||||||
|
registerCouponProducer.sendUserCreateMessage(user.getId());
|
||||||
|
}
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user