From 61e3917c5b0d667d23430890f45396a9bb7731ac Mon Sep 17 00:00:00 2001 From: zxl <763096477@qq.com> Date: 星期五, 26 九月 2025 18:39:27 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/send_coupon' into send_coupon --- framework/src/main/java/cn/lili/modules/lmk/service/impl/StoreCouponServiceImpl.java | 126 ++++++++++++++++++++++++++++++++++++++++- 1 files changed, 122 insertions(+), 4 deletions(-) diff --git a/framework/src/main/java/cn/lili/modules/lmk/service/impl/StoreCouponServiceImpl.java b/framework/src/main/java/cn/lili/modules/lmk/service/impl/StoreCouponServiceImpl.java index c640c03..b85c97a 100644 --- a/framework/src/main/java/cn/lili/modules/lmk/service/impl/StoreCouponServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/lmk/service/impl/StoreCouponServiceImpl.java @@ -1,21 +1,40 @@ package cn.lili.modules.lmk.service.impl; +import cn.lili.common.exception.ServiceException; +import cn.lili.modules.lmk.domain.entity.CouponVirtual; +import cn.lili.modules.lmk.domain.entity.StoreCouponSingle; +import cn.lili.modules.lmk.enums.general.GenerateCouponStausEnum; +import cn.lili.modules.lmk.enums.general.StoreCouponStausEnum; +import cn.lili.modules.lmk.service.StoreCouponSingleService; +import cn.lili.modules.order.order.entity.enums.ClaimStatusEnum; +import cn.lili.modules.promotion.entity.dos.Coupon; +import cn.lili.modules.promotion.service.CouponService; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import cn.lili.modules.lmk.domain.entity.StoreCoupon; import cn.lili.modules.lmk.mapper.StoreCouponMapper; import cn.lili.modules.lmk.service.StoreCouponService; 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.StoreCouponForm; import cn.lili.modules.lmk.domain.vo.StoreCouponVO; import cn.lili.modules.lmk.domain.query.StoreCouponQuery; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; import org.springframework.stereotype.Service; 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; /** @@ -29,6 +48,10 @@ public class StoreCouponServiceImpl extends ServiceImpl<StoreCouponMapper, StoreCoupon> implements StoreCouponService { private final StoreCouponMapper storeCouponMapper; + private final RedissonClient redissonClient; + private static final String STORE_COUPON_GENERATE = "store_coupon_generate:"; + private final CouponService couponService; + private final StoreCouponSingleService storeCouponSingleService; /** * 娣诲姞 @@ -87,8 +110,12 @@ */ @Override public Result page(StoreCouponQuery query) { - IPage<StoreCouponVO> page = PageUtil.getPage(query, StoreCouponVO.class); - baseMapper.getPage(page, query); + IPage<StoreCoupon> page = PageUtil.getPage(query, StoreCoupon.class); + LambdaQueryWrapper<StoreCoupon> wrapper = Wrappers.lambdaQuery(); + wrapper.eq(Objects.nonNull(query.getStoreId()), StoreCoupon::getStoreId, query.getStoreId()); + wrapper.eq(StringUtils.isNotBlank(query.getStatus()), StoreCoupon::getStatus, query.getStatus()); + wrapper.eq(StringUtils.isNotBlank(query.getGenerateStatus()), StoreCoupon::getGenerateStatus, query.getGenerateStatus()); + this.page(page, wrapper); return Result.ok().data(page.getRecords()).total(page.getTotal()); } @@ -119,7 +146,98 @@ @Override public Result getCoupon(String id) { - StoreCoupon storeCoupon = this.getById(id); - return Result.ok().data(storeCoupon); + StoreCouponSingle storeCouponSingle = storeCouponSingleService.getById(id); + StoreCoupon storeCoupon = this.getById(storeCouponSingle.getStoreCoupRef()); + if (storeCoupon == null) { + throw new ServiceException("搴楅摵绀煎搧鍗″寘涓嶅瓨鍦�"); + } + if (!StoreCouponStausEnum.ENABLE.name().equals(storeCoupon.getStatus())) { + throw new ServiceException("搴楅摵绀煎搧鍗″寘娌℃湁鍚敤鏃犳硶棰嗗彇"); + } + if (ClaimStatusEnum.CLAIM.name().equals(storeCouponSingle.getClaimStatus())) { + throw new ServiceException("褰撳墠绀煎搧鍗″寘宸茶棰嗗彇"); + } + return Result.ok().data(storeCouponSingle); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Result addStoreCoupon(StoreCouponForm storeCoupon) { + StoreCoupon entity = StoreCouponForm.getEntityByForm(storeCoupon, null); + entity.setStatus(StoreCouponStausEnum.ENABLE.name()); + entity.setCouponClaimNum(0); + entity.setGenerateStatus(GenerateCouponStausEnum.NOT_GENERATE.name()); + Coupon coupon = couponService.getById(entity.getCouponId()); + Integer publishNum = coupon.getPublishNum(); + //琛ㄧず涓嶉檺鍒堕鍙栨暟閲� + if (!Integer.valueOf(0).equals(publishNum)) { + if (publishNum < storeCoupon.getCouponNum()) { + throw new ServiceException("浼樻儬鍗峰彂琛屾暟閲忓皬浜庣敓鎴愪簩缁寸爜鏁伴噺"); + } + } + this.save(entity); + return Result.ok(); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Result generateStoreCoupon(String id) { + RLock redissonLock = redissonClient.getLock(STORE_COUPON_GENERATE + id); + try { + redissonLock.lock(); + LambdaQueryWrapper<StoreCoupon> forUpdate = Wrappers.<StoreCoupon>lambdaQuery().eq(StoreCoupon::getId, id).last("FOR UPDATE"); + StoreCoupon storeCoupon = this.getOne(forUpdate); + if (storeCoupon == null) { + throw new ServiceException("褰撳墠搴楅摵浼樻儬鍗蜂笉瀛樺湪鏃犳硶鐢熸垚"); + } + if (!GenerateCouponStausEnum.NOT_GENERATE.name().equals( storeCoupon.getGenerateStatus())) { + throw new ServiceException("褰撳墠搴楅摵浼樻儬鍗风姸鎬佸紓甯告棤娉曠敓鎴�"); + } + //鐢熸垚浼樻儬鍗� + Integer couponNum = storeCoupon.getCouponNum(); + if (couponNum == null) { + throw new ServiceException("鍙戣鏁伴噺涓虹┖涓嶈兘鐢熸垚"); + } + List<StoreCouponSingle> storeCouponSingles = new ArrayList<>(); + for (int i = 1; i <= couponNum; i++) { + StoreCouponSingle storeCouponSingle = getStoreCouponSingle(storeCoupon, i); + storeCouponSingles.add(storeCouponSingle); + } + if (!storeCouponSingles.isEmpty()) { + storeCouponSingleService.saveBatch(storeCouponSingles); + } + //鏇存柊鐘舵�佺敓鎴愮姸鎬� + storeCoupon.setGenerateStatus(GenerateCouponStausEnum.GENERATE.name()); + this.updateById(storeCoupon); + return Result.ok(); + }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(); + } + } + }); + } + } + + private static StoreCouponSingle getStoreCouponSingle(StoreCoupon storeCoupon, int i) { + StoreCouponSingle storeCouponSingle = new StoreCouponSingle(); + storeCouponSingle.setStoreCoupRef(storeCoupon.getId()); + storeCouponSingle.setStoreId(storeCoupon.getStoreId()); + storeCouponSingle.setStoreName(storeCoupon.getStoreName()); + storeCouponSingle.setCouponName(storeCoupon.getCouponName()); + storeCouponSingle.setCouponId(storeCoupon.getCouponId()); + storeCouponSingle.setClaimStatus(ClaimStatusEnum.NOT_CLAIM.name()); + storeCouponSingle.setCouponNo(String.format("%08d", i)); + return storeCouponSingle; } } -- Gitblit v1.8.0