gongzuming
2024-09-19 abd5db316be6c8f6897a9cb0505459ef5cce7fe5
src/main/java/com/mzl/flower/service/impl/coupon/CouponTemplateServiceImpl2.java
@@ -10,14 +10,15 @@
import com.mzl.flower.constant.Constants;
import com.mzl.flower.dto.request.coupon.*;
import com.mzl.flower.dto.response.coupon.CouponPointStatisVO;
import com.mzl.flower.dto.response.coupon.CouponTemplateCustomerVO;
import com.mzl.flower.dto.response.coupon.CouponTemplateVO;
import com.mzl.flower.entity.coupon.CouponRecordDO;
import com.mzl.flower.entity.coupon.CouponTemplateCustomerDO;
import com.mzl.flower.entity.coupon.CouponTemplateDO;
import com.mzl.flower.entity.customer.Customer;
import com.mzl.flower.entity.menber.Member;
import com.mzl.flower.entity.point.CustomerPoint;
import com.mzl.flower.entity.point.CustomerPointDetail;
import com.mzl.flower.entity.point.PointGoodsRecord;
import com.mzl.flower.enums.*;
import com.mzl.flower.mapper.coupon.CouponTemplateMapper;
import com.mzl.flower.mapper.coupon.CouponTemplateMapperCustom;
@@ -27,8 +28,8 @@
import com.mzl.flower.service.coupon.CouponRecordService;
import com.mzl.flower.service.coupon.CouponTemplateCustomerService;
import com.mzl.flower.service.coupon.CouponTemplateService2;
import com.mzl.flower.service.payment.OrderService;
import com.mzl.flower.utils.UUIDGenerator;
import com.mzl.flower.service.menber.MemberService;
import com.mzl.flower.service.payment.RedisLockService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
@@ -38,7 +39,9 @@
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
@@ -73,6 +76,14 @@
    @Autowired
    private CustomerPointDetailMapper customerPointDetailMapper;
    @Autowired
    private MemberService memberService;
    @Autowired
    private RedisLockService lockService;
    @Transactional
    @Override
    public boolean createCouponTemplate(CreateCouponTemplateBO dto) {
@@ -92,6 +103,8 @@
            final List<CouponTemplateCustomerDO> couponCustomList = dto.getPointCostomIdList().stream().map(customId -> {
                CouponTemplateCustomerDO customReDO = new CouponTemplateCustomerDO();
                // 解决本地不加ID不报错,线上报错问题
                customReDO.setId(IdUtil.simpleUUID());
                customReDO.setCouponId(couponTemplateDO.getId());
                customReDO.setCustomId(customId);
                return customReDO;
@@ -124,6 +137,8 @@
            final List<CouponTemplateCustomerDO> couponCustomList = dto.getPointCostomIdList().stream().map(customId -> {
                CouponTemplateCustomerDO customReDO = new CouponTemplateCustomerDO();
                // 解决本地不加ID不报错,线上报错问题
                customReDO.setId(IdUtil.simpleUUID());
                customReDO.setCouponId(couponTemplateDO.getId());
                customReDO.setCustomId(customId);
                return customReDO;
@@ -144,13 +159,29 @@
    @Override
    public List<CouponTemplateVO> getList(QueryCouponDTO dto) {
        List<CouponTemplateVO> list = couponTemplateMapperCustom.getList(dto);
        List<CouponTemplateVO> list =new ArrayList<>();
        if(StringUtils.isNotBlank(dto.getCategory())
                && dto.getCategory().equals(CouponCategoryEnum.MEMBER.getStatus())
        ){
            // 会员优惠券
            list = couponTemplateMapperCustom.getVipList(dto);
        }else{
            list = couponTemplateMapperCustom.getList(dto);
        }
        return list;
    }
    @Override
    public Page<CouponTemplateVO> getPage(Page page, QueryCouponDTO dto) {
        List<CouponTemplateVO> result = couponTemplateMapperCustom.getCouponTemplatePage(page, dto);
        List<CouponTemplateVO> result =new ArrayList<>();
        if(StringUtils.isNotBlank(dto.getCategory())
                && dto.getCategory().equals(CouponCategoryEnum.MEMBER.getStatus())
        ){
            // 会员优惠券
            result = couponTemplateMapperCustom.getCouponTemplateVipPage(page, dto);
        }else{
            result = couponTemplateMapperCustom.getCouponTemplatePage(page, dto);
        }
        return page.setRecords(result);
    }
@@ -160,7 +191,25 @@
        dto.setId(id);
        final List<CouponTemplateVO> list = getList(dto);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
            CouponTemplateVO vo =list.get(0);
            // 用户获取
            if(StringUtils.isNotBlank(vo.getCategory())
                  &&  vo.getCategory().equals(CouponCategoryEnum.USER.getStatus())){
                List<CouponTemplateCustomerVO> customerList= couponTemplateMapperCustom.getCouponCustomerList(id);
                vo.setCustomerList(customerList);
            }
            // 会员等级
            if(StringUtils.isNotBlank(vo.getCategory()) && null!=vo.getMemberId()
                    &&  vo.getCategory().equals(CouponCategoryEnum.MEMBER.getStatus())){
                final Member member = memberService.getById(vo.getMemberId());
                if(null!=member){
                    vo.setMember(member);
                    vo.setMemberName(member.getName());
                }
            }
            return vo;
        }
        return null;
    }
@@ -181,7 +230,7 @@
        // 判断当前的优惠券的用户类型是指定用户还是全部用户,如果是指定用户的情况下需要发布优惠券
        if (StringUtils.isNotBlank(couponTemplateDO.getGetUserType())
                && StringUtils.isNotBlank(couponTemplateDO.getCategory())
                && couponTemplateDO.getGetUserType().equals(CouponGetUserTypeEnum.POINT.getType())
                && couponTemplateDO.getGetUserType().equals(CouponGetUserTypeEnum.TARGET.getType())
                && couponTemplateDO.getCategory().equals(CouponCategoryEnum.USER.getStatus())
        ) {
@@ -192,7 +241,7 @@
                // 根据发放后有效期来设置时间
                if (couponTemplateDO.getUsageTimeNum() == null || couponTemplateDO.getUsageTimeNum() <= 0) {
                    throw new IllegalArgumentException("使用时间数量必须为正整数");
                    throw new ValidationException("使用时间数量必须为正整数");
                }
                LocalDateTime currentTime = LocalDateTime.now();
                couponTemplateDO.setUsageStartDate(currentTime);
@@ -215,6 +264,8 @@
                List<CouponRecordDO> couponUsageDOList = couponTemplateCustomerDOList.stream().map(pointCustomRe -> {
                    CouponRecordDO couponRecordDO = new CouponRecordDO();
                    couponRecordDO.setId(IdUtil.simpleUUID());
                    couponRecordDO.setCouponId(pointCustomRe.getCouponId());
                    couponRecordDO.setCustomerId(pointCustomRe.getCustomId());
                    final Customer customer = customerMapper.selectById(pointCustomRe.getCustomId());
@@ -233,24 +284,41 @@
                    couponRecordDO.setCouponCode(couponTemplateDO.getCouponCode());
                    couponRecordDO.setCouponName(couponTemplateDO.getCouponName());
                    //  优惠券种类
                    couponRecordDO.setCategory(couponTemplateDO.getGetUserType());
                    couponRecordDO.setCategory(couponTemplateDO.getCategory());
                    couponRecordDO.setMinOrderAmount(couponTemplateDO.getMinOrderAmount());
                    couponRecordDO.setCouponDiscountValue(couponTemplateDO.getCouponDiscountValue());
                    couponRecordDO.setGetType(couponTemplateDO.getGetType());
                    couponRecordDO.setCouponDiscountType(couponTemplateDO.getCouponDiscountType());
                    couponRecordDO.setGetUserType(couponTemplateDO.getGetUserType());
                    couponRecordDO.setPoint(couponTemplateDO.getPoint());
                    couponRecordDO.setMemberId(couponTemplateDO.getMemberId());
                    couponRecordDO.setImageUrl(couponTemplateDO.getImageUrl());
                    // 创建相关信息
                    couponRecordDO.create(SecurityUtils.getUserId());
                    return couponRecordDO;
                }).collect(Collectors.toList());
                    // 查看当前优惠券是不是已经存在,存在的话则不能添加,防止同一人员重复下发同一张指定的优惠券
                    if(!couponRecordService.checkUserCouponExists(pointCustomRe.getCouponId(),pointCustomRe.getCustomId())){
                        return couponRecordDO;
                    }else{
                        return null;
                    }
                }).filter(Objects::nonNull).collect(Collectors.toList());
                // 批量保存优惠券信息
                couponRecordService.saveBatch(couponUsageDOList);
            }
        }
        // 如果是活动优惠券且领取渠道是Home类型的,那么只能设置当前优惠券为激活状态,其他优惠券是激活状态的设置为下架状态
        if (StringUtils.isNotBlank(couponTemplateDO.getCategory())  && couponTemplateDO.getCategory().equals(CouponCategoryEnum.ACTIVITY.getStatus())
                && StringUtils.isNotBlank(couponTemplateDO.getGetType()) && couponTemplateDO.getGetType().equals(CouponGetTypeEnum.HOME.getType())
        ) {
            couponTemplateMapperCustom.expireHomeActivityCouponTemplate();
        }
        return baseMapper.updateById(couponTemplateDO) > 0;
    }
@@ -340,46 +408,87 @@
    }
    @Override
    public synchronized void exchangeCoupon(ExchangeCouponDTO dto) {
        dto.setNum(1);
    public  void exchangeCoupon(ExchangeCouponDTO dto) {
        final CouponTemplateDO couponTemplateDO = couponTemplateService.getById(dto.getCouponId());
        if(couponTemplateDO==null){
            throw new ValidationException("优惠券不存在");
        String key="EXCHANGE_COUPON:"+dto.getCouponId()+":"+SecurityUtils.getUserId();
        boolean lock = lockService.getObjectLock(key, "");
        if(!lock){
            throw new ValidationException("系统操作频繁,请稍后重试");
        }
        try {
            dto.setNum(1);
            final CouponTemplateDO couponTemplateDO = couponTemplateService.getById(dto.getCouponId());
            if(couponTemplateDO==null){
                throw new ValidationException("优惠券不存在");
            }
            if(couponTemplateDO.getCouponAmount()<=0 ){
               throw new ValidationException("优惠券已兑换完");
            }
            CustomerPoint cp = customerPointMapper.selectOne(new LambdaQueryWrapper<CustomerPoint>()
                    .eq(CustomerPoint::getUserId, SecurityUtils.getUserId()));
            if(cp == null || (cp.getTotalPoint()-cp.getUsedPoint()-cp.getExpiredPoint()- cp.getExpiredPoint()) < couponTemplateDO.getPoint() * dto.getNum()){
                throw new ValidationException("积分不足");
            }
            CreateCouponRecordDTO recordDTO =new CreateCouponRecordDTO();
            recordDTO.setCouponId(dto.getCouponId());
            recordDTO.setUserId(SecurityUtils.getUserId());
            Customer customer = customerMapper.selectOne(new LambdaQueryWrapper<Customer>()
                    .eq(Customer::getUserId, SecurityUtils.getUserId()));
            if(customer == null){
                throw new ValidationException("商户不存在");
            }
            recordDTO.setCustomerId(customer.getId());
            couponRecordService.createCouponRecord(recordDTO);
//            //更新优惠券数量
//            couponTemplateDO.setCouponAmount(couponTemplateDO.getCouponAmount()-dto.getNum());
//            couponTemplateService.updateById(couponTemplateDO);
            //更新积分汇总
            cp.setUsedPoint(cp.getUsedPoint()+couponTemplateDO.getPoint());
            customerPointMapper.updateById(cp);
            //记录积分明细
            CustomerPointDetail detail = new CustomerPointDetail();
            detail.setUserId(customer.getUserId());
            detail.setCustomerId(customer.getId());
            detail.setPoint(couponTemplateDO.getPoint());
            detail.setChangeType(Constants.POINT_CHANGE_TYPE.reduce.name());
            detail.setType(Constants.POINT_TYPE.exchange.name());
            detail.setRecordDate(LocalDate.now());
            detail.setRemarks(couponTemplateDO.getCouponName());
            detail.create(SecurityUtils.getUserId());
            customerPointDetailMapper.insert(detail);
        }catch (Exception e){
            log.error("兑换失败",e);
            throw new ValidationException("兑换失败");
        }finally {
            lockService.releaseObjectLock(key,"");
        }
        CustomerPoint cp = customerPointMapper.selectOne(new LambdaQueryWrapper<CustomerPoint>()
                .eq(CustomerPoint::getUserId, SecurityUtils.getUserId()));
        if(cp == null || (cp.getTotalPoint()-cp.getUsedPoint()-cp.getExpiredPoint()) < couponTemplateDO.getPoint() * dto.getNum()){
            throw new ValidationException("积分不足");
    }
    @Override
    public CouponTemplateVO getHomeActivityEffectAlert(QueryActivityEffectCouponDTO dto) {
        // 存在用户是空的情况
        final CouponTemplateVO homeActivityEffectAlert = couponTemplateMapperCustom.getHomeActivityEffectAlert(dto);
        if(null!=homeActivityEffectAlert ){
            if(StringUtils.isNotBlank(SecurityUtils.getUserId()) ){
                // 查看当前已经领取了几张
                final Integer getCnt = couponRecordService.getUserGainCouponRecordAmountByUserId(homeActivityEffectAlert.getId(), SecurityUtils.getUserId());
                // 如果当前领取的数量小于限制领取的数量的时候,可以再次领取
                if(null!=homeActivityEffectAlert.getGetLimit() && null!=getCnt
                        && homeActivityEffectAlert.getGetLimit().compareTo(getCnt)>0){
                    return homeActivityEffectAlert;
                }
            }else{
                return homeActivityEffectAlert;
            }
        }
        CreateCouponRecordDTO recordDTO =new CreateCouponRecordDTO();
        recordDTO.setCouponId(dto.getCouponId());
        recordDTO.setUserId(SecurityUtils.getUserId());
        Customer customer = customerMapper.selectOne(new LambdaQueryWrapper<Customer>()
                .eq(Customer::getUserId, SecurityUtils.getUserId()));
        if(customer == null){
            throw new ValidationException("商户不存在");
        }
        recordDTO.setCustomerId(customer.getId());
        couponRecordService.createCouponRecord(recordDTO);
        //更新积分汇总
        cp.setUsedPoint(cp.getUsedPoint()+couponTemplateDO.getPoint());
        customerPointMapper.updateById(cp);
        //记录积分明细
        CustomerPointDetail detail = new CustomerPointDetail();
        detail.setUserId(customer.getUserId());
        detail.setCustomerId(customer.getId());
        detail.setPoint(couponTemplateDO.getPoint());
        detail.setChangeType(Constants.POINT_CHANGE_TYPE.reduce.name());
        detail.setType(Constants.POINT_TYPE.exchange.name());
        detail.setRecordDate(LocalDate.now());
        detail.setRemarks(couponTemplateDO.getCouponName());
        detail.create(SecurityUtils.getUserId());
        customerPointDetailMapper.insert(detail);
        return null;
    }
    @Override