|
@@ -89,6 +89,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
import java.time.*;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.util.*;
|
|
@@ -125,6 +126,11 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
*/
|
|
|
private static final String REDPACKET_COMPANY_MONEY = "redpacket_money";
|
|
|
|
|
|
+ /**
|
|
|
+ * 用户领取红包限制
|
|
|
+ */
|
|
|
+ private static final String REDPACKET_USER_LIMIT = "redpacket_user_limit:%s:%d";
|
|
|
+
|
|
|
/**
|
|
|
* 红包改变记录
|
|
|
*/
|
|
@@ -255,6 +261,14 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
@Autowired
|
|
|
private RedisTemplate<String,BigDecimal> redisTemplate;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private RedisTemplate<String,Integer> redisTemplateInteger;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 红包领取数量限制 默认一个用户当天最多只能领取10个
|
|
|
+ */
|
|
|
+ @Value("${RED_PACKET_LIMIT_COUNT:10}")
|
|
|
+ private Integer RED_PACKET_LIMIT_COUNT;
|
|
|
|
|
|
/**
|
|
|
* 查询课堂视频
|
|
@@ -1245,6 +1259,18 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
|
|
|
private R sendRedPacketRewardToUser(FsCourseSendRewardUParam param, FsCourseWatchLog log, CourseConfig config, WxSendRedPacketParam packetParam, BigDecimal amount) {
|
|
|
|
|
|
+ // 判断当前用户是否限流
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
|
|
|
+ String today = sdf.format(new Date());
|
|
|
+ String userLimitKey = String.format(REDPACKET_USER_LIMIT, today, param.getUserId());
|
|
|
+ Integer userCount = redisTemplateInteger.opsForValue().get(userLimitKey);
|
|
|
+
|
|
|
+ if(userCount != null){
|
|
|
+ if(userCount >= RED_PACKET_LIMIT_COUNT){
|
|
|
+ return R.error("[红包领取] 当前用户当前已经领取红包已经达到限制!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
BigDecimal companyMoney = null;
|
|
|
if(StringUtils.equals(ENABLE_RED_PACK_ACCOUNT,"1")) {
|
|
|
companyMoney = redisTemplate.opsForValue().get(REDPACKET_COMPANY_MONEY);
|
|
@@ -1306,6 +1332,20 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
companyMoney = companyMoney.subtract(amount);
|
|
|
redisTemplate.opsForValue().set(REDPACKET_COMPANY_MONEY,companyMoney);
|
|
|
}
|
|
|
+
|
|
|
+ // 用户领取红包次数+1
|
|
|
+ redisTemplateInteger.opsForValue().increment(userLimitKey, 1);
|
|
|
+ // 设置过期时间为第二天凌晨0点
|
|
|
+ Calendar calendar = Calendar.getInstance();
|
|
|
+ calendar.add(Calendar.DAY_OF_YEAR, 1);
|
|
|
+ calendar.set(Calendar.HOUR_OF_DAY, 0);
|
|
|
+ calendar.set(Calendar.MINUTE, 0);
|
|
|
+ calendar.set(Calendar.SECOND, 0);
|
|
|
+ calendar.set(Calendar.MILLISECOND, 0);
|
|
|
+ // 计算从现在到明天凌晨的秒数
|
|
|
+ long expireSeconds = (calendar.getTimeInMillis() - System.currentTimeMillis()) / 1000;
|
|
|
+ // 设置过期时间
|
|
|
+ redisTemplateInteger.expire(userLimitKey, expireSeconds, TimeUnit.SECONDS);
|
|
|
return sendRedPacket;
|
|
|
} else {
|
|
|
return R.error("奖励发送失败,请联系客服");
|
|
@@ -1427,6 +1467,18 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
return R.error("[红包领取] 系统繁忙,请重试!");
|
|
|
}
|
|
|
|
|
|
+ // 判断当前用户是否限流
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
|
|
|
+ String today = sdf.format(new Date());
|
|
|
+ String userLimitKey = String.format(REDPACKET_USER_LIMIT, today, param.getUserId());
|
|
|
+ Integer userCount = redisTemplateInteger.opsForValue().get(userLimitKey);
|
|
|
+
|
|
|
+ if(userCount != null){
|
|
|
+ if(userCount >= RED_PACKET_LIMIT_COUNT){
|
|
|
+ return R.error("[红包领取] 当前用户当前已经领取红包已经达到限制!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
BigDecimal companyMoney = null;
|
|
|
if(StringUtils.equals(ENABLE_RED_PACK_ACCOUNT,"1")) {
|
|
|
companyMoney = redisTemplate.opsForValue().get(REDPACKET_COMPANY_MONEY);
|
|
@@ -1490,6 +1542,20 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
redisTemplate.opsForValue().set(REDPACKET_COMPANY_MONEY,companyMoney);
|
|
|
}
|
|
|
|
|
|
+ // 用户领取红包次数+1
|
|
|
+ redisTemplateInteger.opsForValue().increment(userLimitKey, 1);
|
|
|
+ // 设置过期时间为第二天凌晨0点
|
|
|
+ Calendar calendar = Calendar.getInstance();
|
|
|
+ calendar.add(Calendar.DAY_OF_YEAR, 1);
|
|
|
+ calendar.set(Calendar.HOUR_OF_DAY, 0);
|
|
|
+ calendar.set(Calendar.MINUTE, 0);
|
|
|
+ calendar.set(Calendar.SECOND, 0);
|
|
|
+ calendar.set(Calendar.MILLISECOND, 0);
|
|
|
+ // 计算从现在到明天凌晨的秒数
|
|
|
+ long expireSeconds = (calendar.getTimeInMillis() - System.currentTimeMillis()) / 1000;
|
|
|
+ // 设置过期时间
|
|
|
+ redisTemplateInteger.expire(userLimitKey, expireSeconds, TimeUnit.SECONDS);
|
|
|
+
|
|
|
return sendRedPacket;
|
|
|
} else {
|
|
|
return R.error("奖励发送失败,请联系客服");
|
|
@@ -2861,3 +2927,4 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
}
|
|
|
|
|
|
}
|
|
|
+
|