|
@@ -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;
|
|
|
|
|
|
/**
|
|
|
* 查询课堂视频
|
|
@@ -1024,6 +1038,9 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
if (log == null) {
|
|
|
return R.error("无记录");
|
|
|
}
|
|
|
+ if (log.getLogType() != 2) {
|
|
|
+ return R.error("未完课");
|
|
|
+ }
|
|
|
if (log.getRewardType() != null) {
|
|
|
FsCourseRedPacketLog packetLog = redPacketLogMapper.selectFsCourseRedPacketLogByTemporary(param.getVideoId(), param.getUserId());
|
|
|
if(packetLog != null && packetLog.getStatus() == 1) {
|
|
@@ -1239,6 +1256,25 @@ 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) {
|
|
|
+ userCount = 0;
|
|
|
+ long expireSeconds = getExpireSeconds();
|
|
|
+ redisTemplateInteger.opsForValue().set(userLimitKey, userCount, expireSeconds, TimeUnit.SECONDS);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(userCount >= RED_PACKET_LIMIT_COUNT){
|
|
|
+ logger.info("[红包领取] 用户{} 领取红包已经达到最大限制!",param.getUserId());
|
|
|
+ return R.error("[红包领取] 当前用户当前已经领取红包已经达到限制!");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
BigDecimal companyMoney = null;
|
|
|
if(StringUtils.equals(ENABLE_RED_PACK_ACCOUNT,"1")) {
|
|
|
companyMoney = redisTemplate.opsForValue().get(REDPACKET_COMPANY_MONEY);
|
|
@@ -1300,12 +1336,28 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
companyMoney = companyMoney.subtract(amount);
|
|
|
redisTemplate.opsForValue().set(REDPACKET_COMPANY_MONEY,companyMoney);
|
|
|
}
|
|
|
+
|
|
|
+ // 用户领取红包次数+1
|
|
|
+ redisTemplateInteger.opsForValue().increment(userLimitKey, 1);
|
|
|
+
|
|
|
return sendRedPacket;
|
|
|
} else {
|
|
|
return R.error("奖励发送失败,请联系客服");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private static long getExpireSeconds() {
|
|
|
+ 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;
|
|
|
+ return expireSeconds;
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
private void handleFsUserWx(FsUser user, String appId) {
|
|
|
FsUserWx fsUserWx = new FsUserWx();
|
|
@@ -1421,6 +1473,24 @@ 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) {
|
|
|
+ userCount = 0;
|
|
|
+ long expireSeconds = getExpireSeconds();
|
|
|
+ redisTemplateInteger.opsForValue().set(userLimitKey, userCount, expireSeconds, TimeUnit.SECONDS);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(userCount >= RED_PACKET_LIMIT_COUNT){
|
|
|
+ logger.info("[红包领取] 用户{} 领取红包已经达到最大限制!",param.getUserId());
|
|
|
+ return R.error("[红包领取] 当前用户当前已经领取红包已经达到限制!");
|
|
|
+ }
|
|
|
+
|
|
|
BigDecimal companyMoney = null;
|
|
|
if(StringUtils.equals(ENABLE_RED_PACK_ACCOUNT,"1")) {
|
|
|
companyMoney = redisTemplate.opsForValue().get(REDPACKET_COMPANY_MONEY);
|
|
@@ -1484,6 +1554,8 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
redisTemplate.opsForValue().set(REDPACKET_COMPANY_MONEY,companyMoney);
|
|
|
}
|
|
|
|
|
|
+ // 用户领取红包次数+1
|
|
|
+ redisTemplateInteger.opsForValue().increment(userLimitKey, 1);
|
|
|
return sendRedPacket;
|
|
|
} else {
|
|
|
return R.error("奖励发送失败,请联系客服");
|
|
@@ -1796,7 +1868,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
}
|
|
|
|
|
|
// 查询【用户-项目】关系
|
|
|
- FsUserCompanyUser userCompanyUser = userCompanyUserService.selectByUserIdAndProjectId(fsUser.getUserId(), courseProject);
|
|
|
+ FsUserCompanyUser userCompanyUser = userCompanyUserService.selectByUserIdAndProjectId(fsUser.getUserId(), courseProject,companyUser.getUserId());
|
|
|
|
|
|
// 添加逻辑:如果存在fs_user表数据,但是又不存在fs_user_company_user表,则表示是以前企微看课的,需要手动绑定
|
|
|
if(Objects.isNull(userCompanyUser)) {
|
|
@@ -2856,3 +2928,4 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
}
|
|
|
|
|
|
}
|
|
|
+
|