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.StoreCoupon;
|
import cn.lili.modules.lmk.enums.general.PrizeStatusEnum;
|
import cn.lili.modules.lmk.service.StoreCouponService;
|
import cn.lili.modules.promotion.entity.dos.MemberCoupon;
|
import cn.lili.modules.promotion.service.MemberCouponService;
|
import cn.lili.rocketmq.RocketmqSendCallbackBuilder;
|
import com.alibaba.fastjson.JSON;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import cn.lili.modules.lmk.domain.entity.StoreCouponClaimRecord;
|
import cn.lili.modules.lmk.mapper.StoreCouponClaimRecordMapper;
|
import cn.lili.modules.lmk.service.StoreCouponClaimRecordService;
|
import cn.lili.base.Result;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import cn.lili.modules.lmk.domain.form.StoreCouponClaimRecordForm;
|
import cn.lili.modules.lmk.domain.vo.StoreCouponClaimRecordVO;
|
import cn.lili.modules.lmk.domain.query.StoreCouponClaimRecordQuery;
|
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.List;
|
import java.util.stream.Collectors;
|
|
/**
|
* 店铺优惠卷领取记录 服务实现类
|
*
|
* @author peng
|
* @since 2025-09-25
|
*/
|
@Service
|
@RequiredArgsConstructor
|
public class StoreCouponClaimRecordServiceImpl extends ServiceImpl<StoreCouponClaimRecordMapper, StoreCouponClaimRecord> implements StoreCouponClaimRecordService {
|
|
private final StoreCouponClaimRecordMapper storeCouponClaimRecordMapper;
|
private final RedissonClient redissonClient;
|
private static final String STORE_COUPON_CLAIM = "store_coupon_claim:";
|
private final MemberCouponService memberCouponService;
|
private final StoreCouponService storeCouponService;
|
/**
|
* 添加
|
* @param form
|
* @return
|
*/
|
@Override
|
public Result add(StoreCouponClaimRecordForm form) {
|
StoreCouponClaimRecord entity = StoreCouponClaimRecordForm.getEntityByForm(form, null);
|
baseMapper.insert(entity);
|
return Result.ok("添加成功");
|
}
|
|
/**
|
* 修改
|
* @param form
|
* @return
|
*/
|
@Override
|
public Result update(StoreCouponClaimRecordForm form) {
|
StoreCouponClaimRecord entity = baseMapper.selectById(form.getId());
|
|
// 为空抛IllegalArgumentException,做全局异常处理
|
Assert.notNull(entity, "记录不存在");
|
BeanUtils.copyProperties(form, entity);
|
baseMapper.updateById(entity);
|
return Result.ok("修改成功");
|
}
|
|
/**
|
* 批量删除
|
* @param ids
|
* @return
|
*/
|
@Override
|
public Result remove(List<String> ids) {
|
baseMapper.deleteBatchIds(ids);
|
return Result.ok("删除成功");
|
}
|
|
/**
|
* id删除
|
* @param id
|
* @return
|
*/
|
@Override
|
public Result removeById(String id) {
|
baseMapper.deleteById(id);
|
return Result.ok("删除成功");
|
}
|
|
/**
|
* 分页查询
|
* @param query
|
* @return
|
*/
|
@Override
|
public Result page(StoreCouponClaimRecordQuery query) {
|
IPage<StoreCouponClaimRecordVO> page = PageUtil.getPage(query, StoreCouponClaimRecordVO.class);
|
baseMapper.getPage(page, query);
|
return Result.ok().data(page.getRecords()).total(page.getTotal());
|
}
|
|
/**
|
* 根据id查找
|
* @param id
|
* @return
|
*/
|
@Override
|
public Result detail(String id) {
|
StoreCouponClaimRecordVO vo = baseMapper.getById(id);
|
Assert.notNull(vo, "记录不存在");
|
return Result.ok().data(vo);
|
}
|
|
/**
|
* 列表
|
* @return
|
*/
|
@Override
|
public Result all() {
|
List<StoreCouponClaimRecord> entities = baseMapper.selectList(null);
|
List<StoreCouponClaimRecordVO> vos = entities.stream()
|
.map(entity -> StoreCouponClaimRecordVO.getVoByEntity(entity, null))
|
.collect(Collectors.toList());
|
return Result.ok().data(vos);
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Result claimCoupon(String id) {
|
AuthUser currentUser = UserContext.getCurrentUser();
|
if (currentUser == null) {
|
throw new ServiceException("当前用户没有登录无法领取");
|
}
|
String userId = currentUser.getId();
|
String nickName = currentUser.getNickName();
|
|
//锁住店铺某一个优惠卷
|
RLock redissonLock = redissonClient.getLock(STORE_COUPON_CLAIM + id);
|
try {
|
redissonLock.lock();
|
StoreCoupon storeCoupon = storeCouponService.getById(id);
|
if (storeCoupon == null) {
|
throw new ServiceException("当前店铺不存在优惠卷");
|
}
|
//处理幂等问题限制一个用户只能该店铺领取一种优惠卷
|
LambdaQueryWrapper<StoreCouponClaimRecord> memCoupon = Wrappers.<StoreCouponClaimRecord>lambdaQuery()
|
.eq(StoreCouponClaimRecord::getUserId, userId)
|
.eq(StoreCouponClaimRecord::getCouponId, storeCoupon.getCouponId());
|
List<StoreCouponClaimRecord> list = this.list(memCoupon);
|
if (!list.isEmpty()){
|
throw new ServiceException("当前用户已经领取过了无法再次领取");
|
}
|
//领取对应的优惠卷写入记录
|
memberCouponService.receiveCoupon(storeCoupon.getCouponId(),userId , nickName);
|
StoreCouponClaimRecord storeCouponClaimRecord = new StoreCouponClaimRecord();
|
storeCouponClaimRecord.setCouponId(storeCoupon.getCouponId());
|
storeCouponClaimRecord.setCouponName(storeCoupon.getCouponName());
|
storeCouponClaimRecord.setStoreId(storeCoupon.getStoreId());
|
storeCouponClaimRecord.setStoreName(storeCoupon.getStoreName());
|
storeCouponClaimRecord.setUserId(userId);
|
this.save(storeCouponClaimRecord);
|
//领取成功返回优惠卷id用于跳转购物使用
|
return Result.ok().data(storeCoupon.getCouponId());
|
|
} finally {
|
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
@Override
|
public void afterCommit() {
|
if (redissonLock.isHeldByCurrentThread()) {
|
redissonLock.unlock();
|
}
|
}
|
});
|
|
}
|
}
|
}
|