抽奖接口加锁

This commit is contained in:
谭凯凯
2025-01-13 16:57:43 +08:00
committed by Tankaikai
parent 53c5bd3fb8
commit 381d40d699

View File

@@ -1,11 +1,13 @@
package com.sqx.modules.discSpinning.controller; package com.sqx.modules.discSpinning.controller;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import com.sqx.common.annotation.Debounce; import com.sqx.common.annotation.Debounce;
import com.sqx.common.exception.CzgException; import com.sqx.common.exception.CzgException;
import com.sqx.common.exception.SqxException;
import com.sqx.common.utils.*; import com.sqx.common.utils.*;
import com.sqx.modules.app.annotation.Login; import com.sqx.modules.app.annotation.Login;
import com.sqx.modules.app.service.UserInfoService; import com.sqx.modules.app.service.UserInfoService;
@@ -54,7 +56,7 @@ public class DiscSpinningController {
public DiscSpinningController(CommonInfoService commonRepository, DiscSpinningService discSpinningService, public DiscSpinningController(CommonInfoService commonRepository, DiscSpinningService discSpinningService,
OrdersService ordersService, DiscSpinningRecordService recordService, OrdersService ordersService, DiscSpinningRecordService recordService,
TaskCenterService taskCenterService, UserService userService, RedisUtils redisUtils, TaskCenterService taskCenterService, UserService userService, RedisUtils redisUtils,
TaskCenterRecordService taskRecordService,UserInfoService userInfoService) { TaskCenterRecordService taskRecordService, UserInfoService userInfoService) {
this.commonRepository = commonRepository; this.commonRepository = commonRepository;
this.discSpinningService = discSpinningService; this.discSpinningService = discSpinningService;
this.ordersService = ordersService; this.ordersService = ordersService;
@@ -175,76 +177,99 @@ public class DiscSpinningController {
@ApiOperation("抽取大转盘") @ApiOperation("抽取大转盘")
@Debounce(value = "#userId") @Debounce(value = "#userId")
public Result draw(@ApiIgnore @RequestAttribute("userId") Long userId, @RequestParam(required = false, defaultValue = "1") Integer source) throws CzgException { public Result draw(@ApiIgnore @RequestAttribute("userId") Long userId, @RequestParam(required = false, defaultValue = "1") Integer source) throws CzgException {
double amount = 0; String lockKey = StrUtil.format("user:disc-spinning:limit:user:lock:{}", userId);
Long sourceId = null; if (redisUtils.hasKey(lockKey)) {
Integer i = recordService.countDraw(userId); return Result.error("抽奖进行中,请等待!");
if ((i != null && i.equals(2)) || !source.equals(1)) {
boolean auth = userInfoService.isAuth(userId);
if(!auth) {
return Result.error("剩余抽奖活动需要实名认证后进行");
}
} }
if (source == null || source.equals(1)) { String intervalKey = StrUtil.format("user:disc-spinning:interval:limit:user:{}", userId);
source = 1; if (redisUtils.hasKey(intervalKey)) {
//订单抽奖 return Result.error("抽奖请求过于频繁,请稍后再试!");
int drawCount = Integer.parseInt(commonRepository.findOne(901).getValue()); }
if (i != null && i >= drawCount) { redisUtils.set(lockKey, true, 30);
throw new CzgException("当日可抽奖次数已超限"); Result ret = Result.error();
} try {
Orders orders = ordersService.selectOrdersByDay(userId); double amount = 0;
if (orders == null) { Long sourceId = null;
throw new CzgException("无可抽奖机会"); Integer i = recordService.countDraw(userId);
} if ((i != null && i.equals(2)) || !source.equals(1)) {
amount = orders.getPayMoney().doubleValue(); boolean auth = userInfoService.isAuth(userId);
sourceId = orders.getOrdersId(); if (!auth) {
} else { return Result.error("剩余抽奖活动需要实名认证后进行");
String redisKey = "";
if (source.equals(2)) {
redisKey = RedisKeys.getDateKey("spinning:amount:taskW") + userId;
} else if (source.equals(3)) {
redisKey = RedisKeys.getDateKey("spinning:amount:taskM") + userId;
}
Map<String, Object> week = redisUtils.get(redisKey, Map.class);
for (Map.Entry<String, Object> entry : week.entrySet()) {
int value = new BigDecimal(entry.getValue().toString()).intValue();
if (value > 1) {
value = value - 1;
week.put(entry.getKey(), value);
sourceId = Long.valueOf(entry.getKey());
break;
} else {
TaskCenterRecord centerRecord = new TaskCenterRecord();
centerRecord.setUserId(userId);
centerRecord.setTaskId(Long.valueOf(entry.getKey()));
if (source.equals(2)) {
sourceId = Long.valueOf(entry.getKey());
centerRecord.setSourceId(sourceId);
}
centerRecord.setName(source.equals(2) ? "周任务奖励" : "月任务奖励");
centerRecord.setType(9);
centerRecord.setNumber(1);
centerRecord.setCreateTime(DateUtil.now());
centerRecord.setUpdateTime(DateUtil.now());
taskRecordService.save(centerRecord);
week.remove(entry.getKey());
break;
} }
} }
redisUtils.set(redisKey, week, DateUtils.todayAfterSecond()); if (source == null || source.equals(1)) {
} source = 1;
if (source == 1 && sourceId == null) { //订单抽奖
throw new CzgException("异常请求"); int drawCount = Integer.parseInt(commonRepository.findOne(901).getValue());
} if (i != null && i >= drawCount) {
if(sourceId == null){ throw new CzgException("当日可抽奖次数已超限");
return Result.error("请求失败,请联系管理员"); }
} Orders orders = ordersService.selectOrdersByDay(userId);
if (DataLimitUtil.isAllowed(RedisKeys.getDateKey("spinning:draw:") + sourceId, 120)) { if (orders == null) {
DiscSpinningRecord draws = discSpinningService.draws(i == null ? 1 : i + 1, amount, sourceId, userId, source); throw new CzgException("无可抽奖机会");
executor.schedule(() -> discSpinningService.receive1(draws), 4, TimeUnit.SECONDS); }
return new Result().put("data", draws); amount = orders.getPayMoney().doubleValue();
} else { sourceId = orders.getOrdersId();
throw new CzgException("异常请求"); } else {
String redisKey = "";
if (source.equals(2)) {
redisKey = RedisKeys.getDateKey("spinning:amount:taskW") + userId;
} else if (source.equals(3)) {
redisKey = RedisKeys.getDateKey("spinning:amount:taskM") + userId;
}
Map<String, Object> week = redisUtils.get(redisKey, Map.class);
for (Map.Entry<String, Object> entry : week.entrySet()) {
int value = new BigDecimal(entry.getValue().toString()).intValue();
if (value > 1) {
value = value - 1;
week.put(entry.getKey(), value);
sourceId = Long.valueOf(entry.getKey());
break;
} else {
TaskCenterRecord centerRecord = new TaskCenterRecord();
centerRecord.setUserId(userId);
centerRecord.setTaskId(Long.valueOf(entry.getKey()));
if (source.equals(2)) {
sourceId = Long.valueOf(entry.getKey());
centerRecord.setSourceId(sourceId);
}
centerRecord.setName(source.equals(2) ? "周任务奖励" : "月任务奖励");
centerRecord.setType(9);
centerRecord.setNumber(1);
centerRecord.setCreateTime(DateUtil.now());
centerRecord.setUpdateTime(DateUtil.now());
taskRecordService.save(centerRecord);
week.remove(entry.getKey());
break;
}
}
redisUtils.set(redisKey, week, DateUtils.todayAfterSecond());
}
if (source == 1 && sourceId == null) {
throw new CzgException("异常请求");
}
if (sourceId == null) {
return Result.error("请求失败,请联系管理员");
}
if (DataLimitUtil.isAllowed(RedisKeys.getDateKey("spinning:draw:") + sourceId, 120)) {
DiscSpinningRecord draws = discSpinningService.draws(i == null ? 1 : i + 1, amount, sourceId, userId, source);
executor.schedule(() -> discSpinningService.receive1(draws), 4, TimeUnit.SECONDS);
redisUtils.set(intervalKey, true, 5);
return new Result().put("data", draws);
} else {
throw new CzgException("异常请求");
}
} catch (CzgException e) {
throw e;
} catch (SqxException e) {
ret.put("msg", e.getMsg());
} catch (Exception e) {
log.error("抽奖异常", e);
ret.put("msg", "请求失败,请联系管理员");
} finally {
redisUtils.delete(lockKey);
} }
return ret;
} }
@ApiOperation("大转盘奖项领取") @ApiOperation("大转盘奖项领取")