【功能】完成商品列表价格计算时,需要支持减免金额的功能

This commit is contained in:
痴货
2024-09-14 19:01:57 +08:00
parent e47b3f0aab
commit e44c0e668e
15 changed files with 350 additions and 50 deletions

View File

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.promotion.api.reward;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO;
import cn.iocoder.yudao.module.promotion.convert.reward.RewardActivityConvert;
import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO;
import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService;
import jakarta.annotation.Resource;
@@ -9,6 +10,7 @@ import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
/**
@@ -29,4 +31,10 @@ public class RewardActivityApiImpl implements RewardActivityApi {
return BeanUtils.toBean(list, RewardActivityMatchRespDTO.class);
}
@Override
public List<RewardActivityMatchRespDTO> getRewardActivityBySpuIdsAndStatusAndDateTimeLt(Collection<Long> spuIds, Integer status, LocalDateTime dateTime) {
List<RewardActivityDO> rewardActivityBySpuIdsAndStatusAndDateTimeLt = rewardActivityService.getRewardActivityBySpuIdsAndStatusAndDateTimeLt(spuIds, status, dateTime);
return RewardActivityConvert.INSTANCE.convertList(rewardActivityBySpuIdsAndStatusAndDateTimeLt);
}
}

View File

@@ -33,6 +33,7 @@ import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
@@ -150,36 +151,32 @@ public class AppActivityController {
}
private void getRewardActivityList(Collection<Long> spuIds, LocalDateTime now, List<AppActivityRespVO> activityList) {
// 1.1 获得所有的活动
List<RewardActivityDO> rewardActivityList = rewardActivityService.getRewardActivityListByStatusAndDateTimeLt(
CommonStatusEnum.ENABLE.getStatus(), now);
// TODO @puhui999有 3 范围,不只 spuId还有 categoryId全部下次 fix
List<RewardActivityDO> rewardActivityList = rewardActivityService.getRewardActivityBySpuIdsAndStatusAndDateTimeLt(
spuIds, CommonStatusEnum.ENABLE.getStatus(), now);
if (CollUtil.isEmpty(rewardActivityList)) {
return;
}
// 1.2 获得所有的商品信息
List<ProductSpuRespDTO> spuList = productSpuApi.getSpuList(spuIds);
if (CollUtil.isEmpty(spuList)) {
return;
}
// 2. 构建活动
for (RewardActivityDO rewardActivity : rewardActivityList) {
// 情况一:所有商品都能参加
if (PromotionProductScopeEnum.isAll(rewardActivity.getProductScope())) {
buildAppActivityRespVO(rewardActivity, spuIds, activityList);
}
// 情况二:指定商品参加
if (PromotionProductScopeEnum.isSpu(rewardActivity.getProductScope())) {
List<Long> fSpuIds = spuList.stream().map(ProductSpuRespDTO::getId).filter(id ->
rewardActivity.getProductScopeValues().contains(id)).toList();
buildAppActivityRespVO(rewardActivity, fSpuIds, activityList);
}
// 情况三:指定商品类型参加
if (PromotionProductScopeEnum.isCategory(rewardActivity.getProductScope())) {
List<Long> fSpuIds = spuList.stream().filter(spuItem -> rewardActivity.getProductScopeValues()
.contains(spuItem.getCategoryId())).map(ProductSpuRespDTO::getId).toList();
buildAppActivityRespVO(rewardActivity, fSpuIds, activityList);
Map<Long, Optional<RewardActivityDO>> spuIdAndActivityMap = spuIds.stream()
.collect(Collectors.toMap(
spuId -> spuId,
spuId -> rewardActivityList.stream()
.filter(activity ->
( activity.getProductScopeValues()!=null &&
(activity.getProductScopeValues().contains(spuId) ||
activity.getProductScopeValues().contains(productSpuApi.getSpu(spuId).getCategoryId()))) ||
activity.getProductScope()==1
)
.max(Comparator.comparing(RewardActivityDO::getCreateTime))));
for (Long supId : spuIdAndActivityMap.keySet()) {
if (spuIdAndActivityMap.get(supId).isEmpty()) {
continue;
}
RewardActivityDO rewardActivityDO = spuIdAndActivityMap.get(supId).get();
activityList.add(new AppActivityRespVO(rewardActivityDO.getId(), PromotionTypeEnum.REWARD_ACTIVITY.getType(),
rewardActivityDO.getName(), supId, rewardActivityDO.getStartTime(), rewardActivityDO.getEndTime()));
}
}

View File

@@ -1,14 +1,19 @@
package cn.iocoder.yudao.module.promotion.dal.mysql.reward;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.promotion.controller.admin.reward.vo.RewardActivityPageReqVO;
import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.ibatis.annotations.Mapper;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 满减送活动 Mapper
@@ -25,13 +30,47 @@ public interface RewardActivityMapper extends BaseMapperX<RewardActivityDO> {
.orderByDesc(RewardActivityDO::getId));
}
default List<RewardActivityDO> selectListBySpuIdsAndStatus(Collection<Long> spuIds, Integer status) {
Function<Collection<Long>, String> productScopeValuesFindInSetFunc = ids -> ids.stream()
.map(id -> StrUtil.format("FIND_IN_SET({}, product_scope_values) ", id))
.collect(Collectors.joining(" OR "));
return selectList(new QueryWrapper<RewardActivityDO>()
.eq("status", status)
.apply(productScopeValuesFindInSetFunc.apply(spuIds)));
}
/**
* 获取指定活动编号的活动列表且
* 开始时间和结束时间小于给定时间 dateTime 的活动列表
*
* @param status 状态
* @param dateTime 指定日期
* @return 活动列表
*/
default List<RewardActivityDO> selectListByStatusAndDateTimeLt(Integer status, LocalDateTime dateTime) {
return selectList(new LambdaQueryWrapperX<RewardActivityDO>()
.eq(RewardActivityDO::getStatus, status)
// 开始时间 < 指定时间dateTime < 结束时间,也就是说获取指定时间段的活动
.lt(RewardActivityDO::getStartTime, dateTime).gt(RewardActivityDO::getEndTime, dateTime)
.lt(RewardActivityDO::getStartTime, dateTime)
.gt(RewardActivityDO::getEndTime, dateTime)// 开始时间 < 指定时间 < 结束时间,也就是说获取指定时间段的活动
.orderByAsc(RewardActivityDO::getStartTime)
);
}
default List<RewardActivityDO> getRewardActivityByStatusAndDateTimeLt(Collection<Long> spuIds,Collection<Long> categoryIds, Integer status, LocalDateTime dateTime) {
//拼接通用券查询语句
Function<Collection<Long>, String> productScopeValuesFindInSetFunc = ids -> ids.stream()
.map(id -> StrUtil.format("FIND_IN_SET({}, product_scope_values) ", id))
.collect(Collectors.joining(" OR "));
return selectList(new LambdaQueryWrapperX<RewardActivityDO>()
.eq(RewardActivityDO::getStatus,status)
.lt(RewardActivityDO::getStartTime, dateTime)
.gt(RewardActivityDO::getEndTime, dateTime)
.and(i -> i. eq(RewardActivityDO::getProductScope, 2).and(i1 -> i1.apply(productScopeValuesFindInSetFunc.apply(spuIds))))
.or(i -> i.eq(RewardActivityDO::getProductScope, 1))
.or(i -> i. eq(RewardActivityDO::getProductScope, 3).and(i1 -> i1.apply(productScopeValuesFindInSetFunc.apply(categoryIds))))
.orderByDesc(RewardActivityDO::getId)
.last("limit 1")
);
}
}

View File

@@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO;
import jakarta.validation.Valid;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
/**
@@ -71,4 +72,14 @@ public interface RewardActivityService {
*/
List<RewardActivityDO> getRewardActivityListByStatusAndDateTimeLt(Integer status, LocalDateTime dateTime);
/**
* 获取指定 spu 编号最近参加的活动,每个 spuId 只返回一条记录
*
* @param spuIds spu 编号
* @param status 状态
* @param dateTime 当前日期时间
* @return 满减送活动列表
*/
List<RewardActivityDO> getRewardActivityBySpuIdsAndStatusAndDateTimeLt(Collection<Long> spuIds, Integer status, LocalDateTime dateTime);
}

View File

@@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.promotion.service.reward;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
@@ -22,8 +23,11 @@ import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static cn.hutool.core.collection.CollUtil.intersectionDistinct;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -205,4 +209,19 @@ public class RewardActivityServiceImpl implements RewardActivityService {
return rewardActivityMapper.selectListByStatusAndDateTimeLt(status, dateTime);
}
@Override
public List<RewardActivityDO> getRewardActivityBySpuIdsAndStatusAndDateTimeLt(Collection<Long> spuIds, Integer status, LocalDateTime dateTime) {
List<ProductSpuRespDTO> spuList = productSpuApi.validateSpuList(spuIds);
//查询出商品的分类ids
List<Long> categoryIds = spuList.stream().map(ProductSpuRespDTO::getCategoryId).collect(Collectors.toList());
// 1. 查询出指定 spuId 的 spu 参加的活动
List<RewardActivityDO> rewardActivityList = rewardActivityMapper.getRewardActivityByStatusAndDateTimeLt(spuIds, categoryIds,status,dateTime);
if (CollUtil.isEmpty(rewardActivityList)) {
return Collections.emptyList();
}
// 2. 查询活动详情
return rewardActivityList;
}
}

View File

@@ -16,7 +16,7 @@
</foreach>
</if>
AND pda.start_time &lt;= CURRENT_TIME AND pda.end_time &gt;= CURRENT_TIME
AND pda.`status` = 20
AND pda.`status` = 0
AND pda.deleted != 1
</where>
</select>