package com.ruoyi.goods.service.impl.lottery;
|
|
import cn.hutool.core.bean.BeanUtil;
|
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.ruoyi.common.core.domain.R;
|
import com.ruoyi.common.core.utils.bean.BeanUtils;
|
import com.ruoyi.common.core.utils.uuid.IdUtils;
|
import com.ruoyi.common.security.utils.SecurityUtils;
|
import com.ruoyi.goods.api.domain.*;
|
import com.ruoyi.goods.domain.dto.*;
|
import com.ruoyi.goods.domain.vo.*;
|
import com.ruoyi.goods.mapper.lottery.LotteryEventMapper;
|
import com.ruoyi.goods.service.lottery.*;
|
import com.ruoyi.system.api.domain.poji.member.Member;
|
import com.ruoyi.system.api.domain.poji.member.MemberGiftRecord;
|
import com.ruoyi.system.api.domain.poji.shop.Shop;
|
import com.ruoyi.system.api.service.RemoteCouponService;
|
import com.ruoyi.system.api.service.RemoteMemberService;
|
import com.ruoyi.system.api.service.RemoteShopService;
|
import org.redisson.api.RLock;
|
import org.redisson.api.RedissonClient;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import javax.annotation.Resource;
|
import javax.annotation.Resources;
|
import java.text.SimpleDateFormat;
|
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 IUserLotteryEventQuestionsService userLotteryEventQuestionsAnswersService;
|
|
@Resource
|
private RemoteShopService remoteShopService;
|
|
@Resource
|
private ILotteryEventQuestionsAnswersService lotteryEventQuestionsAnswersService;
|
|
@Resource
|
private ILotteryEventQuestionsService lotteryEventQuestionsService;
|
|
/**
|
* 根据id查询抽奖活动信息
|
*
|
* @param id
|
* @return
|
*/
|
@Override
|
public LotteryEventVo getLotteryEvent(String id) {
|
Long userId = SecurityUtils.getUserId();
|
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);
|
//答题正确率
|
if (5 == lotteryEvent.getActivityType()) {
|
UserLotteryEventQuestions questionsServiceOne = userLotteryEventQuestionsAnswersService.getOne(new QueryWrapper<UserLotteryEventQuestions>().eq("lottery_event_id", id).eq("user_id", userId));
|
if (null == questionsServiceOne) {
|
vo.setCorrectAnswerRate(questionsServiceOne.getCorrectAnswerRate());
|
}
|
}
|
//构建我的奖品明细
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm");
|
List<UserLotteryEventVo> collect = userLotteryEvents.stream().map(s -> {
|
UserLotteryEventVo userLotteryEventVo = new UserLotteryEventVo();
|
userLotteryEventVo.setName(s.getObjectName());
|
userLotteryEventVo.setPrizeType(s.getPrizeType());
|
userLotteryEventVo.setNumber(s.getNumber());
|
MemberGiftRecord memberGiftRecord = remoteMemberService.getVerifyPrizeByGiftId(s.getId()).getData();
|
userLotteryEventVo.setVerifyCode("3-" + memberGiftRecord.getPrizeId());
|
userLotteryEventVo.setIsVerify(1 == memberGiftRecord.getVerifyStatus() ? 0 : 1);
|
userLotteryEventVo.setVerifyTime(null == memberGiftRecord.getVerifyTime() ? "" : sdf.format(memberGiftRecord.getVerifyTime()));
|
Member member = remoteMemberService.getMember(userId).getData();
|
userLotteryEventVo.setVerifyShop("全部门店");
|
if (null != member && null != member.getRelationShopId()) {
|
Shop shop = remoteShopService.getShop(member.getRelationShopId()).getData();
|
userLotteryEventVo.setVerifyShop(shop.getShopName());
|
}
|
return userLotteryEventVo;
|
}).collect(Collectors.toList());
|
vo.setYourPrizeList(collect);
|
return vo;
|
}
|
|
|
/**
|
* 抽奖操作
|
*
|
* @param id
|
* @return
|
*/
|
@Override
|
public R lotteryDraw(String id) {
|
Long userId = SecurityUtils.getUserId();
|
Member member = remoteMemberService.getMember(userId).getData();
|
LotteryEvent lotteryEvent = this.getById(id);
|
//判断答题抽奖是否满足抽奖条件
|
if (lotteryEvent.getActivityType() == 5) {
|
UserLotteryEventQuestions questionsServiceOne = userLotteryEventQuestionsAnswersService.getOne(new QueryWrapper<UserLotteryEventQuestions>().eq("lottery_event_id", id).eq("user_id", userId));
|
if (questionsServiceOne.getCorrectAnswerRate().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 (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);
|
//添加奖品数据
|
MemberGiftRecord memberGiftRecord = new MemberGiftRecord();
|
memberGiftRecord.setPrizeId(IdUtils.simpleUUID());
|
memberGiftRecord.setDelFlag(0);
|
memberGiftRecord.setUserId(userId);
|
memberGiftRecord.setGiftId(userLotteryEvent.getId());
|
memberGiftRecord.setGiftFrom(1);
|
memberGiftRecord.setShopId(member.getRelationShopId());
|
switch (lotteryEventPrize.getPrizeType()) {
|
case 1:
|
memberGiftRecord.setGiftType(1);
|
memberGiftRecord.setCouponId(userLotteryEvent.getObjectId());
|
memberGiftRecord.setCouponNumber(userLotteryEvent.getNumber());
|
break;
|
case 2:
|
memberGiftRecord.setGiftType(2);
|
memberGiftRecord.setGoodsId(userLotteryEvent.getObjectId());
|
memberGiftRecord.setGiftName(userLotteryEvent.getObjectName());
|
memberGiftRecord.setGoodsNumber(userLotteryEvent.getNumber());
|
break;
|
case 3:
|
memberGiftRecord.setGiftType(4);
|
memberGiftRecord.setGiftName(userLotteryEvent.getObjectName());
|
memberGiftRecord.setGiftNumber(userLotteryEvent.getNumber());
|
break;
|
case 4:
|
memberGiftRecord.setGiftType(5);
|
memberGiftRecord.setIntegralNumber(userLotteryEvent.getNumber());
|
break;
|
}
|
memberGiftRecord.setPrizeFrom(2);
|
memberGiftRecord.setCreateTime(new Date());
|
memberGiftRecord.setVerifyStatus(1);
|
remoteMemberService.saveMemberGiftRecord(memberGiftRecord);
|
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);
|
}
|
|
|
/**
|
* 获取门店抽奖列表
|
*
|
* @param page
|
* @param shopId
|
* @return
|
*/
|
@Override
|
public List<ShopLotteryDrawListVo> getShopLotteryDrawList(Page<ShopLotteryDrawListVo> page, Long shopId) {
|
return this.baseMapper.getShopLotteryDrawList(page, shopId);
|
}
|
|
@Override
|
@Transactional
|
public R<ShopLotteryDrawVo> editLotteryEvent(MgtLotteryEventEditDTO dto) {
|
//先检查开始-结束时间范围内,系统中是否有该活动
|
List<LotteryEvent> lotteryEvents = this.baseMapper.selectList(new LambdaQueryWrapper<LotteryEvent>()
|
.eq(LotteryEvent::getDelFlag, 0)//未删除的
|
.eq(LotteryEvent::getActivityType, dto.getActivityType())//类型相同的
|
.between(LotteryEvent::getStartTime, dto.getStartTime(), dto.getEndTime())//开始时间在这个活动的(开始-结束)范围内的
|
.or()
|
.between(LotteryEvent::getEndTime, dto.getStartTime(), dto.getEndTime())//结束时间在这个活动的(开始-结束)范围内的
|
);
|
if (null != lotteryEvents && !lotteryEvents.isEmpty()) {
|
// 新增记录时直接返回错误
|
if (dto.getId() == null) {
|
return R.fail("新增抽奖活动与现有抽奖活动时间范围冲突");
|
}
|
// 更新记录时,检查是否与其他记录(非自身)冲突
|
boolean hasConflict = lotteryEvents.stream()
|
.anyMatch(event -> !event.getId().equals(dto.getId()));
|
if (hasConflict) {
|
return R.fail("编辑抽奖活动与现有其他活动时间范围冲突");
|
}
|
}
|
LotteryEvent lotteryEvent = new LotteryEvent();
|
if (null != dto.getId()) {
|
//编辑
|
lotteryEvent=this.baseMapper.selectById(dto.getId());
|
if (null == lotteryEvent||lotteryEvent.getDelFlag() != 0) {
|
return R.fail("该抽奖活动已被删除");
|
}
|
if (!lotteryEvent.getActivityType().equals(dto.getActivityType())) {
|
return R.fail("编辑抽奖活动不能修改开启方式");
|
}
|
if(!lotteryEvent.getName().equals(dto.getName())) {
|
return R.fail("编辑抽奖活动不能修改抽奖名称");
|
}
|
//答题类型
|
if (lotteryEvent.getActivityType().equals(5)){
|
//将之前的题干数据、答案选项数据删除
|
//先删除答案选项数据
|
lotteryEventQuestionsAnswersService.remove(new LambdaQueryWrapper<LotteryEventQuestionsAnswers>()
|
.eq(LotteryEventQuestionsAnswers::getLotteryEventId,lotteryEvent.getId()));
|
//再删除题干数据
|
lotteryEventQuestionsService.remove(new LambdaQueryWrapper<LotteryEventQuestions>()
|
.eq(LotteryEventQuestions::getLotteryEventId,lotteryEvent.getId()));
|
}
|
//奖品数据删除
|
lotteryEventPrizeService.remove(new LambdaQueryWrapper<LotteryEventPrize>()
|
.eq(LotteryEventPrize::getLotteryEventId,lotteryEvent.getId()));
|
}
|
//新增
|
BeanUtils.copyProperties(dto, lotteryEvent);
|
if (dto.getId() == null) {
|
lotteryEvent.setCreateTime(LocalDateTime.now());
|
lotteryEvent.setCreateUserId(dto.getUserId());
|
}else {
|
lotteryEvent.setUpdateTime(LocalDateTime.now());
|
lotteryEvent.setUpdateUserId(dto.getUserId());
|
}
|
//保存抽奖活动
|
this.saveOrUpdate(lotteryEvent);
|
// 保存奖品数据
|
LotteryEvent finalLotteryEvent = lotteryEvent;//jdk8及之后 变量在初始化后确实没有被重新赋值,可直接引用,无需显式声明为 final
|
List<LotteryEventPrize> prizeList = dto.getMgtLotteryEventPrizeDTOList().stream()
|
.map(prizeDTO -> {
|
LotteryEventPrize prize = new LotteryEventPrize();
|
prize.setLotteryEventId(finalLotteryEvent.getId());
|
prize.setPrizeType(prizeDTO.getPrizeType());
|
if (null != prizeDTO.getObjectId()){
|
prize.setObjectId(prizeDTO.getObjectId());
|
}
|
prize.setObjectName(prizeDTO.getObjectName());
|
prize.setNumber(prizeDTO.getNumber());
|
prize.setWinRate(prizeDTO.getWinRate());
|
return prize;
|
})
|
.collect(Collectors.toList());
|
lotteryEventPrizeService.saveBatch(prizeList);
|
if (dto.getActivityType().equals(5)) {
|
//保存题干数据
|
for (MgtLotteryEventQuestionDTO questionDTO : dto.getMgtLotteryQuestionDTOList()) {
|
LotteryEventQuestions question = new LotteryEventQuestions();
|
question.setLotteryEventId(finalLotteryEvent.getId());
|
question.setName(questionDTO.getName());
|
question.setSort(questionDTO.getSort());
|
lotteryEventQuestionsService.save(question);
|
//保存答案选项数据
|
List<LotteryEventQuestionsAnswers> answersList = questionDTO.getAnswersDTOList().stream()
|
.map(answersDTO -> {
|
LotteryEventQuestionsAnswers answer = new LotteryEventQuestionsAnswers();
|
answer.setLotteryEventId(finalLotteryEvent.getId());
|
answer.setLotteryEventQuestionsId(question.getId());
|
answer.setAnswer(answersDTO.getAnswer());
|
answer.setIsRight(answersDTO.getIsRight());
|
return answer;
|
}).collect(Collectors.toList());
|
lotteryEventQuestionsAnswersService.saveBatch(answersList);
|
}
|
}
|
return R.ok();
|
}
|
|
@Override
|
public List<MgtLotteryEventPageVo> pageMgtLotteryEvent(Page<MgtLotteryEventPageVo> page, MgtLotteryEventPageDto dto) {
|
Map<Long,Shop> map;
|
if (dto.getCreateObject()!=null){
|
//根据 条件-创建对象 模糊查找门店集合
|
List<Shop> shopList=remoteShopService.getShopListByShopName(dto.getCreateObject());
|
if (null != shopList && !shopList.isEmpty()) {
|
List<Long> shopIds = shopList.stream().map(Shop::getShopId).collect(Collectors.toList());
|
dto.setShopIds(shopIds);
|
//转为map 方便后续取商户名称
|
map = shopList.stream().collect(Collectors.toMap(Shop::getShopId, shop -> shop));
|
} else {
|
map = new HashMap<>();
|
}
|
//判断“平台创建”是否包含了 条件-创建对象
|
if (!"平台创建".contains(dto.getCreateObject())){
|
dto.setFlag(0);//未包含,只查找门店ids
|
}
|
} else {
|
map = new HashMap<>();
|
}
|
//获取分页信息
|
List<MgtLotteryEventPageVo> voList = this.baseMapper.pageMgtLotteryEvent(page, dto);
|
//填充创建对象
|
voList.forEach(x->{
|
if (x.getActivityType()!=6){
|
x.setCreateObject("平台创建");
|
}else {
|
//线下抽奖,获取门店名称
|
x.setCreateObject(map.get(Long.valueOf(x.getShopId())).getShopName());
|
}
|
|
});
|
return voList;
|
}
|
|
@Override
|
public R<MgtLotteryEventDetailVO> getLotteryEventDetailById(String id) {
|
LotteryEvent lotteryEvent = this.getById(id);
|
if (null == lotteryEvent) {
|
return R.fail("该抽奖活动不存在");
|
}
|
MgtLotteryEventDetailVO vo = new MgtLotteryEventDetailVO();
|
BeanUtils.copyProperties(lotteryEvent, vo);
|
if (lotteryEvent.getActivityType()==6){
|
//线下抽奖 取商户名称
|
Shop data = remoteShopService.getShop(Long.valueOf(lotteryEvent.getShopId())).getData();
|
if (null != data){
|
vo.setShopName(data.getShopName());
|
}
|
//题干数据
|
List<LotteryEventQuestions> questionsList = lotteryEventQuestionsService.getBaseMapper().selectList(new LambdaQueryWrapper<LotteryEventQuestions>().eq(LotteryEventQuestions::getLotteryEventId, lotteryEvent.getId()));
|
|
List<MgtLotteryEventQuestionVO> questionsVOList = questionsList.stream().map(question -> {
|
MgtLotteryEventQuestionVO questionVO = new MgtLotteryEventQuestionVO();
|
BeanUtils.copyProperties(question, questionVO);
|
//答案选项数据
|
List<LotteryEventQuestionsAnswers> answersList = lotteryEventQuestionsAnswersService.getBaseMapper().selectList(new LambdaQueryWrapper<LotteryEventQuestionsAnswers>()
|
.eq(LotteryEventQuestionsAnswers::getLotteryEventId, lotteryEvent.getId())
|
.eq(LotteryEventQuestionsAnswers::getLotteryEventQuestionsId, questionVO.getLotteryEventId()));
|
questionVO.setAnswersVOList(answersList);
|
return questionVO;
|
}).collect(Collectors.toList());
|
//题干数据排序
|
// 自定义 Comparator 实现
|
Comparator<LotteryEventQuestions> sortComparator = new Comparator<LotteryEventQuestions>() {
|
@Override
|
public int compare(LotteryEventQuestions q1, LotteryEventQuestions q2) {
|
return Integer.compare(q1.getSort(), q2.getSort());
|
}
|
};
|
// 应用排序
|
Collections.sort(questionsList, sortComparator);
|
vo.setMgtLotteryQuestionVOList(questionsVOList);
|
}
|
//奖项信息
|
List<LotteryEventPrize> prizeList = lotteryEventPrizeService.getBaseMapper().selectList(new LambdaQueryWrapper<LotteryEventPrize>()
|
.eq(LotteryEventPrize::getLotteryEventId, lotteryEvent.getId()));
|
vo.setLotteryEventPrizeList(prizeList);
|
|
return R.ok(vo);
|
}
|
|
@Override
|
public R deleteMgtLotteryEvent(String id) {
|
LotteryEvent lotteryEvent = this.getById(id);
|
if (null == lotteryEvent || lotteryEvent.getDelFlag()!=0) {
|
return R.ok();
|
}
|
|
//1.奖品数据删除
|
lotteryEventPrizeService.remove(new LambdaQueryWrapper<LotteryEventPrize>()
|
.eq(LotteryEventPrize::getLotteryEventId,lotteryEvent.getId()));
|
//2.答题类型
|
if (lotteryEvent.getActivityType().equals(5)){
|
//先删除答案选项数据
|
lotteryEventQuestionsAnswersService.remove(new LambdaQueryWrapper<LotteryEventQuestionsAnswers>()
|
.eq(LotteryEventQuestionsAnswers::getLotteryEventId,lotteryEvent.getId()));
|
//再删除题干数据
|
lotteryEventQuestionsService.remove(new LambdaQueryWrapper<LotteryEventQuestions>()
|
.eq(LotteryEventQuestions::getLotteryEventId,lotteryEvent.getId()));
|
}
|
//3.抽奖活动删除
|
lotteryEvent.setDelFlag(1);
|
this.updateById(lotteryEvent);
|
return R.ok();
|
}
|
|
@Override
|
public R endImmediatelyLotteryEvent(String id) {
|
LotteryEvent lotteryEvent = this.getById(id);
|
if (null == lotteryEvent || lotteryEvent.getDelFlag()!=0) {
|
return R.fail("该抽奖活动不存在");
|
}
|
LocalDateTime now = LocalDateTime.now();
|
if (!now.isBefore(lotteryEvent.getStartTime()) && !now.isAfter(lotteryEvent.getEndTime())) {
|
return R.fail("该抽奖活动不在活动时间范围内");
|
}
|
lotteryEvent.setEndTime(now);//将结束时间设置为当前时间
|
lotteryEvent.setUpdateUserId(SecurityUtils.getUserId());
|
lotteryEvent.setUpdateTime(now);
|
this.updateById(lotteryEvent);
|
return R.ok();
|
}
|
}
|