package cn.lili.modules.promotion.serviceimpl;
|
|
import cn.hutool.core.text.CharSequenceUtil;
|
import cn.lili.cache.Cache;
|
import cn.lili.common.enums.ResultCode;
|
import cn.lili.common.exception.ServiceException;
|
import cn.lili.common.security.AuthUser;
|
import cn.lili.common.security.context.UserContext;
|
import cn.lili.common.vo.PageVO;
|
import cn.lili.modules.promotion.entity.dos.Coupon;
|
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
|
import cn.lili.modules.promotion.entity.dto.search.MemberCouponSearchParams;
|
import cn.lili.modules.promotion.entity.enums.CouponGetEnum;
|
import cn.lili.modules.promotion.entity.enums.MemberCouponStatusEnum;
|
import cn.lili.modules.promotion.entity.enums.PromotionsScopeTypeEnum;
|
import cn.lili.modules.promotion.entity.enums.PromotionsStatusEnum;
|
import cn.lili.modules.promotion.entity.vos.MemberCouponVO;
|
import cn.lili.modules.promotion.mapper.MemberCouponMapper;
|
import cn.lili.modules.promotion.service.CouponService;
|
import cn.lili.modules.promotion.service.MemberCouponService;
|
import cn.lili.modules.promotion.tools.PromotionTools;
|
import cn.lili.mybatis.util.PageUtil;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.cache.annotation.CacheConfig;
|
import org.springframework.cache.annotation.CacheEvict;
|
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.util.*;
|
|
/**
|
* 会员优惠券业务层实现
|
*
|
* @author Chopper
|
* @since 2020/8/21
|
*/
|
@Service
|
@CacheConfig(cacheNames = "{MemberCoupon}")
|
public class MemberCouponServiceImpl extends ServiceImpl<MemberCouponMapper, MemberCoupon> implements MemberCouponService {
|
|
/**
|
* 优惠券
|
*/
|
@Autowired
|
private CouponService couponService;
|
|
/**
|
* 缓存
|
*/
|
@Autowired
|
private Cache cache;
|
|
@Override
|
public void checkCouponLimit(String couponId, String memberId) {
|
Coupon coupon = couponService.getById(couponId);
|
LambdaQueryWrapper<MemberCoupon> queryWrapper = new LambdaQueryWrapper<MemberCoupon>()
|
.eq(MemberCoupon::getCouponId, couponId)
|
.eq(MemberCoupon::getMemberId, memberId);
|
long haveCoupons = this.count(queryWrapper);
|
if (!PromotionsStatusEnum.START.name().equals(coupon.getPromotionStatus())) {
|
throw new ServiceException(ResultCode.COUPON_RECEIVE_ERROR);
|
}
|
if (coupon.getPublishNum() != 0 && coupon.getReceivedNum() >= coupon.getPublishNum()) {
|
throw new ServiceException(ResultCode.COUPON_NUM_INSUFFICIENT_ERROR);
|
}
|
if (!coupon.getCouponLimitNum().equals(0) && haveCoupons >= coupon.getCouponLimitNum()) {
|
throw new ServiceException(ResultCode.COUPON_LIMIT_ERROR, "此优惠券最多领取" + coupon.getCouponLimitNum() + "张");
|
}
|
}
|
|
/**
|
* 领取优惠券
|
*
|
* @param couponId 优惠券编号
|
* @param memberId 会员
|
* @param memberName 会员名称
|
*/
|
@Override
|
@CacheEvict(key = "#memberId")
|
@Transactional(rollbackFor = Exception.class)
|
public void receiveBuyerCoupon(String couponId, String memberId, String memberName) {
|
Coupon coupon = couponService.getById(couponId);
|
if (coupon != null && !CouponGetEnum.FREE.name().equals(coupon.getGetType())) {
|
throw new ServiceException(ResultCode.COUPON_DO_NOT_RECEIVER);
|
} else if (coupon != null) {
|
this.receiverCoupon(couponId, memberId, memberName, coupon);
|
}
|
|
}
|
|
@Override
|
@CacheEvict(key = "#memberId")
|
@Transactional(rollbackFor = Exception.class)
|
public void receiveCoupon(String couponId, String memberId, String memberName) {
|
Coupon coupon = couponService.getById(couponId);
|
if (coupon != null) {
|
this.receiverCoupon(couponId, memberId, memberName, coupon);
|
} else {
|
throw new ServiceException(ResultCode.COUPON_NOT_EXIST);
|
}
|
}
|
|
@Override
|
public IPage<MemberCoupon> getMemberCoupons(MemberCouponSearchParams param, PageVO pageVo) {
|
QueryWrapper<MemberCoupon> queryWrapper = param.queryWrapper();
|
Page<MemberCoupon> page = this.page(PageUtil.initPage(pageVo), queryWrapper);
|
if (page.getRecords() != null && page.getRecords().size() > 0) {
|
if (page.getRecords().stream().anyMatch(i -> i.getEndTime().before(new Date()))) {
|
this.expireInvalidMemberCoupon(param.getMemberId());
|
return this.page(PageUtil.initPage(pageVo), queryWrapper);
|
}
|
}
|
return page;
|
}
|
|
/**
|
* 获取会员优惠券列表
|
*
|
* @param param 查询参数
|
* @return 会员优惠券列表
|
*/
|
@Override
|
public List<MemberCoupon> getMemberCoupons(MemberCouponSearchParams param) {
|
List<MemberCoupon> list = this.list(param.queryWrapper());
|
if (list.stream().anyMatch(i -> i.getEndTime().before(new Date()))) {
|
this.expireInvalidMemberCoupon(param.getMemberId());
|
return this.list(param.queryWrapper());
|
}
|
return list;
|
}
|
|
/**
|
* 获取当前用户的优惠券列表(优先读取缓存)
|
*
|
* @param memberId 会员id
|
* @return 会员优惠券列表
|
*/
|
@Override
|
@Cacheable(key = "#memberId")
|
public List<MemberCoupon> getMemberCoupons(String memberId) {
|
MemberCouponSearchParams searchParams = new MemberCouponSearchParams();
|
searchParams.setMemberId(Objects.requireNonNull(UserContext.getCurrentUser()).getId());
|
searchParams.setMemberCouponStatus(MemberCouponStatusEnum.NEW.name());
|
searchParams.setPromotionStatus(PromotionsStatusEnum.START.name());
|
return this.getMemberCoupons(searchParams);
|
}
|
|
/**
|
* 获取会员优惠券列表
|
*
|
* @param param 查询参数
|
* @param pageVo 分页参数
|
* @return 会员优惠券列表
|
*/
|
@Override
|
public IPage<MemberCoupon> getMemberCouponsByCanUse(MemberCouponSearchParams param, Double totalPrice, PageVO pageVo) {
|
LambdaQueryWrapper<MemberCoupon> queryWrapper = new LambdaQueryWrapper<>();
|
List<String> storeIds = new ArrayList<>(Arrays.asList(param.getStoreId().split(",")));
|
storeIds.add(PromotionTools.PLATFORM_ID);
|
queryWrapper.in(MemberCoupon::getStoreId, storeIds);
|
queryWrapper.eq(MemberCoupon::getMemberId, param.getMemberId());
|
queryWrapper.and(
|
i -> i.like(MemberCoupon::getScopeId, param.getScopeId())
|
.or(j -> j.eq(MemberCoupon::getScopeType, PromotionsScopeTypeEnum.ALL.name())));
|
queryWrapper.eq(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.NEW.name());
|
queryWrapper.le(MemberCoupon::getConsumeThreshold, totalPrice);
|
queryWrapper.ge(MemberCoupon::getEndTime, new Date());
|
return this.page(PageUtil.initPage(pageVo), queryWrapper);
|
}
|
|
/**
|
* 获取当前会员当前商品可用的会员优惠券
|
*
|
* @param memberId 会员Id
|
* @param couponIds 优惠券id列表
|
* @return 会员优惠券列表
|
*/
|
@Override
|
public List<MemberCoupon> getCurrentGoodsCanUse(String memberId, List<String> couponIds, Double totalPrice) {
|
LambdaQueryWrapper<MemberCoupon> queryWrapper = new LambdaQueryWrapper<>();
|
queryWrapper.eq(MemberCoupon::getMemberId, memberId);
|
queryWrapper.eq(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.NEW.name());
|
queryWrapper.in(MemberCoupon::getCouponId, couponIds);
|
queryWrapper.ne(MemberCoupon::getScopeType, PromotionsScopeTypeEnum.ALL.name());
|
queryWrapper.le(MemberCoupon::getConsumeThreshold, totalPrice);
|
queryWrapper.ge(MemberCoupon::getEndTime, new Date());
|
return this.list(queryWrapper);
|
}
|
|
/**
|
* 获取当前会员全品类优惠券
|
*
|
* @param memberId 会员Id
|
* @param storeId 店铺id
|
* @return 会员优惠券列表
|
*/
|
@Override
|
public List<MemberCoupon> getAllScopeMemberCoupon(String memberId, List<String> storeId) {
|
LambdaQueryWrapper<MemberCoupon> queryWrapper = new LambdaQueryWrapper<>();
|
queryWrapper.eq(MemberCoupon::getMemberId, memberId);
|
queryWrapper.eq(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.NEW.name());
|
queryWrapper.eq(MemberCoupon::getScopeType, PromotionsScopeTypeEnum.ALL.name());
|
queryWrapper.ge(MemberCoupon::getEndTime, new Date()).and(i -> i.in(MemberCoupon::getStoreId, storeId).or(j -> j.eq(MemberCoupon::getPlatformFlag, true)));
|
return this.list(queryWrapper);
|
}
|
|
/**
|
* 获取当前会员全品类优惠券
|
*
|
* @param param 查询参数
|
* @return 会员优惠券列表
|
*/
|
@Override
|
public MemberCoupon getMemberCoupon(MemberCouponSearchParams param) {
|
return this.getOne(param.queryWrapper(), false);
|
}
|
|
@Override
|
public long getMemberCouponsNum() {
|
AuthUser authUser = Objects.requireNonNull(UserContext.getCurrentUser());
|
QueryWrapper<MemberCoupon> queryWrapper = Wrappers.query();
|
queryWrapper.eq("member_id", authUser.getId());
|
queryWrapper.eq("member_coupon_status", MemberCouponStatusEnum.NEW.name());
|
queryWrapper.eq("delete_flag", false);
|
return this.count(queryWrapper);
|
}
|
|
|
@Override
|
@CacheEvict(key = "#memberId")
|
@Transactional(rollbackFor = Exception.class)
|
public void used(String memberId, List<String> ids) {
|
if (ids != null && !ids.isEmpty()) {
|
List<MemberCoupon> memberCoupons = this.listByIds(ids);
|
|
//如果查出来的优惠券数量不一致
|
if (memberCoupons.size() != ids.size()) {
|
throw new ServiceException(ResultCode.COUPON_EXPIRED);
|
}
|
//循环处理
|
memberCoupons.forEach(item -> {
|
if (!item.getMemberCouponStatus().equals(MemberCouponStatusEnum.NEW.name())) {
|
throw new ServiceException(ResultCode.COUPON_EXPIRED);
|
}
|
item.setMemberCouponStatus(MemberCouponStatusEnum.USED.name());
|
item.setConsumptionTime(new Date());
|
});
|
|
this.updateBatchById(memberCoupons);
|
}
|
}
|
|
/**
|
* 作废当前会员优惠券
|
*
|
* @param id id
|
*/
|
@Override
|
@CacheEvict(key = "#memberId")
|
@Transactional(rollbackFor = Exception.class)
|
public void cancellation(String memberId, String id) {
|
LambdaUpdateWrapper<MemberCoupon> updateWrapper = new LambdaUpdateWrapper<>();
|
updateWrapper.eq(MemberCoupon::getId, id);
|
updateWrapper.set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.CLOSED.name());
|
this.update(updateWrapper);
|
}
|
|
/**
|
* 关闭会员优惠券
|
*
|
* @param couponIds 优惠券id集合
|
*/
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public void closeMemberCoupon(List<String> couponIds) {
|
LambdaUpdateWrapper<MemberCoupon> memberCouponLambdaUpdateWrapper = new LambdaUpdateWrapper<MemberCoupon>()
|
.in(MemberCoupon::getCouponId, couponIds)
|
.set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.CLOSED.name());
|
this.cache.vagueDel("{MemberCoupon}");
|
this.update(memberCouponLambdaUpdateWrapper);
|
}
|
|
@Override
|
public boolean recoveryMemberCoupon(List<String> memberCouponIds) {
|
LambdaUpdateWrapper<MemberCoupon> updateWrapper = new LambdaUpdateWrapper<>();
|
updateWrapper.in(MemberCoupon::getId, memberCouponIds);
|
updateWrapper.set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.NEW.name());
|
updateWrapper.set(MemberCoupon::getConsumptionTime, null);
|
return this.update(updateWrapper);
|
}
|
|
@Override
|
public void voidCoupon(String couponId) {
|
LambdaUpdateWrapper<MemberCoupon> updateWrapper = new LambdaUpdateWrapper<>();
|
updateWrapper.in(MemberCoupon::getCouponId, couponId);
|
updateWrapper.set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.CLOSED.name());
|
updateWrapper.set(MemberCoupon::getDeleteFlag, true);
|
this.update(updateWrapper);
|
}
|
|
@Override
|
public Page<MemberCouponVO> getMemberCouponsPage(Page<MemberCoupon> page, MemberCouponSearchParams param) {
|
QueryWrapper<MemberCouponVO> queryWrapper = new QueryWrapper<>();
|
queryWrapper.eq(CharSequenceUtil.isNotEmpty(param.getMemberId()), "mc.member_id", param.getMemberId());
|
queryWrapper.eq(CharSequenceUtil.isNotEmpty(param.getStoreId()), "c.store_id", param.getStoreId());
|
queryWrapper.like(CharSequenceUtil.isNotEmpty(param.getMemberName()), "mc.member_name", param.getMemberName());
|
queryWrapper.eq(CharSequenceUtil.isNotEmpty(param.getCouponId()), "mc.coupon_id", param.getCouponId());
|
queryWrapper.like(CharSequenceUtil.isNotEmpty(param.getCouponName()), "c.coupon_name", param.getCouponName());
|
queryWrapper.eq(CharSequenceUtil.isNotEmpty(param.getGetType()), "mc.get_type", param.getGetType());
|
queryWrapper.eq(CharSequenceUtil.isNotEmpty(param.getScopeType()), "mc.scope_type", param.getPromotionStatus());
|
queryWrapper.eq(CharSequenceUtil.isNotEmpty(param.getCouponType()), "mc.coupon_type", param.getCouponType());
|
queryWrapper.eq(CharSequenceUtil.isNotEmpty(param.getMemberCouponStatus()), "mc.member_coupon_status", param.getMemberCouponStatus());
|
if (param.getStartTime() != null) {
|
queryWrapper.ge("mc.start_time", new Date(param.getStartTime()));
|
}
|
if (param.getEndTime() != null) {
|
queryWrapper.le("mc.end_time", new Date(param.getEndTime()));
|
}
|
return this.baseMapper.getMemberCoupons(page, queryWrapper);
|
}
|
|
@Override
|
public long getMemberCouponNum(String memberId, String couponId) {
|
LambdaQueryWrapper<MemberCoupon> queryWrapper = new LambdaQueryWrapper<>();
|
queryWrapper.eq(MemberCoupon::getMemberId, memberId);
|
queryWrapper.eq(MemberCoupon::getCouponId, couponId);
|
return this.count(queryWrapper);
|
}
|
|
/**
|
* 清除无效的会员优惠券
|
*
|
* @return 是否操作成功
|
*/
|
@Override
|
@CacheEvict(key = "#memberId")
|
public boolean expireInvalidMemberCoupon(String memberId) {
|
//将过期优惠券变更为过期状体
|
LambdaUpdateWrapper<MemberCoupon> updateWrapper = new LambdaUpdateWrapper<MemberCoupon>()
|
.eq(CharSequenceUtil.isNotEmpty(memberId), MemberCoupon::getMemberId, memberId)
|
.eq(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.NEW.name())
|
.le(MemberCoupon::getEndTime, new Date())
|
.set(MemberCoupon::getMemberCouponStatus, MemberCouponStatusEnum.EXPIRE.name());
|
return this.update(updateWrapper);
|
}
|
|
private void receiverCoupon(String couponId, String memberId, String memberName, Coupon coupon) {
|
this.checkCouponLimit(couponId, memberId);
|
MemberCoupon memberCoupon = new MemberCoupon(coupon);
|
memberCoupon.setMemberId(memberId);
|
memberCoupon.setMemberName(memberName);
|
memberCoupon.setMemberCouponStatus(MemberCouponStatusEnum.NEW.name());
|
memberCoupon.setPlatformFlag((PromotionTools.PLATFORM_ID).equals(coupon.getStoreId()));
|
this.save(memberCoupon);
|
couponService.receiveCoupon(couponId, 1);
|
}
|
}
|