From 0a9a71a81a9d4c3c0df7ddf49e5e2f2d0a10f7de Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Thu, 05 Jun 2025 16:23:51 +0800
Subject: [PATCH] feat(mall): 添加积分排行榜功能
---
src/main/java/cc/mrbird/febs/mall/dto/memberLevel/ApiScoreRecordInfoDto.java | 16 +++
src/main/java/cc/mrbird/febs/mall/vo/memberLevel/ApiMemberLabelItemVo.java | 5 +
src/main/java/cc/mrbird/febs/mall/controller/member/ApiMallMemberController.java | 22 ++-
src/main/java/cc/mrbird/febs/mall/vo/memberLevel/ApiScoreRecordInfoVo.java | 21 ++++
src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberService.java | 7
src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallMemberServiceImpl.java | 209 +++++++++++++++++++++++++++++++++++++++++
6 files changed, 264 insertions(+), 16 deletions(-)
diff --git a/src/main/java/cc/mrbird/febs/mall/controller/member/ApiMallMemberController.java b/src/main/java/cc/mrbird/febs/mall/controller/member/ApiMallMemberController.java
index 0099f5c..c895a2f 100644
--- a/src/main/java/cc/mrbird/febs/mall/controller/member/ApiMallMemberController.java
+++ b/src/main/java/cc/mrbird/febs/mall/controller/member/ApiMallMemberController.java
@@ -2,10 +2,8 @@
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.mall.dto.*;
-import cc.mrbird.febs.mall.dto.memberLevel.ApiMemberLabelAddDto;
-import cc.mrbird.febs.mall.dto.memberLevel.ApiMemberLabelInfoDto;
-import cc.mrbird.febs.mall.dto.memberLevel.ApiMemberLabelInsureDto;
-import cc.mrbird.febs.mall.dto.memberLevel.ApiMemberLabelItemDto;
+import cc.mrbird.febs.mall.dto.memberLevel.*;
+import cc.mrbird.febs.mall.dto.sale.ApiSaleRecordInfoDto;
import cc.mrbird.febs.mall.entity.MallMember;
import cc.mrbird.febs.mall.entity.MallMemberPayment;
import cc.mrbird.febs.mall.service.IApiMallAgentService;
@@ -13,10 +11,8 @@
import cc.mrbird.febs.mall.service.IApiMallMemberWalletService;
import cc.mrbird.febs.mall.service.IMallMemberWithdrawService;
import cc.mrbird.febs.mall.vo.*;
-import cc.mrbird.febs.mall.vo.memberLevel.ApiMemberLabelAddVo;
-import cc.mrbird.febs.mall.vo.memberLevel.ApiMemberLabelInfoVo;
-import cc.mrbird.febs.mall.vo.memberLevel.ApiMemberLabelItemVo;
-import cc.mrbird.febs.mall.vo.memberLevel.ApiMemberLabelVo;
+import cc.mrbird.febs.mall.vo.memberLevel.*;
+import cc.mrbird.febs.mall.vo.sale.ApiSaleRecordInfoVo;
import cc.mrbird.febs.vip.service.IMallVipBenefitsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -84,6 +80,16 @@
return memberService.getLabelListById(dto);
}
+ @ApiOperation(value = "积分排行榜", notes = "积分排行榜")
+ @ApiResponses({
+ @ApiResponse(code = 200, message = "success", response = ApiScoreRecordInfoVo.class)
+ })
+ @PostMapping(value = "/scoreRecord")
+ public FebsResponse scoreRecord(@RequestBody @Validated ApiScoreRecordInfoDto dto) {
+
+ return memberService.scoreRecord(dto);
+ }
+
@ApiOperation(value = "我的团列表(我的团)", notes = "我的团列表(我的团)")
@ApiResponses({
@ApiResponse(code = 200, message = "success", response = ApiMemberLabelItemVo.class)
diff --git a/src/main/java/cc/mrbird/febs/mall/dto/memberLevel/ApiScoreRecordInfoDto.java b/src/main/java/cc/mrbird/febs/mall/dto/memberLevel/ApiScoreRecordInfoDto.java
new file mode 100644
index 0000000..bece1d5
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/dto/memberLevel/ApiScoreRecordInfoDto.java
@@ -0,0 +1,16 @@
+package cc.mrbird.febs.mall.dto.memberLevel;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Data
+@ApiModel(value = "ApiScoreRecordInfoDto", description = "参数")
+public class ApiScoreRecordInfoDto {
+
+ @NotNull(message = "分类不能为空")
+ @ApiModelProperty(value = "分类 1-月排行 2-周", example = "1")
+ private Integer type;
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberService.java b/src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberService.java
index ba8189a..62844a0 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberService.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/IApiMallMemberService.java
@@ -2,10 +2,7 @@
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.mall.dto.*;
-import cc.mrbird.febs.mall.dto.memberLevel.ApiMemberLabelAddDto;
-import cc.mrbird.febs.mall.dto.memberLevel.ApiMemberLabelInfoDto;
-import cc.mrbird.febs.mall.dto.memberLevel.ApiMemberLabelInsureDto;
-import cc.mrbird.febs.mall.dto.memberLevel.ApiMemberLabelItemDto;
+import cc.mrbird.febs.mall.dto.memberLevel.*;
import cc.mrbird.febs.mall.entity.MallMember;
import cc.mrbird.febs.mall.entity.MallMemberPayment;
import cc.mrbird.febs.mall.entity.MallShopApply;
@@ -130,6 +127,8 @@
FebsResponse getLabelListById(ApiMemberLabelInfoDto dto);
+ FebsResponse scoreRecord(ApiScoreRecordInfoDto dto);
+
FebsResponse getMemberLabelListById(ApiMemberLabelItemDto dto);
FebsResponse addLabelMember(ApiMemberLabelAddDto dto);
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 a6d7626..17e3d44 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
@@ -9,16 +9,14 @@
import cc.mrbird.febs.mall.conversion.MallShopApplyConversion;
import cc.mrbird.febs.mall.conversion.MallStoreConversion;
import cc.mrbird.febs.mall.dto.*;
-import cc.mrbird.febs.mall.dto.memberLevel.ApiMemberLabelAddDto;
-import cc.mrbird.febs.mall.dto.memberLevel.ApiMemberLabelInfoDto;
-import cc.mrbird.febs.mall.dto.memberLevel.ApiMemberLabelInsureDto;
-import cc.mrbird.febs.mall.dto.memberLevel.ApiMemberLabelItemDto;
+import cc.mrbird.febs.mall.dto.memberLevel.*;
import cc.mrbird.febs.mall.dto.signActivity.ApiNewGiftSettingDto;
import cc.mrbird.febs.mall.entity.*;
import cc.mrbird.febs.mall.mapper.*;
import cc.mrbird.febs.mall.service.*;
import cc.mrbird.febs.mall.vo.*;
import cc.mrbird.febs.mall.vo.memberLevel.*;
+import cc.mrbird.febs.mall.vo.sale.ApiSaleRecordInfoVo;
import cc.mrbird.febs.pay.model.BrandWCPayRequestData;
import cc.mrbird.febs.pay.service.IXcxPayService;
import cc.mrbird.febs.pay.util.MD5;
@@ -27,6 +25,7 @@
import cc.mrbird.febs.vip.mapper.MallVipConfigMapper;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
@@ -55,6 +54,7 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
+import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
/**
@@ -1741,6 +1741,7 @@
new LambdaQueryWrapper<HappyMemberLabel>()
.select( HappyMemberLabel::getId, HappyMemberLabel::getCode,HappyMemberLabel::getIconPng, HappyMemberLabel::getName, HappyMemberLabel::getContent, HappyMemberLabel::getHeaderPng)
.in(HappyMemberLabel::getId, collect)
+ .orderByDesc(HappyMemberLabel::getCode)
);
if(CollUtil.isNotEmpty(happyMemberLabels)){
for (HappyMemberLabel happyMemberLabel : happyMemberLabels) {
@@ -1800,6 +1801,187 @@
}
@Override
+ public FebsResponse scoreRecord(ApiScoreRecordInfoDto dto) {
+ // 初始化结果列表
+ 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);
+
+ // 返回成功响应,包含销售记录信息
+ return new FebsResponse().success().data(apiSaleRecordInfoVos);
+ }
+
+ @Override
public FebsResponse getMemberLabelListById(ApiMemberLabelItemDto dto) {
// 获取当前登录用户的ID
@@ -1822,11 +2004,30 @@
.in(MallMember::getId, memberIdSet)
.eq(MallMember::getAccountStatus, MallMember.ACCOUNT_STATUS_ENABLE)
);
+
+ 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)
+ );
+ //stream流操作mallMoneyFlows,返回一个map<Long,BigDecimal>,其中key为memberId,value为mallMoneyFlow的memberId等于key的amount的总和
+ Map<Long, BigDecimal> prizeScoreMap = mallMoneyFlows.stream()
+ .filter(Objects::nonNull) // 防止 MallMoneyFlow 为 null
+ .collect(Collectors.groupingBy(
+ MallMoneyFlow::getMemberId,
+ Collectors.mapping(
+ MallMoneyFlow::getAmount,
+ Collectors.reducing(BigDecimal.ZERO, BigDecimal::add)
+ )
+ ));
for (MallMember mallMember : mallMembers){
ApiMemberLabelItemVo apiMemberLabelItemVo = new ApiMemberLabelItemVo();
apiMemberLabelItemVo.setName(mallMember.getName());
apiMemberLabelItemVo.setAvatar(mallMember.getAvatar());
apiMemberLabelItemVo.setPhone(mallMember.getPhone());
+ apiMemberLabelItemVo.setScore(prizeScoreMap.get(mallMember.getId()).setScale(0,RoundingMode.DOWN));
apiMemberLabelItemVos.add(apiMemberLabelItemVo);
}
}
diff --git a/src/main/java/cc/mrbird/febs/mall/vo/memberLevel/ApiMemberLabelItemVo.java b/src/main/java/cc/mrbird/febs/mall/vo/memberLevel/ApiMemberLabelItemVo.java
index f5f0fd8..7d88515 100644
--- a/src/main/java/cc/mrbird/febs/mall/vo/memberLevel/ApiMemberLabelItemVo.java
+++ b/src/main/java/cc/mrbird/febs/mall/vo/memberLevel/ApiMemberLabelItemVo.java
@@ -4,6 +4,8 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
+import java.math.BigDecimal;
+
@Data
@ApiModel(value = "ApiMemberLabelItemVo", description = "商城用户信息返回类")
public class ApiMemberLabelItemVo {
@@ -17,4 +19,7 @@
@ApiModelProperty(value = "电话")
private String phone;
+ @ApiModelProperty(value = "积分")
+ private BigDecimal score;
+
}
diff --git a/src/main/java/cc/mrbird/febs/mall/vo/memberLevel/ApiScoreRecordInfoVo.java b/src/main/java/cc/mrbird/febs/mall/vo/memberLevel/ApiScoreRecordInfoVo.java
new file mode 100644
index 0000000..0ec5ae2
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/mall/vo/memberLevel/ApiScoreRecordInfoVo.java
@@ -0,0 +1,21 @@
+package cc.mrbird.febs.mall.vo.memberLevel;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+@ApiModel(value = "ApiScoreRecordInfoVo", description = "商城用户信息返回类")
+public class ApiScoreRecordInfoVo {
+
+ @ApiModelProperty(value = "昵称")
+ private String name;
+
+ @ApiModelProperty(value = "头像")
+ private String avatar;
+
+ @ApiModelProperty(value = "总积分")
+ private BigDecimal score;
+}
--
Gitblit v1.9.1