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