Commit 7d68bdc7c83f97030134c5793516cc4da74ab038

Authored by owen
1 parent cafa938f

分销:重构下级分销统计

yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/BrokerageUserConvert.java
@@ -11,7 +11,6 @@ import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokera @@ -11,7 +11,6 @@ import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokera
11 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO; 11 import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
12 import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageWithdrawSummaryRespBO; 12 import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageWithdrawSummaryRespBO;
13 import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryRespBO; 13 import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryRespBO;
14 -import com.baomidou.mybatisplus.core.metadata.IPage;  
15 import org.mapstruct.Mapper; 14 import org.mapstruct.Mapper;
16 import org.mapstruct.MappingTarget; 15 import org.mapstruct.MappingTarget;
17 import org.mapstruct.factory.Mappers; 16 import org.mapstruct.factory.Mappers;
@@ -88,8 +87,8 @@ public interface BrokerageUserConvert { @@ -88,8 +87,8 @@ public interface BrokerageUserConvert {
88 return respVO; 87 return respVO;
89 } 88 }
90 89
91 - default void copyTo(IPage<AppBrokerageUserChildSummaryRespVO> pageResult, Map<Long, MemberUserRespDTO> userMap) {  
92 - for (AppBrokerageUserChildSummaryRespVO vo : pageResult.getRecords()) { 90 + default void copyTo(List<AppBrokerageUserChildSummaryRespVO> list, Map<Long, MemberUserRespDTO> userMap) {
  91 + for (AppBrokerageUserChildSummaryRespVO vo : list) {
93 Optional.ofNullable(userMap.get(vo.getId())).ifPresent(user -> 92 Optional.ofNullable(userMap.get(vo.getId())).ifPresent(user ->
94 vo.setNickname(user.getNickname()).setAvatar(user.getAvatar())); 93 vo.setNickname(user.getNickname()).setAvatar(user.getAvatar()));
95 } 94 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/BrokerageUserMapper.java
@@ -138,13 +138,35 @@ public interface BrokerageUserMapper extends BaseMapperX&lt;BrokerageUserDO&gt; { @@ -138,13 +138,35 @@ public interface BrokerageUserMapper extends BaseMapperX&lt;BrokerageUserDO&gt; {
138 @Param("beginTime") LocalDateTime beginTime, 138 @Param("beginTime") LocalDateTime beginTime,
139 @Param("endTime") LocalDateTime endTime); 139 @Param("endTime") LocalDateTime endTime);
140 140
  141 + /**
  142 + * 下级分销统计(分页)
  143 + *
  144 + * @param bizType 业务类型
  145 + * @param status 状态
  146 + * @param bindUserIds 绑定用户编号列表
  147 + * @param sortingField 排序字段
  148 + * @return 下级分销统计分页列表
  149 + */
141 IPage<AppBrokerageUserChildSummaryRespVO> selectSummaryPageByUserId(Page<?> page, 150 IPage<AppBrokerageUserChildSummaryRespVO> selectSummaryPageByUserId(Page<?> page,
142 - @Param("ids") List<Long> ids, // BrokerageUser 的 ids 数组  
143 @Param("bizType") Integer bizType, 151 @Param("bizType") Integer bizType,
144 @Param("status") Integer status, 152 @Param("status") Integer status,
145 @Param("bindUserIds") List<Long> bindUserIds, 153 @Param("bindUserIds") List<Long> bindUserIds,
146 @Param("sortingField") SortingField sortingField); 154 @Param("sortingField") SortingField sortingField);
147 155
  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 +
148 default List<BrokerageUserDO> selectListByBindUserId(Long bindUserId) { 170 default List<BrokerageUserDO> selectListByBindUserId(Long bindUserId) {
149 return selectList(BrokerageUserDO::getBindUserId, bindUserId); 171 return selectList(BrokerageUserDO::getBindUserId, bindUserId);
150 } 172 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/BrokerageUserServiceImpl.java
@@ -31,6 +31,7 @@ import org.springframework.validation.annotation.Validated; @@ -31,6 +31,7 @@ import org.springframework.validation.annotation.Validated;
31 import javax.annotation.Resource; 31 import javax.annotation.Resource;
32 import java.time.LocalDateTime; 32 import java.time.LocalDateTime;
33 import java.util.*; 33 import java.util.*;
  34 +import java.util.stream.Collectors;
34 35
35 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 36 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
36 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; 37 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@@ -225,25 +226,66 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { @@ -225,25 +226,66 @@ public class BrokerageUserServiceImpl implements BrokerageUserService {
225 226
226 @Override 227 @Override
227 public PageResult<AppBrokerageUserChildSummaryRespVO> getBrokerageUserChildSummaryPage(AppBrokerageUserChildSummaryPageReqVO pageReqVO, Long userId) { 228 public PageResult<AppBrokerageUserChildSummaryRespVO> getBrokerageUserChildSummaryPage(AppBrokerageUserChildSummaryPageReqVO pageReqVO, Long userId) {
228 - // 1.1 根据昵称过滤用户  
229 - List<Long> ids = StrUtil.isBlank(pageReqVO.getNickname())  
230 - ? Collections.emptyList()  
231 - : convertList(memberUserApi.getUserListByNickname(pageReqVO.getNickname()), MemberUserRespDTO::getId);  
232 - // 1.2 生成推广员编号列表  
233 - // TODO @疯狂:是不是可以先 1.2 查询出来,然后查询对应的昵称,进行过滤?避免昵称过滤返回的 id 过多; 229 + // 生成推广员编号列表
234 List<Long> bindUserIds = buildBindUserIdsByLevel(userId, pageReqVO.getLevel()); 230 List<Long> bindUserIds = buildBindUserIdsByLevel(userId, pageReqVO.getLevel());
235 231
236 - // 2. 分页查询  
237 - IPage<AppBrokerageUserChildSummaryRespVO> pageResult = brokerageUserMapper.selectSummaryPageByUserId(  
238 - MyBatisUtils.buildPage(pageReqVO), ids, BrokerageRecordBizTypeEnum.ORDER.getType(),  
239 - BrokerageRecordStatusEnum.SETTLEMENT.getStatus(), bindUserIds, pageReqVO.getSortingField() 232 + // 情况一:没有昵称过滤条件时,直接使用数据库的分页查询
  233 + if (StrUtil.isBlank(pageReqVO.getNickname())) {
  234 + // 1.1 分页查询
  235 + IPage<AppBrokerageUserChildSummaryRespVO> pageResult = brokerageUserMapper.selectSummaryPageByUserId(
  236 + MyBatisUtils.buildPage(pageReqVO), BrokerageRecordBizTypeEnum.ORDER.getType(),
  237 + BrokerageRecordStatusEnum.SETTLEMENT.getStatus(), bindUserIds, pageReqVO.getSortingField()
  238 + );
  239 +
  240 + // 1.2 拼接数据并返回
  241 + List<Long> userIds = convertList(pageResult.getRecords(), AppBrokerageUserChildSummaryRespVO::getId);
  242 + Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(userIds);
  243 + BrokerageUserConvert.INSTANCE.copyTo(pageResult.getRecords(), userMap);
  244 + return new PageResult<>(pageResult.getRecords(), pageResult.getTotal());
  245 + }
  246 +
  247 + // 情况二:有昵称过滤条件时,需要跨模块(Member)过滤
  248 + // 2.1 查询所有匹配的分销用户
  249 + List<AppBrokerageUserChildSummaryRespVO> list = brokerageUserMapper.selectSummaryListByUserId(
  250 + BrokerageRecordBizTypeEnum.ORDER.getType(), BrokerageRecordStatusEnum.SETTLEMENT.getStatus(),
  251 + bindUserIds, pageReqVO.getSortingField()
240 ); 252 );
  253 + if (CollUtil.isEmpty(list)) {
  254 + return PageResult.empty();
  255 + }
241 256
242 - // 3. 拼接数据并返回  
243 - List<Long> userIds = convertList(pageResult.getRecords(), AppBrokerageUserChildSummaryRespVO::getId);  
244 - Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(userIds);  
245 - BrokerageUserConvert.INSTANCE.copyTo(pageResult, userMap);  
246 - return new PageResult<>(pageResult.getRecords(), pageResult.getTotal()); 257 + // 2.2 查出对应的用户信息
  258 + List<MemberUserRespDTO> users = memberUserApi.getUserList(convertList(list, AppBrokerageUserChildSummaryRespVO::getId));
  259 + if (CollUtil.isEmpty(users)) {
  260 + return PageResult.empty();
  261 + }
  262 +
  263 + // 2.3 根据昵称过滤出用户编号
  264 + Map<Long, MemberUserRespDTO> userMap = users.stream()
  265 + .filter(user -> StrUtil.contains(user.getNickname(), pageReqVO.getNickname()))
  266 + .collect(Collectors.toMap(MemberUserRespDTO::getId, dto -> dto));
  267 + if (CollUtil.isEmpty(userMap)) {
  268 + return PageResult.empty();
  269 + }
  270 +
  271 + // 2.4 根据用户编号过滤结果
  272 + list.removeIf(vo -> !userMap.containsKey(vo.getId()));
  273 + if (CollUtil.isEmpty(list)) {
  274 + return PageResult.empty();
  275 + }
  276 +
  277 + // 2.5 处理分页
  278 + List<AppBrokerageUserChildSummaryRespVO> result = list.stream()
  279 + .skip((long) (pageReqVO.getPageNo() - 1) * pageReqVO.getPageSize())
  280 + .limit(pageReqVO.getPageSize())
  281 + .collect(Collectors.toList());
  282 + if (CollUtil.isEmpty(result)) {
  283 + return PageResult.empty();
  284 + }
  285 +
  286 + // 2.6 拼接数据并返回
  287 + BrokerageUserConvert.INSTANCE.copyTo(result, userMap);
  288 + return new PageResult<>(result, (long) list.size());
247 } 289 }
248 290
249 private boolean isUserCanBind(BrokerageUserDO user) { 291 private boolean isUserCanBind(BrokerageUserDO user) {
yudao-module-mall/yudao-module-trade-biz/src/main/resources/mapper/brokerage/BrokerageUserMapper.xml
@@ -2,8 +2,7 @@ @@ -2,8 +2,7 @@
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 <mapper namespace="cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageUserMapper"> 3 <mapper namespace="cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageUserMapper">
4 4
5 - <select id="selectSummaryPageByUserId"  
6 - resultType="cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO"> 5 + <sql id="selectSummaryListByUserId">
7 SELECT bu.id, bu.bind_user_time AS brokerageTime, 6 SELECT bu.id, bu.bind_user_time AS brokerageTime,
8 (SELECT SUM(price) FROM trade_brokerage_record r 7 (SELECT SUM(price) FROM trade_brokerage_record r
9 WHERE r.user_id = bu.id AND biz_type = #{bizType} AND r.status = #{status} AND r.deleted = FALSE) AS brokeragePrice, 8 WHERE r.user_id = bu.id AND biz_type = #{bizType} AND r.status = #{status} AND r.deleted = FALSE) AS brokeragePrice,
@@ -14,12 +13,6 @@ @@ -14,12 +13,6 @@
14 FROM trade_brokerage_user AS bu 13 FROM trade_brokerage_user AS bu
15 <where> 14 <where>
16 bu.deleted = false 15 bu.deleted = false
17 - <if test="ids != null and ids.size() > 0">  
18 - and bu.id in  
19 - <foreach collection="ids" open="(" item="id" separator="," close=")">  
20 - #{id}  
21 - </foreach>  
22 - </if>  
23 <if test="bindUserIds != null and bindUserIds.size() > 0"> 16 <if test="bindUserIds != null and bindUserIds.size() > 0">
24 and bu.bind_user_id in 17 and bu.bind_user_id in
25 <foreach collection="bindUserIds" open="(" item="bindUserId" separator="," close=")"> 18 <foreach collection="bindUserIds" open="(" item="bindUserId" separator="," close=")">
@@ -41,6 +34,15 @@ @@ -41,6 +34,15 @@
41 ORDER BY bu.bind_user_time DESC 34 ORDER BY bu.bind_user_time DESC
42 </otherwise> 35 </otherwise>
43 </choose> 36 </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" />
44 </select> 46 </select>
45 47
46 </mapper> 48 </mapper>