package com.doumee.service.business.impl;
|
|
import com.doumee.core.constants.ResponseStatus;
|
import com.doumee.core.exception.BusinessException;
|
import com.doumee.core.model.LoginUserInfo;
|
import com.doumee.core.model.PageData;
|
import com.doumee.core.model.PageWrap;
|
import com.doumee.core.utils.Constants;
|
import com.doumee.core.utils.DateUtil;
|
import com.doumee.core.utils.ListUtil;
|
import com.doumee.core.utils.Utils;
|
import com.doumee.dao.business.*;
|
import com.doumee.dao.business.model.*;
|
import com.doumee.dao.web.dto.CouponDTO;
|
import com.doumee.dao.web.dto.MemberCouponDTO;
|
import com.doumee.dao.web.request.PayDetailRequest;
|
import com.doumee.dao.web.response.goods.OrderGoodsCalculateResponse;
|
import com.doumee.service.business.MemberCouponService;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
|
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
import org.apache.commons.lang3.StringUtils;
|
import org.apache.shiro.SecurityUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.time.LocalDateTime;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* 用户优惠券关联表Service实现
|
* @author 江蹄蹄
|
* @date 2023/03/21 15:48
|
*/
|
@Service
|
public class MemberCouponServiceImpl implements MemberCouponService {
|
|
@Autowired
|
private MemberCouponMapper memberCouponMapper;
|
|
@Autowired
|
private GoodsMapper goodsMapper;
|
|
@Autowired
|
private GoodsSkuMapper goodsSkuMapper;
|
|
@Autowired
|
private MemberCouponJoinMapper memberCouponJoinMapper;
|
|
@Autowired
|
private CouponMapper couponMapper;
|
|
@Autowired
|
private MemberMapper memberMapper;
|
@Override
|
public Integer create(MemberCoupon memberCoupon) {
|
LoginUserInfo loginUserInfo = (LoginUserInfo)SecurityUtils.getSubject().getPrincipal();
|
|
Coupon coupon = couponMapper.selectById(memberCoupon.getCouponId());
|
if(Objects.isNull(coupon)){
|
throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "未查询到优惠券信息");
|
}
|
|
if(coupon.getStatus().equals(Constants.ONE)){
|
throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "该优惠券已禁用,无法兑换!");
|
}
|
//查询已兑换数量
|
QueryWrapper queryWrapper = new QueryWrapper<MemberCoupon>();
|
queryWrapper.eq("COUPON_ID",coupon.getId());
|
Long exchangeNum = memberCouponMapper.selectCount(queryWrapper);
|
if(exchangeNum.compareTo(coupon.getNum()) >= Constants.ZERO){
|
throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "该优惠券已兑换完,无法兑换!");
|
}
|
//是否已兑换
|
queryWrapper.eq("MEMBER_ID",coupon.getId());
|
if(memberCouponMapper.selectCount(queryWrapper) > Constants.ZERO){
|
throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "已兑换该优惠券,无法兑换!");
|
};
|
|
MemberCoupon insert = new MemberCoupon();
|
Date now = new Date();
|
insert.setCreator(loginUserInfo.getId());
|
insert.setCreateDate(now);
|
insert.setEditor(loginUserInfo.getId());
|
insert.setEditDate(now);
|
insert.setIsdeleted(Constants.ZERO);
|
insert.setRemark(memberCoupon.getRemark());
|
insert.setMemberId(loginUserInfo.getMemberId());
|
insert.setShopId(coupon.getShopId());
|
insert.setType(coupon.getType());
|
insert.setLimitPrice(coupon.getLimitPrice());
|
insert.setPrice(coupon.getPrice());
|
insert.setStartDate(now);
|
//推迟天数
|
LocalDateTime localDateTime = LocalDateTime.now().minusDays(coupon.getValidDays());
|
insert.setEndDate(DateUtil.toDate(localDateTime));
|
insert.setGetMethod(Constants.ONE);
|
insert.setIntegral(coupon.getIntegral());
|
insert.setStatus(Constants.ZERO);
|
insert.setInfo(coupon.getInfo());
|
// insert.setBackIntegral(coupon.getB);
|
insert.setName(coupon.getName());
|
insert.setCouponId(coupon.getId());
|
memberCouponMapper.insert(insert);
|
return memberCoupon.getId();
|
}
|
|
@Override
|
public void deleteById(Integer id) {
|
memberCouponMapper.deleteById(id);
|
}
|
|
@Override
|
public void delete(MemberCoupon memberCoupon) {
|
UpdateWrapper<MemberCoupon> deleteWrapper = new UpdateWrapper<>(memberCoupon);
|
memberCouponMapper.delete(deleteWrapper);
|
}
|
|
@Override
|
public void deleteByIdInBatch(List<Integer> ids) {
|
if (CollectionUtils.isEmpty(ids)) {
|
return;
|
}
|
memberCouponMapper.deleteBatchIds(ids);
|
}
|
|
@Override
|
public void updateById(MemberCoupon memberCoupon) {
|
memberCouponMapper.updateById(memberCoupon);
|
}
|
|
@Override
|
public void updateByIdInBatch(List<MemberCoupon> memberCoupons) {
|
if (CollectionUtils.isEmpty(memberCoupons)) {
|
return;
|
}
|
for (MemberCoupon memberCoupon: memberCoupons) {
|
this.updateById(memberCoupon);
|
}
|
}
|
|
@Override
|
public MemberCoupon findById(Integer id) {
|
return memberCouponMapper.selectById(id);
|
}
|
|
@Override
|
public MemberCoupon findOne(MemberCoupon memberCoupon) {
|
QueryWrapper<MemberCoupon> wrapper = new QueryWrapper<>(memberCoupon);
|
return memberCouponMapper.selectOne(wrapper);
|
}
|
|
@Override
|
public List<MemberCoupon> findList(MemberCoupon memberCoupon) {
|
QueryWrapper<MemberCoupon> wrapper = new QueryWrapper<>(memberCoupon);
|
return memberCouponMapper.selectList(wrapper);
|
}
|
|
@Override
|
public PageData<MemberCoupon> findPage(PageWrap<MemberCoupon> pageWrap) {
|
IPage<MemberCoupon> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
|
MPJLambdaWrapper<MemberCoupon> queryWrapper = new MPJLambdaWrapper<>();
|
Utils.MP.blankToNull(pageWrap.getModel());
|
|
queryWrapper.selectAll(MemberCoupon.class);
|
queryWrapper.selectAs(Member::getNickname,MemberCoupon::getNikeName);
|
|
queryWrapper.leftJoin(Member.class,Member::getId,MemberCoupon::getMemberId);
|
|
queryWrapper.eq(MemberCoupon::getIsdeleted, Constants.ZERO);
|
queryWrapper.eq(pageWrap.getModel().getStatus()!=null,MemberCoupon::getStatus, pageWrap.getModel().getStatus());
|
queryWrapper.eq(pageWrap.getModel().getGetMethod()!=null,MemberCoupon::getGetMethod, pageWrap.getModel().getGetMethod());
|
queryWrapper.and(StringUtils.isNotBlank(pageWrap.getModel().getNikeName()),ms -> ms.like( Member::getNickname, pageWrap.getModel().getNikeName()).
|
or().eq( Member::getName, pageWrap.getModel().getNikeName()).
|
or().eq( Member::getPhone, pageWrap.getModel().getNikeName()));
|
queryWrapper.orderByDesc(MemberCoupon::getCreateDate);
|
IPage<MemberCoupon> result = memberCouponJoinMapper.selectJoinPage(page, MemberCoupon.class, queryWrapper);
|
return PageData.from(result);
|
}
|
|
@Override
|
public long count(MemberCoupon memberCoupon) {
|
QueryWrapper<MemberCoupon> wrapper = new QueryWrapper<>(memberCoupon);
|
return memberCouponMapper.selectCount(wrapper);
|
}
|
|
/****************************************移动端接口开始********************************************************************/
|
|
|
/**
|
* 优惠券列表
|
* @param pages
|
* @param price
|
* @param memberId
|
* @param couponType
|
* @return
|
*/
|
@Override
|
public IPage<CouponDTO> memberCouponPage(IPage pages, BigDecimal price, Integer memberId,Integer couponType) {
|
IPage<CouponDTO> page = memberCouponMapper.memberCouponPage(pages,new QueryWrapper<CouponDTO>()
|
.eq("m.MEMBER_ID",memberId)
|
.eq("m.TYPE",Constants.ONE)
|
.eq("m.STATUS",Constants.ZERO)
|
.eq("TYPE",couponType)
|
.apply(!Objects.isNull(price)," m.LIMIT_PRICE >= "+price+" ")
|
.apply(" now() between m.START_DATE and m.END_DATE ")
|
.orderByDesc(" m.PRICE ")
|
);
|
return page;
|
}
|
|
|
|
|
|
/**
|
* 优惠券数量
|
* @param price
|
* @param memberId
|
* @param couponType
|
* @return
|
*/
|
@Override
|
public long memberCouponNum( BigDecimal price, Integer memberId,Integer couponType) {
|
long count = memberCouponMapper.selectCount(new QueryWrapper<MemberCoupon>()
|
.eq("MEMBER_ID",memberId)
|
.eq("STATUS",Constants.ZERO)
|
.eq("TYPE",couponType)
|
.apply("LIMIT_PRICE >= "+price+" ")
|
.apply(" now() between START_DATE and END_DATE ")
|
.orderByDesc(" PRICE ")
|
);
|
return count;
|
}
|
|
@Override
|
public PageData<MemberCouponDTO> findMemberCouponDTO(PageWrap<MemberCouponDTO> pageWrap) {
|
IPage<MemberCoupon> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
|
MPJLambdaWrapper<MemberCoupon> queryWrapper = new MPJLambdaWrapper<>();
|
Utils.MP.blankToNull(pageWrap.getModel());
|
queryWrapper.selectAs(MemberCoupon::getId,MemberCouponDTO::getId);
|
queryWrapper.selectAs(Member::getId,MemberCouponDTO::getMemberId);
|
queryWrapper.selectAs(Member::getImgurl,MemberCouponDTO::getImgurl);
|
queryWrapper.selectAs(MemberCoupon::getShopId,MemberCouponDTO::getShopId);
|
queryWrapper.selectAs(MemberCoupon::getType,MemberCouponDTO::getType);
|
queryWrapper.selectAs(MemberCoupon::getLimitPrice,MemberCouponDTO::getLimitPrice);
|
queryWrapper.selectAs(MemberCoupon::getPrice,MemberCouponDTO::getPrice);
|
queryWrapper.selectAs(MemberCoupon::getStartDate,MemberCouponDTO::getStartDate);
|
queryWrapper.selectAs(MemberCoupon::getEndDate,MemberCouponDTO::getEndDate);
|
queryWrapper.selectAs(MemberCoupon::getUseDate,MemberCouponDTO::getUseDate);
|
queryWrapper.selectAs(MemberCoupon::getStatus,MemberCouponDTO::getStatus);
|
queryWrapper.leftJoin(MemberCoupon.class,MemberCoupon::getMemberId,Member::getId);
|
queryWrapper.eq(MemberCoupon::getCouponId,pageWrap.getModel().getCouponId())
|
.like(StringUtils.isNotBlank(pageWrap.getModel().getNikeName()),Member::getNickname,pageWrap.getModel().getNikeName())
|
.eq(MemberCoupon::getStatus,pageWrap.getModel().getStatus());
|
IPage<MemberCouponDTO> result = memberCouponJoinMapper.selectJoinPage(page, MemberCouponDTO.class, queryWrapper);
|
|
if (CollectionUtils.isEmpty(result.getRecords())){
|
return PageData.from(new Page<>());
|
}
|
result.getRecords().stream().filter(s->Constants.equalsInteger(Constants.ZERO,s.getStatus()))
|
.forEach(s->{
|
s.setStatus(s.getEndDate().before(new Date()) ? -1 : 0);
|
});
|
return PageData.from(result);
|
}
|
|
public void exchangeCoupon(Integer couponId, Integer memberId){
|
Coupon coupon = couponMapper.selectById(couponId);
|
if(Objects.isNull(coupon)){
|
throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "未查询到优惠券信息");
|
}
|
if(!coupon.getType().equals(Constants.ONE)){
|
throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "非平台优惠券,无法兑换!");
|
}
|
if(coupon.getStatus().equals(Constants.ONE)){
|
throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "该优惠券已禁用,无法兑换!");
|
}
|
//查询已兑换数量
|
QueryWrapper queryWrapper = new QueryWrapper<MemberCoupon>();
|
queryWrapper.eq("COUPON_ID",couponId);
|
Long exchangeNum = memberCouponMapper.selectCount(queryWrapper);
|
if(exchangeNum.compareTo(coupon.getNum())>=Constants.ZERO){
|
throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "该优惠券已兑换完,无法兑换!");
|
}
|
//是否已兑换
|
queryWrapper.eq("MEMBER_ID",memberId);
|
if(memberCouponMapper.selectCount(queryWrapper)>Constants.ZERO){
|
throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "已兑换该优惠券,无法兑换!");
|
};
|
//查询剩余咖豆是否足够购买
|
Member member = memberMapper.selectById(memberId);
|
if(member.getIntegral().compareTo(coupon.getIntegral())<Constants.ZERO){
|
throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "咖豆不足,无法兑换!");
|
}
|
MemberCoupon memberCoupon = new MemberCoupon();
|
memberCoupon.setCreator(memberId);
|
memberCoupon.setCreateDate(new Date());
|
memberCoupon.setIsdeleted(Constants.ZERO);
|
memberCoupon.setMemberId(memberId);
|
memberCoupon.setType(coupon.getType());
|
memberCoupon.setLimitPrice(coupon.getLimitPrice());
|
memberCoupon.setPrice(coupon.getPrice());
|
memberCoupon.setStartDate(new Date());
|
//推迟天数
|
LocalDateTime localDateTime = LocalDateTime.now().minusDays(coupon.getValidDays());
|
memberCoupon.setEndDate(DateUtil.toDate(localDateTime));
|
memberCoupon.setGetMethod(Constants.ONE);
|
memberCoupon.setIntegral(coupon.getIntegral());
|
memberCoupon.setStatus(Constants.ZERO);
|
memberCoupon.setInfo(coupon.getInfo());
|
memberCoupon.setCouponId(couponId);
|
memberCoupon.setBackIntegral(BigDecimal.ZERO);
|
memberCoupon.setName(coupon.getName());
|
memberCouponMapper.insert(memberCoupon);
|
//TODO 添加积分变动记录
|
|
//更新用户积分
|
memberMapper.subtractIntegral(memberId,memberCoupon.getIntegral());
|
}
|
|
|
/**
|
* 根据商品信息获取适用的优惠券
|
*/
|
@Override
|
public List<MemberCoupon> getApplyCoupon(List<PayDetailRequest> requestList,Integer memberId){
|
List<MemberCoupon> memberCouponList = new ArrayList<>();
|
List<GoodsSku> goodsSkuList = goodsSkuMapper.selectList(new QueryWrapper<GoodsSku>()
|
.lambda()
|
.eq(GoodsSku::getIsdeleted,Constants.ZERO)
|
.in(GoodsSku::getId,requestList.stream().map(i->i.getGoodsSkuId()).collect(Collectors.toList()))
|
);
|
if(CollectionUtils.isEmpty(goodsSkuList)||!Constants.equalsInteger(goodsSkuList.size(),requestList.size())){
|
throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"商品SKU信息错误,请刷新重试");
|
}
|
|
//查询商品列表
|
List<Goods> goodsList = goodsMapper.selectJoinList(Goods.class,
|
new MPJLambdaWrapper<Goods>()
|
.selectAs(GoodsSku::getPrice,Goods::getSkuPrice)
|
.selectAs(GoodsSku::getId,Goods::getSkuId)
|
.leftJoin(GoodsSku.class,GoodsSku::getGoodsId,Goods::getId)
|
.in(GoodsSku::getId,requestList.stream().map(i->i.getGoodsSkuId()).collect(Collectors.toList())));
|
|
if(Objects.isNull(goodsList)){
|
return memberCouponList;
|
}
|
|
//获取选择的商品总金额 与 单个商品金额
|
BigDecimal totalAmount = BigDecimal.ZERO;
|
for (Goods goods:goodsList) {
|
List<PayDetailRequest> request = requestList.stream().filter(i->Constants.equalsInteger(i.getGoodsSkuId(), goods.getSkuId())).collect(Collectors.toList());
|
if(CollectionUtils.isNotEmpty(request)){
|
goods.setSkuAmount(goods.getSkuPrice().multiply(new BigDecimal(request.get(Constants.ZERO).getGoodsNum()+"")));
|
totalAmount = totalAmount.add(goods.getSkuAmount());
|
}
|
}
|
List<OrderGoodsCalculateResponse> goodsCalculateList = ListUtil.copyProperties(goodsList,OrderGoodsCalculateResponse::new);
|
//获取所有满足金额且可用的优惠券
|
List<MemberCoupon> allCoupon = memberCouponMapper.selectList(new QueryWrapper<MemberCoupon>().lambda()
|
.eq(MemberCoupon::getIsdeleted,Constants.ZERO)
|
.eq(MemberCoupon::getStatus,Constants.ZERO)
|
.apply(" LIMIT_PRICE <= " + totalAmount)
|
.apply(" now() between START_DATE and END_DATE "));
|
|
if(CollectionUtils.isNotEmpty(allCoupon)){
|
for (MemberCoupon memberCoupon:allCoupon) {
|
//适用类型:0=全场;1=品类;2=指定商品
|
if(Constants.equalsInteger(memberCoupon.getApplyType(),Constants.ZERO)){
|
memberCoupon.setValidAmount(memberCoupon.getPrice());
|
}else{
|
List<String> applyIdList = Arrays.asList(memberCoupon.getApplyIds().split(","));
|
//获取有效可以使用优惠券的数据
|
isVaildUse(applyIdList,goodsCalculateList,
|
Constants.equalsInteger(memberCoupon.getApplyType(),Constants.ONE)?Constants.ONE:Constants.ZERO);
|
BigDecimal skuAmount = goodsCalculateList.stream().filter(i->i.getUseCoupon()).map(i->i.getSkuAmount()).reduce(BigDecimal.ZERO,BigDecimal::add);
|
if(skuAmount.compareTo(memberCoupon.getLimitPrice())>=Constants.ZERO){
|
//根据金额计算实际折扣金额
|
BigDecimal couponPrice = skuAmount.multiply(memberCoupon.getPrice()).divide(new BigDecimal("100"),2, RoundingMode.HALF_UP);
|
//折扣金额大于最大可折扣金额 则使用最大可折扣金额
|
memberCoupon.setValidAmount(couponPrice.compareTo(memberCoupon.getMaxPrice())>Constants.ZERO?memberCoupon.getMaxPrice():couponPrice);
|
memberCouponList.add(memberCoupon);
|
}
|
}
|
}
|
}
|
// 使用 Stream 排序 reversed() 表示倒序
|
memberCouponList = memberCouponList.stream().sorted(Comparator.comparing(MemberCoupon::getValidAmount,Comparator.nullsFirst(BigDecimal::compareTo)).reversed())
|
.collect(Collectors.toList());
|
return memberCouponList;
|
}
|
|
|
/**
|
* 计算当前已选择优惠券每个商品占比金额
|
* @param coupon 优惠券信息
|
* @param goodsCalculateList 商品集合
|
* @param totalAmount 订单总金额
|
*/
|
public void calculateCouponRata(MemberCoupon coupon,List<OrderGoodsCalculateResponse> goodsCalculateList,BigDecimal totalAmount){
|
//总余额
|
BigDecimal validAmount = coupon.getValidAmount();
|
//剩余可分配金额
|
BigDecimal surplusValidAmount = validAmount;
|
//已用占比比例值
|
BigDecimal rata = BigDecimal.ZERO;
|
//根据优惠券类型 计算可以使用优惠券的商品信息 适用类型:0=全场;1=品类;2=指定商品
|
if(!Constants.equalsInteger(coupon.getApplyType(),Constants.ZERO)){
|
List<String> applyIdList = Arrays.asList(coupon.getApplyIds().split(","));
|
isVaildUse(applyIdList,goodsCalculateList,
|
Constants.equalsInteger(coupon.getApplyType(),Constants.ONE)?Constants.ONE:Constants.ZERO);
|
}
|
//使用了优惠券的商品数量
|
Integer countCouponNum = goodsCalculateList.stream().filter(i->i.getUseCoupon()).collect(Collectors.toList()).size();
|
Integer useCouponNum = Constants.ZERO;
|
for (int i = 0; i < goodsCalculateList.size(); i++) {
|
if(!goodsCalculateList.get(i).getUseCoupon()){
|
goodsCalculateList.get(i).setCouponDeductCash(BigDecimal.ZERO);
|
continue;
|
}
|
if(Constants.equalsInteger(useCouponNum+1,countCouponNum)){
|
goodsCalculateList.get(i).setOrderCouponRata(new BigDecimal("1").subtract(rata));
|
goodsCalculateList.get(i).setCouponDeductCash(surplusValidAmount);
|
break;
|
}
|
goodsCalculateList.get(i).setOrderCouponRata(goodsCalculateList.get(i).getSkuAmount().divide(totalAmount,2,BigDecimal.ROUND_DOWN));
|
goodsCalculateList.get(i).setCouponDeductCash(validAmount.multiply(goodsCalculateList.get(i).getOrderCouponRata()));
|
surplusValidAmount = surplusValidAmount.subtract(goodsCalculateList.get(i).getCouponDeductCash());
|
rata = rata.add(goodsCalculateList.get(i).getOrderCouponRata());
|
useCouponNum = useCouponNum + 1;
|
}
|
}
|
|
|
|
|
|
/**
|
* 判断是否可以有效使用
|
* @param idList
|
* @param goodsList
|
* @param vaildType 0=商品;1=品类
|
* @return
|
*/
|
public void isVaildUse(List<String> idList,List<OrderGoodsCalculateResponse> goodsList,Integer vaildType){
|
for (OrderGoodsCalculateResponse response:goodsList) {
|
response.setUseCoupon(idList.contains(Constants.equalsInteger(vaildType,Constants.ZERO)?response.getId().toString():response.getCategoryId().toString())?true:false);
|
}
|
}
|
// public Set<Integer> isVaildUse(List<String> idList,List<OrderGoodsCalculateResponse> goodsList,Integer vaildType){
|
// List<OrderGoodsCalculateResponse> resultList = new ArrayList<>();
|
// for (String id:idList) {
|
// if(Constants.equalsInteger(vaildType,Constants.ZERO)){
|
// resultList.addAll(goodsList.stream().filter(i->i.getId().toString().equals(id)).collect(Collectors.toList()));
|
// }else{
|
// resultList.addAll(goodsList.stream().filter(i->i.getCategoryId().toString().equals(id)).collect(Collectors.toList()));
|
// }
|
// }
|
// if(CollectionUtils.isNotEmpty(resultList)){
|
// return new HashSet<>(resultList.stream().map(i->i.getId()).collect(Collectors.toList()));
|
// }
|
// return new HashSet<>();
|
// }
|
|
|
|
|
|
|
}
|