feat(market):新增查询用户可用优惠卷的功能

This commit is contained in:
JIAN 2024-10-01 12:42:06 +08:00
parent 31b5b7c8f2
commit 34c78b0d62
5 changed files with 137 additions and 8 deletions

View File

@ -0,0 +1,22 @@
package com.jzo2o.api.market;
import com.jzo2o.api.market.dto.response.AvailableCouponsResDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.math.BigDecimal;
import java.util.List;
/**
* 内部接口 - 优惠卷相关接口
* @author JIAN
*/
@FeignClient(contextId = "jzo2o-market", value = "jzo2o-market", path = "/market/inner/coupon")
public interface CouponApi {
/**
* 根据订单金额获取当前用户可用优惠卷
*/
@GetMapping("/getAvailable")
List<AvailableCouponsResDTO> getAvailableCoupon(@RequestParam BigDecimal totalAmount);
}

View File

@ -3,12 +3,17 @@ package com.jzo2o.api.market.dto.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* @author JIAN
*/
@Data
@ApiModel("优惠券信息")
@Accessors(chain = true)
public class AvailableCouponsResDTO {
@ApiModelProperty("优惠券id")
private Long id;
@ -16,34 +21,34 @@ public class AvailableCouponsResDTO {
/**
* 优惠券名称
*/
@ApiModelProperty(value = "活动名称",required = true)
@ApiModelProperty(value = "活动名称", required = true)
private String name;
/**
* 活动id
*/
@ApiModelProperty(value = "活动id",required = true)
@ApiModelProperty(value = "活动id", required = true)
private Long activityId;
@ApiModelProperty(value = "使用类型1满减2折扣",required = true)
@ApiModelProperty(value = "使用类型1满减2折扣", required = true)
private Integer type;
/**
* 折扣
*/
@ApiModelProperty(value = "折扣",required = false)
@ApiModelProperty(value = "折扣")
private Integer discountRate;
/**
* 优惠金额
*/
@ApiModelProperty(value = "优惠金额",required = false)
@ApiModelProperty(value = "优惠金额")
private BigDecimal discountAmount;
/**
* 满减金额
*/
@ApiModelProperty(value = "满减条件,0:表示无门槛",required = true)
@ApiModelProperty(value = "满减条件,0:表示无门槛", required = true)
private BigDecimal amountCondition;
/**
@ -51,4 +56,4 @@ public class AvailableCouponsResDTO {
*/
@ApiModelProperty("优惠券过期时间")
private LocalDateTime validityTime;
}
}

View File

@ -0,0 +1,39 @@
package com.jzo2o.market.controller.inner;
import com.jzo2o.api.market.CouponApi;
import com.jzo2o.api.market.dto.response.AvailableCouponsResDTO;
import com.jzo2o.market.service.ICouponService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
/**
* 内部接口 - 优惠卷管理控制器
* @author JIAN
*/
@Slf4j
@RestController("innerCouponController")
@RequestMapping("/inner/coupon")
public class CouponController implements CouponApi {
@Resource
private ICouponService couponService;
/**
* 根据订单金额获取当前用户可用优惠卷
*/
@Override
@GetMapping("/getAvailable")
@ApiOperation("获取可用优惠券列表")
@ApiImplicitParam(name = "totalAmount", value = "总金额,单位分", required = true, dataTypeClass = BigDecimal.class)
public List<AvailableCouponsResDTO> getAvailableCoupon(@RequestParam BigDecimal totalAmount) {
return couponService.getAvailableCoupon(totalAmount);
}
}

View File

@ -1,6 +1,7 @@
package com.jzo2o.market.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.jzo2o.api.market.dto.response.AvailableCouponsResDTO;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.market.enums.CouponStatusEnum;
import com.jzo2o.market.model.domain.Coupon;
@ -8,6 +9,7 @@ import com.jzo2o.market.model.dto.request.CouponPageQueryDTO;
import com.jzo2o.market.model.dto.response.CouponPageInfoResDTO;
import com.jzo2o.market.model.dto.response.CouponSimpleInfoResDTO;
import java.math.BigDecimal;
import java.util.List;
/**
@ -37,4 +39,9 @@ public interface ICouponService extends IService<Coupon> {
* 同步优惠卷数据到数据库中
*/
void syncCouponRecord(long activityId, long userId);
/**
* 根据订单金额获取当前用户可用优惠卷
*/
List<AvailableCouponsResDTO> getAvailableCoupon(BigDecimal totalAmount);
}

View File

@ -1,18 +1,21 @@
package com.jzo2o.market.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.api.customer.CommonUserApi;
import com.jzo2o.api.customer.dto.response.CommonUserResDTO;
import com.jzo2o.api.market.dto.response.AvailableCouponsResDTO;
import com.jzo2o.common.expcetions.BadRequestException;
import com.jzo2o.common.expcetions.CommonException;
import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.common.model.PageResult;
import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.market.enums.CouponStatusEnum;
import com.jzo2o.market.enums.CouponTypeEnum;
import com.jzo2o.market.mapper.CouponMapper;
import com.jzo2o.market.model.domain.Activity;
import com.jzo2o.market.model.domain.Coupon;
@ -28,9 +31,12 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
@ -137,4 +143,54 @@ public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> impleme
throw new DBException("更新活动库存失败");
}
}
@Override
public List<AvailableCouponsResDTO> getAvailableCoupon(BigDecimal totalAmount) {
Long userId = Optional
.ofNullable(UserContext.currentUserId())
.orElseThrow(() -> new CommonException("用户信息不存在"));
List<Coupon> couponList = lambdaQuery()
.eq(Coupon::getUserId, userId)
.le(Coupon::getAmountCondition, totalAmount)
.eq(Coupon::getStatus, CouponStatusEnum.NO_USE)
.ge(Coupon::getValidityTime, LocalDateTime.now())
.and(and -> and
.isNull(Coupon::getDiscountAmount)
.or(or -> or.le(Coupon::getDiscountAmount, totalAmount)))
.list();
if (CollUtils.isEmpty(couponList)) {
return new ArrayList<>();
}
return couponList.stream()
.map(coupon -> BeanUtils
.toBean(coupon, AvailableCouponsResDTO.class)
.setType(coupon.getType().getType())
.setDiscountAmount(this.calcDiscountAmount(coupon, totalAmount)))
// 默认BigDecimal的比较器排序从小到大 需要按优惠金额从大到小排序
.sorted(Comparator.comparing(AvailableCouponsResDTO::getDiscountAmount).reversed())
.collect(Collectors.toList());
}
/**
* 计算优惠卷的优惠价格
* @param coupon 优惠卷信息
* @param totalAmount 订单总金额
*/
private BigDecimal calcDiscountAmount(Coupon coupon, BigDecimal totalAmount) {
CouponTypeEnum type = coupon.getType();
BigDecimal discountAmount = BigDecimal.ZERO;
if (type == CouponTypeEnum.AMOUNT_DISCOUNT) {
discountAmount = coupon.getDiscountAmount();
} else if (type == CouponTypeEnum.RATE_DISCOUNT) {
// 1 <= coupon.getDiscountRate() <= 99
BigDecimal discountRate = new BigDecimal(String.format("0.%02d", 100 - coupon.getDiscountRate()));
discountAmount = totalAmount.multiply(discountRate);
}
return discountAmount;
}
}