Commit d0f0bc58888f16f0b02c9252283c2d00709192f5

Authored by owen
1 parent 7fdd36d9

分销:调整推广人列表查询方式

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&lt;BrokerageUserDO&gt; {
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&lt;BrokerageUserDO&gt; {
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>
... ...