|
|
@@ -1291,15 +1291,16 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
|
|
|
|
|
|
// 发送红包
|
|
|
- R sendRedPacket = paymentService.sendRedPacket(packetParam);
|
|
|
+ R sendRedPacket = paymentService.sendRedPacket(packetParam);
|
|
|
+ logger.error("红包发送结果:{}", sendRedPacket);
|
|
|
if (sendRedPacket.get("code").equals(200)) {
|
|
|
FsCourseRedPacketLog redPacketLog = new FsCourseRedPacketLog();
|
|
|
TransferBillsResult transferBillsResult;
|
|
|
- if (sendRedPacket.get("isNew").equals(1)){
|
|
|
- transferBillsResult = (TransferBillsResult)sendRedPacket.get("data");
|
|
|
+ if (sendRedPacket.get("isNew").equals(1)) {
|
|
|
+ transferBillsResult = (TransferBillsResult) sendRedPacket.get("data");
|
|
|
redPacketLog.setResult(JSON.toJSONString(sendRedPacket));
|
|
|
redPacketLog.setOutBatchNo(transferBillsResult.getOutBillNo());
|
|
|
- }else {
|
|
|
+ } else {
|
|
|
redPacketLog.setOutBatchNo(sendRedPacket.get("orderCode").toString());
|
|
|
}
|
|
|
// 添加红包记录
|
|
|
@@ -2962,6 +2963,198 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
return R.ok();
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ @Transactional
|
|
|
+ public R sendAppRewardByFsUser(FsCourseSendRewardUParam param) {
|
|
|
+ Long userId = param.getUserId();
|
|
|
+ // 生成锁的key,基于用户ID和视频ID确保同一用户同一视频的请求被锁定
|
|
|
+ String lockKey = "reward_integral_lock:user:" + userId;
|
|
|
+ RLock lock = redissonClient.getLock(lockKey);
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 尝试获取锁,等待时间5秒,锁过期时间30秒
|
|
|
+ boolean isLocked = lock.tryLock(5, 300, TimeUnit.SECONDS);
|
|
|
+ if (!isLocked) {
|
|
|
+ logger.warn("获取锁失败,用户ID:{}", userId);
|
|
|
+ return R.error("操作频繁,请稍后再试!");
|
|
|
+ }
|
|
|
+
|
|
|
+ logger.info("成功获取锁,开始处理奖励发放,用户ID:{}", userId);
|
|
|
+ return executeAppReward(param);
|
|
|
+
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
+ logger.error("获取锁被中断,用户ID:{}", userId, e);
|
|
|
+ return R.error("系统繁忙,请重试!");
|
|
|
+ } finally {
|
|
|
+ // 释放锁
|
|
|
+ if (lock.isHeldByCurrentThread()) {
|
|
|
+ lock.unlock();
|
|
|
+ logger.info("释放锁成功,用户ID:{}", userId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private R executeAppReward(FsCourseSendRewardUParam param){
|
|
|
+ //查询可提现
|
|
|
+ Long userId = param.getUserId();
|
|
|
+ FsUser user = fsUserMapper.selectFsUserById(userId);
|
|
|
+ if (user == null) {
|
|
|
+ return R.error("用户不存在");
|
|
|
+ }
|
|
|
+ //拉黑用户不能提现
|
|
|
+ if (user.getStatus() == 0){
|
|
|
+ return R.error("暂无法提现!");
|
|
|
+ }
|
|
|
+ if (StringUtils.isBlank(user.getAppOpenId())){
|
|
|
+ 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 (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());
|
|
|
+ if(fsCourseRedPacketLog != null && fsCourseRedPacketLog.getStatus() == 1) {
|
|
|
+ return R.error("已领取该课程奖励,不可重复领取!");
|
|
|
+ }
|
|
|
+ if(fsCourseRedPacketLog != null && fsCourseRedPacketLog.getStatus() == 0) {
|
|
|
+ if(StringUtils.isNotEmpty(fsCourseRedPacketLog.getResult())){
|
|
|
+ R r = JSON.parseObject(fsCourseRedPacketLog.getResult(), R.class);
|
|
|
+ return r;
|
|
|
+ } else {
|
|
|
+ return R.error("操作频繁,请稍后再试!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else if (log.getRewardType() == 2){
|
|
|
+ return R.error("已领取该课程奖励,不可重复领取!");
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ // 获取视频信息
|
|
|
+ FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
|
|
|
+
|
|
|
+ // 获取配置信息
|
|
|
+ String json = configService.selectConfigByKey("course.config");
|
|
|
+ CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
|
|
|
+ try {
|
|
|
+ // 红包奖励
|
|
|
+ return sendAppRedPacketRewardFsUser(param, user, log, video, config);
|
|
|
+ } catch (CustomException e) {
|
|
|
+ return R.error(e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 发放红包奖励
|
|
|
+ *
|
|
|
+ * @param param 请求参数
|
|
|
+ * @param user 用户信息
|
|
|
+ * @param log 观看日志
|
|
|
+ * @param video 视频信息
|
|
|
+ * @param config 配置信息
|
|
|
+ * @return 处理结果
|
|
|
+ */
|
|
|
+ private R sendAppRedPacketRewardFsUser(FsCourseSendRewardUParam param, FsUser user, FsCourseWatchLog log, FsUserCourseVideo video, CourseConfig config) {
|
|
|
+
|
|
|
+ FsUserCoursePeriodDays periodDays = new FsUserCoursePeriodDays();
|
|
|
+ periodDays.setVideoId(param.getVideoId());
|
|
|
+ periodDays.setPeriodId(param.getPeriodId());
|
|
|
+ //正常情况是只能查询到一条,之前可能存在重复的脏数据,暂使用查询list的方式
|
|
|
+ List<FsUserCoursePeriodDays> fsUserCoursePeriodDays = fsUserCoursePeriodDaysMapper.selectFsUserCoursePeriodDaysList(periodDays);
|
|
|
+ if(fsUserCoursePeriodDays != null && !fsUserCoursePeriodDays.isEmpty()){
|
|
|
+ periodDays = fsUserCoursePeriodDays.get(0);
|
|
|
+ }
|
|
|
+ if(periodDays != null && periodDays.getLastJoinTime() !=null && LocalDateTime.now().isAfter(periodDays.getLastJoinTime())) {
|
|
|
+ return R.error(403,"已超过领取红包时间");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确定红包金额
|
|
|
+ BigDecimal amount = BigDecimal.ZERO;
|
|
|
+ FsUserCourseVideoRedPackage redPackage = fsUserCourseVideoRedPackageMapper.selectRedPacketByCompanyId(param.getVideoId(), param.getCompanyId(), param.getPeriodId());
|
|
|
+
|
|
|
+ if (redPackage != null) {
|
|
|
+ amount = redPackage.getRedPacketMoney();
|
|
|
+ } else if (video != null) {
|
|
|
+ amount = video.getRedPacketMoney();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 准备发送红包参数
|
|
|
+ WxSendRedPacketParam packetParam = new WxSendRedPacketParam();
|
|
|
+ packetParam.setOpenId(user.getMpOpenId());
|
|
|
+ //判断服务号配置是否存在
|
|
|
+ if (StringUtils.isNotEmpty(config.getMpAppId())){
|
|
|
+ packetParam.setMpAppId(config.getMpAppId());
|
|
|
+ }
|
|
|
+ //组装发红包数据
|
|
|
+ packetParam.setAmount(amount);
|
|
|
+ packetParam.setSource(param.getSource());
|
|
|
+ packetParam.setRedPacketMode(config.getRedPacketMode());
|
|
|
+ packetParam.setCompanyId(param.getCompanyId());
|
|
|
+ packetParam.setAppId(param.getAppId());
|
|
|
+ packetParam.setUser(user);
|
|
|
+ packetParam.setOpenId(user.getAppOpenId());
|
|
|
+
|
|
|
+ logger.info("红包金额 {},红包参数 {}",amount,packetParam);
|
|
|
+
|
|
|
+
|
|
|
+ if (amount.compareTo(BigDecimal.ZERO)<=0){
|
|
|
+ return R.error("用户提现金额错误");
|
|
|
+ }
|
|
|
+ Company company = companyMapper.selectCompanyById(param.getCompanyId());
|
|
|
+ BigDecimal money = company.getMoney();
|
|
|
+ if (money.compareTo(BigDecimal.ZERO)<0) {
|
|
|
+ return R.error("服务商余额不足,请联系群主服务器充值!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 发送App红包
|
|
|
+ R sendRedPacket = paymentService.sendRedPacketAppReward(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());
|
|
|
+ }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("奖励发送失败,请联系客服");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
//根据vid获取视频详情
|
|
|
public void getVideoInfoByVid(FsVideoResource videoResource) {
|
|
|
try {
|