mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-01-31 09:30:05 +08:00
commit
ebf5693255
@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
|
|||||||
import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponValidReqDTO;
|
import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponValidReqDTO;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -36,23 +37,21 @@ public interface CouponApi {
|
|||||||
*/
|
*/
|
||||||
CouponRespDTO validateCoupon(@Valid CouponValidReqDTO validReqDTO);
|
CouponRespDTO validateCoupon(@Valid CouponValidReqDTO validReqDTO);
|
||||||
|
|
||||||
// TODO @puhui999:可能需要根据 TradeOrderDO 的建议,进行修改;需要返回优惠劵编号
|
|
||||||
/**
|
/**
|
||||||
* 【管理员】给指定用户批量发送优惠券
|
* 【管理员】给指定用户批量发送优惠券
|
||||||
*
|
*
|
||||||
* @param giveCouponsMap key: 优惠劵编号,value:对应的优惠券数量
|
* @param giveCoupons key: 优惠劵模版编号,value:对应的数量
|
||||||
* @param userId 用户编号
|
* @param userId 用户编号
|
||||||
|
* @return 优惠券编号列表
|
||||||
*/
|
*/
|
||||||
// TODO @puhui999:giveCouponsMap 可能改成 giveCoupons 更合适?优惠劵模版编号、数量
|
List<Long> takeCouponsByAdmin(Map<Long, Integer> giveCoupons, Long userId);
|
||||||
void takeCouponsByAdmin(Map<Long, Integer> giveCouponsMap, Long userId);
|
|
||||||
|
|
||||||
// TODO @puhui999:可能需要根据 TradeOrderDO 的建议,进行修改 giveCouponsMap 参数
|
|
||||||
/**
|
/**
|
||||||
* 【管理员】作废指定用户的指定优惠劵
|
* 【管理员】作废指定用户的指定优惠劵
|
||||||
*
|
*
|
||||||
* @param giveCouponsMap key: 优惠劵编号,value:对应的优惠券数量
|
* @param giveCouponIds 赠送的优惠券编号
|
||||||
* @param userId 用户编号
|
* @param userId 用户编号
|
||||||
*/
|
*/
|
||||||
void invalidateCouponsByAdmin(Map<Long, Integer> giveCouponsMap, Long userId);
|
void invalidateCouponsByAdmin(List<Long> giveCouponIds, Long userId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -86,27 +86,17 @@ public class RewardActivityMatchRespDTO {
|
|||||||
* 是否包邮
|
* 是否包邮
|
||||||
*/
|
*/
|
||||||
private Boolean freeDelivery;
|
private Boolean freeDelivery;
|
||||||
// TODO @puhui999:建议不返回 + 去掉 givePoint、giveCoupon 字段哈。
|
|
||||||
/**
|
|
||||||
* 是否赠送积分
|
|
||||||
*/
|
|
||||||
private Boolean givePoint;
|
|
||||||
/**
|
/**
|
||||||
* 赠送的积分
|
* 赠送的积分
|
||||||
*/
|
*/
|
||||||
private Integer point;
|
private Integer point;
|
||||||
/**
|
|
||||||
* 是否赠送优惠券
|
|
||||||
*/
|
|
||||||
private Boolean giveCoupon;
|
|
||||||
// TODO @puhui999:giveCoupons 即可
|
|
||||||
/**
|
/**
|
||||||
* 赠送的优惠劵
|
* 赠送的优惠劵
|
||||||
*
|
*
|
||||||
* key: 优惠劵模版编号
|
* key: 优惠劵模版编号
|
||||||
* value:对应的优惠券数量
|
* value:对应的优惠券数量
|
||||||
*/
|
*/
|
||||||
private Map<Long, Integer> giveCouponsMap;
|
private Map<Long, Integer> giveCoupons;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,9 +17,7 @@ public enum CouponStatusEnum implements IntArrayValuable {
|
|||||||
|
|
||||||
UNUSED(1, "未使用"),
|
UNUSED(1, "未使用"),
|
||||||
USED(2, "已使用"),
|
USED(2, "已使用"),
|
||||||
EXPIRE(3, "已过期"),
|
EXPIRE(3, "已过期");
|
||||||
// TODO @puhui999:捉摸了下,貌似搞成逻辑删除好了?不然好多地方的 status 都要做一些变动。可能未来加个 invalidateType 来标识,是管理后台删除,还是取消回收。或者优惠劵的 change log 可能更好。
|
|
||||||
INVALID(4, "已作废");
|
|
||||||
|
|
||||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CouponStatusEnum::getStatus).toArray();
|
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CouponStatusEnum::getStatus).toArray();
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import jakarta.annotation.Resource;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,13 +44,13 @@ public class CouponApiImpl implements CouponApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void takeCouponsByAdmin(Map<Long, Integer> giveCouponsMap, Long userId) {
|
public List<Long> takeCouponsByAdmin(Map<Long, Integer> giveCoupons, Long userId) {
|
||||||
couponService.takeCouponsByAdmin(giveCouponsMap, userId);
|
return couponService.takeCouponsByAdmin(giveCoupons, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidateCouponsByAdmin(Map<Long, Integer> giveCouponsMap, Long userId) {
|
public void invalidateCouponsByAdmin(List<Long> giveCouponIds, Long userId) {
|
||||||
couponService.invalidateCouponsByAdmin(giveCouponsMap, userId);
|
couponService.invalidateCouponsByAdmin(giveCouponIds, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo;
|
package cn.iocoder.yudao.module.promotion.controller.admin.reward.vo;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.util.BooleanUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum;
|
import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum;
|
||||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
||||||
@ -77,24 +76,16 @@ public class RewardActivityBaseVO {
|
|||||||
@NotNull(message = "规则是否包邮不能为空")
|
@NotNull(message = "规则是否包邮不能为空")
|
||||||
private Boolean freeDelivery;
|
private Boolean freeDelivery;
|
||||||
|
|
||||||
@Schema(description = "是否赠送积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
|
||||||
@NotNull(message = "规则是否赠送积分不能为空")
|
|
||||||
private Boolean givePoint;
|
|
||||||
|
|
||||||
@Schema(description = "赠送的积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
@Schema(description = "赠送的积分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
||||||
private Integer point;
|
private Integer point;
|
||||||
|
|
||||||
@Schema(description = "是否赠送优惠券", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
|
|
||||||
@NotNull(message = "规则是否赠送优惠券不能为空")
|
|
||||||
private Boolean giveCoupon;
|
|
||||||
|
|
||||||
@Schema(description = "赠送的优惠劵编号的数组", example = "1,2,3")
|
@Schema(description = "赠送的优惠劵编号的数组", example = "1,2,3")
|
||||||
private Map<Long, Integer> giveCouponsMap;
|
private Map<Long, Integer> giveCouponsMap;
|
||||||
|
|
||||||
@AssertTrue(message = "赠送的积分不能小于 1")
|
@AssertTrue(message = "赠送的积分不能小于 1")
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
public boolean isPointValid() {
|
public boolean isPointValid() {
|
||||||
return BooleanUtil.isFalse(givePoint) || (point != null && point >= 1);
|
return point == null || point >= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -100,20 +100,10 @@ public class RewardActivityDO extends BaseDO {
|
|||||||
* 是否包邮
|
* 是否包邮
|
||||||
*/
|
*/
|
||||||
private Boolean freeDelivery;
|
private Boolean freeDelivery;
|
||||||
// TODO @puhui999:是不是大于零,就认为赠送积分哈;简洁一点;
|
|
||||||
/**
|
|
||||||
* 是否赠送积分
|
|
||||||
*/
|
|
||||||
private Boolean givePoint;
|
|
||||||
/**
|
/**
|
||||||
* 赠送的积分
|
* 赠送的积分
|
||||||
*/
|
*/
|
||||||
private Integer point;
|
private Integer point;
|
||||||
// TODO @puhui999:非空,就认为赠送优惠劵
|
|
||||||
/**
|
|
||||||
* 是否赠送优惠券
|
|
||||||
*/
|
|
||||||
private Boolean giveCoupon;
|
|
||||||
/**
|
/**
|
||||||
* 赠送的优惠劵
|
* 赠送的优惠劵
|
||||||
*
|
*
|
||||||
|
@ -8,6 +8,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
|||||||
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO;
|
import cn.iocoder.yudao.module.promotion.controller.admin.coupon.vo.coupon.CouponPageReqVO;
|
||||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
|
import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
|
||||||
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.github.yulichang.toolkit.MPJWrappers;
|
import com.github.yulichang.toolkit.MPJWrappers;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
@ -72,15 +73,6 @@ public interface CouponMapper extends BaseMapperX<CouponDO> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
default List<CouponDO> selectListByTemplateIdAndUserIdAndTakeType(Long templateId, Collection<Long> userIds,
|
|
||||||
Integer takeType) {
|
|
||||||
return selectList(new LambdaQueryWrapperX<CouponDO>()
|
|
||||||
.eq(CouponDO::getTemplateId, templateId)
|
|
||||||
.eq(CouponDO::getTakeType, takeType)
|
|
||||||
.in(CouponDO::getUserId, userIds)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
default Map<Long, Integer> selectCountByUserIdAndTemplateIdIn(Long userId, Collection<Long> templateIds) {
|
default Map<Long, Integer> selectCountByUserIdAndTemplateIdIn(Long userId, Collection<Long> templateIds) {
|
||||||
String templateIdAlias = "templateId";
|
String templateIdAlias = "templateId";
|
||||||
String countAlias = "count";
|
String countAlias = "count";
|
||||||
@ -116,4 +108,11 @@ public interface CouponMapper extends BaseMapperX<CouponDO> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default List<CouponDO> selectListByIdAndUserIdAndTakeType(Long couponId, Long userId, Integer takeType) {
|
||||||
|
return selectList(new LambdaQueryWrapper<CouponDO>()
|
||||||
|
.eq(CouponDO::getId, couponId)
|
||||||
|
.eq(CouponDO::getUserId, userId)
|
||||||
|
.eq(CouponDO::getTakeType, takeType));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,14 +38,6 @@ public interface CouponService {
|
|||||||
*/
|
*/
|
||||||
void validCoupon(CouponDO coupon);
|
void validCoupon(CouponDO coupon);
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得优惠劵分页
|
|
||||||
*
|
|
||||||
* @param pageReqVO 分页查询
|
|
||||||
* @return 优惠劵分页
|
|
||||||
*/
|
|
||||||
PageResult<CouponDO> getCouponPage(CouponPageReqVO pageReqVO);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用优惠劵
|
* 使用优惠劵
|
||||||
*
|
*
|
||||||
@ -69,57 +61,43 @@ public interface CouponService {
|
|||||||
*/
|
*/
|
||||||
void deleteCoupon(Long id);
|
void deleteCoupon(Long id);
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得用户的优惠劵列表
|
|
||||||
*
|
|
||||||
* @param userId 用户编号
|
|
||||||
* @param status 优惠劵状态
|
|
||||||
* @return 优惠劵列表
|
|
||||||
*/
|
|
||||||
List<CouponDO> getCouponList(Long userId, Integer status);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得未使用的优惠劵数量
|
|
||||||
*
|
|
||||||
* @param userId 用户编号
|
|
||||||
* @return 未使用的优惠劵数量
|
|
||||||
*/
|
|
||||||
Long getUnusedCouponCount(Long userId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 领取优惠券
|
* 领取优惠券
|
||||||
*
|
*
|
||||||
* @param templateId 优惠券模板编号
|
* @param templateId 优惠券模板编号
|
||||||
* @param userIds 用户编号列表
|
* @param userIds 用户编号列表
|
||||||
* @param takeType 领取方式
|
* @param takeType 领取方式
|
||||||
|
* @return key: userId, value: 优惠券编号列表
|
||||||
*/
|
*/
|
||||||
void takeCoupon(Long templateId, Set<Long> userIds, CouponTakeTypeEnum takeType);
|
Map<Long, List<Long>> takeCoupon(Long templateId, Set<Long> userIds, CouponTakeTypeEnum takeType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【管理员】给用户发送优惠券
|
* 【管理员】给用户发送优惠券
|
||||||
*
|
*
|
||||||
* @param templateId 优惠券模板编号
|
* @param templateId 优惠券模板编号
|
||||||
* @param userIds 用户编号列表
|
* @param userIds 用户编号列表
|
||||||
|
* @return key: userId, value: 优惠券编号列表
|
||||||
*/
|
*/
|
||||||
default void takeCouponByAdmin(Long templateId, Set<Long> userIds) {
|
default Map<Long, List<Long>> takeCouponByAdmin(Long templateId, Set<Long> userIds) {
|
||||||
takeCoupon(templateId, userIds, CouponTakeTypeEnum.ADMIN);
|
return takeCoupon(templateId, userIds, CouponTakeTypeEnum.ADMIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【管理员】给指定用户批量发送优惠券
|
* 【管理员】给指定用户批量发送优惠券
|
||||||
*
|
*
|
||||||
* @param giveCouponsMap key: 优惠劵编号,value:对应的优惠券数量
|
* @param giveCoupons key: 优惠劵模版编号,value:对应的数量
|
||||||
* @param userId 用户编号
|
* @param userId 用户编号
|
||||||
|
* @return 优惠券编号列表
|
||||||
*/
|
*/
|
||||||
void takeCouponsByAdmin(Map<Long, Integer> giveCouponsMap, Long userId);
|
List<Long> takeCouponsByAdmin(Map<Long, Integer> giveCoupons, Long userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【管理员】收回给指定用户批量发送优惠券
|
* 【管理员】作废指定用户的指定优惠劵
|
||||||
*
|
*
|
||||||
* @param giveCouponsMap key: 优惠劵编号,value:对应的优惠券数量
|
* @param giveCouponIds 赠送的优惠券编号
|
||||||
* @param userId 用户编号
|
* @param userId 用户编号
|
||||||
*/
|
*/
|
||||||
void invalidateCouponsByAdmin(Map<Long, Integer> giveCouponsMap, Long userId);
|
void invalidateCouponsByAdmin(List<Long> giveCouponIds, Long userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【会员】领取优惠券
|
* 【会员】领取优惠券
|
||||||
@ -138,6 +116,49 @@ public interface CouponService {
|
|||||||
*/
|
*/
|
||||||
void takeCouponByRegister(Long userId);
|
void takeCouponByRegister(Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过期优惠券
|
||||||
|
*
|
||||||
|
* @return 过期数量
|
||||||
|
*/
|
||||||
|
int expireCoupon();
|
||||||
|
|
||||||
|
//======================= 查询相关 =======================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得未使用的优惠劵数量
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @return 未使用的优惠劵数量
|
||||||
|
*/
|
||||||
|
Long getUnusedCouponCount(Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得优惠劵分页
|
||||||
|
*
|
||||||
|
* @param pageReqVO 分页查询
|
||||||
|
* @return 优惠劵分页
|
||||||
|
*/
|
||||||
|
PageResult<CouponDO> getCouponPage(CouponPageReqVO pageReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得用户的优惠劵列表
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param status 优惠劵状态
|
||||||
|
* @return 优惠劵列表
|
||||||
|
*/
|
||||||
|
List<CouponDO> getCouponList(Long userId, Integer status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计会员领取优惠券的数量
|
||||||
|
*
|
||||||
|
* @param templateIds 优惠券模板编号列表
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @return 领取优惠券的数量
|
||||||
|
*/
|
||||||
|
Map<Long, Integer> getTakeCountMapByTemplateIds(Collection<Long> templateIds, Long userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取会员领取指定优惠券的数量
|
* 获取会员领取指定优惠券的数量
|
||||||
*
|
*
|
||||||
@ -150,15 +171,6 @@ public interface CouponService {
|
|||||||
return MapUtil.getInt(map, templateId, 0);
|
return MapUtil.getInt(map, templateId, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 统计会员领取优惠券的数量
|
|
||||||
*
|
|
||||||
* @param templateIds 优惠券模板编号列表
|
|
||||||
* @param userId 用户编号
|
|
||||||
* @return 领取优惠券的数量
|
|
||||||
*/
|
|
||||||
Map<Long, Integer> getTakeCountMapByTemplateIds(Collection<Long> templateIds, Long userId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户匹配的优惠券列表
|
* 获取用户匹配的优惠券列表
|
||||||
*
|
*
|
||||||
@ -168,13 +180,6 @@ public interface CouponService {
|
|||||||
*/
|
*/
|
||||||
List<CouponDO> getMatchCouponList(Long userId, AppCouponMatchReqVO matchReqVO);
|
List<CouponDO> getMatchCouponList(Long userId, AppCouponMatchReqVO matchReqVO);
|
||||||
|
|
||||||
/**
|
|
||||||
* 过期优惠券
|
|
||||||
*
|
|
||||||
* @return 过期数量
|
|
||||||
*/
|
|
||||||
int expireCoupon();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户是否可以领取优惠券
|
* 获取用户是否可以领取优惠券
|
||||||
*
|
*
|
||||||
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.service.coupon;
|
|||||||
import cn.hutool.core.collection.CollStreamUtil;
|
import cn.hutool.core.collection.CollStreamUtil;
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
@ -31,6 +32,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
|
||||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
|
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
|
|
||||||
@ -75,20 +77,6 @@ public class CouponServiceImpl implements CouponService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public PageResult<CouponDO> getCouponPage(CouponPageReqVO pageReqVO) {
|
|
||||||
// 获得用户编号
|
|
||||||
if (StrUtil.isNotEmpty(pageReqVO.getNickname())) {
|
|
||||||
List<MemberUserRespDTO> users = memberUserApi.getUserListByNickname(pageReqVO.getNickname());
|
|
||||||
if (CollUtil.isEmpty(users)) {
|
|
||||||
return PageResult.empty();
|
|
||||||
}
|
|
||||||
pageReqVO.setUserIds(convertSet(users, MemberUserRespDTO::getId));
|
|
||||||
}
|
|
||||||
// 分页查询
|
|
||||||
return couponMapper.selectPage(pageReqVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void useCoupon(Long id, Long userId, Long orderId) {
|
public void useCoupon(Long id, Long userId, Long orderId) {
|
||||||
// 校验优惠劵
|
// 校验优惠劵
|
||||||
@ -145,27 +133,9 @@ public class CouponServiceImpl implements CouponService {
|
|||||||
couponTemplateService.updateCouponTemplateTakeCount(coupon.getTemplateId(), -1);
|
couponTemplateService.updateCouponTemplateTakeCount(coupon.getTemplateId(), -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<CouponDO> getCouponList(Long userId, Integer status) {
|
|
||||||
return couponMapper.selectListByUserIdAndStatus(userId, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
private CouponDO validateCouponExists(Long id) {
|
|
||||||
CouponDO coupon = couponMapper.selectById(id);
|
|
||||||
if (coupon == null) {
|
|
||||||
throw exception(COUPON_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
return coupon;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long getUnusedCouponCount(Long userId) {
|
|
||||||
return couponMapper.selectCountByUserIdAndStatus(userId, CouponStatusEnum.UNUSED.getStatus());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void takeCoupon(Long templateId, Set<Long> userIds, CouponTakeTypeEnum takeType) {
|
public Map<Long, List<Long>> takeCoupon(Long templateId, Set<Long> userIds, CouponTakeTypeEnum takeType) {
|
||||||
CouponTemplateDO template = couponTemplateService.getCouponTemplate(templateId);
|
CouponTemplateDO template = couponTemplateService.getCouponTemplate(templateId);
|
||||||
// 1. 过滤掉达到领取限制的用户
|
// 1. 过滤掉达到领取限制的用户
|
||||||
removeTakeLimitUser(userIds, template);
|
removeTakeLimitUser(userIds, template);
|
||||||
@ -173,40 +143,45 @@ public class CouponServiceImpl implements CouponService {
|
|||||||
validateCouponTemplateCanTake(template, userIds, takeType);
|
validateCouponTemplateCanTake(template, userIds, takeType);
|
||||||
|
|
||||||
// 3. 批量保存优惠劵
|
// 3. 批量保存优惠劵
|
||||||
couponMapper.insertBatch(convertList(userIds, userId -> CouponConvert.INSTANCE.convert(template, userId)));
|
List<CouponDO> couponList = convertList(userIds, userId -> CouponConvert.INSTANCE.convert(template, userId));
|
||||||
|
couponMapper.insertBatch(couponList);
|
||||||
|
|
||||||
// 4. 增加优惠劵模板的领取数量
|
// 4. 增加优惠劵模板的领取数量
|
||||||
couponTemplateService.updateCouponTemplateTakeCount(templateId, userIds.size());
|
couponTemplateService.updateCouponTemplateTakeCount(templateId, userIds.size());
|
||||||
|
|
||||||
|
return convertMultiMap(couponList, CouponDO::getUserId, CouponDO::getId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void takeCouponsByAdmin(Map<Long, Integer> giveCouponsMap, Long userId) {
|
public List<Long> takeCouponsByAdmin(Map<Long, Integer> giveCoupons, Long userId) {
|
||||||
if (CollUtil.isEmpty(giveCouponsMap)) {
|
if (CollUtil.isEmpty(giveCoupons)) {
|
||||||
return;
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<Long> couponIds = new ArrayList<>();
|
||||||
// 循环发放
|
// 循环发放
|
||||||
for (Map.Entry<Long, Integer> entry : giveCouponsMap.entrySet()) {
|
for (Map.Entry<Long, Integer> entry : giveCoupons.entrySet()) {
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < entry.getValue(); i++) {
|
for (int i = 0; i < entry.getValue(); i++) {
|
||||||
getSelf().takeCoupon(entry.getKey(), CollUtil.newHashSet(userId), CouponTakeTypeEnum.ADMIN);
|
Map<Long, List<Long>> userCouponIdsMap = getSelf().takeCoupon(entry.getKey(), CollUtil.newHashSet(userId),
|
||||||
|
CouponTakeTypeEnum.ADMIN);
|
||||||
|
findAndThen(userCouponIdsMap, userId, couponIds::addAll);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("[takeCouponsByAdmin][coupon({}) 优惠券发放失败]", entry, e);
|
log.error("[takeCouponsByAdmin][coupon({}) 优惠券发放失败]", entry, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return couponIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidateCouponsByAdmin(Map<Long, Integer> giveCouponsMap, Long userId) {
|
public void invalidateCouponsByAdmin(List<Long> giveCouponIds, Long userId) {
|
||||||
// 循环收回
|
// 循环收回
|
||||||
for (Map.Entry<Long, Integer> entry : giveCouponsMap.entrySet()) {
|
for (Long couponId : giveCouponIds) {
|
||||||
try {
|
try {
|
||||||
for (int i = 0; i < entry.getValue(); i++) {
|
getSelf().takeBackCoupon(couponId, userId, CouponTakeTypeEnum.ADMIN);
|
||||||
getSelf().takeBackCoupon(entry.getKey(), CollUtil.newHashSet(userId), CouponTakeTypeEnum.ADMIN);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("[takeBackCouponsByAdmin][coupon({}) 收回优惠券失败]", entry, e);
|
log.error("[invalidateCouponsByAdmin][couponId({}) 收回优惠券失败]", couponId, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -214,32 +189,36 @@ public class CouponServiceImpl implements CouponService {
|
|||||||
/**
|
/**
|
||||||
* 【管理员】收回优惠券
|
* 【管理员】收回优惠券
|
||||||
*
|
*
|
||||||
* @param templateId 模版编号
|
* @param couponId 模版编号
|
||||||
* @param userIds 用户编号列表
|
* @param userId 用户编号
|
||||||
* @param takeType 领取方式
|
* @param takeType 领取方式
|
||||||
*/
|
*/
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void takeBackCoupon(Long templateId, Set<Long> userIds, CouponTakeTypeEnum takeType) {
|
public void takeBackCoupon(Long couponId, Long userId, CouponTakeTypeEnum takeType) {
|
||||||
CouponTemplateDO couponTemplate = couponTemplateService.getCouponTemplate(templateId);
|
// 1.1 校验优惠券
|
||||||
// 1.1 校验模板
|
CouponDO coupon = couponMapper.selectByIdAndUserId(couponId, userId);
|
||||||
|
if (coupon == null) {
|
||||||
|
throw exception(COUPON_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
// 1.2 校验模板
|
||||||
|
CouponTemplateDO couponTemplate = couponTemplateService.getCouponTemplate(coupon.getTemplateId());
|
||||||
if (couponTemplate == null) {
|
if (couponTemplate == null) {
|
||||||
throw exception(COUPON_TEMPLATE_NOT_EXISTS);
|
throw exception(COUPON_TEMPLATE_NOT_EXISTS);
|
||||||
}
|
}
|
||||||
// 1.2 校验领取方式
|
// 1.3 校验领取方式
|
||||||
if (ObjectUtil.notEqual(couponTemplate.getTakeType(), takeType.getValue())) {
|
if (ObjectUtil.notEqual(couponTemplate.getTakeType(), takeType.getValue())) {
|
||||||
throw exception(COUPON_TEMPLATE_CANNOT_TAKE);
|
throw exception(COUPON_TEMPLATE_CANNOT_TAKE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2.1 过滤出还未使用的赠送的优惠券
|
// 2.1 校验优惠券是否已经使用,如若使用则先不管
|
||||||
List<CouponDO> couponList = couponMapper.selectListByTemplateIdAndUserIdAndTakeType(templateId, userIds,
|
if (ObjUtil.equal(coupon.getStatus(), CouponStatusEnum.USED.getStatus())) {
|
||||||
takeType.getValue());
|
return;
|
||||||
List<CouponDO> unUsedCouponList = filterList(couponList, item -> !CouponStatusEnum.USED.getStatus().equals(item.getStatus()));
|
}
|
||||||
// 2.2 减少优惠劵模板的领取数量
|
// 2.2 减少优惠劵模板的领取数量
|
||||||
couponTemplateService.updateCouponTemplateTakeCount(templateId, unUsedCouponList.size() * -1);
|
couponTemplateService.updateCouponTemplateTakeCount(couponTemplate.getId(), -1);
|
||||||
// 2.3 批量更新优惠劵状态
|
// 2.3 批量作废优惠劵
|
||||||
couponMapper.updateById(convertList(unUsedCouponList, item -> new CouponDO().setId(item.getId())
|
// TODO @puhui999:捉摸了下,貌似搞成逻辑删除好了?不然好多地方的 status 都要做一些变动。可能未来加个 invalidateType 来标识,是管理后台删除,还是取消回收。或者优惠劵的 change log 可能更好。
|
||||||
.setStatus(CouponStatusEnum.INVALID.getStatus())));
|
couponMapper.deleteById(couponId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -251,24 +230,6 @@ public class CouponServiceImpl implements CouponService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Long, Integer> getTakeCountMapByTemplateIds(Collection<Long> templateIds, Long userId) {
|
|
||||||
if (CollUtil.isEmpty(templateIds)) {
|
|
||||||
return Collections.emptyMap();
|
|
||||||
}
|
|
||||||
return couponMapper.selectCountByUserIdAndTemplateIdIn(userId, templateIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<CouponDO> getMatchCouponList(Long userId, AppCouponMatchReqVO matchReqVO) {
|
|
||||||
List<CouponDO> list = couponMapper.selectListByUserIdAndStatusAndUsePriceLeAndProductScope(userId,
|
|
||||||
CouponStatusEnum.UNUSED.getStatus(),
|
|
||||||
matchReqVO.getPrice(), matchReqVO.getSpuIds(), matchReqVO.getCategoryIds());
|
|
||||||
// 兜底逻辑:如果 CouponExpireJob 未执行,status 未变成 EXPIRE ,但是 validEndTime 已经过期了,需要进行过滤
|
|
||||||
list.removeIf(coupon -> !LocalDateTimeUtils.isBetween(coupon.getValidStartTime(), coupon.getValidEndTime()));
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int expireCoupon() {
|
public int expireCoupon() {
|
||||||
// 1. 查询待过期的优惠券
|
// 1. 查询待过期的优惠券
|
||||||
@ -293,27 +254,6 @@ public class CouponServiceImpl implements CouponService {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<Long, Boolean> getUserCanCanTakeMap(Long userId, List<CouponTemplateDO> templates) {
|
|
||||||
// 1. 未登录时,都显示可以领取
|
|
||||||
Map<Long, Boolean> userCanTakeMap = convertMap(templates, CouponTemplateDO::getId, templateId -> true);
|
|
||||||
if (userId == null) {
|
|
||||||
return userCanTakeMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2.1 过滤领取数量无限制的
|
|
||||||
Set<Long> templateIds = convertSet(templates, CouponTemplateDO::getId, template -> template.getTakeLimitCount() != -1);
|
|
||||||
// 2.2 检查用户领取的数量是否超过限制
|
|
||||||
if (CollUtil.isNotEmpty(templateIds)) {
|
|
||||||
Map<Long, Integer> couponTakeCountMap = this.getTakeCountMapByTemplateIds(templateIds, userId);
|
|
||||||
for (CouponTemplateDO template : templates) {
|
|
||||||
Integer takeCount = couponTakeCountMap.get(template.getId());
|
|
||||||
userCanTakeMap.put(template.getId(), takeCount == null || takeCount < template.getTakeLimitCount());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return userCanTakeMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 过期单个优惠劵
|
* 过期单个优惠劵
|
||||||
*
|
*
|
||||||
@ -385,11 +325,84 @@ public class CouponServiceImpl implements CouponService {
|
|||||||
userIds.removeIf(userId -> MapUtil.getInt(userTakeCountMap, userId, 0) >= couponTemplate.getTakeLimitCount());
|
userIds.removeIf(userId -> MapUtil.getInt(userTakeCountMap, userId, 0) >= couponTemplate.getTakeLimitCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//======================= 查询相关 =======================
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long getUnusedCouponCount(Long userId) {
|
||||||
|
return couponMapper.selectCountByUserIdAndStatus(userId, CouponStatusEnum.UNUSED.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<CouponDO> getCouponPage(CouponPageReqVO pageReqVO) {
|
||||||
|
// 获得用户编号
|
||||||
|
if (StrUtil.isNotEmpty(pageReqVO.getNickname())) {
|
||||||
|
List<MemberUserRespDTO> users = memberUserApi.getUserListByNickname(pageReqVO.getNickname());
|
||||||
|
if (CollUtil.isEmpty(users)) {
|
||||||
|
return PageResult.empty();
|
||||||
|
}
|
||||||
|
pageReqVO.setUserIds(convertSet(users, MemberUserRespDTO::getId));
|
||||||
|
}
|
||||||
|
// 分页查询
|
||||||
|
return couponMapper.selectPage(pageReqVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<CouponDO> getCouponList(Long userId, Integer status) {
|
||||||
|
return couponMapper.selectListByUserIdAndStatus(userId, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Long, Integer> getTakeCountMapByTemplateIds(Collection<Long> templateIds, Long userId) {
|
||||||
|
if (CollUtil.isEmpty(templateIds)) {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
return couponMapper.selectCountByUserIdAndTemplateIdIn(userId, templateIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<CouponDO> getMatchCouponList(Long userId, AppCouponMatchReqVO matchReqVO) {
|
||||||
|
List<CouponDO> list = couponMapper.selectListByUserIdAndStatusAndUsePriceLeAndProductScope(userId,
|
||||||
|
CouponStatusEnum.UNUSED.getStatus(),
|
||||||
|
matchReqVO.getPrice(), matchReqVO.getSpuIds(), matchReqVO.getCategoryIds());
|
||||||
|
// 兜底逻辑:如果 CouponExpireJob 未执行,status 未变成 EXPIRE ,但是 validEndTime 已经过期了,需要进行过滤
|
||||||
|
list.removeIf(coupon -> !LocalDateTimeUtils.isBetween(coupon.getValidStartTime(), coupon.getValidEndTime()));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Long, Boolean> getUserCanCanTakeMap(Long userId, List<CouponTemplateDO> templates) {
|
||||||
|
// 1. 未登录时,都显示可以领取
|
||||||
|
Map<Long, Boolean> userCanTakeMap = convertMap(templates, CouponTemplateDO::getId, templateId -> true);
|
||||||
|
if (userId == null) {
|
||||||
|
return userCanTakeMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2.1 过滤领取数量无限制的
|
||||||
|
Set<Long> templateIds = convertSet(templates, CouponTemplateDO::getId, template -> template.getTakeLimitCount() != -1);
|
||||||
|
// 2.2 检查用户领取的数量是否超过限制
|
||||||
|
if (CollUtil.isNotEmpty(templateIds)) {
|
||||||
|
Map<Long, Integer> couponTakeCountMap = this.getTakeCountMapByTemplateIds(templateIds, userId);
|
||||||
|
for (CouponTemplateDO template : templates) {
|
||||||
|
Integer takeCount = couponTakeCountMap.get(template.getId());
|
||||||
|
userCanTakeMap.put(template.getId(), takeCount == null || takeCount < template.getTakeLimitCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return userCanTakeMap;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CouponDO getCoupon(Long userId, Long id) {
|
public CouponDO getCoupon(Long userId, Long id) {
|
||||||
return couponMapper.selectByIdAndUserId(id, userId);
|
return couponMapper.selectByIdAndUserId(id, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CouponDO validateCouponExists(Long id) {
|
||||||
|
CouponDO coupon = couponMapper.selectById(id);
|
||||||
|
if (coupon == null) {
|
||||||
|
throw exception(COUPON_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
return coupon;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得自身的代理对象,解决 AOP 生效问题
|
* 获得自身的代理对象,解决 AOP 生效问题
|
||||||
*
|
*
|
||||||
@ -398,4 +411,5 @@ public class CouponServiceImpl implements CouponService {
|
|||||||
private CouponServiceImpl getSelf() {
|
private CouponServiceImpl getSelf() {
|
||||||
return SpringUtil.getBean(getClass());
|
return SpringUtil.getBean(getClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,6 @@ public class RewardActivityServiceImpl implements RewardActivityService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RewardActivityMatchRespDTO> getMatchRewardActivityList(Collection<Long> spuIds) {
|
public List<RewardActivityMatchRespDTO> getMatchRewardActivityList(Collection<Long> spuIds) {
|
||||||
// TODO 芋艿:待实现;先指定,然后再全局的;
|
|
||||||
List<RewardActivityDO> list = rewardActivityMapper.selectListBySpuIdsAndStatus(spuIds, CommonStatusEnum.ENABLE.getStatus());
|
List<RewardActivityDO> list = rewardActivityMapper.selectListBySpuIdsAndStatus(spuIds, CommonStatusEnum.ENABLE.getStatus());
|
||||||
return BeanUtils.toBean(list, RewardActivityMatchRespDTO.class);
|
return BeanUtils.toBean(list, RewardActivityMatchRespDTO.class);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.order;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
|
import cn.iocoder.yudao.framework.common.enums.TerminalEnum;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.type.LongListTypeHandler;
|
||||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.BrokerageUserDO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
|
||||||
@ -18,6 +19,7 @@ import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -294,17 +296,23 @@ public class TradeOrderDO extends BaseDO {
|
|||||||
*/
|
*/
|
||||||
private Integer vipPrice;
|
private Integer vipPrice;
|
||||||
|
|
||||||
// TODO @puhui999:项了下,貌似这里存储 List<Long> giveCouponIds 更合适。因为优惠劵赠送到最后是对应的编号,然后从而进行取消?
|
|
||||||
/**
|
/**
|
||||||
* 赠送的优惠劵
|
* 赠送的优惠劵
|
||||||
*
|
*
|
||||||
* key: 优惠劵编号
|
* key: 优惠劵编号
|
||||||
* value:对应的优惠券数量
|
* value:对应的优惠券数量
|
||||||
*
|
*
|
||||||
* 目的:用于后续取消或者售后订单时,需要扣减赠送
|
* 目的:用于订单支付后赠送优惠券
|
||||||
*/
|
*/
|
||||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||||
private Map<Long, Integer> giveCouponsMap;
|
private Map<Long, Integer> giveCouponsMap;
|
||||||
|
/**
|
||||||
|
* 赠送的优惠劵编号
|
||||||
|
*
|
||||||
|
* 目的:用于后续取消或者售后订单时,需要扣减赠送
|
||||||
|
*/
|
||||||
|
@TableField(typeHandler = LongListTypeHandler.class)
|
||||||
|
private List<Long> giveCouponIds;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 秒杀活动编号
|
* 秒杀活动编号
|
||||||
|
@ -11,6 +11,8 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderI
|
|||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 交易订单【写】Service 接口
|
* 交易订单【写】Service 接口
|
||||||
*
|
*
|
||||||
@ -194,4 +196,13 @@ public interface TradeOrderUpdateService {
|
|||||||
*/
|
*/
|
||||||
void cancelPaidOrder(Long userId, Long orderId, Integer cancelType);
|
void cancelPaidOrder(Long userId, Long orderId, Integer cancelType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新下单赠送的优惠券编号到订单
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param orderId 订单编号
|
||||||
|
* @param giveCouponIds 赠送的优惠券编号列表
|
||||||
|
*/
|
||||||
|
void updateOrderGiveCouponIds(Long userId, Long orderId, List<Long> giveCouponIds);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum));
|
order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum));
|
||||||
order.setUserIp(getClientIP()).setTerminal(getTerminal());
|
order.setUserIp(getClientIP()).setTerminal(getTerminal());
|
||||||
// 使用 + 赠送优惠券
|
// 使用 + 赠送优惠券
|
||||||
order.setGiveCouponsMap(calculateRespBO.getGiveCouponsMap());
|
order.setGiveCouponsMap(calculateRespBO.getGiveCoupons());
|
||||||
// 支付 + 退款信息
|
// 支付 + 退款信息
|
||||||
order.setAdjustPrice(0).setPayStatus(false);
|
order.setAdjustPrice(0).setPayStatus(false);
|
||||||
order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()).setRefundPrice(0);
|
order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()).setRefundPrice(0);
|
||||||
@ -890,6 +890,22 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
.setReason(TradeOrderCancelTypeEnum.COMBINATION_CLOSE.getName()).setPrice(order.getPayPrice()));// 价格信息
|
.setReason(TradeOrderCancelTypeEnum.COMBINATION_CLOSE.getName()).setPrice(order.getPayPrice()));// 价格信息
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateOrderGiveCouponIds(Long userId, Long orderId, List<Long> giveCouponIds) {
|
||||||
|
// 1.1 检验订单存在
|
||||||
|
TradeOrderDO order = tradeOrderMapper.selectOrderByIdAndUserId(orderId, userId);
|
||||||
|
if (order == null) {
|
||||||
|
throw exception(ORDER_NOT_FOUND);
|
||||||
|
}
|
||||||
|
// 1.2 校验订单是否支付
|
||||||
|
if (!order.getPayStatus()) {
|
||||||
|
throw exception(ORDER_CANCEL_PAID_FAIL, "已支付");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 更新订单赠送的优惠券编号列表
|
||||||
|
tradeOrderMapper.updateById(new TradeOrderDO().setId(orderId).setGiveCouponIds(giveCouponIds));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建单个订单的评论
|
* 创建单个订单的评论
|
||||||
*
|
*
|
||||||
|
@ -5,7 +5,10 @@ import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
|
|||||||
import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
|
import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService;
|
||||||
|
import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -18,6 +21,12 @@ import java.util.List;
|
|||||||
@Component
|
@Component
|
||||||
public class TradeCouponOrderHandler implements TradeOrderHandler {
|
public class TradeCouponOrderHandler implements TradeOrderHandler {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
@Lazy // 延迟加载,避免循环依赖
|
||||||
|
private TradeOrderUpdateService orderUpdateService;
|
||||||
|
@Resource
|
||||||
|
private TradeOrderQueryService orderQueryService;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private CouponApi couponApi;
|
private CouponApi couponApi;
|
||||||
|
|
||||||
@ -37,7 +46,11 @@ public class TradeCouponOrderHandler implements TradeOrderHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 赠送优惠券
|
// 赠送优惠券
|
||||||
couponApi.takeCouponsByAdmin(order.getGiveCouponsMap(), order.getUserId());
|
List<Long> couponIds = couponApi.takeCouponsByAdmin(order.getGiveCouponsMap(), order.getUserId());
|
||||||
|
if (CollUtil.isEmpty(couponIds)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
orderUpdateService.updateOrderGiveCouponIds(order.getUserId(), order.getId(), couponIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -48,10 +61,10 @@ public class TradeCouponOrderHandler implements TradeOrderHandler {
|
|||||||
couponApi.returnUsedCoupon(order.getCouponId());
|
couponApi.returnUsedCoupon(order.getCouponId());
|
||||||
}
|
}
|
||||||
// 情况二:收回赠送的优惠券
|
// 情况二:收回赠送的优惠券
|
||||||
if (CollUtil.isEmpty(order.getGiveCouponsMap())) {
|
if (CollUtil.isEmpty(order.getGiveCouponIds())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
couponApi.invalidateCouponsByAdmin(order.getGiveCouponsMap(), order.getUserId());
|
couponApi.invalidateCouponsByAdmin(order.getGiveCouponIds(), order.getUserId());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,7 @@ public class TradePriceCalculateRespBO {
|
|||||||
* key: 优惠劵编号,value:对应的优惠券数量
|
* key: 优惠劵编号,value:对应的优惠券数量
|
||||||
* 目的:用于后续取消或者售后订单时,需要扣减赠送
|
* 目的:用于后续取消或者售后订单时,需要扣减赠送
|
||||||
*/
|
*/
|
||||||
private Map<Long, Integer> giveCouponsMap;
|
private Map<Long, Integer> giveCoupons;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单价格
|
* 订单价格
|
||||||
|
@ -32,7 +32,7 @@ public class TradePriceCalculatorHelper {
|
|||||||
List<ProductSpuRespDTO> spuList, List<ProductSkuRespDTO> skuList) {
|
List<ProductSpuRespDTO> spuList, List<ProductSkuRespDTO> skuList) {
|
||||||
// 创建 PriceCalculateRespDTO 对象
|
// 创建 PriceCalculateRespDTO 对象
|
||||||
TradePriceCalculateRespBO result = new TradePriceCalculateRespBO();
|
TradePriceCalculateRespBO result = new TradePriceCalculateRespBO();
|
||||||
result.setType(getOrderType(param)).setPromotions(new ArrayList<>()).setGiveCouponsMap(new LinkedHashMap<>());
|
result.setType(getOrderType(param)).setPromotions(new ArrayList<>()).setGiveCoupons(new LinkedHashMap<>());
|
||||||
|
|
||||||
// 创建它的 OrderItem 属性
|
// 创建它的 OrderItem 属性
|
||||||
result.setItems(new ArrayList<>(param.getItems().size()));
|
result.setItems(new ArrayList<>(param.getItems().size()));
|
||||||
|
@ -93,7 +93,7 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator
|
|||||||
TradePriceCalculatorHelper.recountAllPrice(result);
|
TradePriceCalculatorHelper.recountAllPrice(result);
|
||||||
|
|
||||||
// 4.1 记录赠送的积分
|
// 4.1 记录赠送的积分
|
||||||
if (Boolean.TRUE.equals(rule.getGivePoint())) {
|
if (rule.getPoint() != null && rule.getPoint() > 0) {
|
||||||
List<Integer> dividePoints = TradePriceCalculatorHelper.dividePrice(orderItems, rule.getPoint());
|
List<Integer> dividePoints = TradePriceCalculatorHelper.dividePrice(orderItems, rule.getPoint());
|
||||||
for (int i = 0; i < orderItems.size(); i++) {
|
for (int i = 0; i < orderItems.size(); i++) {
|
||||||
// 商品可能赠送了积分,所以这里要加上
|
// 商品可能赠送了积分,所以这里要加上
|
||||||
@ -107,13 +107,13 @@ public class TradeRewardActivityPriceCalculator implements TradePriceCalculator
|
|||||||
result.setFreeDelivery(true);
|
result.setFreeDelivery(true);
|
||||||
}
|
}
|
||||||
// 4.3 记录赠送的优惠券
|
// 4.3 记录赠送的优惠券
|
||||||
if (Boolean.TRUE.equals(rule.getGiveCoupon())) {
|
if (CollUtil.isNotEmpty(rule.getGiveCoupons())) {
|
||||||
for (Map.Entry<Long, Integer> entry : rule.getGiveCouponsMap().entrySet()) {
|
for (Map.Entry<Long, Integer> entry : rule.getGiveCoupons().entrySet()) {
|
||||||
Map<Long, Integer> giveCouponsMap = result.getGiveCouponsMap();
|
Map<Long, Integer> giveCoupons = result.getGiveCoupons();
|
||||||
if (giveCouponsMap.get(entry.getKey()) == null) { // 情况一:还没有赠送的优惠券
|
if (giveCoupons.get(entry.getKey()) == null) { // 情况一:还没有赠送的优惠券
|
||||||
result.setGiveCouponsMap(rule.getGiveCouponsMap());
|
result.setGiveCoupons(rule.getGiveCoupons());
|
||||||
} else { // 情况二:别的满减活动送过同类优惠券,则直接增加数量
|
} else { // 情况二:别的满减活动送过同类优惠券,则直接增加数量
|
||||||
giveCouponsMap.put(entry.getKey(), giveCouponsMap.get(entry.getKey()) + entry.getValue());
|
giveCoupons.put(entry.getKey(), giveCoupons.get(entry.getKey()) + entry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ public class TradeRewardActivityPriceCalculatorTest extends BaseMockitoUnitTest
|
|||||||
TradePriceCalculateRespBO result = new TradePriceCalculateRespBO()
|
TradePriceCalculateRespBO result = new TradePriceCalculateRespBO()
|
||||||
.setType(TradeOrderTypeEnum.NORMAL.getType())
|
.setType(TradeOrderTypeEnum.NORMAL.getType())
|
||||||
.setPrice(new TradePriceCalculateRespBO.Price())
|
.setPrice(new TradePriceCalculateRespBO.Price())
|
||||||
.setPromotions(new ArrayList<>()).setGiveCouponsMap(new LinkedHashMap<>())
|
.setPromotions(new ArrayList<>()).setGiveCoupons(new LinkedHashMap<>())
|
||||||
.setItems(asList(
|
.setItems(asList(
|
||||||
new TradePriceCalculateRespBO.OrderItem().setSkuId(10L).setCount(2).setSelected(true)
|
new TradePriceCalculateRespBO.OrderItem().setSkuId(10L).setCount(2).setSelected(true)
|
||||||
.setPrice(100).setSpuId(1L),
|
.setPrice(100).setSpuId(1L),
|
||||||
@ -68,16 +68,16 @@ public class TradeRewardActivityPriceCalculatorTest extends BaseMockitoUnitTest
|
|||||||
.setConditionType(PromotionConditionTypeEnum.PRICE.getType())
|
.setConditionType(PromotionConditionTypeEnum.PRICE.getType())
|
||||||
.setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductScopeValues(asList(1L, 2L))
|
.setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductScopeValues(asList(1L, 2L))
|
||||||
.setRules(singletonList(new RewardActivityMatchRespDTO.Rule().setLimit(20).setDiscountPrice(70)
|
.setRules(singletonList(new RewardActivityMatchRespDTO.Rule().setLimit(20).setDiscountPrice(70)
|
||||||
.setGivePoint(false).setFreeDelivery(false)))),
|
.setFreeDelivery(false)))),
|
||||||
randomPojo(RewardActivityMatchRespDTO.class, o -> o.setId(2000L).setName("活动 2000 号")
|
randomPojo(RewardActivityMatchRespDTO.class, o -> o.setId(2000L).setName("活动 2000 号")
|
||||||
.setConditionType(PromotionConditionTypeEnum.COUNT.getType())
|
.setConditionType(PromotionConditionTypeEnum.COUNT.getType())
|
||||||
.setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductScopeValues(singletonList(3L))
|
.setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductScopeValues(singletonList(3L))
|
||||||
.setRules(asList(new RewardActivityMatchRespDTO.Rule().setLimit(1).setDiscountPrice(10)
|
.setRules(asList(new RewardActivityMatchRespDTO.Rule().setLimit(1).setDiscountPrice(10)
|
||||||
.setGivePoint(true).setPoint(50).setFreeDelivery(false),
|
.setPoint(50).setFreeDelivery(false),
|
||||||
new RewardActivityMatchRespDTO.Rule().setLimit(2).setDiscountPrice(60).setGivePoint(true)
|
new RewardActivityMatchRespDTO.Rule().setLimit(2).setDiscountPrice(60)
|
||||||
.setPoint(100).setFreeDelivery(false), // 最大可满足,因为是 4 个
|
.setPoint(100).setFreeDelivery(false), // 最大可满足,因为是 4 个
|
||||||
new RewardActivityMatchRespDTO.Rule().setLimit(10).setDiscountPrice(100)
|
new RewardActivityMatchRespDTO.Rule().setLimit(10).setDiscountPrice(100)
|
||||||
.setGivePoint(false).setFreeDelivery(false))))
|
.setFreeDelivery(false))))
|
||||||
));
|
));
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
|
Loading…
Reference in New Issue
Block a user