From 6127f9c2f53b4e11d2ddfc5575631e5403da0410 Mon Sep 17 00:00:00 2001 From: Administrator <15274802129@163.com> Date: Thu, 05 Jun 2025 17:34:45 +0800 Subject: [PATCH] feat(mall): 添加年排行功能并优化积分查询性能 --- src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java | 315 ++++++++++++++++++++++++---------------------------- 1 files changed, 144 insertions(+), 171 deletions(-) diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java index 17e3d44..5afa1cb 100644 --- a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java +++ b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java @@ -1,5 +1,6 @@ package cc.mrbird.febs.mall.service.impl; +import cc.mrbird.febs.common.configure.FebsConfigure; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.enumerates.*; import cc.mrbird.febs.common.exception.FebsException; @@ -98,6 +99,7 @@ private final IApiMallMemberWalletService mallMemberWalletService; private final HappyMemberLabelRecordMapper happyMemberLabelRecordMapper; private final HappyMemberLabelMapper happyMemberLabelMapper; + private final FebsConfigure febsConfigure; @Value("${spring.profiles.active}") @@ -1805,177 +1807,148 @@ // 初始化结果列表 List<ApiScoreRecordInfoVo> apiSaleRecordInfoVos = new ArrayList<>(); -// List<HappyMemberLabel> happyMemberLabels = happyMemberLabelMapper.selectList( -// Wrappers.lambdaQuery(HappyMemberLabel.class) -// .eq(HappyMemberLabel::getCode, 1) -// .eq(HappyMemberLabel::getParentId, 0) -// ); -// if(CollUtil.isEmpty(happyMemberLabels)){ -// return new FebsResponse().success().data(apiSaleRecordInfoVos); -// } -// -// // 获取类型参数 -// Integer type = dto.getType(); -// // 校验类型参数,确保其为1(月)或2(周) -// if (type == null || (type != 1 && type != 2)) { -// return new FebsResponse().fail().message("非法的类型参数"); -// } -// -// // 根据类型参数确定开始时间 -// DateTime startTime = type == 1 ? DateUtil.beginOfMonth(new Date()) : DateUtil.beginOfWeek(new Date()); -// -// // 查询指定时间范围内的团队积分记录 -// for (HappyMemberLabel happyMemberLabel : happyMemberLabels){ -// //初始化公共部分 -// ApiScoreRecordInfoVo apiScoreRecordInfoVo = new ApiScoreRecordInfoVo(); -// apiScoreRecordInfoVo.setName(happyMemberLabel.getName()); -// apiScoreRecordInfoVo.setAvatar(happyMemberLabel.getIconPng()); -// -// //获取这个全部的标识的二级标识 -// List<HappyMemberLabel> happyMemberLabelChildList = happyMemberLabelMapper.selectList( -// Wrappers.lambdaQuery(HappyMemberLabel.class) -// .eq(HappyMemberLabel::getParentId, happyMemberLabel.getId()) -// ); -// if(CollUtil.isEmpty(happyMemberLabelChildList)){ -// apiScoreRecordInfoVo.setScore(BigDecimal.ZERO); -// apiSaleRecordInfoVos.add(apiScoreRecordInfoVo); -// continue; -// } -// -// //stream流操作happyMemberLabelChildList,返回一个id的set集合 -// Set<Long> labelIdSet = happyMemberLabelChildList.stream().map(HappyMemberLabel::getId).collect(Collectors.toSet()); -// //获取全部会员的绑定关系 -// List<HappyMemberLabelRecord> happyMemberLabelRecords = happyMemberLabelRecordMapper.selectList( -// Wrappers.lambdaQuery(HappyMemberLabelRecord.class) -// .in(HappyMemberLabelRecord::getLabelId, labelIdSet) -// ); -// if(CollUtil.isEmpty(happyMemberLabelRecords)){ -// apiScoreRecordInfoVo.setScore(BigDecimal.ZERO); -// apiSaleRecordInfoVos.add(apiScoreRecordInfoVo); -// continue; -// } -// //stream流操作happyMemberLabelRecords,返回一个memberId的set集合 -// Set<Long> memberIdSet = happyMemberLabelRecords.stream().map(HappyMemberLabelRecord::getMemberId).collect(Collectors.toSet()); -// List<MallMoneyFlow> mallMoneyFlows = mallMoneyFlowMapper.selectList( -// Wrappers.lambdaQuery(MallMoneyFlow.class) -// .select(MallMoneyFlow::getAmount, MallMoneyFlow::getMemberId) -// .in(MallMoneyFlow::getMemberId, memberIdSet) -// .eq(MallMoneyFlow::getFlowType, FlowTypeEnum.PRIZE_SCORE.getValue()) -// .gt(MallMoneyFlow::getAmount, BigDecimal.ZERO) -// .ge(MallMoneyFlow::getCreatedTime, startTime) -// ); -// -// } -// -// if(CollUtil.isNotEmpty(happyMemberLabels)){ -// List<CompletableFuture<ApiScoreRecordInfoVo>> futures = new ArrayList<>(); -// DateTime endTime = DateUtil.date(); -// happyMemberLabels.forEach(item -> { -// CompletableFuture<ApiScoreRecordInfoVo> uCompletableFuture = CompletableFuture.supplyAsync(() -> { -// //初始化公共部分 -// ApiScoreRecordInfoVo apiScoreRecordInfoVo = new ApiScoreRecordInfoVo(); -// apiScoreRecordInfoVo.setName(item.getName()); -// apiScoreRecordInfoVo.setAvatar(item.getIconPng()); -// apiScoreRecordInfoVo.setScore(BigDecimal.ZERO); -// -// //获取这个全部的标识的二级标识 -// List<HappyMemberLabel> happyMemberLabelChildList = happyMemberLabelMapper.selectList( -// Wrappers.lambdaQuery(HappyMemberLabel.class) -// .eq(HappyMemberLabel::getParentId, item.getId()) -// ); -// if(CollUtil.isNotEmpty(happyMemberLabelChildList)){ -// //stream流操作happyMemberLabelChildList,返回一个id的set集合 -// Set<Long> labelIdSet = happyMemberLabelChildList.stream().map(HappyMemberLabel::getId).collect(Collectors.toSet()); -// //获取全部会员的绑定关系 -// List<HappyMemberLabelRecord> happyMemberLabelRecords = happyMemberLabelRecordMapper.selectList( -// Wrappers.lambdaQuery(HappyMemberLabelRecord.class) -// .in(HappyMemberLabelRecord::getLabelId, labelIdSet) -// ); -// if(CollUtil.isNotEmpty(happyMemberLabelRecords)){ -// apiScoreRecordInfoVo.setScore(BigDecimal.ZERO); -// apiSaleRecordInfoVos.add(apiScoreRecordInfoVo); -// continue; -// } -// //stream流操作happyMemberLabelRecords,返回一个memberId的set集合 -// Set<Long> memberIdSet = happyMemberLabelRecords.stream().map(HappyMemberLabelRecord::getMemberId).collect(Collectors.toSet()); -// List<MallMoneyFlow> mallMoneyFlows = mallMoneyFlowMapper.selectList( -// Wrappers.lambdaQuery(MallMoneyFlow.class) -// .select(MallMoneyFlow::getAmount, MallMoneyFlow::getMemberId) -// .in(MallMoneyFlow::getMemberId, memberIdSet) -// .eq(MallMoneyFlow::getFlowType, FlowTypeEnum.PRIZE_SCORE.getValue()) -// .gt(MallMoneyFlow::getAmount, BigDecimal.ZERO) -// .ge(MallMoneyFlow::getCreatedTime, startTime) -// ); -// } -// -// -// return item; -// }, febsConfigure.asyncThreadPoolTaskExecutor()); -// futures.add(uCompletableFuture); -// }); -// // 等待所有任务完成 -// CompletableFuture<Void> allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); -// allOf.join(); // 阻塞直到所有任务完成 -// } -// -// -// -// // 如果查询到销售记录,则进行处理 -// if (CollUtil.isNotEmpty(mallAchieveRecords)) { -// // 提取 memberId 集合,避免重复 stream -// Set<Long> memberIds = mallAchieveRecords.stream() -// .map(MallAchieveRecord::getMemberId) -// .collect(Collectors.toSet()); -// -// // 分组求和 -// Map<Long, BigDecimal> memberIdToCostAmount = mallAchieveRecords.stream() -// .collect(Collectors.groupingBy( -// MallAchieveRecord::getMemberId, -// Collectors.mapping( -// MallAchieveRecord::getCostAmount, -// Collectors.reducing(BigDecimal.ZERO, BigDecimal::add) -// ) -// )); -// -// // 查询会员信息 -// List<MallMember> mallMembers = this.baseMapper.selectList( -// new LambdaQueryWrapper<MallMember>() -// .select(MallMember::getId, MallMember::getName, MallMember::getAvatar) -// .in(MallMember::getId, memberIds) -// ); -// -// // 构建会员信息映射表 -// Map<Long, MallMember> mallMemberMap = mallMembers.stream() -// .collect(Collectors.toMap(MallMember::getId, m -> m)); -// -// // 构建结果列表并避免空指针 -// for (Map.Entry<Long, BigDecimal> entry : memberIdToCostAmount.entrySet()) { -// MallMember member = mallMemberMap.get(entry.getKey()); -// if (member == null) { -// continue; // 忽略不存在的会员 -// } -// ApiSaleRecordInfoVo vo = new ApiSaleRecordInfoVo(); -// vo.setId(member.getId()); -// vo.setName(member.getName()); -// vo.setAvatar(member.getAvatar()); -// vo.setCostAmount(entry.getValue()); -// apiSaleRecordInfoVos.add(vo); -// } -// -// // 排序 -// apiSaleRecordInfoVos.sort(Comparator.comparing(ApiSaleRecordInfoVo::getCostAmount).reversed()); -// -// //stream流操作apiSaleRecordInfoVos获取id等于memberId的数据,并且返回第一个数据和在数组中的下标索引 -// ApiSaleRecordInfoVo memberSale = apiSaleRecordInfoVos.stream() -// .filter(vo -> vo.getId().equals(memberId)) -// .findFirst() -// .orElse(null); -// if (memberSale != null) { -// apiSaleRecordInfoVo.setSortCnt(apiSaleRecordInfoVos.indexOf(memberSale)+1); -// apiSaleRecordInfoVo.setCostAmount(memberSale.getCostAmount()); -// } -// } -// apiSaleRecordInfoVo.setSaleRecord(apiSaleRecordInfoVos); + List<HappyMemberLabel> happyMemberLabels = happyMemberLabelMapper.selectList( + Wrappers.lambdaQuery(HappyMemberLabel.class) + .eq(HappyMemberLabel::getCode, 1) + .eq(HappyMemberLabel::getParentId, 0) + ); + if(CollUtil.isEmpty(happyMemberLabels)){ + return new FebsResponse().success().data(apiSaleRecordInfoVos); + } + + // 获取类型参数 + Integer type = dto.getType(); + // 校验类型参数,确保其为1(月)或2(周) + if (type == null || (type != 1 && type != 2 && type != 3)) { + return new FebsResponse().fail().message("非法的类型参数"); + } + DateTime startTime = DateUtil.beginOfMonth(new Date()); + if(1 == type){ + startTime = DateUtil.beginOfMonth(new Date()); + } + if(2 == type){ + startTime = DateUtil.beginOfWeek(new Date()); + } + if(3 == type){ + startTime = DateUtil.beginOfYear(new Date()); + } + + // 合并查询所有子标签 + Set<Long> parentIds = happyMemberLabels.stream() + .map(HappyMemberLabel::getId) + .collect(Collectors.toSet()); + + List<HappyMemberLabel> allChildLabels = happyMemberLabelMapper.selectList( + Wrappers.lambdaQuery(HappyMemberLabel.class) + .in(HappyMemberLabel::getParentId, parentIds) + ); + + Map<Long, List<HappyMemberLabel>> childLabelMap = new HashMap<>(); + if (CollUtil.isNotEmpty(allChildLabels)) { + childLabelMap = allChildLabels.stream() + .collect(Collectors.groupingBy(HappyMemberLabel::getParentId)); + } + + // 提取所有子标签 ID + Set<Long> labelIds = allChildLabels.stream() + .map(HappyMemberLabel::getId) + .collect(Collectors.toSet()); + + // 获取所有绑定关系 + List<HappyMemberLabelRecord> labelRecords = CollUtil.isEmpty(labelIds) ? Collections.emptyList() : + happyMemberLabelRecordMapper.selectList( + Wrappers.lambdaQuery(HappyMemberLabelRecord.class) + .in(HappyMemberLabelRecord::getLabelId, labelIds) + ); + + Map<Long, Set<Long>> labelToMembersMap = new HashMap<>(); + if (CollUtil.isNotEmpty(labelRecords)) { + labelToMembersMap = labelRecords.stream() + .collect(Collectors.groupingBy( + HappyMemberLabelRecord::getLabelId, + Collectors.mapping(HappyMemberLabelRecord::getMemberId, Collectors.toSet()) + )); + } + + Set<Long> memberIds = labelToMembersMap.values().stream() + .flatMap(Set::stream) + .collect(Collectors.toSet()); + + // 获取资金流 + List<MallMoneyFlow> moneyFlows = CollUtil.isEmpty(memberIds) ? Collections.emptyList() : + mallMoneyFlowMapper.selectList( + Wrappers.lambdaQuery(MallMoneyFlow.class) + .select(MallMoneyFlow::getAmount, MallMoneyFlow::getMemberId) + .in(MallMoneyFlow::getMemberId, memberIds) + .eq(MallMoneyFlow::getFlowType, FlowTypeEnum.PRIZE_SCORE.getValue()) + .gt(MallMoneyFlow::getAmount, BigDecimal.ZERO) + .ge(MallMoneyFlow::getCreatedTime, startTime) + ); + + Map<Long, BigDecimal> memberScoreMap = new HashMap<>(); + if (CollUtil.isNotEmpty(moneyFlows)) { + memberScoreMap = moneyFlows.stream() + .collect(Collectors.groupingBy( + MallMoneyFlow::getMemberId, + Collectors.mapping(MallMoneyFlow::getAmount, Collectors.reducing(BigDecimal.ZERO, BigDecimal::add)) + )); + } + + List<CompletableFuture<ApiScoreRecordInfoVo>> futures = new ArrayList<>(); + + Map<Long, List<HappyMemberLabel>> finalChildLabelMap = childLabelMap; + Map<Long, Set<Long>> finalLabelToMembersMap = labelToMembersMap; + Map<Long, BigDecimal> finalMemberScoreMap = memberScoreMap; + happyMemberLabels.forEach(item -> { + CompletableFuture<ApiScoreRecordInfoVo> uCompletableFuture = CompletableFuture.supplyAsync(() -> { + ApiScoreRecordInfoVo vo = new ApiScoreRecordInfoVo(); + vo.setName(item.getName()); + vo.setAvatar(item.getIconPng()); + vo.setScore(BigDecimal.ZERO); + + List<HappyMemberLabel> children = finalChildLabelMap.getOrDefault(item.getId(), Collections.emptyList()); + if (CollUtil.isEmpty(children)) { + return vo; + } + + Set<Long> childIds = children.stream().map(HappyMemberLabel::getId).collect(Collectors.toSet()); + Set<Long> members = new HashSet<>(); + for (Long childId : childIds) { + Set<Long> ids = finalLabelToMembersMap.getOrDefault(childId, Collections.emptySet()); + members.addAll(ids); + } + + if (CollUtil.isEmpty(members)) { + return vo; + } + + BigDecimal total = BigDecimal.ZERO; + for (Long memberId : members) { + total = total.add(finalMemberScoreMap.getOrDefault(memberId, BigDecimal.ZERO)); + } + vo.setScore(total.setScale(0, RoundingMode.DOWN)); + return vo; + }, febsConfigure.asyncThreadPoolTaskExecutor()).exceptionally(ex -> { + // 异常兜底返回默认值 + ApiScoreRecordInfoVo vo = new ApiScoreRecordInfoVo(); + vo.setName(item.getName()); + vo.setAvatar(item.getIconPng()); + vo.setScore(BigDecimal.ZERO); + return vo; + }); + + futures.add(uCompletableFuture); + }); + // 等待所有任务完成 + CompletableFuture<Void> allOf = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])); + allOf.join(); // 阻塞直到所有任务完成 + + //等任务结束,获取返回结果 + apiSaleRecordInfoVos = futures.stream() + .map(CompletableFuture::join) + .sorted(Comparator.comparing(ApiScoreRecordInfoVo::getScore).reversed()) + .collect(Collectors.toList()); + // 返回成功响应,包含销售记录信息 return new FebsResponse().success().data(apiSaleRecordInfoVos); -- Gitblit v1.9.1