package com.ruoyi.goods.service.impl.lottery;
|
|
import cn.hutool.core.bean.BeanUtil;
|
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.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.utils.uuid.IdUtils;
|
import com.ruoyi.common.security.utils.SecurityUtils;
|
import com.ruoyi.goods.api.domain.LotteryEvent;
|
import com.ruoyi.goods.api.domain.LotteryEventPrize;
|
import com.ruoyi.goods.api.domain.UserLotteryEvent;
|
import com.ruoyi.goods.domain.vo.AppLotteryEventPageVo;
|
import com.ruoyi.goods.domain.vo.LotteryEventVo;
|
import com.ruoyi.goods.domain.vo.UserLotteryEventVo;
|
import com.ruoyi.goods.mapper.lottery.LotteryEventMapper;
|
import com.ruoyi.goods.service.lottery.ILotteryEventPrizeService;
|
import com.ruoyi.goods.service.lottery.ILotteryEventService;
|
import com.ruoyi.goods.service.lottery.IUserLotteryEventQuestionsAnswersService;
|
import com.ruoyi.goods.service.lottery.IUserLotteryEventService;
|
import com.ruoyi.system.api.service.RemoteCouponService;
|
import com.ruoyi.system.api.service.RemoteMemberService;
|
import org.redisson.api.RLock;
|
import org.redisson.api.RedissonClient;
|
import org.springframework.stereotype.Service;
|
|
import javax.annotation.Resource;
|
import java.math.BigDecimal;
|
import java.time.LocalDateTime;
|
import java.util.*;
|
import java.util.concurrent.TimeUnit;
|
import java.util.stream.Collectors;
|
|
/**
|
* @author zhibing.pu
|
* @Date 2025/5/8 18:05
|
*/
|
@Service
|
public class LotteryEventServiceImpl extends ServiceImpl<LotteryEventMapper, LotteryEvent> implements ILotteryEventService {
|
|
@Resource
|
private IUserLotteryEventService userLotteryEventService;
|
|
@Resource
|
private ILotteryEventPrizeService lotteryEventPrizeService;
|
|
@Resource
|
private RemoteCouponService remoteCouponService;
|
|
@Resource
|
private RemoteMemberService remoteMemberService;
|
|
@Resource
|
private RedissonClient redissonClient;
|
|
@Resource
|
private IUserLotteryEventQuestionsAnswersService userLotteryEventQuestionsService;
|
|
|
/**
|
* 根据id查询抽奖活动信息
|
*
|
* @param id
|
* @return
|
*/
|
@Override
|
public LotteryEventVo getLotteryEvent(String id) {
|
LotteryEvent lotteryEvent = this.getById(id);
|
//构建返回结果
|
LotteryEventVo vo = new LotteryEventVo();
|
vo.setId(lotteryEvent.getId());
|
vo.setName(lotteryEvent.getName());
|
vo.setActivityProfile(lotteryEvent.getActivityProfile());
|
List<UserLotteryEvent> userLotteryEvents = userLotteryEventService.list(new QueryWrapper<UserLotteryEvent>().eq("lottery_event_id", id));
|
vo.setLaveTimes(lotteryEvent.getTimes() - userLotteryEvents.size());
|
//查询抽检活动奖品
|
List<LotteryEventPrize> lotteryEventPrizeList = lotteryEventPrizeService.list(new QueryWrapper<LotteryEventPrize>().eq("lottery_event_id", id));
|
vo.setPrizeList(lotteryEventPrizeList);
|
|
//构建我的奖品明细
|
List<UserLotteryEventVo> collect = userLotteryEvents.stream().map(s -> {
|
UserLotteryEventVo userLotteryEventVo = new UserLotteryEventVo();
|
userLotteryEventVo.setName(s.getObjectName());
|
userLotteryEventVo.setPrizeType(s.getPrizeType());
|
userLotteryEventVo.setNumber(s.getNumber());
|
userLotteryEventVo.setVerifyCode(s.getVerifyCode());
|
return userLotteryEventVo;
|
}).collect(Collectors.toList());
|
vo.setYourPrizeList(collect);
|
return vo;
|
}
|
|
|
/**
|
* 抽奖操作
|
*
|
* @param id
|
* @return
|
*/
|
@Override
|
public R lotteryDraw(String id) {
|
Long userId = SecurityUtils.getUserId();
|
LotteryEvent lotteryEvent = this.getById(id);
|
//判断答题抽奖是否满足抽奖条件
|
if (lotteryEvent.getActivityType() == 5) {
|
BigDecimal correctAnswerRate = userLotteryEventQuestionsService.getCorrectAnswerRate(userId, id);
|
if (correctAnswerRate.compareTo(lotteryEvent.getAccuracy()) < 0) {
|
return R.fail("答题抽奖失败,答题正确率低于活动要求");
|
}
|
}
|
|
//使用redis锁处理高并发
|
RLock lock = redissonClient.getLock("lottery_event::" + userId + "::" + id);
|
try {
|
boolean tryLock = lock.tryLock(30, TimeUnit.SECONDS);
|
if (tryLock) {
|
//判断抽奖次数是否用完
|
int count = userLotteryEventService.count(new QueryWrapper<UserLotteryEvent>().eq("lottery_event_id", id).eq("user_id", userId));
|
if (lotteryEvent.getTimes() <= count) {
|
return R.fail("抽奖次数已用完");
|
}
|
List<LotteryEventPrize> lotteryEventPrizeList = lotteryEventPrizeService.list(new QueryWrapper<LotteryEventPrize>().eq("lottery_event_id", id));
|
//开始抽奖,根据中奖概率来抽奖
|
List<LotteryEventPrize> list = new ArrayList<>();
|
for (LotteryEventPrize lotteryEventPrize : lotteryEventPrizeList) {
|
int winRate = lotteryEventPrize.getWinRate().intValue();
|
for (int i = 0; i < winRate; i++) {
|
LotteryEventPrize event = new LotteryEventPrize();
|
BeanUtil.copyProperties(lotteryEventPrize, event);
|
list.add(event);
|
}
|
}
|
//将待抽奖的集合进行随机排序
|
Collections.shuffle(list);
|
//开始获取随机数
|
int random = new Random().nextInt(list.size());
|
LotteryEventPrize lotteryEventPrize = lotteryEventPrizeList.get(random);
|
//添加中奖商品
|
UserLotteryEvent userLotteryEvent = new UserLotteryEvent();
|
userLotteryEvent.setId(IdUtils.simpleUUID());
|
userLotteryEvent.setUserId(userId);
|
userLotteryEvent.setLotteryEventId(id);
|
userLotteryEvent.setLotteryEventPrizeId(lotteryEventPrize.getId());
|
userLotteryEvent.setPrizeType(lotteryEventPrize.getPrizeType());
|
userLotteryEvent.setObjectId(lotteryEventPrize.getObjectId());
|
userLotteryEvent.setObjectName(lotteryEventPrize.getObjectName());
|
userLotteryEvent.setNumber(lotteryEventPrize.getNumber());
|
//商品需要生成核销码和核销状态
|
if (Arrays.asList(2, 3).contains(lotteryEventPrize.getPrizeType())) {
|
userLotteryEvent.setVerifyCode(IdUtils.simpleUUID());
|
userLotteryEvent.setIsVerify(0);
|
}
|
//中奖优惠券
|
if (1 == lotteryEventPrize.getPrizeType()) {
|
remoteCouponService.addMemberCoupon(lotteryEventPrize.getObjectId(), lotteryEventPrize.getNumber(), userId);
|
}
|
//中奖积分
|
if (4 == lotteryEventPrize.getPrizeType()) {
|
remoteMemberService.addIntegralRecord(lotteryEventPrize.getNumber(), userId, id);
|
}
|
userLotteryEvent.setCreateTime(LocalDateTime.now());
|
userLotteryEventService.save(userLotteryEvent);
|
return R.ok();
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
} finally {
|
lock.unlock();
|
}
|
return R.fail("抽奖失败");
|
}
|
|
|
/**
|
* 获取APP抽奖列表
|
*
|
* @param page
|
* @param userId
|
* @return
|
*/
|
@Override
|
public List<AppLotteryEventPageVo> pageAppLotteryEvent(Page<AppLotteryEventPageVo> page, Long userId) {
|
return this.baseMapper.pageAppLotteryEvent(page, userId);
|
}
|
}
|