From ad08bf184ca45affe429b192751244d2654b954a Mon Sep 17 00:00:00 2001
From: peng <peng.com>
Date: 星期二, 30 九月 2025 17:20:56 +0800
Subject: [PATCH] 店铺扫码抽奖功能

---
 framework/src/main/java/cn/lili/modules/lmk/service/impl/ScanPrizeServiceImpl.java |  118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 117 insertions(+), 1 deletions(-)

diff --git a/framework/src/main/java/cn/lili/modules/lmk/service/impl/ScanPrizeServiceImpl.java b/framework/src/main/java/cn/lili/modules/lmk/service/impl/ScanPrizeServiceImpl.java
index 3338e6d..df4f826 100644
--- a/framework/src/main/java/cn/lili/modules/lmk/service/impl/ScanPrizeServiceImpl.java
+++ b/framework/src/main/java/cn/lili/modules/lmk/service/impl/ScanPrizeServiceImpl.java
@@ -1,18 +1,26 @@
 package cn.lili.modules.lmk.service.impl;
 
 import cn.lili.common.exception.ServiceException;
+import cn.lili.common.security.AuthUser;
+import cn.lili.common.security.context.UserContext;
 import cn.lili.modules.lmk.domain.entity.PrizeClaimRecord;
 import cn.lili.modules.lmk.domain.entity.StoreCoupon;
 import cn.lili.modules.lmk.domain.entity.StoreCouponSingle;
+import cn.lili.modules.lmk.domain.form.AddPrizeNumForm;
+import cn.lili.modules.lmk.domain.vo.StorePrizeVO;
 import cn.lili.modules.lmk.enums.general.*;
 import cn.lili.modules.lmk.service.PrizeClaimRecordService;
+import cn.lili.modules.lmk.service.PrizeService;
 import cn.lili.modules.order.order.entity.enums.ClaimStatusEnum;
+import cn.lili.utils.COSUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import cn.lili.modules.lmk.domain.entity.ScanPrize;
 import cn.lili.modules.lmk.mapper.ScanPrizeMapper;
 import cn.lili.modules.lmk.service.ScanPrizeService;
 import cn.lili.base.Result;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import cn.lili.modules.lmk.domain.form.ScanPrizeForm;
@@ -24,12 +32,14 @@
 import lombok.RequiredArgsConstructor;
 import cn.lili.utils.PageUtil;
 import org.springframework.beans.BeanUtils;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.support.TransactionSynchronization;
 import org.springframework.transaction.support.TransactionSynchronizationManager;
 import org.springframework.util.Assert;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.stream.Collectors;
 
 /**
@@ -46,7 +56,9 @@
     private final RedissonClient redissonClient;
     private static final String STORE_PRIZE_GENERATE = "store_prize_generate:";
     private final PrizeClaimRecordService prizeClaimRecordService;
-
+    private static final String STORE_PRIZE_CLAIM = "store_prize_claim:";
+    private final PrizeService prizeService;
+    private final COSUtil cosUtil;
     /**
      * 娣诲姞
      * @param form
@@ -107,7 +119,12 @@
      */
     @Override
     public Result page(ScanPrizeQuery query) {
+
         IPage<ScanPrizeVO> page = PageUtil.getPage(query, ScanPrizeVO.class);
+        LambdaQueryWrapper<ScanPrize> wrapper = Wrappers.lambdaQuery();
+        wrapper.eq(Objects.nonNull(query.getStoreId()), ScanPrize::getStoreId, query.getStoreId());
+        wrapper.eq(StringUtils.isNotBlank(query.getStatus()), ScanPrize::getStatus, query.getStatus());
+        wrapper.eq(StringUtils.isNotBlank(query.getGenerateStatus()), ScanPrize::getGenerateStatus, query.getGenerateStatus());
         baseMapper.getPage(page, query);
         return Result.ok().data(page.getRecords()).total(page.getTotal());
     }
@@ -156,6 +173,7 @@
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Result generateStorePrize(String id) {
 
         RLock redissonLock = redissonClient.getLock(STORE_PRIZE_GENERATE + id);
@@ -215,4 +233,102 @@
         prizeClaimRecord.setMaterial(MaterialStatusEnum.NOT_GENERATE.name());
         return prizeClaimRecord;
     }
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Result claimPrize(String id) {
+        AuthUser currentUser = UserContext.getCurrentUser();
+        if (currentUser == null) {
+            throw new ServiceException("褰撳墠鐢ㄦ埛娌℃湁鐧诲綍鏃犳硶棰嗗彇");
+        }
+        String userId = currentUser.getId();
+        String nickName = currentUser.getNickName();
+
+        //閿佷綇绀煎搧鐮乮d
+        RLock redissonLock = redissonClient.getLock(STORE_PRIZE_CLAIM + id);
+        try {
+            redissonLock.lock();
+            LambdaQueryWrapper<PrizeClaimRecord> forUpdate = Wrappers.<PrizeClaimRecord>lambdaQuery()
+                    .eq(PrizeClaimRecord::getId, id).last("FOR UPDATE");
+            PrizeClaimRecord prizeClaimRecord = prizeClaimRecordService.getOne(forUpdate);
+            if (prizeClaimRecord == null) {
+                throw new ServiceException("褰撳墠棰嗗彇鎶藉鏈轰細浜岀淮鐮佷笉瀛樺湪");
+            }
+            if (!ClaimStatusEnum.NOT_CLAIM.name().equals(prizeClaimRecord.getClaimStatus())) {
+                throw new ServiceException("褰撳墠棰嗗彇鎶藉鏈轰細鐘舵�佸紓甯�");
+            }
+            //鏇存柊琚鍙栫殑璁板綍
+            prizeClaimRecord.setClaimStatus(ClaimStatusEnum.CLAIM.name());
+            prizeClaimRecord.setUserId(userId);
+            prizeClaimRecord.setNickName(nickName);
+            LambdaQueryWrapper<ScanPrize> storeCoupQuery = Wrappers.<ScanPrize>lambdaQuery()
+                    .eq(ScanPrize::getId, prizeClaimRecord.getStorePrizeId()).last("FOR UPDATE");
+            ScanPrize scanPrize = this.getOne(storeCoupQuery);
+            AddPrizeNumForm addPrizeNumForm = new AddPrizeNumForm();
+            addPrizeNumForm.setUserId(userId);
+            addPrizeNumForm.setPrizeActivityId(prizeClaimRecord.getPrizeActivityId());
+            addPrizeNumForm.setAddType(PrizeUserActionEnum.USER_SCAN_STORE.name());
+            prizeService.addPrizeNum(addPrizeNumForm);
+            if (scanPrize == null) {
+                throw new ServiceException("褰撳墠搴楅摵鎶藉鍗蜂笉瀛樺湪");
+            }
+            if (!StoreScanPrizeStausEnum.ENABLE.name().equals(scanPrize.getStatus())) {
+                throw new ServiceException("褰撳墠搴楅摵鎶藉鍗风姸鎬佸紓甯�");
+            }
+            //棰嗗彇瀵瑰簲鐨勪紭鎯犲嵎鍐欏叆璁板綍
+            prizeClaimRecordService.updateById(prizeClaimRecord);
+            LambdaUpdateWrapper<ScanPrize> updateStoreCoupon = Wrappers.<ScanPrize>lambdaUpdate()
+                    .eq(ScanPrize::getId, scanPrize.getId())
+                    .set(ScanPrize::getClaimNum, scanPrize.getClaimNum() + 1)
+                    .ge(ScanPrize::getGenerateNum, scanPrize.getClaimNum() + 1);
+            boolean update = this.update(updateStoreCoupon);
+            if (!update) {
+                throw new ServiceException("棰嗗彇澶辫触");
+            }
+            return Result.ok().data(0);
+
+        } finally {
+            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
+                @Override
+                public void afterCommit() {
+                    if (redissonLock.isHeldByCurrentThread()) {
+                        redissonLock.unlock();
+                    }
+                }
+
+                @Override
+                public void afterCompletion(int status) {
+                    // 纭繚鍗充娇鍦ㄤ簨鍔″洖婊氱殑鎯呭喌涓嬩篃鑳介噴鏀鹃攣
+                    if (redissonLock.isHeldByCurrentThread()) {
+                        redissonLock.unlock();
+                    }
+                }
+
+            });
+
+        }
+    }
+
+    @Override
+    public Result getStorePrize(String id) {
+        StorePrizeVO storePrize = baseMapper.getStorePrize(id);
+        if (storePrize == null) {
+            throw new ServiceException("褰撳墠娲诲姩涓嶅瓨鍦�");
+        }
+        Boolean popup = storePrize.getPopup();
+        if (!Boolean.TRUE.equals(popup)) {
+            throw new ServiceException("褰撳墠娲诲姩娌℃湁寮�鍚�");
+        }
+        if (!PrizeActivityStatusEnum.ON.name().equals(storePrize.getEnableStatus())) {
+            throw new ServiceException("褰撳墠娲诲姩娌℃湁寮�鍚�");
+        }
+        if (!ClaimStatusEnum.NOT_CLAIM.name().equals(storePrize.getClaimStatus())) {
+            throw new ServiceException("褰撳墠鎶藉鏈轰細琚鍙�");
+        }
+
+        String activityCover = storePrize.getActivityCover();
+        if (StringUtils.isNotBlank(activityCover)&&!activityCover.contains("http")) {
+            storePrize.setActivityCover(cosUtil.getPreviewUrl(activityCover));
+        }
+        return Result.ok().data(storePrize);
+    }
 }

--
Gitblit v1.8.0