|
@@ -4,6 +4,7 @@ import com.seamew.lottery.common.Constants;
|
|
|
import com.seamew.lottery.common.Result;
|
|
|
import com.seamew.lottery.domain.activity.model.req.PartakeReq;
|
|
|
import com.seamew.lottery.domain.activity.model.res.PartakeResult;
|
|
|
+import com.seamew.lottery.domain.activity.model.res.StockResult;
|
|
|
import com.seamew.lottery.domain.activity.model.vo.ActivityBillVO;
|
|
|
import com.seamew.lottery.domain.activity.model.vo.UserTakeActivityVO;
|
|
|
import com.seamew.lottery.domain.support.ids.IIdGenerator;
|
|
@@ -29,7 +30,7 @@ public abstract class BaseActivityPartake extends ActivityPartakeSupport impleme
|
|
|
// 1. 查询是否存在未执行抽奖领取活动单【user_take_activity 存在 state = 0,领取了但抽奖过程失败的,可以直接返回领取结果继续抽奖】
|
|
|
UserTakeActivityVO userTakeActivityVO = queryNoConsumedTakeActivityOrder(req.getActivityId(), req.getUId());
|
|
|
if (null != userTakeActivityVO) {
|
|
|
- return buildPartakeResult(userTakeActivityVO.getStrategyId(), userTakeActivityVO.getTakeId());
|
|
|
+ return buildPartakeResult(userTakeActivityVO.getStrategyId(), userTakeActivityVO.getTakeId(), Constants.ResponseCode.NOT_CONSUMED_TAKE);
|
|
|
}
|
|
|
|
|
|
// 2. 查询活动账单
|
|
@@ -41,9 +42,11 @@ public abstract class BaseActivityPartake extends ActivityPartakeSupport impleme
|
|
|
return new PartakeResult(checkResult.getCode(), checkResult.getInfo());
|
|
|
}
|
|
|
|
|
|
- // 4. 扣减活动库存【目前为直接对配置库中的 lottery.activity 直接操作表扣减库存,后续优化为Redis扣减】
|
|
|
- Result subtractionActivityResult = subtractionActivityStock(req);
|
|
|
+ // 4. 扣减活动库存,通过Redis【活动库存扣减编号,作为锁的Key,缩小颗粒度】 Begin
|
|
|
+ StockResult subtractionActivityResult = subtractionActivityStockByRedis(req.getUId(), req.getActivityId(), activityBillVO.getStockCount());
|
|
|
+
|
|
|
if (!Constants.ResponseCode.SUCCESS.getCode().equals(subtractionActivityResult.getCode())) {
|
|
|
+ recoverActivityCacheStockByRedis(req.getActivityId(), subtractionActivityResult.getStockKey(), subtractionActivityResult.getCode());
|
|
|
return new PartakeResult(subtractionActivityResult.getCode(), subtractionActivityResult.getInfo());
|
|
|
}
|
|
|
|
|
@@ -51,10 +54,33 @@ public abstract class BaseActivityPartake extends ActivityPartakeSupport impleme
|
|
|
Long takeId = idGeneratorMap.get(Constants.Ids.SnowFlake).nextId();
|
|
|
Result grabResult = grabActivity(req, activityBillVO, takeId);
|
|
|
if (!Constants.ResponseCode.SUCCESS.getCode().equals(grabResult.getCode())) {
|
|
|
+ recoverActivityCacheStockByRedis(req.getActivityId(), subtractionActivityResult.getStockKey(), grabResult.getCode());
|
|
|
return new PartakeResult(grabResult.getCode(), grabResult.getInfo());
|
|
|
}
|
|
|
|
|
|
- return buildPartakeResult(activityBillVO.getStrategyId(), takeId);
|
|
|
+ // 6. 扣减活动库存,通过Redis End
|
|
|
+ recoverActivityCacheStockByRedis(req.getActivityId(), subtractionActivityResult.getStockKey(), Constants.ResponseCode.SUCCESS.getCode());
|
|
|
+
|
|
|
+ return buildPartakeResult(activityBillVO.getStrategyId(), takeId, activityBillVO.getStockCount(), subtractionActivityResult.getStockSurplusCount(), Constants.ResponseCode.SUCCESS);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 封装结果【返回的策略ID,用于继续完成抽奖步骤】
|
|
|
+ *
|
|
|
+ * @param strategyId 策略ID
|
|
|
+ * @param takeId 领取ID
|
|
|
+ * @param stockCount 库存
|
|
|
+ * @param stockSurplusCount 剩余库存
|
|
|
+ * @param code 状态码
|
|
|
+ * @return 封装结果
|
|
|
+ */
|
|
|
+ private PartakeResult buildPartakeResult(Long strategyId, Long takeId, Integer stockCount, Integer stockSurplusCount, Constants.ResponseCode code) {
|
|
|
+ PartakeResult partakeResult = new PartakeResult(code.getCode(), code.getInfo());
|
|
|
+ partakeResult.setStrategyId(strategyId);
|
|
|
+ partakeResult.setTakeId(takeId);
|
|
|
+ partakeResult.setStockCount(stockCount);
|
|
|
+ partakeResult.setStockSurplusCount(stockSurplusCount);
|
|
|
+ return partakeResult;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -62,10 +88,11 @@ public abstract class BaseActivityPartake extends ActivityPartakeSupport impleme
|
|
|
*
|
|
|
* @param strategyId 策略ID
|
|
|
* @param takeId 领取ID
|
|
|
+ * @param code 状态码
|
|
|
* @return 封装结果
|
|
|
*/
|
|
|
- private PartakeResult buildPartakeResult(Long strategyId, Long takeId) {
|
|
|
- PartakeResult partakeResult = new PartakeResult(Constants.ResponseCode.SUCCESS.getCode(), Constants.ResponseCode.SUCCESS.getInfo());
|
|
|
+ private PartakeResult buildPartakeResult(Long strategyId, Long takeId, Constants.ResponseCode code) {
|
|
|
+ PartakeResult partakeResult = new PartakeResult(code.getCode(), code.getInfo());
|
|
|
partakeResult.setStrategyId(strategyId);
|
|
|
partakeResult.setTakeId(takeId);
|
|
|
return partakeResult;
|
|
@@ -97,6 +124,25 @@ public abstract class BaseActivityPartake extends ActivityPartakeSupport impleme
|
|
|
*/
|
|
|
protected abstract Result subtractionActivityStock(PartakeReq req);
|
|
|
|
|
|
+ /**
|
|
|
+ * 扣减活动库存,通过Redis
|
|
|
+ *
|
|
|
+ * @param uId 用户ID
|
|
|
+ * @param activityId 活动号
|
|
|
+ * @param stockCount 总库存
|
|
|
+ * @return 扣减结果
|
|
|
+ */
|
|
|
+ protected abstract StockResult subtractionActivityStockByRedis(String uId, Long activityId, Integer stockCount);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 恢复活动库存,通过Redis 【如果非常异常,则需要进行缓存库存恢复,只保证不超卖的特性,所以不保证一定能恢复占用库存,另外最终可以由任务进行补偿库存】
|
|
|
+ *
|
|
|
+ * @param activityId 活动ID
|
|
|
+ * @param tokenKey 分布式 KEY 用于清理
|
|
|
+ * @param code 状态
|
|
|
+ */
|
|
|
+ protected abstract void recoverActivityCacheStockByRedis(Long activityId, String tokenKey, String code);
|
|
|
+
|
|
|
/**
|
|
|
* 领取活动
|
|
|
*
|