mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-04 12:18:42 +08:00 
			
		
		
		
	【功能】完成商品列表价格计算时,需要支持减免金额的功能
This commit is contained in:
		@@ -69,8 +69,8 @@ public class AppProductSpuController {
 | 
			
		||||
        list.forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount()));
 | 
			
		||||
        List<AppProductSpuRespVO> voList = BeanUtils.toBean(list, AppProductSpuRespVO.class);
 | 
			
		||||
        // 处理 vip 价格
 | 
			
		||||
        MemberLevelRespDTO memberLevel = getMemberLevel();
 | 
			
		||||
        voList.forEach(vo -> vo.setVipPrice(calculateVipPrice(vo.getPrice(), memberLevel)));
 | 
			
		||||
//        MemberLevelRespDTO memberLevel = getMemberLevel();
 | 
			
		||||
//        voList.forEach(vo -> vo.setVipPrice(calculateVipPrice(vo.getPrice(), memberLevel)));
 | 
			
		||||
        return success(voList);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -86,8 +86,8 @@ public class AppProductSpuController {
 | 
			
		||||
        pageResult.getList().forEach(spu -> spu.setSalesCount(spu.getSalesCount() + spu.getVirtualSalesCount()));
 | 
			
		||||
        PageResult<AppProductSpuRespVO> voPageResult = BeanUtils.toBean(pageResult, AppProductSpuRespVO.class);
 | 
			
		||||
        // 处理 vip 价格
 | 
			
		||||
        MemberLevelRespDTO memberLevel = getMemberLevel();
 | 
			
		||||
        voPageResult.getList().forEach(vo -> vo.setVipPrice(calculateVipPrice(vo.getPrice(), memberLevel)));
 | 
			
		||||
//        MemberLevelRespDTO memberLevel = getMemberLevel();
 | 
			
		||||
//        voPageResult.getList().forEach(vo -> vo.setVipPrice(calculateVipPrice(vo.getPrice(), memberLevel)));
 | 
			
		||||
        return success(voPageResult);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -142,7 +142,7 @@ public class AppProductSpuController {
 | 
			
		||||
     */
 | 
			
		||||
    public Integer calculateVipPrice(Integer price, MemberLevelRespDTO memberLevel) {
 | 
			
		||||
        if (memberLevel == null || memberLevel.getDiscountPercent() == null) {
 | 
			
		||||
            return 0;
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        Integer newPrice = price * memberLevel.getDiscountPercent() / 100;
 | 
			
		||||
        return price - newPrice;
 | 
			
		||||
 
 | 
			
		||||
@@ -38,8 +38,8 @@ public class AppProductSpuRespVO {
 | 
			
		||||
    @Schema(description = "市场价,单位使用:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
 | 
			
		||||
    private Integer marketPrice;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "VIP 价格,单位使用:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "968") // 通过会员等级,计算出折扣后价格
 | 
			
		||||
    private Integer vipPrice;
 | 
			
		||||
//    @Schema(description = "VIP 价格,单位使用:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "968") // 通过会员等级,计算出折扣后价格
 | 
			
		||||
//    private Integer vipPrice;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "库存", requiredMode = Schema.RequiredMode.REQUIRED, example = "666")
 | 
			
		||||
    private Integer stock;
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.promotion.api.discount.dto;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 限时折扣活动商品 Response DTO
 | 
			
		||||
 *
 | 
			
		||||
@@ -44,5 +46,12 @@ public class DiscountProductRespDTO {
 | 
			
		||||
     * 活动标题
 | 
			
		||||
     */
 | 
			
		||||
    private String activityName;
 | 
			
		||||
    /**
 | 
			
		||||
     * 活动结束时间点
 | 
			
		||||
     *
 | 
			
		||||
     * 冗余 {@link DiscountActivityDO#getEndTime()}
 | 
			
		||||
     */
 | 
			
		||||
    private LocalDateTime activityEndTime;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.api.reward;
 | 
			
		||||
import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO;
 | 
			
		||||
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -21,4 +22,13 @@ public interface RewardActivityApi {
 | 
			
		||||
     */
 | 
			
		||||
    List<RewardActivityMatchRespDTO> getRewardActivityListByStatusAndNow(Integer status, LocalDateTime dateTime);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取指定 spu 编号最近参加的活动,每个 spuId 只返回一条记录
 | 
			
		||||
     *
 | 
			
		||||
     * @param spuIds   spu 编号
 | 
			
		||||
     * @param status   状态
 | 
			
		||||
     * @param dateTime 当前日期时间
 | 
			
		||||
     * @return 满减送活动列表
 | 
			
		||||
     */
 | 
			
		||||
    List<RewardActivityMatchRespDTO> getRewardActivityBySpuIdsAndStatusAndDateTimeLt(Collection<Long> spuIds, Integer status, LocalDateTime dateTime);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@ public interface ErrorCodeConstants {
 | 
			
		||||
    ErrorCode DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_001_002, "限时折扣活动已关闭,不能修改");
 | 
			
		||||
    ErrorCode DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1_013_001_003, "限时折扣活动未关闭,不能删除");
 | 
			
		||||
    ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_001_004, "限时折扣活动已关闭,不能重复关闭");
 | 
			
		||||
    ErrorCode DISCOUNT_ACTIVITY_TYPE_NOT_EXISTS = new ErrorCode(1_013_001_005, "限时折扣活动类型不存在");
 | 
			
		||||
 | 
			
		||||
    // ========== Banner 相关 1-013-002-000 ============
 | 
			
		||||
    ErrorCode BANNER_NOT_EXISTS = new ErrorCode(1_013_002_000, "Banner 不存在");
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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()));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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")
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@
 | 
			
		||||
                </foreach>
 | 
			
		||||
            </if>
 | 
			
		||||
            AND pda.start_time <= CURRENT_TIME AND pda.end_time >= CURRENT_TIME
 | 
			
		||||
            AND pda.`status` = 20
 | 
			
		||||
            AND pda.`status` = 0
 | 
			
		||||
            AND pda.deleted != 1
 | 
			
		||||
        </where>
 | 
			
		||||
    </select>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,23 @@
 | 
			
		||||
package cn.iocoder.yudao.module.trade.controller.app.order;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
 | 
			
		||||
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
 | 
			
		||||
import cn.iocoder.yudao.module.member.api.level.MemberLevelApi;
 | 
			
		||||
import cn.iocoder.yudao.module.member.api.level.dto.MemberLevelRespDTO;
 | 
			
		||||
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
 | 
			
		||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
 | 
			
		||||
import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
 | 
			
		||||
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
 | 
			
		||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
 | 
			
		||||
import cn.iocoder.yudao.module.promotion.api.discount.DiscountActivityApi;
 | 
			
		||||
import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO;
 | 
			
		||||
import cn.iocoder.yudao.module.promotion.api.reward.RewardActivityApi;
 | 
			
		||||
import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO;
 | 
			
		||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum;
 | 
			
		||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionDiscountTypeEnum;
 | 
			
		||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum;
 | 
			
		||||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.*;
 | 
			
		||||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
 | 
			
		||||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO;
 | 
			
		||||
@@ -27,12 +41,14 @@ import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.validation.annotation.Validated;
 | 
			
		||||
import org.springframework.web.bind.annotation.*;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 | 
			
		||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 | 
			
		||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
 | 
			
		||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
 | 
			
		||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.DISCOUNT_ACTIVITY_TYPE_NOT_EXISTS;
 | 
			
		||||
 | 
			
		||||
@Tag(name = "用户 App - 交易订单")
 | 
			
		||||
@RestController
 | 
			
		||||
@@ -54,6 +70,17 @@ public class AppTradeOrderController {
 | 
			
		||||
    @Resource
 | 
			
		||||
    private TradeOrderProperties tradeOrderProperties;
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private MemberLevelApi memberLevelApi;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private MemberUserApi memberUserApi;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private DiscountActivityApi discountActivityApi;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private RewardActivityApi rewardActivityApi;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private ProductSkuApi productKpuApi;
 | 
			
		||||
 | 
			
		||||
    @GetMapping("/settlement")
 | 
			
		||||
    @Operation(summary = "获得订单结算信息")
 | 
			
		||||
    @PreAuthenticated
 | 
			
		||||
@@ -61,6 +88,51 @@ public class AppTradeOrderController {
 | 
			
		||||
        return success(tradeOrderUpdateService.settlementOrder(getLoginUserId(), settlementReqVO));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @GetMapping("/settlementProduct")
 | 
			
		||||
    @Operation(summary = "获得商品结算信息")
 | 
			
		||||
    public CommonResult<List<AppTradeProductSettlementRespVO>> settlementProduct(@RequestParam("ids") Set<Long> ids) {
 | 
			
		||||
        List<AppTradeProductSettlementRespVO> appTradeProductSettlementRespVOS = new ArrayList<>();
 | 
			
		||||
        MemberLevelRespDTO memberLevel = getMemberLevel();
 | 
			
		||||
        ids.forEach(spuId -> {
 | 
			
		||||
            List<AppTradeProductSettlementRespVO.Sku> skus = new ArrayList<>();
 | 
			
		||||
            List<ProductSkuRespDTO> skuList = productKpuApi.getSkuListBySpuId(Collections.singletonList(spuId));
 | 
			
		||||
            //查询sku的会员和限时优惠
 | 
			
		||||
            skuList.forEach(sku -> {
 | 
			
		||||
                //查询限时优惠价格
 | 
			
		||||
                AppTradeProductSettlementRespVO.Sku skuDiscount = calculateDiscountPrice(sku.getId(), sku.getPrice());
 | 
			
		||||
                if(skuDiscount != null){
 | 
			
		||||
                    skus.add(skuDiscount);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                //查询会员价
 | 
			
		||||
                AppTradeProductSettlementRespVO.Sku skuVip = calculateVipPrice(sku.getId(), sku.getPrice(), memberLevel);
 | 
			
		||||
                if(skuVip != null){
 | 
			
		||||
                    skus.add(skuVip);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
            AppTradeProductSettlementRespVO.Reward reward = calculateReward(spuId);
 | 
			
		||||
            AppTradeProductSettlementRespVO respVO = AppTradeProductSettlementRespVO.builder().id(spuId).skus(skus).build();
 | 
			
		||||
            if(reward != null){
 | 
			
		||||
                //创建满减活动对象
 | 
			
		||||
                respVO.setReward(reward);
 | 
			
		||||
            }
 | 
			
		||||
            appTradeProductSettlementRespVOS.add(respVO);
 | 
			
		||||
        });
 | 
			
		||||
        return success(appTradeProductSettlementRespVOS);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private MemberLevelRespDTO getMemberLevel() {
 | 
			
		||||
        Long userId = getLoginUserId();
 | 
			
		||||
        if (userId == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        MemberUserRespDTO user = memberUserApi.getUser(userId);
 | 
			
		||||
        if (user.getLevelId() == null || user.getLevelId() <= 0) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        return memberLevelApi.getMemberLevel(user.getLevelId());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @PostMapping("/create")
 | 
			
		||||
    @Operation(summary = "创建订单")
 | 
			
		||||
    @PreAuthenticated
 | 
			
		||||
@@ -188,4 +260,78 @@ public class AppTradeOrderController {
 | 
			
		||||
        return success(tradeOrderUpdateService.createOrderItemCommentByMember(getLoginUserId(), createReqVO));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 计算会员 VIP 优惠价格
 | 
			
		||||
     *
 | 
			
		||||
     * @param price 原价
 | 
			
		||||
     * @param memberLevel 会员等级
 | 
			
		||||
     * @return 优惠价格
 | 
			
		||||
     */
 | 
			
		||||
    public AppTradeProductSettlementRespVO.Sku calculateVipPrice(Long skuId, Integer price, MemberLevelRespDTO memberLevel) {
 | 
			
		||||
        if (memberLevel == null || memberLevel.getDiscountPercent() == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        Integer newPrice = price * memberLevel.getDiscountPercent() / 100;
 | 
			
		||||
        return AppTradeProductSettlementRespVO.Sku.builder().
 | 
			
		||||
                skuId(skuId).
 | 
			
		||||
                type(PromotionTypeEnum.MEMBER_LEVEL.getType()).
 | 
			
		||||
                price(price - newPrice).build();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 计算限时优惠信息
 | 
			
		||||
     *
 | 
			
		||||
     * @param price 原价
 | 
			
		||||
     * @param skuId 商品规格id
 | 
			
		||||
     * @return 优惠价格
 | 
			
		||||
     */
 | 
			
		||||
    private AppTradeProductSettlementRespVO.Sku calculateDiscountPrice(Long skuId, Integer price) {
 | 
			
		||||
        if (skuId == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //根据商品id查询限时优惠
 | 
			
		||||
        List<DiscountProductRespDTO> matchDiscountProductList = discountActivityApi.getMatchDiscountProductList(Collections.singletonList(skuId));
 | 
			
		||||
        if (matchDiscountProductList != null && !matchDiscountProductList.isEmpty()) {
 | 
			
		||||
            DiscountProductRespDTO discountProductRespDTO = matchDiscountProductList.get(matchDiscountProductList.size() - 1);
 | 
			
		||||
            AppTradeProductSettlementRespVO.Sku sku = AppTradeProductSettlementRespVO.Sku.builder().
 | 
			
		||||
                    skuId(skuId).
 | 
			
		||||
                    discountId(discountProductRespDTO.getId()).
 | 
			
		||||
                    type(PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()).
 | 
			
		||||
                    endTime(discountProductRespDTO.getActivityEndTime()).
 | 
			
		||||
                    build();
 | 
			
		||||
            Integer discountType = discountProductRespDTO.getDiscountType();
 | 
			
		||||
            if(Objects.equals(PromotionDiscountTypeEnum.PRICE.getType(), discountType)){
 | 
			
		||||
                sku.setPrice(price - discountProductRespDTO.getDiscountPrice() * 100);
 | 
			
		||||
            }else if(Objects.equals(PromotionDiscountTypeEnum.PERCENT.getType(), discountType)){
 | 
			
		||||
                Integer newPrice = price * discountProductRespDTO.getDiscountPercent() / 100;
 | 
			
		||||
                sku.setPrice(price - newPrice);
 | 
			
		||||
            }else{
 | 
			
		||||
                throw exception(DISCOUNT_ACTIVITY_TYPE_NOT_EXISTS);
 | 
			
		||||
            }
 | 
			
		||||
            return sku;
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取第一层满减活动
 | 
			
		||||
     *
 | 
			
		||||
     * @param spuId 商品规格id
 | 
			
		||||
     * @return 优惠价格
 | 
			
		||||
     */
 | 
			
		||||
    private AppTradeProductSettlementRespVO.Reward calculateReward(Long spuId) {
 | 
			
		||||
        List<RewardActivityMatchRespDTO> matchRewardActivityList = rewardActivityApi.getRewardActivityBySpuIdsAndStatusAndDateTimeLt(Collections.singletonList(spuId), CommonStatusEnum.ENABLE.getStatus(), LocalDateTime.now());
 | 
			
		||||
        if(matchRewardActivityList != null && !matchRewardActivityList.isEmpty()){
 | 
			
		||||
            RewardActivityMatchRespDTO rewardActivityMatchRespDTO = matchRewardActivityList.get(matchRewardActivityList.size() - 1);
 | 
			
		||||
            if(rewardActivityMatchRespDTO != null){
 | 
			
		||||
                RewardActivityMatchRespDTO.Rule rule = rewardActivityMatchRespDTO.getRules().get(0);
 | 
			
		||||
                return AppTradeProductSettlementRespVO.Reward.builder().
 | 
			
		||||
                        rewardActivity("满" + rule.getLimit() / 100 + (Objects.equals(rewardActivityMatchRespDTO.getConditionType(), PromotionConditionTypeEnum.PRICE.getType())?"元":"件"+"减") +rule.getDiscountPrice() / 100)
 | 
			
		||||
                        .rewardId(rewardActivityMatchRespDTO.getId()).build();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,59 @@
 | 
			
		||||
package cn.iocoder.yudao.module.trade.controller.app.order.vo;
 | 
			
		||||
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
import lombok.Builder;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
@Schema(description = "用户 App - 商品结算信息 Response VO")
 | 
			
		||||
@Data
 | 
			
		||||
@Builder
 | 
			
		||||
public class AppTradeProductSettlementRespVO {
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
 | 
			
		||||
    private Long id;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "满减活动对象", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
 | 
			
		||||
    private Reward reward;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "sku活动信息", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
 | 
			
		||||
    private List<Sku> skus;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 满减活动
 | 
			
		||||
     */
 | 
			
		||||
    @Data
 | 
			
		||||
    @Builder
 | 
			
		||||
    public static class Reward implements Serializable {
 | 
			
		||||
        @Schema(description = "满减活动编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
 | 
			
		||||
        private Long rewardId;
 | 
			
		||||
 | 
			
		||||
        @Schema(description = "满减活动信息", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
 | 
			
		||||
        private String rewardActivity;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * SKU 数组
 | 
			
		||||
     */
 | 
			
		||||
    @Data
 | 
			
		||||
    @Builder
 | 
			
		||||
    public static class Sku implements Serializable {
 | 
			
		||||
        @Schema(description = "商品 SKU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
 | 
			
		||||
        private Long skuId;
 | 
			
		||||
 | 
			
		||||
        @Schema(description = "价格", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
 | 
			
		||||
        private Integer price;
 | 
			
		||||
 | 
			
		||||
        @Schema(description = "营销类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") //PromotionTypeEnum
 | 
			
		||||
        private Integer type;
 | 
			
		||||
 | 
			
		||||
        @Schema(description = "限时优惠id", requiredMode = Schema.RequiredMode.REQUIRED)
 | 
			
		||||
        private Long discountId;
 | 
			
		||||
 | 
			
		||||
        @Schema(description = "活动结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
 | 
			
		||||
        private LocalDateTime endTime;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -23,6 +23,7 @@ import java.util.Comparator;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
 | 
			
		||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
 | 
			
		||||
import static cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculatorHelper.formatPrice;
 | 
			
		||||
 | 
			
		||||
@@ -47,8 +48,8 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        // 获得 SKU 对应的满减送活动
 | 
			
		||||
        List<RewardActivityMatchRespDTO> rewardActivities = rewardActivityApi.getRewardActivityListByStatusAndNow(
 | 
			
		||||
                CommonStatusEnum.ENABLE.getStatus(), LocalDateTime.now());
 | 
			
		||||
        List<RewardActivityMatchRespDTO> rewardActivities = rewardActivityApi.getRewardActivityBySpuIdsAndStatusAndDateTimeLt(
 | 
			
		||||
                convertSet(result.getItems(), TradePriceCalculateRespBO.OrderItem::getSpuId), CommonStatusEnum.ENABLE.getStatus(), LocalDateTime.now());
 | 
			
		||||
        if (CollUtil.isEmpty(rewardActivities)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ spring:
 | 
			
		||||
  # 数据源配置项
 | 
			
		||||
  autoconfigure:
 | 
			
		||||
    exclude:
 | 
			
		||||
      - org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration # 默认 local 环境,不开启 Quartz 的自动配置
 | 
			
		||||
      #- org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration # 默认 local 环境,不开启 Quartz 的自动配置
 | 
			
		||||
      - de.codecentric.boot.admin.server.config.AdminServerAutoConfiguration # 禁用 Spring Boot Admin 的 Server 的自动配置
 | 
			
		||||
      - de.codecentric.boot.admin.server.ui.config.AdminServerUiAutoConfiguration # 禁用 Spring Boot Admin 的 Server UI 的自动配置
 | 
			
		||||
      - de.codecentric.boot.admin.client.config.SpringBootAdminClientAutoConfiguration # 禁用 Spring Boot Admin 的 Client 的自动配置
 | 
			
		||||
@@ -45,7 +45,7 @@ spring:
 | 
			
		||||
      primary: master
 | 
			
		||||
      datasource:
 | 
			
		||||
        master:
 | 
			
		||||
          url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例
 | 
			
		||||
          url: jdbc:mysql://192.168.10.207:3306/specialty?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true # MySQL Connector/J 8.X 连接的示例
 | 
			
		||||
          #          url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=true&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true # MySQL Connector/J 5.X 连接的示例
 | 
			
		||||
          #          url: jdbc:postgresql://127.0.0.1:5432/ruoyi-vue-pro # PostgreSQL 连接的示例
 | 
			
		||||
          #          url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例
 | 
			
		||||
@@ -61,19 +61,19 @@ spring:
 | 
			
		||||
          #          password: SYSDBA001 # DM 连接的示例
 | 
			
		||||
          #          username: root # OpenGauss 连接的示例
 | 
			
		||||
          #          password: Yudao@2024 # OpenGauss 连接的示例
 | 
			
		||||
        slave: # 模拟从库,可根据自己需要修改
 | 
			
		||||
          lazy: true # 开启懒加载,保证启动速度
 | 
			
		||||
          url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true&nullCatalogMeansCurrent=true
 | 
			
		||||
          username: root
 | 
			
		||||
          password: 123456
 | 
			
		||||
#        slave: # 模拟从库,可根据自己需要修改
 | 
			
		||||
#          lazy: true # 开启懒加载,保证启动速度
 | 
			
		||||
#          url: jdbc:mysql://192.168.10.207:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true&nullCatalogMeansCurrent=true
 | 
			
		||||
#          username: root
 | 
			
		||||
#          password: 123456
 | 
			
		||||
 | 
			
		||||
  # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
 | 
			
		||||
  data:
 | 
			
		||||
    redis:
 | 
			
		||||
      host: 127.0.0.1 # 地址
 | 
			
		||||
      host: 192.168.10.207 # 地址
 | 
			
		||||
      port: 6379 # 端口
 | 
			
		||||
      database: 0 # 数据库索引
 | 
			
		||||
#    password: dev # 密码,建议生产环境开启
 | 
			
		||||
      password: 123456 # 密码,建议生产环境开启
 | 
			
		||||
 | 
			
		||||
--- #################### 定时任务相关配置 ####################
 | 
			
		||||
 | 
			
		||||
@@ -200,8 +200,8 @@ wx:
 | 
			
		||||
#    secret: 6f270509224a7ae1296bbf1c8cb97aed
 | 
			
		||||
#    appid: wxc4598c446f8a9cb3 # 测试号(Kongdy 提供的)
 | 
			
		||||
#    secret: 4a1a04e07f6a4a0751b39c3064a92c8b
 | 
			
		||||
    appid: wx66186af0759f47c9 # 测试号(puhui 提供的)
 | 
			
		||||
    secret: 3218bcbd112cbc614c7264ceb20144ac
 | 
			
		||||
    appid: wx9a0a5b259d852380 # 测试号(puhui 提供的)
 | 
			
		||||
    secret: 70e65fa9d1a4f2c4e1b2aa8751d3b75e
 | 
			
		||||
    config-storage:
 | 
			
		||||
      type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
 | 
			
		||||
      key-prefix: wa # Redis Key 的前缀
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user