3
0
Fork 0

## Opt - 重构统计盒数逻辑

This commit is contained in:
sangelxiu1 2025-06-12 14:37:33 +08:00
parent 4bca022430
commit cd3c17c6dc
8 changed files with 414 additions and 7 deletions

View File

@ -5,14 +5,13 @@ import com.hzs.common.core.web.controller.BaseController;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.core.web.page.TableDataInfo;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.retail.member.service.ICuMemberRetailAchieveService;
import com.hzs.retail.member.vo.CuMemberRetailAchieveVO;
import com.hzs.retail.member.vo.CuMemberRetailDataStatisticsResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.util.List;
/**
@ -44,7 +43,13 @@ public class ApiRetailHomePageController extends BaseController {
Long pkMember = SecurityUtils.getUserId();
Integer pkCountry = SecurityUtils.getPkCountry();
Integer systemType = SecurityUtils.getSystemType();
return AjaxResult.success(retailAchieveService.selectMemberSmallBox(pkMember, pkCountry, systemType));
CuMemberRetailDataStatisticsResultVO result = retailAchieveService.getRetailDataStatisticsDetail(pkMember, pkCountry, systemType);
CuMemberRetailAchieveVO vo = CuMemberRetailAchieveVO.builder()
.totalBox(result.getTotalBoxNum())
.smallAreaBox(result.getSmallRangeTotalBoxNum())
.build();
return AjaxResult.success(vo);
// return AjaxResult.success(retailAchieveService.selectMemberSmallBox(pkMember, pkCountry, systemType));
}
/**

View File

@ -3,6 +3,7 @@ package com.hzs.retail.member.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hzs.common.domain.member.achieve.CuMemberRetailRange;
import com.hzs.retail.member.vo.CuMemberRetailAchieveVO;
import com.hzs.retail.member.vo.CuMemberRetailDataStatisticsDetailVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@ -166,6 +167,13 @@ public interface CuMemberRetailRangeMapper extends BaseMapper<CuMemberRetailRang
*/
List<CuMemberRetailAchieveVO> selectMemberSumAchieve(CuMemberRetailAchieveVO cuMemberAchieveVO);
/**
* 获取会员结算明细
* @param cuMemberAchieveVO
* @return
*/
List<CuMemberRetailDataStatisticsDetailVO> getRetailDataStatisticsDetail(CuMemberRetailAchieveVO cuMemberAchieveVO);
/**
* 查询当天自己新增盒数
*

View File

@ -3,8 +3,11 @@ package com.hzs.retail.member.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.hzs.common.domain.member.achieve.CuMemberRetailRange;
import com.hzs.retail.member.vo.CuMemberRetailAchieveVO;
import com.hzs.retail.member.vo.CuMemberRetailDataStatisticsDetailVO;
import com.hzs.retail.member.vo.CuMemberRetailDataStatisticsResultVO;
import java.util.List;
import java.util.Map;
public interface ICuMemberRetailAchieveService extends IService<CuMemberRetailRange> {
@ -100,4 +103,12 @@ public interface ICuMemberRetailAchieveService extends IService<CuMemberRetailRa
*/
List<CuMemberRetailAchieveVO> selectMemberSmallBoxList(CuMemberRetailAchieveVO param);
/**
* 获取会员结算明细
* @param pkMember
* @param pkCountry
* @param systemType
* @return
*/
CuMemberRetailDataStatisticsResultVO getRetailDataStatisticsDetail(Long pkMember, Integer pkCountry, Integer systemType);
}

View File

@ -1,19 +1,26 @@
package com.hzs.retail.member.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzs.common.core.constant.TableNameConstants;
import com.hzs.common.core.enums.EGrade;
import com.hzs.common.core.enums.EYesNo;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.domain.member.achieve.CuMemberRetailRange;
import com.hzs.common.domain.member.achieve.CuMemberSettlePeriod;
import com.hzs.common.domain.member.base.CuMember;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.member.account.service.ICuMemberBaseService;
import com.hzs.member.achieve.service.ICuMemberSettlePeriodService;
import com.hzs.member.base.service.ICuMemberService;
import com.hzs.retail.member.mapper.CuMemberRetailRangeMapper;
import com.hzs.retail.member.service.ICuMemberRetailAchieveService;
import com.hzs.retail.member.utils.DataStatisticsUtil;
import com.hzs.retail.member.vo.CuMemberRetailAchieveVO;
import com.hzs.retail.member.vo.CuMemberRetailDataStatisticsDetailVO;
import com.hzs.retail.member.vo.CuMemberRetailDataStatisticsResultVO;
import com.hzs.system.config.IGradeServiceApi;
import com.hzs.system.config.dto.GradeDTO;
import lombok.extern.slf4j.Slf4j;
@ -388,9 +395,9 @@ public class CuMemberRetailAchieveServiceImpl extends ServiceImpl<CuMemberRetail
String memberRetailTable = getTableName();
String memberSecondTable = getDayTableName();
//查询直推会员
// List<Long> pkMemberList = baseMapper.selectDirectPushByPkMember(pkMember, systemType);
List<Long> pkMemberList = baseMapper.selectDirectPushByPkMember(pkMember, systemType);
// 2025年6月11日 取伞下 + 自己的ID
List<Long> pkMemberList = baseMapper.selectSubMemberIdByRootMember(pkMember, systemType);
// List<Long> pkMemberList = baseMapper.selectSubMemberIdByRootMember(pkMember, systemType);
//根据国家查汇率
BigDecimal rate = iCuMemberBaseService.getCurrency(pkCountry).getInExchangeRate();
//查询自己业绩
@ -486,8 +493,12 @@ public class CuMemberRetailAchieveServiceImpl extends ServiceImpl<CuMemberRetail
* @return String
*/
private String getAchieveAndBoxTableName(String date) {
int period = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(date).getPkId();
return TableNameConstants.CU_MEMBER_AMOUNT_BOX + period;
CuMemberSettlePeriod cuMemberSettlePeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(date);
if(ObjectUtil.isNotEmpty(cuMemberSettlePeriod)){
int period = cuMemberSettlePeriod.getPkId();
return TableNameConstants.CU_MEMBER_AMOUNT_BOX + period;
}
return "";
}
@Override
@ -546,6 +557,25 @@ public class CuMemberRetailAchieveServiceImpl extends ServiceImpl<CuMemberRetail
return new ArrayList<>();
}
@Override
public CuMemberRetailDataStatisticsResultVO getRetailDataStatisticsDetail(Long pkMember, Integer pkCountry, Integer systemType) {
Long userId = SecurityUtils.getUserId();
String memberRetailTable = getTableName();
String memberSecondTable = getDayTableName();
//查询直推会员
List<Long> pkMemberList = baseMapper.selectDirectPushByPkMember(pkMember, systemType);
pkMemberList.add(userId);
CuMemberRetailAchieveVO memberAchieveVO = CuMemberRetailAchieveVO.builder()
.memberRetailTable(memberRetailTable)
.memberRetailSTable(memberSecondTable)
.pkMemberList(pkMemberList).systemType(systemType).build();
List<CuMemberRetailDataStatisticsDetailVO> statisticsDetailVOList = baseMapper.getRetailDataStatisticsDetail(memberAchieveVO);
CuMemberRetailDataStatisticsResultVO result = DataStatisticsUtil.getCalcMap(statisticsDetailVOList, userId);
log.info("statisticsDetailVOList: {}", JSONUtil.toJsonStr(statisticsDetailVOList));
log.info("calcMap -> {}", JSONUtil.toJsonStr(result));
return result;
}
/**
* 查询会员是否激活
*

View File

@ -0,0 +1,156 @@
package com.hzs.retail.member.utils;
import cn.hutool.core.util.ObjectUtil;
import com.hzs.retail.member.vo.CuMemberRetailDataStatisticsDetailVO;
import com.hzs.retail.member.vo.CuMemberRetailDataStatisticsResultVO;
import java.math.BigDecimal;
import java.util.*;
/**
* 用户统计数据工具
* 主要用户统计用户的业绩/盒数/明细等
* 主要处理的类为
* @link com.hzs.retail.member.vo.CuMemberRetailDataStatisticsDetailVO
*/
public class DataStatisticsUtil {
private static final Long SELF_VIRTUAL_ID = -1000L;
private static final Long BIG_RANGE_VIRTUAL_ID = -2000L;
private static final Long SMALL_RANGE_VIRTUAL_ID = -3000L;
private static final String SELF_VIRTUAL_NAME = "个人消费虚拟分支";
private static final String BIG_RANGE_VIRTUAL_NAME = "注水大区虚拟分支";
private static final String SMALL_RANGE_VIRTUAL_NAME = "注水小区虚拟分支";
public static CuMemberRetailDataStatisticsResultVO getCalcMap(List<CuMemberRetailDataStatisticsDetailVO> detailVOList, Long pkId){
calcDetailVOTotalField(detailVOList);
addVirtualBranch(detailVOList, pkId);
CuMemberRetailDataStatisticsDetailVO total = getDetailVOByPKID(detailVOList, pkId);
CuMemberRetailDataStatisticsDetailVO bigRange = getBigRangeDetailVO(detailVOList, pkId);
return CuMemberRetailDataStatisticsResultVO.builder()
.totalBoxNum(total.getTotalBoxNum())
.totalPv(total.getTotalPv())
.bigRangeTotalBoxNum(bigRange.getTotalBoxNum())
.bigRangeTotalPv(bigRange.getTotalPv())
.smallRangeTotalBoxNum(total.getTotalBoxNum() - bigRange.getTotalBoxNum())
.smallRangeTotalPv(total.getTotalPv().subtract(bigRange.getTotalPv()))
.build();
}
/**
* 计算集合内数据总数
* @param detailVOList
*/
public static void calcDetailVOTotalField(List<CuMemberRetailDataStatisticsDetailVO> detailVOList){
detailVOList.parallelStream().forEach(detailVO -> {
detailVO.setTotalBoxNum(
detailVO.getConsumeBoxNum() // 个人累计消费盒数(日结)
+ detailVO.getNewBoxNum() // 个人新增盒数(日结)
+ detailVO.getTeamBoxNum() // 团队累计消费盒数(日结)
+ detailVO.getTeamNewBoxNum() // 团队新增盒数(日结)
+ detailVO.getSNewBoxNum() // 个人新增消费盒数(秒结)
+ detailVO.getSTeamNewBoxNum() // 团队新增盒数(秒结)
// - detailVO.getBigBoxNum() // 个人注水大区盒数(日结)
// - detailVO.getSmallBoxNum() // 个人注水小区盒数(日结)
);
detailVO.setTotalPv(detailVO.getConsumePv()
.add(detailVO.getNewConsumePv())
.add(detailVO.getTeamConsumePv())
.add(detailVO.getTeamNewPv())
.add(detailVO.getSNewConsumePv())
.add(detailVO.getSTeamNewPv())
);
});
}
/**
* 增加虚拟分支 主要为
* 1.自己的消费总数
* 2.注水的大小区
*
* @param detailVOList
*/
public static void addVirtualBranch(List<CuMemberRetailDataStatisticsDetailVO> detailVOList, Long pkId){
CuMemberRetailDataStatisticsDetailVO detailVO = getDetailVOByPKID(detailVOList, pkId);
if(ObjectUtil.isNotEmpty(detailVO)){
CuMemberRetailDataStatisticsDetailVO selfVirtualDetailVO = getCuMemberRetailDataStatisticsDetailVO(detailVO);
detailVOList.add(selfVirtualDetailVO);
if(detailVO.getBigBoxNum() >0 || detailVO.getSmallBoxNum() > 0){
CuMemberRetailDataStatisticsDetailVO bigRangeVirtualDetailVO = CuMemberRetailDataStatisticsDetailVO.builder()
.pkId(BIG_RANGE_VIRTUAL_ID)
.memberCode(BIG_RANGE_VIRTUAL_NAME)
.totalBoxNum(detailVO.getBigBoxNum())
.totalPv(BigDecimal.ZERO)
.build();
CuMemberRetailDataStatisticsDetailVO smallRangeVirtualDetailVO = CuMemberRetailDataStatisticsDetailVO.builder()
.pkId(SMALL_RANGE_VIRTUAL_ID)
.memberCode(SMALL_RANGE_VIRTUAL_NAME)
.totalBoxNum(detailVO.getBigBoxNum())
.totalPv(BigDecimal.ZERO)
.build();
detailVOList.add(bigRangeVirtualDetailVO);
detailVOList.add(smallRangeVirtualDetailVO);
}
}
}
private static CuMemberRetailDataStatisticsDetailVO getCuMemberRetailDataStatisticsDetailVO(CuMemberRetailDataStatisticsDetailVO detailVO) {
return CuMemberRetailDataStatisticsDetailVO.builder()
.pkId(SELF_VIRTUAL_ID)
.memberCode(SELF_VIRTUAL_NAME)
.totalBoxNum(
detailVO.getConsumeBoxNum()
+ detailVO.getNewBoxNum()
+ detailVO.getSNewBoxNum()
)
.totalPv(
detailVO.getConsumePv()
.add(detailVO.getNewConsumePv())
.add(detailVO.getSNewConsumePv())
)
.build();
}
/**
* 移除总数Top1
* @param detailVOList
*/
public static List<CuMemberRetailDataStatisticsDetailVO> getSmallRangeList(List<CuMemberRetailDataStatisticsDetailVO> detailVOList){
List<CuMemberRetailDataStatisticsDetailVO> result = new ArrayList<>();
Integer maxTotalBoxNum = getMaxTotalBoxNum(detailVOList);
if (maxTotalBoxNum == null) {
return new ArrayList<>(detailVOList);
}
boolean removed = false;
for (CuMemberRetailDataStatisticsDetailVO vo : detailVOList) {
if (!removed && Objects.equals(vo.getTotalBoxNum(), maxTotalBoxNum)) {
removed = true;
} else {
result.add(vo);
}
}
return result;
}
/**
* 根据ID获取对应数据
* @param detailVOList
* @return
*/
public static CuMemberRetailDataStatisticsDetailVO getDetailVOByPKID(List<CuMemberRetailDataStatisticsDetailVO> detailVOList, Long pkId){
return detailVOList.stream().filter(o -> o.getPkId().equals(pkId)).findFirst().orElse(null);
}
private static Integer getMaxTotalBoxNum(List<CuMemberRetailDataStatisticsDetailVO> detailVOList) {
return detailVOList.stream()
.map(CuMemberRetailDataStatisticsDetailVO::getTotalBoxNum)
.filter(Objects::nonNull)
.max(Integer::compare)
.orElse(null);
}
private static CuMemberRetailDataStatisticsDetailVO getBigRangeDetailVO(List<CuMemberRetailDataStatisticsDetailVO> detailVOList, Long pkId){
return detailVOList.stream()
.filter(vo -> vo.getTotalBoxNum() != null && !vo.getPkId().equals(pkId))
.max(Comparator.comparingInt(CuMemberRetailDataStatisticsDetailVO::getTotalBoxNum))
.orElse(null);
}
}

View File

@ -0,0 +1,104 @@
package com.hzs.retail.member.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 会员数据统计
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class CuMemberRetailDataStatisticsDetailVO implements Serializable {
private static final long serialVersionUID = 4225390345989552207L;
/**
* 用户主键
*/
private Long pkId;
/**
* 用户编号
*/
private String memberCode;
/**
* 日结表-个人累计消费pv
*/
private BigDecimal consumePv;
/**
* 日结表-个人当日新消费PV
*/
private BigDecimal newConsumePv;
/**
* 日结表-个人伞下累计消费pv
*/
private BigDecimal teamConsumePv;
/**
* 日结表-个人伞下新消费pv
*/
private BigDecimal teamNewPv;
/**
* 日结表-个人累计消费盒数
*/
private Integer consumeBoxNum;
/**
* 日结表-个人当日新消费盒数
*/
private Integer newBoxNum;
/**
* 日结表-个人伞下累计消费盒数
*/
private Integer teamBoxNum;
/**
* 日结表-个人伞下新消费盒数
*/
private Integer teamNewBoxNum;
/**
* 秒结表-个人新消费盒数
*/
private Integer sNewBoxNum;
/**
* 秒结表-团队新消费盒数
*/
private Integer sTeamNewBoxNum;
/**
* 秒结表-个人新消费pv
*/
private BigDecimal sNewConsumePv;
/**
* 秒结表-团队新消费pv
*/
private BigDecimal sTeamNewPv;
private Integer sTeamBoxNum;
/**
* 个人总业绩
*/
private BigDecimal totalPv;
/**
* 个人总盒数
*/
private Integer totalBoxNum;
/**
* 注水大区
*/
private Integer bigBoxNum;
/**
* 注水小区
*/
private Integer smallBoxNum;
}

View File

@ -0,0 +1,58 @@
package com.hzs.retail.member.vo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 会员数据统计
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class CuMemberRetailDataStatisticsResultVO implements Serializable {
private static final long serialVersionUID = 747472786422852424L;
/**
* 用户主键
*/
private Long pkId;
/**
* 用户编号
*/
private String memberCode;
/**
* 总盒数
*/
private Integer totalBoxNum;
/**
* 大区盒数
*/
private Integer bigRangeTotalBoxNum;
/**
* 小区盒数
*/
private Integer smallRangeTotalBoxNum;
/**
* 总业绩
*/
private BigDecimal totalPv;
/**
* 大区业绩
*/
private BigDecimal bigRangeTotalPv;
/**
* 小区业绩
*/
private BigDecimal smallRangeTotalPv;
}

View File

@ -836,4 +836,39 @@
connect by prior cm.pk_id = cm.pk_parent
order by level
</select>
<select id="getRetailDataStatisticsDetail"
resultType="com.hzs.retail.member.vo.CuMemberRetailDataStatisticsDetailVO">
SELECT
cu.pk_id,
cu.MEMBER_CODE,
NVL( mr.CONSUME_PV, 0 ) consumePv,
NVL( mr.NEW_CONSUME_PV, 0 ) newConsumePv,
NVL( mr.TEAM_CONSUME_PV, 0 ) teamConsumePv,
NVL( mr.TEAM_NEW_PV, 0 ) teamNewPv,
NVL( mr.CONSUME_BOX_NUM, 0 ) consumeBoxNum,
NVL( mr.NEW_BOX_NUM, 0 ) newBoxNum,
NVL( mr.TEAM_BOX_NUM, 0 ) teamBoxNum,
NVL( mr.TEAM_NEW_BOX_NUM, 0 ) teamNewBoxNum,
NVL( mr.BIG_BOX_NUM, 0 ) bigBoxNum,
NVL( mr.SMALL_BOX_NUM, 0 ) smallBoxNum,
NVL( mrs.NEW_BOX_NUM, 0 ) sNewBoxNum,
NVL( mrs.TEAM_NEW_BOX_NUM, 0 ) sTeamNewBoxNum,
NVL( mrs.NEW_CONSUME_PV, 0 ) sNewConsumePv,
NVL( mrs.TEAM_NEW_PV, 0 ) sTeamNewPv
FROM
cu_member cu
left join ${memberRetailTable} mr on cu.PK_ID = mr.PK_MEMBER and mr.CATEGORY = 0
left JOIN ${memberRetailSTable} mrs on cu.PK_ID = mrs.PK_MEMBER
<where>
<if test="pkMemberList != null and pkMemberList.size > 0">
cu.pk_id in
<foreach collection="pkMemberList" item="pkMember" separator="," open="(" close=")">
#{pkMember}
</foreach>
</if>
</where>
</select>
</mapper>