|
|
@@ -8,7 +8,6 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.fs.common.BeanCopyUtils;
|
|
|
-import com.fs.common.core.domain.AjaxResult;
|
|
|
import com.fs.common.constant.FsConstants;
|
|
|
import com.fs.common.core.domain.R;
|
|
|
import com.fs.common.core.domain.ResponseResult;
|
|
|
@@ -71,7 +70,6 @@ import com.github.binarywang.wxpay.bean.transfer.TransferBillsResult;
|
|
|
import com.google.common.collect.Sets;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
|
-import org.apache.commons.lang.exception.ExceptionUtils;
|
|
|
import org.apache.rocketmq.spring.core.RocketMQTemplate;
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
import org.redisson.api.RLock;
|
|
|
@@ -93,9 +91,6 @@ import java.text.SimpleDateFormat;
|
|
|
import java.time.*;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.time.temporal.ChronoUnit;
|
|
|
-import java.text.SimpleDateFormat;
|
|
|
-import java.time.*;
|
|
|
-import java.time.format.DateTimeFormatter;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.CompletableFuture;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
@@ -247,15 +242,17 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
@Autowired
|
|
|
private IFsUserCompanyBindService fsUserCompanyBindService;
|
|
|
|
|
|
- @Autowired
|
|
|
- private IFsUserCoursePeriodService fsUserCoursePeriodService;
|
|
|
@Autowired
|
|
|
private BalanceRollbackErrorMapper balanceRollbackErrorMapper;
|
|
|
-
|
|
|
+ @Autowired
|
|
|
+ private IFsUserCoursePeriodService fsUserCoursePeriodService;
|
|
|
|
|
|
@Autowired
|
|
|
private IFsUserCoursePeriodDaysService fsUserCoursePeriodDaysService;
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
* 查询课堂视频
|
|
|
*
|
|
|
@@ -1085,72 +1082,99 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
// if (isWithin10Minutes){
|
|
|
// return R.error("非有效期内,不允许领取!");
|
|
|
// }
|
|
|
- // 获取用户信息
|
|
|
- FsUser user = fsUserMapper.selectFsUserByUserId(param.getUserId());
|
|
|
+ // 生成锁的key,基于用户ID和视频ID确保同一用户同一视频的请求被锁定
|
|
|
+ String lockKey = "reward_lock:user:" + param.getUserId() + ":video:" + param.getVideoId();
|
|
|
+ RLock lock = redissonClient.getLock(lockKey);
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 尝试获取锁,等待时间5秒,锁过期时间30秒
|
|
|
+ boolean isLocked = lock.tryLock(5, 60, TimeUnit.SECONDS);
|
|
|
+ if (!isLocked) {
|
|
|
+ logger.warn("获取锁失败,用户ID:{},视频ID:{}", param.getUserId(), param.getVideoId());
|
|
|
+ return R.error("操作频繁,请稍后再试!");
|
|
|
+ }
|
|
|
+
|
|
|
+ logger.info("成功获取锁,开始处理奖励发放,用户ID:{},视频ID:{}", param.getUserId(), param.getVideoId());
|
|
|
+ // 获取用户信息
|
|
|
+ FsUser user = fsUserMapper.selectFsUserByUserId(param.getUserId());
|
|
|
// if (StringUtils.isEmpty(user.getMpOpenId())){
|
|
|
// return R.error("未识别到领取信息");
|
|
|
// }
|
|
|
- log.info("查询会员信息:{}", user);
|
|
|
- if (user.getStatus()==0){
|
|
|
- return R.error("会员被停用,无权限,请联系客服!");
|
|
|
- }
|
|
|
- FsCourseWatchLog watchLog = new FsCourseWatchLog();
|
|
|
+ log.info("查询会员信息:{}", user);
|
|
|
+ if (user.getStatus()==0){
|
|
|
+ return R.error("会员被停用,无权限,请联系客服!");
|
|
|
+ }
|
|
|
+ FsCourseWatchLog watchLog = new FsCourseWatchLog();
|
|
|
|
|
|
- // 根据链接类型判断是否已发放奖励
|
|
|
- watchLog = courseWatchLogMapper.getWatchCourseVideo(param.getUserId(), param.getVideoId(), param.getQwUserId(), param.getQwExternalId());
|
|
|
- log.info("看课记录:{}", watchLog);
|
|
|
- if (watchLog == null) {
|
|
|
- return R.error("无记录");
|
|
|
- }
|
|
|
- if (watchLog.getLogType() != 2) {
|
|
|
- return R.error("未完课");
|
|
|
- }
|
|
|
- if (watchLog.getRewardType() != null) {
|
|
|
- FsCourseRedPacketLog packetLog = redPacketLogMapper.selectFsCourseRedPacketLogByTemporary(param.getVideoId(), param.getUserId());
|
|
|
- log.info("课程红包:{}", packetLog);
|
|
|
- if(packetLog != null && packetLog.getStatus() == 1) {
|
|
|
- return R.error("已领取该课程奖励,不可重复领取!");
|
|
|
+ // 根据链接类型判断是否已发放奖励
|
|
|
+ watchLog = courseWatchLogMapper.getWatchCourseVideo(param.getUserId(), param.getVideoId(), param.getQwUserId(), param.getQwExternalId());
|
|
|
+ log.info("看课记录:{}", watchLog);
|
|
|
+ if (watchLog == null) {
|
|
|
+ return R.error("无记录");
|
|
|
}
|
|
|
- if(packetLog != null && packetLog.getStatus() == 0) {
|
|
|
- log.info("判断领取记录");
|
|
|
- if(StringUtils.isNotEmpty(packetLog.getResult())){
|
|
|
- log.info("是否有结果");
|
|
|
- R r = JSON.parseObject(packetLog.getResult(), R.class);
|
|
|
- return r;
|
|
|
- } else {
|
|
|
- return R.error("操作频繁,请稍后再试!");
|
|
|
+ if (watchLog.getLogType() != 2) {
|
|
|
+ return R.error("未完课");
|
|
|
+ }
|
|
|
+ if (watchLog.getRewardType() != null) {
|
|
|
+ FsCourseRedPacketLog packetLog = redPacketLogMapper.selectFsCourseRedPacketLogByTemporary(param.getVideoId(), param.getUserId());
|
|
|
+ log.info("课程红包:{}", packetLog);
|
|
|
+ if(packetLog != null && packetLog.getStatus() == 1) {
|
|
|
+ return R.error("已领取该课程奖励,不可重复领取!");
|
|
|
+ }
|
|
|
+ if(packetLog != null && packetLog.getStatus() == 0) {
|
|
|
+ log.info("判断领取记录");
|
|
|
+ if(StringUtils.isNotEmpty(packetLog.getResult())){
|
|
|
+ log.info("是否有结果");
|
|
|
+ R r = JSON.parseObject(packetLog.getResult(), R.class);
|
|
|
+ return r;
|
|
|
+ } else {
|
|
|
+ return R.error("操作频繁,请稍后再试!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(packetLog != null && packetLog.getStatus() == 2) {
|
|
|
+ return R.error("请联系客服补发");
|
|
|
}
|
|
|
+ return R.error("奖励已发放");
|
|
|
+ }
|
|
|
+ // 获取视频信息
|
|
|
+ FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
|
|
|
+
|
|
|
+ // 获取配置信息
|
|
|
+ String json = configService.selectConfigByKey("course.config");
|
|
|
+ CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
|
|
|
+ log.info("奖励类型:{}", config.getRewardType());
|
|
|
+ // 根据奖励类型发放不同奖励
|
|
|
+ switch (config.getRewardType()) {
|
|
|
+ // 红包奖励
|
|
|
+ case 1:
|
|
|
+ return sendRedPacketReward(param, user, watchLog, video, config);
|
|
|
+ // 积分奖励
|
|
|
+ case 2:
|
|
|
+ return sendIntegralReward(param,user, watchLog, config);
|
|
|
+ // 红包+积分
|
|
|
+ case 3:
|
|
|
+ R sendRed = sendRedPacketReward(param, user, watchLog, video, config);
|
|
|
+ if (!Objects.equals(sendRed.get("code"), 200)) {
|
|
|
+ return sendRed;
|
|
|
+ }
|
|
|
+ return sendIntegralReward(param,user, watchLog, config);
|
|
|
+ default:
|
|
|
+ return R.error("参数错误!");
|
|
|
}
|
|
|
- if(packetLog != null && packetLog.getStatus() == 2) {
|
|
|
- return R.error("请联系客服补发");
|
|
|
+// return executeSendRewardBusiness(param);
|
|
|
+
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
+ logger.error("获取锁被中断,用户ID:{},视频ID:{}", param.getUserId(), param.getVideoId(), e);
|
|
|
+ return R.error("系统繁忙,请重试!");
|
|
|
+ } finally {
|
|
|
+ // 释放锁
|
|
|
+ if (lock.isHeldByCurrentThread()) {
|
|
|
+ lock.unlock();
|
|
|
+ logger.info("释放锁成功,用户ID:{},视频ID:{}", param.getUserId(), param.getVideoId());
|
|
|
}
|
|
|
- return R.error("奖励已发放");
|
|
|
}
|
|
|
- // 获取视频信息
|
|
|
- FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
|
|
|
|
|
|
- // 获取配置信息
|
|
|
- String json = configService.selectConfigByKey("course.config");
|
|
|
- CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
|
|
|
- log.info("奖励类型:{}", config.getRewardType());
|
|
|
- // 根据奖励类型发放不同奖励
|
|
|
- switch (config.getRewardType()) {
|
|
|
- // 红包奖励
|
|
|
- case 1:
|
|
|
- return sendRedPacketReward(param, user, watchLog, video, config);
|
|
|
- // 积分奖励
|
|
|
- case 2:
|
|
|
- return sendIntegralReward(param,user, watchLog, config);
|
|
|
- // 红包+积分
|
|
|
- case 3:
|
|
|
- R sendRed = sendRedPacketReward(param, user, watchLog, video, config);
|
|
|
- if (!Objects.equals(sendRed.get("code"), 200)) {
|
|
|
- return sendRed;
|
|
|
- }
|
|
|
- return sendIntegralReward(param,user, watchLog, config);
|
|
|
- default:
|
|
|
- return R.error("参数错误!");
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -1178,22 +1202,60 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
|
|
|
@Override
|
|
|
public R sendRewardByFsUser(FsCourseSendRewardUParam param) {
|
|
|
+ // 生成锁的key,基于用户ID和视频ID确保同一用户同一视频的请求被锁定
|
|
|
+ String lockKey = "reward_lock:user:" + param.getUserId() + ":video:" + param.getVideoId();
|
|
|
+ RLock lock = redissonClient.getLock(lockKey);
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 尝试获取锁,等待时间5秒,锁过期时间30秒
|
|
|
+ boolean isLocked = lock.tryLock(5, 60, TimeUnit.SECONDS);
|
|
|
+ if (!isLocked) {
|
|
|
+ logger.warn("获取锁失败,用户ID:{},视频ID:{}", param.getUserId(), param.getVideoId());
|
|
|
+ return R.error("操作频繁,请稍后再试!");
|
|
|
+ }
|
|
|
+
|
|
|
+ logger.info("成功获取锁,开始处理奖励发放,用户ID:{},视频ID:{}", param.getUserId(), param.getVideoId());
|
|
|
+ return executeSendRewardBusiness(param);
|
|
|
+
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
+ logger.error("获取锁被中断,用户ID:{},视频ID:{}", param.getUserId(), param.getVideoId(), e);
|
|
|
+ return R.error("系统繁忙,请重试!");
|
|
|
+ } finally {
|
|
|
+ // 释放锁
|
|
|
+ if (lock.isHeldByCurrentThread()) {
|
|
|
+ lock.unlock();
|
|
|
+ logger.info("释放锁成功,用户ID:{},视频ID:{}", param.getUserId(), param.getVideoId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 实际的奖励发放业务逻辑
|
|
|
+ */
|
|
|
+ private R executeSendRewardBusiness(FsCourseSendRewardUParam param) {
|
|
|
log.info("进入用户判断");
|
|
|
FsUser user = fsUserMapper.selectFsUserByUserId(param.getUserId());
|
|
|
- if (user == null){
|
|
|
+ if (user == null || user.getStatus()==0){
|
|
|
return R.error("未识别到用户信息");
|
|
|
}
|
|
|
+
|
|
|
FsCourseWatchLog log = courseWatchLogMapper.getWatchCourseVideoByFsUser(param.getUserId(), param.getVideoId(), param.getCompanyUserId());
|
|
|
if (log == null) {
|
|
|
return R.error("无记录");
|
|
|
}
|
|
|
|
|
|
- FsCourseAnswerLogs rightLog = courseAnswerLogsMapper.selectRightLogByCourseVideo(param.getVideoId(), param.getUserId(), param.getQwUserId());
|
|
|
+ if (log.getLogType() != 2){
|
|
|
+ return R.error("未完课");
|
|
|
+ }
|
|
|
|
|
|
+ FsCourseAnswerLogs rightLog = courseAnswerLogsMapper.selectRightLogByCourseVideo(param.getVideoId(), param.getUserId(), param.getQwUserId());
|
|
|
if (rightLog == null) {
|
|
|
logger.error("未答题:{}",param.getUserId());
|
|
|
return R.error("未答题");
|
|
|
}
|
|
|
+
|
|
|
if (log.getRewardType() != null ) {
|
|
|
if (log.getRewardType() == 1){
|
|
|
FsCourseRedPacketLog fsCourseRedPacketLog = redPacketLogMapper.selectUserFsCourseRedPacketLog(param.getVideoId(), param.getUserId(),param.getPeriodId());
|
|
|
@@ -1211,11 +1273,8 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
}else if (log.getRewardType() == 2){
|
|
|
return R.error("已领取该课程奖励,不可重复领取!");
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
// 获取视频信息
|
|
|
FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
|
|
|
|
|
|
@@ -1223,6 +1282,12 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
String json = configService.selectConfigByKey("course.config");
|
|
|
CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
|
|
|
|
|
|
+ // 判断来源是否是app,如是app,则发放积分奖励
|
|
|
+ int sourceApp = 3;
|
|
|
+ if(sourceApp == param.getSource()){
|
|
|
+ return sendIntegralReward(param, user, log, config);
|
|
|
+ }
|
|
|
+
|
|
|
// 根据奖励类型发放不同奖励
|
|
|
switch (config.getRewardType()) {
|
|
|
// 红包奖励
|
|
|
@@ -1321,11 +1386,6 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
logger.info("红包金额 {},红包商户号 {}",amount,packetParam);
|
|
|
//2025.6.19 红包金额为0的时候
|
|
|
if (amount.compareTo(BigDecimal.ZERO)>0){
|
|
|
- Company company = companyMapper.selectCompanyById(param.getCompanyId());
|
|
|
- BigDecimal money = company.getMoney();
|
|
|
- if (money.compareTo(BigDecimal.ZERO)<0) {
|
|
|
- return R.error("服务商余额不足,请联系群主服务器充值!");
|
|
|
- }
|
|
|
// 发送红包
|
|
|
return sendRedPacketRewardToUser(param, log, config, packetParam, amount);
|
|
|
} else {
|
|
|
@@ -1355,32 +1415,6 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
|
|
|
private R sendRedPacketRewardToUser(FsCourseSendRewardUParam param, FsCourseWatchLog log, CourseConfig config, WxSendRedPacketParam packetParam, BigDecimal amount) {
|
|
|
|
|
|
- // 添加分布式锁,防止同一秒内重复点击
|
|
|
- String lockKey = String.format("redPacket:user:%s:video:%s:period:%s",
|
|
|
- param.getUserId(), param.getVideoId(), param.getPeriodId());
|
|
|
- RLock lock = redissonClient.getLock(lockKey);
|
|
|
-
|
|
|
- try {
|
|
|
- // 尝试获取锁(等待3秒,持有10秒)
|
|
|
- boolean locked = lock.tryLock(3, 10, TimeUnit.SECONDS);
|
|
|
- if (!locked) {
|
|
|
- logger.warn("【红包领取】获取锁失败,userId:{}, videoId:{}, periodId:{}",
|
|
|
- param.getUserId(), param.getVideoId(), param.getPeriodId());
|
|
|
- return R.error("系统繁忙,请稍后重试!");
|
|
|
- }
|
|
|
-
|
|
|
- // 双重检查:再次查询是否已经领取过
|
|
|
- FsCourseRedPacketLog existQuery = new FsCourseRedPacketLog();
|
|
|
- existQuery.setUserId(param.getUserId());
|
|
|
- existQuery.setVideoId(param.getVideoId());
|
|
|
- existQuery.setPeriodId(param.getPeriodId());
|
|
|
- List<FsCourseRedPacketLog> existLogs = redPacketLogMapper.selectFsCourseRedPacketLogList(existQuery);
|
|
|
-
|
|
|
- if (existLogs != null && !existLogs.isEmpty()) {
|
|
|
- logger.warn("【红包领取】用户已领取过红包,userId:{}, videoId:{}, periodId:{}, 已存在{}条记录",
|
|
|
- param.getUserId(), param.getVideoId(), param.getPeriodId(), existLogs.size());
|
|
|
- return R.error("已领取该课程奖励,不可重复领取!");
|
|
|
- }
|
|
|
|
|
|
// 发送红包
|
|
|
R sendRedPacket = paymentService.sendRedPacket(packetParam);
|
|
|
@@ -1418,26 +1452,11 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
} else {
|
|
|
return R.error("奖励发送失败,请联系客服");
|
|
|
}
|
|
|
-
|
|
|
- } catch (InterruptedException e) {
|
|
|
- logger.error("【红包领取】获取锁被中断", e);
|
|
|
- Thread.currentThread().interrupt();
|
|
|
- return R.error("系统繁忙,请稍后重试!");
|
|
|
- } catch (Exception e) {
|
|
|
- logger.error("【红包领取】发放红包异常,userId:{}, videoId:{}",
|
|
|
- param.getUserId(), param.getVideoId(), e);
|
|
|
- return R.error("红包发放失败,请联系客服");
|
|
|
- } finally {
|
|
|
- // 释放锁
|
|
|
- if (lock != null && lock.isHeldByCurrentThread()) {
|
|
|
- lock.unlock();
|
|
|
- logger.info("【红包领取】释放锁成功,userId:{}, videoId:{}",
|
|
|
- param.getUserId(), param.getVideoId());
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
|
|
|
+
|
|
|
+
|
|
|
private void handleFsUserWx(FsUser user, String appId) {
|
|
|
FsUserWx fsUserWx = new FsUserWx();
|
|
|
fsUserWx.setType(1);
|
|
|
@@ -1535,17 +1554,61 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
|
|
|
//2025.6.19 红包金额为0的时候
|
|
|
if (amount.compareTo(BigDecimal.ZERO)>0){
|
|
|
+
|
|
|
Company company = companyMapper.selectCompanyById(param.getCompanyId());
|
|
|
BigDecimal money = company.getMoney();
|
|
|
if (money.compareTo(BigDecimal.ZERO)<=0) {
|
|
|
return R.error("服务商余额不足,请联系群主服务器充值!");
|
|
|
}
|
|
|
+
|
|
|
+ // 发送红包
|
|
|
+ R sendRedPacket = paymentService.sendRedPacket(packetParam);
|
|
|
+ if (sendRedPacket.get("code").equals(200)) {
|
|
|
+ FsCourseRedPacketLog redPacketLog = new FsCourseRedPacketLog();
|
|
|
+ TransferBillsResult transferBillsResult;
|
|
|
+ if (sendRedPacket.get("isNew").equals(1)){
|
|
|
+ transferBillsResult = (TransferBillsResult)sendRedPacket.get("data");
|
|
|
+ redPacketLog.setResult(JSON.toJSONString(sendRedPacket));
|
|
|
+ redPacketLog.setOutBatchNo(transferBillsResult.getOutBillNo());
|
|
|
+ redPacketLog.setBatchId(transferBillsResult.getTransferBillNo());
|
|
|
+ }else {
|
|
|
+ redPacketLog.setOutBatchNo(sendRedPacket.get("orderCode").toString());
|
|
|
+ redPacketLog.setBatchId(sendRedPacket.get("batchId").toString());
|
|
|
+ }
|
|
|
+ // 添加红包记录
|
|
|
+ redPacketLog.setCourseId(param.getCourseId());
|
|
|
+ redPacketLog.setCompanyId(param.getCompanyId());
|
|
|
+ redPacketLog.setUserId(param.getUserId());
|
|
|
+ redPacketLog.setVideoId(param.getVideoId());
|
|
|
+ redPacketLog.setStatus(0);
|
|
|
+ redPacketLog.setQwUserId(param.getQwUserId() != null ? param.getQwUserId() : null);
|
|
|
+ redPacketLog.setCompanyUserId(param.getCompanyUserId());
|
|
|
+ redPacketLog.setCreateTime(new Date());
|
|
|
+ redPacketLog.setAmount(amount);
|
|
|
+ redPacketLog.setWatchLogId(log.getLogId() != null ? log.getLogId() : null);
|
|
|
+ redPacketLog.setPeriodId(param.getPeriodId());
|
|
|
+ redPacketLog.setAppId(param.getAppId());
|
|
|
+
|
|
|
+ redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
|
|
|
+
|
|
|
+ // 更新观看记录的奖励类型
|
|
|
+ log.setRewardType(config.getRewardType());
|
|
|
+ courseWatchLogMapper.updateFsCourseWatchLog(log);
|
|
|
+
|
|
|
+ return sendRedPacket;
|
|
|
+ } else {
|
|
|
+ return R.error("奖励发送失败,请联系客服");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 先注释 20251024 redis 余额 充值没有考虑 其余扣减没有考虑
|
|
|
// ===================== 20251022 xgb 修改 本次修改目的为了实时扣减公司余额=====================
|
|
|
// 1 使用redis缓存加锁 预扣减余额 红包发送失败 恢复redis缓存余额,如果回滚失败登记异常记录表 定时任务重新回滚余额
|
|
|
// 2 另起定时任务 同步缓存余额到redis中
|
|
|
// 3 启动系统时查询公司账户余额(这个时候要保证余额正确)保存到redis缓存中
|
|
|
|
|
|
+
|
|
|
// 预设值异常对象
|
|
|
+ /*
|
|
|
BalanceRollbackError balanceRollbackError = new BalanceRollbackError();
|
|
|
balanceRollbackError.setCompanyId(packetParam.getCompanyId());
|
|
|
balanceRollbackError.setUserId(user.getUserId());
|
|
|
@@ -1603,6 +1666,8 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
// 调用第三方接口(锁外操作)
|
|
|
R sendRedPacket;
|
|
|
try {
|
|
|
@@ -1611,7 +1676,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
logger.error("红包发送异常: 异常请求参数{}",packetParam, e);
|
|
|
// 异常时回滚余额
|
|
|
|
|
|
- rollbackBalance(balanceRollbackError);
|
|
|
+// rollbackBalance(balanceRollbackError);
|
|
|
return R.error("奖励发送失败,请联系客服");
|
|
|
}
|
|
|
|
|
|
@@ -1649,12 +1714,14 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
courseWatchLogMapper.updateFsCourseWatchLog(log);
|
|
|
// 发送成功,记录日志等操作
|
|
|
return sendRedPacket;
|
|
|
+
|
|
|
+
|
|
|
} else {
|
|
|
// 发送失败,回滚余额
|
|
|
- rollbackBalance(balanceRollbackError);
|
|
|
+// rollbackBalance(balanceRollbackError);
|
|
|
return R.error("奖励发送失败,请联系客服");
|
|
|
}
|
|
|
-
|
|
|
+ */
|
|
|
// ===================== 本次修改目的为了实时扣减公司余额=====================
|
|
|
} else {
|
|
|
FsCourseRedPacketLog redPacketLog = new FsCourseRedPacketLog();
|
|
|
@@ -1871,7 +1938,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
redPacketLog.setWatchLogId(log.getLogId() !=null ? log.getLogId() : null);
|
|
|
redPacketLog.setPeriodId(param.getPeriodId());
|
|
|
redPacketLogMapper.insertFsCourseRedPacketLog(redPacketLog);
|
|
|
- return R.ok("奖励发放成功").put("rewardType",config.getRewardType());
|
|
|
+ return R.ok("积分奖励发放成功").put("rewardType",config.getRewardType());
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -2479,6 +2546,7 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
@Override
|
|
|
public void batchUpdateRed(List<BatchRedUpdate> list) {
|
|
|
list.forEach(e -> {
|