package com.mzl.flower.service.impl.coupon; import cn.hutool.core.util.IdUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.mzl.flower.config.exception.ValidationException; import com.mzl.flower.config.security.SecurityUtils; 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.enums.*; import com.mzl.flower.mapper.coupon.CouponTemplateMapper; import com.mzl.flower.mapper.coupon.CouponTemplateMapperCustom; import com.mzl.flower.mapper.customer.CustomerMapper; import com.mzl.flower.mapper.point.CustomerPointDetailMapper; import com.mzl.flower.mapper.point.CustomerPointMapper; 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.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; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; 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; /** *

* 服务实现类 *

* * @author @TaoJie * @since 2024-08-22 */ @Service public class CouponTemplateServiceImpl2 extends ServiceImpl implements CouponTemplateService2 { @Autowired private CouponTemplateMapperCustom couponTemplateMapperCustom; @Autowired private CouponTemplateCustomerService pointCustomReService; @Autowired private CouponRecordService couponRecordService; @Autowired private CustomerMapper customerMapper; @Autowired private CustomerPointMapper customerPointMapper; @Autowired private CouponTemplateService2 couponTemplateService; @Autowired private CustomerPointDetailMapper customerPointDetailMapper; @Autowired private MemberService memberService; @Autowired private RedisLockService lockService; @Transactional @Override public boolean createCouponTemplate(CreateCouponTemplateBO dto) { CouponTemplateDO couponTemplateDO = new CouponTemplateDO(); BeanUtils.copyProperties(dto, couponTemplateDO); // 设置id,关联使用到的id couponTemplateDO.setId(IdUtil.simpleUUID()); couponTemplateDO.create(SecurityUtils.getUserId()); if (StringUtils.isBlank(dto.getStatus())) { // 优惠券状态 初始化为未激活状态 couponTemplateDO.setStatus(CouponStatusEnum.INACTIVE.getStatus()); } // 指定会员:需要添加制定用户的关联信息 if (CollectionUtils.isNotEmpty(dto.getPointCostomIdList())) { final List couponCustomList = dto.getPointCostomIdList().stream().map(customId -> { CouponTemplateCustomerDO customReDO = new CouponTemplateCustomerDO(); // 解决本地不加ID不报错,线上报错问题 customReDO.setId(IdUtil.simpleUUID()); customReDO.setCouponId(couponTemplateDO.getId()); customReDO.setCustomId(customId); return customReDO; }).collect(Collectors.toList()); // 批量插入 优惠券与指定用户关联关系 pointCustomReService.saveBatch(couponCustomList); // 设置优惠券的数量 couponTemplateDO.setCouponAmount(dto.getPointCostomIdList().size()); } return baseMapper.insert(couponTemplateDO) > 0; } @Transactional @Override public boolean updateCouponTemplate(CreateCouponTemplateBO dto) { CouponTemplateDO couponTemplateDO = baseMapper.selectById(dto.getId()); BeanUtils.copyProperties(dto, couponTemplateDO); couponTemplateDO.update(SecurityUtils.getUserId()); if (CollectionUtils.isNotEmpty(dto.getPointCostomIdList())) { // 根据优惠券的信息删除关联信息 pointCustomReService.deleteByCouponTemplateId(couponTemplateDO.getId()); } // 指定会员:需要添加制定用户的关联信息 if (CollectionUtils.isNotEmpty(dto.getPointCostomIdList())) { final List couponCustomList = dto.getPointCostomIdList().stream().map(customId -> { CouponTemplateCustomerDO customReDO = new CouponTemplateCustomerDO(); // 解决本地不加ID不报错,线上报错问题 customReDO.setId(IdUtil.simpleUUID()); customReDO.setCouponId(couponTemplateDO.getId()); customReDO.setCustomId(customId); return customReDO; }).collect(Collectors.toList()); // 批量插入 优惠券与指定用户关联关系 pointCustomReService.saveBatch(couponCustomList); // 设置优惠券总数当前人数 couponTemplateDO.setCouponAmount(couponCustomList.size()); } return baseMapper.updateById(couponTemplateDO) > 0; } @Override public List getList(QueryCouponDTO dto) { List 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 getPage(Page page, QueryCouponDTO dto) { List 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); } @Override public CouponTemplateVO getDetailById(String id) { QueryCouponDTO dto = new QueryCouponDTO(); dto.setId(id); final List list = getList(dto); if (CollectionUtils.isNotEmpty(list)) { CouponTemplateVO vo =list.get(0); // 用户获取 if(StringUtils.isNotBlank(vo.getCategory()) && vo.getCategory().equals(CouponCategoryEnum.USER.getStatus())){ List 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; } @Transactional @Override public boolean deleteCouponTemplate(String id) { return baseMapper.deleteById(id) > 0; } @Transactional @Override public boolean activeCouponTemplate(String id) { CouponTemplateDO couponTemplateDO = baseMapper.selectById(id); couponTemplateDO.setStatus(CouponStatusEnum.ACTIVE.getStatus()); // 判断当前的优惠券的用户类型是指定用户还是全部用户,如果是指定用户的情况下需要发布优惠券 if (StringUtils.isNotBlank(couponTemplateDO.getGetUserType()) && StringUtils.isNotBlank(couponTemplateDO.getCategory()) && couponTemplateDO.getGetUserType().equals(CouponGetUserTypeEnum.TARGET.getType()) && couponTemplateDO.getCategory().equals(CouponCategoryEnum.USER.getStatus()) ) { // 获取当前优惠券下的指定人员信息 List couponTemplateCustomerDOList = pointCustomReService.getPointCustomReList(id); if (CollectionUtils.isNotEmpty(couponTemplateCustomerDOList)) { // 根据发放后有效期来设置时间 if (couponTemplateDO.getUsageTimeNum() == null || couponTemplateDO.getUsageTimeNum() <= 0) { throw new ValidationException("使用时间数量必须为正整数"); } LocalDateTime currentTime = LocalDateTime.now(); couponTemplateDO.setUsageStartDate(currentTime); if (couponTemplateDO.getUsageTimeType().equals(CouponUsageTimeTypeEnum.DAY.getType())) { // 天 couponTemplateDO.setUsageEndDate(currentTime.plusDays(couponTemplateDO.getUsageTimeNum())); } if (couponTemplateDO.getUsageTimeType().equals(CouponUsageTimeTypeEnum.HOUR.getType())) { // 小时 couponTemplateDO.setUsageEndDate(currentTime.plusHours(couponTemplateDO.getUsageTimeNum())); } if (couponTemplateDO.getUsageTimeType().equals(CouponUsageTimeTypeEnum.MINUTE.getType())) { // 分钟 couponTemplateDO.setUsageEndDate(currentTime.plusMinutes(couponTemplateDO.getUsageTimeNum())); } // 优惠券的总数等于下发人员的总数 couponTemplateDO.setCouponAmount(couponTemplateCustomerDOList.size()); List 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()); if (null != customer && StringUtils.isNotBlank(customer.getUserId())) { // 设置所属用户id couponRecordDO.setUserId(customer.getUserId()); } couponRecordDO.setStatus(CouponUsedStatusEnum.UNUSED.getType()); // 设置优惠券的使用开始时间 couponRecordDO.setEffectiveStart(couponTemplateDO.getUsageStartDate()); // 设置优惠券的使用结束时间 couponRecordDO.setEffectiveEnd(couponTemplateDO.getUsageEndDate()); // 优惠券的冗余字段 couponRecordDO.setCouponCode(couponTemplateDO.getCouponCode()); couponRecordDO.setCouponName(couponTemplateDO.getCouponName()); // 优惠券种类 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()); // 查看当前优惠券是不是已经存在,存在的话则不能添加,防止同一人员重复下发同一张指定的优惠券 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; } @Transactional @Override public boolean expireCouponTemplate(String id) { CouponTemplateDO couponTemplateDO = baseMapper.selectById(id); couponTemplateDO.setStatus(CouponStatusEnum.EXPIRED.getStatus()); return baseMapper.updateById(couponTemplateDO) > 0; } /** * 获取所有会员优惠券模版 * * @return */ @Transactional @Override public List getVipCouponTemplate() { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.lambda() .eq(CouponTemplateDO::getDeleted, TrueOrFalseEnum.FALSE.isFlag()) .eq(CouponTemplateDO::getCategory, CouponCategoryEnum.MEMBER.getStatus()) .eq(CouponTemplateDO::getStatus, CouponStatusEnum.ACTIVE.getStatus()); return baseMapper.selectList(queryWrapper); } @Transactional @Override public boolean deleteBatchCouponTemplate(BatchCouponTemplateDTO dto) { if (CollectionUtils.isNotEmpty(dto.getIdList())) { dto.setUpdateBy(SecurityUtils.getUserId()); return couponTemplateMapperCustom.deleteBatchCouponTemplate(dto) > 0; } return false; } @Transactional @Override public boolean activeBatchCouponTemplate(BatchCouponTemplateDTO dto) { if (CollectionUtils.isNotEmpty(dto.getIdList())) { dto.setUpdateBy(SecurityUtils.getUserId()); return couponTemplateMapperCustom.activeBatchCouponTemplate(dto) > 0; } return false; } @Transactional @Override public boolean expireBatchCouponTemplate(BatchCouponTemplateDTO dto) { if (CollectionUtils.isNotEmpty(dto.getIdList())) { dto.setUpdateBy(SecurityUtils.getUserId()); return couponTemplateMapperCustom.expireBatchCouponTemplate(dto) > 0; } return false; } @Override public CouponPointStatisVO statisCouponTemplatePoint(QueryCouponStatisticsBO queryCouponStatisticsBO) { CouponPointStatisVO vo=new CouponPointStatisVO(); //优惠券总数 vo.setTotalAmount(couponRecordService.statisCouponTemplateCount(queryCouponStatisticsBO)); // 本月兑换优惠券总数 vo.setCurMonExchangeAmount(couponRecordService.statisCouponTemplateCurMonCount(queryCouponStatisticsBO)); // 本月兑换积分总数 vo.setCurMonExchangePointAmount(couponRecordService.statisCouponPointCurMonPontAmonut(queryCouponStatisticsBO)); return vo; } @Override public List getPointList(QueryActivePointCouponDTO dto) { if(StringUtils.isBlank(dto.getOrderStr())){ dto.setOrderStr(" create_time desc "); } return couponTemplateMapperCustom.getCouponPointList(dto); } @Override public Page getPointPage(Page page, QueryActivePointCouponDTO dto) { if(StringUtils.isBlank(dto.getOrderStr())){ dto.setOrderStr(" create_time desc "); } return couponTemplateMapperCustom.getPointPage(page,dto); } @Override public void exchangeCoupon(ExchangeCouponDTO dto) { 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() .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() .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,""); } } @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; } } return null; } @Override public List getActivityEffectList(QueryActivityEffectCouponDTO dto) { return couponTemplateMapperCustom.getActivityEffectList(dto); } }