Commit 104b9bbe authored by zhangfeng's avatar zhangfeng

feature-reward:批量兑换

parent c9bc4a60
...@@ -17,5 +17,9 @@ public interface ErrorCodeConstants { ...@@ -17,5 +17,9 @@ public interface ErrorCodeConstants {
ErrorCode REWARD_PICK_METHOD_NOT_ALLOW_CREATE = new ErrorCode(1001011009, "领取方式不合法"); ErrorCode REWARD_PICK_METHOD_NOT_ALLOW_CREATE = new ErrorCode(1001011009, "领取方式不合法");
ErrorCode REWARD_STATUS_NOT_ALLOW_UPDATE = new ErrorCode(1001011010, "礼物状态不允许编辑"); ErrorCode REWARD_STATUS_NOT_ALLOW_UPDATE = new ErrorCode(1001011010, "礼物状态不允许编辑");
ErrorCode REWARD_STATUS_NOT_ALLOW_ENABLE = new ErrorCode(1001011011, "礼物不能启用"); ErrorCode REWARD_STATUS_NOT_ALLOW_ENABLE = new ErrorCode(1001011011, "礼物不能启用");
ErrorCode REWARD_NOT_ENABLE = new ErrorCode(1001011012, "礼物未启用");
ErrorCode REWARD_SCORE_NOT_ENOUGH = new ErrorCode(1001011013, "会员积分不够");
ErrorCode REWARD_COUNT_NOT_ENOUGH = new ErrorCode(1001011014, "礼品数量不够");
ErrorCode REWARD_REDEEM_FAIL = new ErrorCode(1001011015, "批量兑换失败");
} }
...@@ -26,7 +26,16 @@ ...@@ -26,7 +26,16 @@
<artifactId>yudao-module-reward-api</artifactId> <artifactId>yudao-module-reward-api</artifactId>
<version>${revision}</version> <version>${revision}</version>
</dependency> </dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-infra-api</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-member-api</artifactId>
<version>${revision}</version>
</dependency>
</dependencies> </dependencies>
</project> </project>
\ No newline at end of file
package cn.iocoder.yudao.module.reward.api.reward; package cn.iocoder.yudao.module.reward.api.reward;
import cn.iocoder.yudao.framework.redis.helper.RedisDistributedLock;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.UserRespDTO;
import cn.iocoder.yudao.module.reward.api.reward.dto.RedeemRewardReqVO; import cn.iocoder.yudao.module.reward.api.reward.dto.RedeemRewardReqVO;
import cn.iocoder.yudao.module.reward.api.reward.dto.RedeemRewardRespDTO; import cn.iocoder.yudao.module.reward.api.reward.dto.RedeemRewardRespDTO;
import cn.iocoder.yudao.module.reward.dal.dataobject.reward.RewardDO;
import cn.iocoder.yudao.module.reward.dal.mysql.reward.RewardMapper;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.GET_LOCK_FAILED;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.USER_NOT_EXISTS;
import static cn.iocoder.yudao.module.reward.enums.ErrorCodeConstants.*;
@Service @Service
@Validated @Validated
public class RedeemRewardApiImpl implements RedeemRewardApi { public class RedeemRewardApiImpl implements RedeemRewardApi {
@Resource
private RewardMapper rewardMapper;
@Resource
private MemberUserApi memberUserApi;
@Resource
private RedisDistributedLock redisDistributedLock;
@Override @Override
public RedeemRewardRespDTO redeemReward(RedeemRewardReqVO redeemRewardReqVO) { public RedeemRewardRespDTO redeemReward(RedeemRewardReqVO redeemRewardReqVO) {
boolean lock = false;
try {
lock = redisDistributedLock.lock("reward:redeem:lock:" + redeemRewardReqVO.getRewardId());
if (!lock) {
throw exception(GET_LOCK_FAILED);
}
// 查询会员积分
UserRespDTO memberUser = memberUserApi.getUser(redeemRewardReqVO.getRewardId());
if (memberUser == null) {
throw exception(USER_NOT_EXISTS);
}
Integer holdScore = memberUser.getHoldScore();
// 查询礼品
RewardDO rewardDO = rewardMapper.selectById(redeemRewardReqVO.getRewardId());
if (rewardDO == null) {
throw exception(REWARD_NOT_EXISTS);
}
// 礼品未开启
if (rewardDO.getStatus() != 1) {
throw exception(REWARD_NOT_ENABLE);
}
// 会员积分不够
if (holdScore < rewardDO.getPointsRequire() * redeemRewardReqVO.getCount()) {
throw exception(REWARD_SCORE_NOT_ENOUGH);
}
// 礼品数量不够
if (rewardDO.getQuantityRemain() < redeemRewardReqVO.getCount()) {
throw exception(REWARD_COUNT_NOT_ENOUGH);
}
// 兑换方式不匹配
if (!Objects.equals(rewardDO.getPickMethod(), redeemRewardReqVO.getRedeemType())) {
throw exception(REWARD_PICK_METHOD_NOT_ALLOW_CREATE);
}
//TODO:校验兑换次数(查兑换记录)
// 更新礼品
rewardMapper.updateById(rewardDO);
// 添加兑换记录
// 更新会员积分
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
redisDistributedLock.releaseLock("reward:redeem:lock:" + redeemRewardReqVO.getRewardId());
}
return null; return null;
} }
@Override @Override
public List<RedeemRewardRespDTO> redeemRewards(List<RedeemRewardReqVO> redeemRewardReqVOList) { public List<RedeemRewardRespDTO> redeemRewards(List<RedeemRewardReqVO> redeemRewardReqVOList) {
Long rewardId = redeemRewardReqVOList.get(0).getRewardId();
// 查询礼品
RewardDO rewardDO = rewardMapper.selectById(rewardId);
// 礼品未开启
if (rewardDO.getStatus() != 1) {
throw exception(REWARD_NOT_ENABLE);
}
boolean lock = false;
try {
lock = redisDistributedLock.lock("reward:redeem:lock:" + rewardId);
if (!lock) {
throw exception(GET_LOCK_FAILED);
}
// 校验礼品数量
//
ArrayList<Long> memberIds = new ArrayList<>();
int totalCount = 0;
ArrayList<UserRespDTO> members = new ArrayList<>();
for (RedeemRewardReqVO redeemRewardReqVO : redeemRewardReqVOList) {
// 每个兑换VO校验一遍
// 兑换方式不匹配
if (!Objects.equals(rewardDO.getPickMethod(), redeemRewardReqVO.getRedeemType())) {
throw exception(REWARD_PICK_METHOD_NOT_ALLOW_CREATE);
}
// 查询会员id列表,暂时挨个查
memberIds.add(redeemRewardReqVO.getMemberId());
members.add(memberUserApi.getUser(redeemRewardReqVO.getMemberId()));
// 记录兑换总数
totalCount+=redeemRewardReqVO.getCount();
}
// 查询会员列表,获取积分列表
// 判断兑换总数是否大于礼物数量
if (totalCount > rewardDO.getQuantityRemain()){
throw exception(REWARD_COUNT_NOT_ENOUGH);
}
// 判断会员积分是否够(初步校验,实际兑换时会再加锁校验)
} catch (Exception e) {
throw exception(REWARD_REDEEM_FAIL);
}
finally {
redisDistributedLock.releaseLock("reward:redeem:lock:" + rewardId);
}
return null; return null;
} }
} }
...@@ -271,6 +271,7 @@ public class RewardServiceImpl extends AbstractService<RewardMapper, RewardDO> i ...@@ -271,6 +271,7 @@ public class RewardServiceImpl extends AbstractService<RewardMapper, RewardDO> i
} }
//校验礼品是否过期并修改礼品状态 //校验礼品是否过期并修改礼品状态
//TODO:异步更新礼品状态
private void validateExpire(RewardDO rewardDO) { private void validateExpire(RewardDO rewardDO) {
if (rewardDO.getStatus() == 1 && rewardDO.getEndTime().toInstant().isBefore(Instant.now())) { if (rewardDO.getStatus() == 1 && rewardDO.getEndTime().toInstant().isBefore(Instant.now())) {
RewardDO expireReward = new RewardDO(); RewardDO expireReward = new RewardDO();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment