Commit d0f0bc58888f16f0b02c9252283c2d00709192f5
1 parent
7fdd36d9
分销:调整推广人列表查询方式
Showing
5 changed files
with
72 additions
and
114 deletions
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java
| ... | ... | @@ -78,6 +78,13 @@ public class CollectionUtils { |
| 78 | 78 | return from.stream().filter(filter).map(func).filter(Objects::nonNull).collect(Collectors.toSet()); |
| 79 | 79 | } |
| 80 | 80 | |
| 81 | + public static <T, K> Map<K, T> convertMapByFilter(Collection<T> from, Predicate<T> filter, Function<T, K> keyFunc) { | |
| 82 | + if (CollUtil.isEmpty(from)) { | |
| 83 | + return new HashMap<>(); | |
| 84 | + } | |
| 85 | + return from.stream().filter(filter).collect(Collectors.toMap(keyFunc, v -> v)); | |
| 86 | + } | |
| 87 | + | |
| 81 | 88 | public static <T, K> Map<K, T> convertMap(Collection<T> from, Function<T, K> keyFunc) { |
| 82 | 89 | if (CollUtil.isEmpty(from)) { |
| 83 | 90 | return new HashMap<>(); | ... | ... |
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
| ... | ... | @@ -81,6 +81,7 @@ public interface ErrorCodeConstants { |
| 81 | 81 | ErrorCode BROKERAGE_BIND_MODE_REGISTER = new ErrorCode(1_011_007_005, "只有在注册时可以绑定"); |
| 82 | 82 | ErrorCode BROKERAGE_BIND_OVERRIDE = new ErrorCode(1_011_007_006, "已绑定了推广人"); |
| 83 | 83 | ErrorCode BROKERAGE_BIND_LOOP = new ErrorCode(1_011_007_007, "下级不能绑定自己的上级"); |
| 84 | + ErrorCode BROKERAGE_USER_LEVEL_NOT_SUPPORT = new ErrorCode(1_011_007_008, "目前只支持 level 小于等于 2"); | |
| 84 | 85 | |
| 85 | 86 | |
| 86 | 87 | // ========== 分销提现 模块 1-011-008-000 ========== | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageUserMapper.java
| 1 | 1 | package cn.iocoder.yudao.module.trade.dal.mysql.brokerage; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.convert.Convert; | |
| 3 | 4 | import cn.hutool.core.lang.Assert; |
| 4 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 6 | import cn.iocoder.yudao.framework.common.pojo.SortingField; |
| ... | ... | @@ -17,6 +18,8 @@ import org.apache.ibatis.annotations.Param; |
| 17 | 18 | import org.apache.ibatis.annotations.Select; |
| 18 | 19 | |
| 19 | 20 | import java.time.LocalDateTime; |
| 21 | +import java.util.Collection; | |
| 22 | +import java.util.Collections; | |
| 20 | 23 | import java.util.List; |
| 21 | 24 | |
| 22 | 25 | /** |
| ... | ... | @@ -27,12 +30,12 @@ import java.util.List; |
| 27 | 30 | @Mapper |
| 28 | 31 | public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> { |
| 29 | 32 | |
| 30 | - default PageResult<BrokerageUserDO> selectPage(BrokerageUserPageReqVO reqVO, List<Long> bindUserIds) { | |
| 33 | + default PageResult<BrokerageUserDO> selectPage(BrokerageUserPageReqVO reqVO, List<Long> ids) { | |
| 31 | 34 | return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageUserDO>() |
| 35 | + .inIfPresent(BrokerageUserDO::getId, ids) | |
| 32 | 36 | .eqIfPresent(BrokerageUserDO::getBrokerageEnabled, reqVO.getBrokerageEnabled()) |
| 33 | 37 | .betweenIfPresent(BrokerageUserDO::getCreateTime, reqVO.getCreateTime()) |
| 34 | 38 | .betweenIfPresent(BrokerageUserDO::getBindUserTime, reqVO.getBindUserTime()) |
| 35 | - .inIfPresent(BrokerageUserDO::getBindUserId, bindUserIds) | |
| 36 | 39 | .orderByDesc(BrokerageUserDO::getId)); |
| 37 | 40 | } |
| 38 | 41 | |
| ... | ... | @@ -124,11 +127,6 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> { |
| 124 | 127 | .set(BrokerageUserDO::getBrokerageEnabled, false).set(BrokerageUserDO::getBrokerageTime, null)); |
| 125 | 128 | } |
| 126 | 129 | |
| 127 | - default Long selectCountByBindUserIdIn(List<Long> bindUserIds) { | |
| 128 | - return selectCount(new LambdaQueryWrapperX<BrokerageUserDO>() | |
| 129 | - .inIfPresent(BrokerageUserDO::getBindUserId, bindUserIds)); | |
| 130 | - } | |
| 131 | - | |
| 132 | 130 | @Select("SELECT bind_user_id AS id, COUNT(1) AS brokerageUserCount FROM trade_brokerage_user " + |
| 133 | 131 | "WHERE bind_user_id IS NOT NULL AND deleted = FALSE " + |
| 134 | 132 | "AND bind_user_time BETWEEN #{beginTime} AND #{endTime} " + |
| ... | ... | @@ -143,32 +141,21 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> { |
| 143 | 141 | * |
| 144 | 142 | * @param bizType 业务类型 |
| 145 | 143 | * @param status 状态 |
| 146 | - * @param bindUserIds 绑定用户编号列表 | |
| 144 | + * @param ids 用户编号列表 | |
| 147 | 145 | * @param sortingField 排序字段 |
| 148 | 146 | * @return 下级分销统计分页列表 |
| 149 | 147 | */ |
| 150 | 148 | IPage<AppBrokerageUserChildSummaryRespVO> selectSummaryPageByUserId(Page<?> page, |
| 151 | 149 | @Param("bizType") Integer bizType, |
| 152 | 150 | @Param("status") Integer status, |
| 153 | - @Param("bindUserIds") List<Long> bindUserIds, | |
| 151 | + @Param("ids") Collection<Long> ids, | |
| 154 | 152 | @Param("sortingField") SortingField sortingField); |
| 155 | 153 | |
| 156 | - /** | |
| 157 | - * 下级分销统计(不分页) | |
| 158 | - * | |
| 159 | - * @param bizType 业务类型 | |
| 160 | - * @param status 状态 | |
| 161 | - * @param bindUserIds 绑定用户编号列表 | |
| 162 | - * @param sortingField 排序字段 | |
| 163 | - * @return 下级分销统计列表 | |
| 164 | - */ | |
| 165 | - List<AppBrokerageUserChildSummaryRespVO> selectSummaryListByUserId(@Param("bizType") Integer bizType, | |
| 166 | - @Param("status") Integer status, | |
| 167 | - @Param("bindUserIds") List<Long> bindUserIds, | |
| 168 | - @Param("sortingField") SortingField sortingField); | |
| 169 | - | |
| 170 | - default List<BrokerageUserDO> selectListByBindUserId(Long bindUserId) { | |
| 171 | - return selectList(BrokerageUserDO::getBindUserId, bindUserId); | |
| 154 | + default List<Long> selectIdListByBindUserIdIn(Collection<Long> bindUserIds) { | |
| 155 | + return Convert.toList(Long.class, | |
| 156 | + selectObjs(new LambdaQueryWrapperX<BrokerageUserDO>() | |
| 157 | + .select(Collections.singletonList(BrokerageUserDO::getId)) | |
| 158 | + .in(BrokerageUserDO::getBindUserId, bindUserIds))); | |
| 172 | 159 | } |
| 173 | 160 | |
| 174 | 161 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java
| ... | ... | @@ -31,10 +31,9 @@ import org.springframework.validation.annotation.Validated; |
| 31 | 31 | import javax.annotation.Resource; |
| 32 | 32 | import java.time.LocalDateTime; |
| 33 | 33 | import java.util.*; |
| 34 | -import java.util.stream.Collectors; | |
| 35 | 34 | |
| 36 | 35 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 37 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | |
| 36 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMapByFilter; | |
| 38 | 37 | import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; |
| 39 | 38 | |
| 40 | 39 | /** |
| ... | ... | @@ -67,8 +66,12 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { |
| 67 | 66 | |
| 68 | 67 | @Override |
| 69 | 68 | public PageResult<BrokerageUserDO> getBrokerageUserPage(BrokerageUserPageReqVO pageReqVO) { |
| 70 | - List<Long> bindUserIds = buildBindUserIdsByLevel(pageReqVO.getBindUserId(), pageReqVO.getLevel()); | |
| 71 | - return brokerageUserMapper.selectPage(pageReqVO, bindUserIds); | |
| 69 | + List<Long> childIds = getChildUserIdsByLevel(pageReqVO.getBindUserId(), pageReqVO.getLevel()); | |
| 70 | + // 有”绑定用户编号“查询条件时,没有查到下级会员,直接返回空 | |
| 71 | + if (pageReqVO.getBindUserId() != null && CollUtil.isEmpty(childIds)) { | |
| 72 | + return PageResult.empty(); | |
| 73 | + } | |
| 74 | + return brokerageUserMapper.selectPage(pageReqVO, childIds); | |
| 72 | 75 | } |
| 73 | 76 | |
| 74 | 77 | @Override |
| ... | ... | @@ -154,11 +157,8 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { |
| 154 | 157 | |
| 155 | 158 | @Override |
| 156 | 159 | public Long getBrokerageUserCountByBindUserId(Long bindUserId, Integer level) { |
| 157 | - List<Long> bindUserIds = buildBindUserIdsByLevel(bindUserId, level); | |
| 158 | - if (CollUtil.isEmpty(bindUserIds)) { | |
| 159 | - return 0L; | |
| 160 | - } | |
| 161 | - return brokerageUserMapper.selectCountByBindUserIdIn(bindUserIds); | |
| 160 | + List<Long> childIds = getChildUserIdsByLevel(bindUserId, level); | |
| 161 | + return (long) CollUtil.size(childIds); | |
| 162 | 162 | } |
| 163 | 163 | |
| 164 | 164 | @Override |
| ... | ... | @@ -226,70 +226,29 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { |
| 226 | 226 | |
| 227 | 227 | @Override |
| 228 | 228 | public PageResult<AppBrokerageUserChildSummaryRespVO> getBrokerageUserChildSummaryPage(AppBrokerageUserChildSummaryPageReqVO pageReqVO, Long userId) { |
| 229 | - // 生成推广员编号列表 | |
| 230 | - List<Long> bindUserIds = buildBindUserIdsByLevel(userId, pageReqVO.getLevel()); | |
| 231 | - | |
| 232 | - // TODO @疯狂:情况一和情况二,可以合并哈; | |
| 233 | - // 如果有 nickname 的时候,相当于提前查询 users,然后 nickname 过滤掉 bindUserIds; | |
| 234 | - // 之后,继续使用 selectSummaryPageByUserId 里面 in bindUserIds 查询; | |
| 235 | - | |
| 236 | - // 情况一:没有昵称过滤条件时,直接使用数据库的分页查询 | |
| 237 | - if (StrUtil.isBlank(pageReqVO.getNickname())) { | |
| 238 | - // 1.1 分页查询 | |
| 239 | - IPage<AppBrokerageUserChildSummaryRespVO> pageResult = brokerageUserMapper.selectSummaryPageByUserId( | |
| 240 | - MyBatisUtils.buildPage(pageReqVO), BrokerageRecordBizTypeEnum.ORDER.getType(), | |
| 241 | - BrokerageRecordStatusEnum.SETTLEMENT.getStatus(), bindUserIds, pageReqVO.getSortingField() | |
| 242 | - ); | |
| 243 | - | |
| 244 | - // 1.2 拼接数据并返回 | |
| 245 | - List<Long> userIds = convertList(pageResult.getRecords(), AppBrokerageUserChildSummaryRespVO::getId); | |
| 246 | - Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(userIds); | |
| 247 | - BrokerageUserConvert.INSTANCE.copyTo(pageResult.getRecords(), userMap); | |
| 248 | - return new PageResult<>(pageResult.getRecords(), pageResult.getTotal()); | |
| 249 | - } | |
| 250 | - | |
| 251 | - // 情况二:有昵称过滤条件时,需要跨模块(Member)过滤 | |
| 252 | - // 2.1 查询所有匹配的分销用户 | |
| 253 | - List<AppBrokerageUserChildSummaryRespVO> list = brokerageUserMapper.selectSummaryListByUserId( | |
| 254 | - BrokerageRecordBizTypeEnum.ORDER.getType(), BrokerageRecordStatusEnum.SETTLEMENT.getStatus(), | |
| 255 | - bindUserIds, pageReqVO.getSortingField() | |
| 256 | - ); | |
| 257 | - if (CollUtil.isEmpty(list)) { | |
| 229 | + // 1.1 查询下级用户编号列表 | |
| 230 | + List<Long> childIds = getChildUserIdsByLevel(userId, pageReqVO.getLevel()); | |
| 231 | + if (CollUtil.isEmpty(childIds)) { | |
| 258 | 232 | return PageResult.empty(); |
| 259 | 233 | } |
| 260 | 234 | |
| 261 | - // 2.2 查出对应的用户信息 | |
| 262 | - List<MemberUserRespDTO> users = memberUserApi.getUserList(convertList(list, AppBrokerageUserChildSummaryRespVO::getId)); | |
| 263 | - if (CollUtil.isEmpty(users)) { | |
| 264 | - return PageResult.empty(); | |
| 265 | - } | |
| 266 | - | |
| 267 | - // 2.3 根据昵称过滤出用户编号 | |
| 268 | - Map<Long, MemberUserRespDTO> userMap = users.stream() | |
| 269 | - .filter(user -> StrUtil.contains(user.getNickname(), pageReqVO.getNickname())) | |
| 270 | - .collect(Collectors.toMap(MemberUserRespDTO::getId, dto -> dto)); | |
| 235 | + // 1.2 根据昵称过滤下级用户 | |
| 236 | + Map<Long, MemberUserRespDTO> userMap = convertMapByFilter(memberUserApi.getUserList(childIds), | |
| 237 | + user -> StrUtil.contains(user.getNickname(), pageReqVO.getNickname()), | |
| 238 | + MemberUserRespDTO::getId); | |
| 271 | 239 | if (CollUtil.isEmpty(userMap)) { |
| 272 | 240 | return PageResult.empty(); |
| 273 | 241 | } |
| 274 | 242 | |
| 275 | - // 2.4 根据用户编号过滤结果 | |
| 276 | - list.removeIf(vo -> !userMap.containsKey(vo.getId())); | |
| 277 | - if (CollUtil.isEmpty(list)) { | |
| 278 | - return PageResult.empty(); | |
| 279 | - } | |
| 280 | - | |
| 281 | - // 2.5 处理分页 | |
| 282 | - List<AppBrokerageUserChildSummaryRespVO> result = list.stream() | |
| 283 | - .skip((long) (pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize()) | |
| 284 | - .limit(pageReqVO.getPageSize()) | |
| 285 | - .collect(Collectors.toList()); | |
| 286 | - if (CollUtil.isEmpty(result)) { | |
| 287 | - return PageResult.empty(); | |
| 288 | - } | |
| 243 | + // 2 分页查询 | |
| 244 | + IPage<AppBrokerageUserChildSummaryRespVO> pageResult = brokerageUserMapper.selectSummaryPageByUserId( | |
| 245 | + MyBatisUtils.buildPage(pageReqVO), BrokerageRecordBizTypeEnum.ORDER.getType(), | |
| 246 | + BrokerageRecordStatusEnum.SETTLEMENT.getStatus(), userMap.keySet(), pageReqVO.getSortingField() | |
| 247 | + ); | |
| 289 | 248 | |
| 290 | - // 2.6 拼接数据并返回 | |
| 291 | - BrokerageUserConvert.INSTANCE.copyTo(result, userMap); | |
| 292 | - return new PageResult<>(result, (long) list.size()); | |
| 249 | + // 3 拼接数据并返回 | |
| 250 | + BrokerageUserConvert.INSTANCE.copyTo(pageResult.getRecords(), userMap); | |
| 251 | + return new PageResult<>(pageResult.getRecords(), pageResult.getTotal()); | |
| 293 | 252 | } |
| 294 | 253 | |
| 295 | 254 | private boolean isUserCanBind(BrokerageUserDO user) { |
| ... | ... | @@ -360,24 +319,35 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { |
| 360 | 319 | } |
| 361 | 320 | |
| 362 | 321 | /** |
| 363 | - * 根据绑定用户编号,获得绑定用户编号列表 | |
| 322 | + * 根据绑定用户编号,获得下级用户编号列表 | |
| 364 | 323 | * |
| 365 | 324 | * @param bindUserId 绑定用户编号 |
| 366 | - * @param level 绑定用户的层级。 | |
| 325 | + * @param level 下级用户的层级。 | |
| 367 | 326 | * 如果 level 为空,则查询 1+2 两个层级 |
| 368 | - * @return 绑定用户编号列表 | |
| 327 | + * @return 下级用户编号列表 | |
| 369 | 328 | */ |
| 370 | - private List<Long> buildBindUserIdsByLevel(Long bindUserId, Integer level) { | |
| 329 | + private List<Long> getChildUserIdsByLevel(Long bindUserId, Integer level) { | |
| 371 | 330 | if (bindUserId == null) { |
| 372 | 331 | return Collections.emptyList(); |
| 373 | 332 | } |
| 374 | - Assert.isTrue(level == null || level <= 2, "目前只支持 level 小于等于 2"); | |
| 375 | - List<Long> bindUserIds = CollUtil.newArrayList(); | |
| 376 | - if (level == null || level == 1) { | |
| 377 | - bindUserIds.add(bindUserId); | |
| 333 | + | |
| 334 | + // 先查第 1 级 | |
| 335 | + List<Long> bindUserIds = brokerageUserMapper.selectIdListByBindUserIdIn(Collections.singleton(bindUserId)); | |
| 336 | + if (CollUtil.isEmpty(bindUserIds)) { | |
| 337 | + return Collections.emptyList(); | |
| 378 | 338 | } |
| 379 | - if (level == null || level == 2) { | |
| 380 | - bindUserIds.addAll(convertList(brokerageUserMapper.selectListByBindUserId(bindUserId), BrokerageUserDO::getId)); | |
| 339 | + | |
| 340 | + if (level == null) { | |
| 341 | + // level 为空,再查第 2 级,并合并结果 | |
| 342 | + bindUserIds.addAll(brokerageUserMapper.selectIdListByBindUserIdIn(bindUserIds)); | |
| 343 | + } else if (level == 2) { | |
| 344 | + // 只查第 2 级 | |
| 345 | + bindUserIds = brokerageUserMapper.selectIdListByBindUserIdIn(bindUserIds); | |
| 346 | + } else if (level == 1) { | |
| 347 | + // 只查第 1 级 | |
| 348 | + return bindUserIds; | |
| 349 | + } else { | |
| 350 | + throw exception(BROKERAGE_USER_LEVEL_NOT_SUPPORT); | |
| 381 | 351 | } |
| 382 | 352 | return bindUserIds; |
| 383 | 353 | } | ... | ... |
yudao-module-mall/yudao-module-trade-biz/src/main/resources/mapper/brokerage/BrokerageUserMapper.xml
| ... | ... | @@ -2,7 +2,9 @@ |
| 2 | 2 | <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
| 3 | 3 | <mapper namespace="cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageUserMapper"> |
| 4 | 4 | |
| 5 | - <sql id="selectSummaryListByUserId"> | |
| 5 | + <select id="selectSummaryPageByUserId" | |
| 6 | + resultType="cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO"> | |
| 7 | + | |
| 6 | 8 | SELECT bu.id, bu.bind_user_time AS brokerageTime, |
| 7 | 9 | (SELECT SUM(price) FROM trade_brokerage_record r |
| 8 | 10 | WHERE r.user_id = bu.id AND biz_type = #{bizType} AND r.status = #{status} AND r.deleted = FALSE) AS brokeragePrice, |
| ... | ... | @@ -13,10 +15,10 @@ |
| 13 | 15 | FROM trade_brokerage_user AS bu |
| 14 | 16 | <where> |
| 15 | 17 | bu.deleted = false |
| 16 | - <if test="bindUserIds != null and bindUserIds.size() > 0"> | |
| 17 | - and bu.bind_user_id in | |
| 18 | - <foreach collection="bindUserIds" open="(" item="bindUserId" separator="," close=")"> | |
| 19 | - #{bindUserId} | |
| 18 | + <if test="ids != null and ids.size() > 0"> | |
| 19 | + and bu.id in | |
| 20 | + <foreach collection="ids" open="(" item="id" separator="," close=")"> | |
| 21 | + #{id} | |
| 20 | 22 | </foreach> |
| 21 | 23 | </if> |
| 22 | 24 | </where> |
| ... | ... | @@ -34,15 +36,6 @@ |
| 34 | 36 | ORDER BY bu.bind_user_time DESC |
| 35 | 37 | </otherwise> |
| 36 | 38 | </choose> |
| 37 | - </sql> | |
| 38 | - | |
| 39 | - <select id="selectSummaryPageByUserId" | |
| 40 | - resultType="cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO"> | |
| 41 | - <include refid="selectSummaryListByUserId" /> | |
| 42 | - </select> | |
| 43 | - <select id="selectSummaryListByUserId" | |
| 44 | - resultType="cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO"> | |
| 45 | - <include refid="selectSummaryListByUserId" /> | |
| 46 | 39 | </select> |
| 47 | 40 | |
| 48 | 41 | </mapper> | ... | ... |