|  | @@ -1,44 +1,60 @@
 | 
	
		
			
				|  |  |  package com.yonge.cooleshow.biz.dal.service.impl;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import com.baomidou.mybatisplus.core.metadata.IPage;
 | 
	
		
			
				|  |  | +import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 | 
	
		
			
				|  |  |  import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 | 
	
		
			
				|  |  | +import com.google.common.collect.Maps;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.auth.api.entity.SysUser;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.dao.ActivityRewardChangeStockDao;
 | 
	
		
			
				|  |  | -import com.yonge.cooleshow.biz.dal.dto.ActivityPlanRewardDto;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.dao.ActivityRewardDao;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.dto.ActivityRewardDto;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.dto.UserParam;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.dto.search.ActivityRewardChangeStockSearch;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.dto.search.ActivityRewardSearch;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.entity.ActivityPlan;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.entity.ActivityPlanReward;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.entity.ActivityReward;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.entity.ActivityRewardChangeStock;
 | 
	
		
			
				|  |  | -import com.yonge.cooleshow.biz.dal.entity.*;
 | 
	
		
			
				|  |  | -import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 | 
	
		
			
				|  |  | -import com.yonge.cooleshow.biz.dal.enums.InOrOutEnum;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.entity.CouponInfo;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.entity.PianoRoomChangeRecord;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.enums.*;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.mapper.CouponInfoMapper;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.service.ActivityPlanRewardService;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.service.ActivityPlanService;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.service.ActivityRewardService;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.service.CouponIssueService;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.service.MemberPriceSettingsService;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.service.PianoRoomChangeRecordService;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.service.SysMessageService;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.biz.dal.vo.ActivityRewardChangeStockVo;
 | 
	
		
			
				|  |  | -import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
 | 
	
		
			
				|  |  | -import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
 | 
	
		
			
				|  |  | -import com.yonge.cooleshow.biz.dal.service.*;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.vo.ActivityRewardVo;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.common.enums.CacheNameEnum;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.common.enums.EStatus;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.common.enums.RewardTypeEnum;
 | 
	
		
			
				|  |  |  import com.yonge.cooleshow.common.enums.UnitEnum;
 | 
	
		
			
				|  |  |  import com.yonge.toolset.base.exception.BizException;
 | 
	
		
			
				|  |  | -import com.yonge.toolset.base.util.StringUtil;
 | 
	
		
			
				|  |  |  import com.yonge.toolset.payment.util.DistributedLock;
 | 
	
		
			
				|  |  |  import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
 | 
	
		
			
				|  |  |  import org.apache.commons.collections.CollectionUtils;
 | 
	
		
			
				|  |  |  import org.redisson.RedissonMultiLock;
 | 
	
		
			
				|  |  |  import org.redisson.api.RLock;
 | 
	
		
			
				|  |  |  import org.redisson.api.RedissonClient;
 | 
	
		
			
				|  |  | -import org.springframework.beans.factory.annotation.Autowired;
 | 
	
		
			
				|  |  | -import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  |  import org.slf4j.Logger;
 | 
	
		
			
				|  |  |  import org.slf4j.LoggerFactory;
 | 
	
		
			
				|  |  | -import com.yonge.cooleshow.biz.dal.vo.ActivityRewardVo;
 | 
	
		
			
				|  |  | -import com.yonge.cooleshow.biz.dal.dto.search.ActivityRewardSearch;
 | 
	
		
			
				|  |  | -import com.yonge.cooleshow.biz.dal.dao.ActivityRewardDao;
 | 
	
		
			
				|  |  | +import org.springframework.beans.factory.annotation.Autowired;
 | 
	
		
			
				|  |  | +import org.springframework.stereotype.Service;
 | 
	
		
			
				|  |  |  import org.springframework.transaction.annotation.Transactional;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import javax.annotation.Resource;
 | 
	
		
			
				|  |  | -import java.util.*;
 | 
	
		
			
				|  |  | +import java.util.ArrayList;
 | 
	
		
			
				|  |  | +import java.util.Collection;
 | 
	
		
			
				|  |  | +import java.util.Date;
 | 
	
		
			
				|  |  | +import java.util.HashMap;
 | 
	
		
			
				|  |  | +import java.util.List;
 | 
	
		
			
				|  |  | +import java.util.Map;
 | 
	
		
			
				|  |  | +import java.util.Optional;
 | 
	
		
			
				|  |  |  import java.util.stream.Collectors;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -62,13 +78,21 @@ public class ActivityRewardServiceImpl extends ServiceImpl<ActivityRewardDao, Ac
 | 
	
		
			
				|  |  |      @Autowired
 | 
	
		
			
				|  |  |      private PianoRoomChangeRecordService pianoRoomChangeRecordService;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private CouponInfoMapper couponInfoMapper;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Autowired
 | 
	
		
			
				|  |  |      private ActivityPlanRewardService activityPlanRewardService;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Autowired
 | 
	
		
			
				|  |  | +    private ActivityRewardService activityRewardService;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  |      private MemberPriceSettingsService memberPriceSettingsService;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private CouponIssueService couponIssueService;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public ActivityRewardVo detail(Long id) {
 | 
	
		
			
				|  |  |          return baseMapper.detail(id);
 | 
	
	
		
			
				|  | @@ -81,7 +105,43 @@ public class ActivityRewardServiceImpl extends ServiceImpl<ActivityRewardDao, Ac
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public IPage<ActivityRewardVo> selectPage(IPage<ActivityRewardVo> page, ActivityRewardSearch query) {
 | 
	
		
			
				|  |  | -        return page.setRecords(baseMapper.selectPage(page, query));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        List<ActivityRewardVo> rewardInfos = baseMapper.selectPage(page, query);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (CollectionUtils.isEmpty(rewardInfos)) {
 | 
	
		
			
				|  |  | +            // 直接返回请求结果
 | 
	
		
			
				|  |  | +            return page.setRecords(rewardInfos);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 优惠券奖品,查询优惠券名称
 | 
	
		
			
				|  |  | +        List<Long> couponIds = rewardInfos.stream()
 | 
	
		
			
				|  |  | +                .filter(x -> RewardTypeEnum.COUPON == x.getRewardType())
 | 
	
		
			
				|  |  | +                .map(ActivityReward::getCouponId)
 | 
	
		
			
				|  |  | +                .filter(x -> Optional.ofNullable(x).orElse(0L) > 0)
 | 
	
		
			
				|  |  | +                .distinct().collect(Collectors.toList());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 优惠券名称
 | 
	
		
			
				|  |  | +        Map<Long, String> couponNameMap = Maps.newHashMap();
 | 
	
		
			
				|  |  | +        if (CollectionUtils.isNotEmpty(couponIds)) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            couponNameMap = couponInfoMapper.selectBatchIds(couponIds).stream()
 | 
	
		
			
				|  |  | +                    .collect(Collectors.toMap(CouponInfo::getId, CouponInfo::getName, (o, n) -> n));
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 奖品关联活动统计
 | 
	
		
			
				|  |  | +        List<Long> rewardIds = rewardInfos.stream()
 | 
	
		
			
				|  |  | +                .map(ActivityReward::getId).distinct().collect(Collectors.toList());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Map<Long, Integer> collect = getBaseMapper().selectRewardActivityStatInfo(rewardIds).stream()
 | 
	
		
			
				|  |  | +                .collect(Collectors.toMap(StatGroupWrapper::getId, StatGroupWrapper::getTotal, (o, n) -> n));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        for (ActivityRewardVo item : rewardInfos) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            item.activityNum(collect.getOrDefault(item.getId(), 0))
 | 
	
		
			
				|  |  | +                    .setCouponName(couponNameMap.getOrDefault(item.getCouponId(), ""));
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return page.setRecords(rewardInfos);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
	
		
			
				|  | @@ -108,6 +168,13 @@ public class ActivityRewardServiceImpl extends ServiceImpl<ActivityRewardDao, Ac
 | 
	
		
			
				|  |  |              activityReward.setStock(null);
 | 
	
		
			
				|  |  |              activityReward.setUpdateBy(user.getId());
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +            // 校验奖品与活动是否存在关联
 | 
	
		
			
				|  |  | +            int count = activityPlanRewardService.count(Wrappers.<ActivityPlanReward>lambdaQuery()
 | 
	
		
			
				|  |  | +                    .eq(ActivityPlanReward::getRewardId, activityReward.getId()));
 | 
	
		
			
				|  |  | +            if (count > 0) {
 | 
	
		
			
				|  |  | +                throw new BizException("请先解除与活动奖品关联关系");
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |              baseMapper.updateById(activityReward);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          return true;
 | 
	
	
		
			
				|  | @@ -120,6 +187,18 @@ public class ActivityRewardServiceImpl extends ServiceImpl<ActivityRewardDao, Ac
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      public Boolean updateStatus(Long id, Integer status, Long userId) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (EStatus.ENABLE.match(status)) {
 | 
	
		
			
				|  |  | +            // 更新奖品状态为禁用时,需要判断是否已经关联活动;若存在关联数据,提示用户先解除绑定关系
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            int rewardNum = activityPlanRewardService.count(Wrappers.<ActivityPlanReward>lambdaQuery()
 | 
	
		
			
				|  |  | +                    .eq(ActivityPlanReward::getRewardId, id));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if (rewardNum > 0) {
 | 
	
		
			
				|  |  | +                throw new BizException("奖品已被活动关联");
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          ActivityReward activityReward = new ActivityReward();
 | 
	
		
			
				|  |  |          activityReward.setId(id);
 | 
	
		
			
				|  |  |          //更改活动状态
 | 
	
	
		
			
				|  | @@ -157,26 +236,29 @@ public class ActivityRewardServiceImpl extends ServiceImpl<ActivityRewardDao, Ac
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      @Override
 | 
	
		
			
				|  |  |      @Transactional(rollbackFor = Exception.class)
 | 
	
		
			
				|  |  | -    public List<Long> sendReward(Long userId, Long activityId) {
 | 
	
		
			
				|  |  | +    public List<Long> sendReward(Long userId, Long activityId,List<Long> rewardIdList) {
 | 
	
		
			
				|  |  |          if (userRewarded(userId, activityId)) {
 | 
	
		
			
				|  |  |              return new ArrayList<>();
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          ActivityPlan activityPlan = activityPlanService.getById(activityId);
 | 
	
		
			
				|  |  |          if (activityPlan == null) {
 | 
	
		
			
				|  |  |              log.warn("活动不存在");
 | 
	
		
			
				|  |  | -            return null;
 | 
	
		
			
				|  |  | +            return new ArrayList<>();
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (CollectionUtils.isEmpty(rewardIdList)) {
 | 
	
		
			
				|  |  | +            log.warn("奖品不存在");
 | 
	
		
			
				|  |  | +            return new ArrayList<>();
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        List<ActivityPlanRewardDto> activityPlanRewardDtos = activityPlanRewardService.queryActivityPlanReward(
 | 
	
		
			
				|  |  | -                activityId);
 | 
	
		
			
				|  |  | +        Collection<ActivityReward> activityRewards = activityRewardService.listByIds(rewardIdList);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        if (CollectionUtils.isEmpty(activityPlanRewardDtos)) {
 | 
	
		
			
				|  |  | +        if (CollectionUtils.isEmpty(activityRewards)) {
 | 
	
		
			
				|  |  |              return new ArrayList<>();
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          // 级联锁同时处理奖品库存
 | 
	
		
			
				|  |  |          List<RLock> lockList = new ArrayList<>();
 | 
	
		
			
				|  |  | -        for (ActivityPlanRewardDto activityReward : activityPlanRewardDtos) {
 | 
	
		
			
				|  |  | +        for (ActivityReward activityReward : activityRewards) {
 | 
	
		
			
				|  |  |              lockList.add(redissonClient.getLock(CacheNameEnum.LOCK_ACTIVITY_REWARD_STOCK.getRedisKey(activityReward.getId())));
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -186,27 +268,38 @@ public class ActivityRewardServiceImpl extends ServiceImpl<ActivityRewardDao, Ac
 | 
	
		
			
				|  |  |          List<String> rewardNameList = new ArrayList<>();
 | 
	
		
			
				|  |  |          try {
 | 
	
		
			
				|  |  |              lock.lock();
 | 
	
		
			
				|  |  | -            for (ActivityPlanRewardDto activityReward : activityPlanRewardDtos) {
 | 
	
		
			
				|  |  | -                int update = activityPlanRewardService.reduceStock(activityId, activityReward.getActivityReward().getId());
 | 
	
		
			
				|  |  | +            for (ActivityReward activityReward : activityRewards) {
 | 
	
		
			
				|  |  | +                int update = activityPlanRewardService.reduceStock(activityId, activityReward.getId());
 | 
	
		
			
				|  |  |                  if (update == 0) {
 | 
	
		
			
				|  |  |                      continue;
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                if (activityReward.getActivityReward().getRewardType().equals(RewardTypeEnum.PIAMO_ROOM)) {
 | 
	
		
			
				|  |  | +                if (activityReward.getRewardType().equals(RewardTypeEnum.PIAMO_ROOM)) {
 | 
	
		
			
				|  |  |                      PianoRoomChangeRecord pianoRoomChangeRecord = new PianoRoomChangeRecord();
 | 
	
		
			
				|  |  |                      pianoRoomChangeRecord.setUserId(userId);
 | 
	
		
			
				|  |  |                      pianoRoomChangeRecord.setInOrOut(InOrOutEnum.IN);
 | 
	
		
			
				|  |  |                      pianoRoomChangeRecord.setSourceType(SourceTypeEnum.ACTIVITY);
 | 
	
		
			
				|  |  | -                    pianoRoomChangeRecord.setTimes(activityReward.getActivityReward().getNum());
 | 
	
		
			
				|  |  | +                    pianoRoomChangeRecord.setTimes(activityReward.getNum());
 | 
	
		
			
				|  |  |                      pianoRoomChangeRecord.setBizId(activityId.toString());
 | 
	
		
			
				|  |  |                      pianoRoomChangeRecord.setCreateTime(new Date());
 | 
	
		
			
				|  |  |                      pianoRoomChangeRecord.setReason(activityPlan.getActivityName());
 | 
	
		
			
				|  |  |                      pianoRoomChangeRecordService.add(pianoRoomChangeRecord);
 | 
	
		
			
				|  |  | -                } else if (activityReward.getActivityReward().getRewardType().equals(RewardTypeEnum.VIP)) {
 | 
	
		
			
				|  |  | +                } else if (activityReward.getRewardType().equals(RewardTypeEnum.VIP)) {
 | 
	
		
			
				|  |  |                      memberPriceSettingsService.activityReward(userId, activityPlan.getActivityClient(),
 | 
	
		
			
				|  |  | -                                                              activityReward.getActivityReward(), activityId,activityPlan.getActivityName());
 | 
	
		
			
				|  |  | +                                                              activityReward, activityId,activityPlan.getActivityName());
 | 
	
		
			
				|  |  | +                } else if (activityReward.getRewardType().equals(RewardTypeEnum.COUPON)) {
 | 
	
		
			
				|  |  | +                    List<UserParam> list = new ArrayList<>();
 | 
	
		
			
				|  |  | +                    UserParam userParam = new UserParam();
 | 
	
		
			
				|  |  | +                    userParam.setUserId(userId);
 | 
	
		
			
				|  |  | +                    userParam.setClientType(activityPlan.getActivityClient());
 | 
	
		
			
				|  |  | +                    list.add(userParam);
 | 
	
		
			
				|  |  | +                    Boolean issueCoupon = couponIssueService.issueCoupon(activityReward.getCouponId(), list, null, activityPlan.getActivityName(),
 | 
	
		
			
				|  |  | +                                                                         false, false, SendTypeEnum.ACTIVITY);
 | 
	
		
			
				|  |  | +                    if (!issueCoupon) {
 | 
	
		
			
				|  |  | +                        continue;
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                rewardNameList.add(activityReward.getActivityReward().getRewardName());
 | 
	
		
			
				|  |  | -                activityRewardIdList.add(activityReward.getActivityReward().getId());
 | 
	
		
			
				|  |  | +                rewardNameList.add(activityReward.getRewardName());
 | 
	
		
			
				|  |  | +                activityRewardIdList.add(activityReward.getId());
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              // 发送活动获奖推送
 | 
	
		
			
				|  |  |              if (!CollectionUtils.isEmpty(rewardNameList)) {
 | 
	
	
		
			
				|  | @@ -220,7 +313,8 @@ public class ActivityRewardServiceImpl extends ServiceImpl<ActivityRewardDao, Ac
 | 
	
		
			
				|  |  |          return activityRewardIdList;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private Boolean userRewarded(Long userId, Long activityId) {
 | 
	
		
			
				|  |  | +    @Override
 | 
	
		
			
				|  |  | +    public Boolean userRewarded(Long userId, Long activityId) {
 | 
	
		
			
				|  |  |          return baseMapper.userRewarded(userId, activityId);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 |