Kaynağa Gözat

1、调整公开课计算流量

yys 1 ay önce
ebeveyn
işleme
c8e4f89cd3

+ 1 - 0
fs-service/src/main/java/com/fs/course/mapper/FsUserVideoMapper.java

@@ -136,6 +136,7 @@ public interface FsUserVideoMapper
             "SELECT",
             "    v.video_id AS id,",
             "    v.title,",
+            "    v.duration,",
             "    v.description AS msg,",
             "    t.nick_name AS username,",
             "    t.user_id AS userId,",

+ 5 - 0
fs-service/src/main/java/com/fs/course/param/FsUserCourseVideoFinishUParam.java

@@ -24,4 +24,9 @@ public class FsUserCourseVideoFinishUParam implements Serializable {
     private Integer isOpen;//是否公开课
     private Long periodId;
     private Integer projectId;
+
+    /**
+     * 是否公开课
+     */
+    private Integer isPublic;
 }

+ 44 - 8
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -194,6 +194,9 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
     @Autowired
     private FsCourseLinkMapper fsCourseLinkMapper;
 
+    @Autowired
+    private FsUserVideoMapper fsUserVideoMapper;
+
 
     @Autowired
     private RedissonClient redissonClient;
@@ -1322,20 +1325,53 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
             trafficLog.setCreateTime(new Date());
             BeanUtils.copyProperties(param, trafficLog);
 
-            FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
-            if (video == null) {
-                return R.error("视频不存在");
-            }
+            Long fileSize = 0L;
+            if (ObjectUtil.isNotEmpty(param.getIsPublic()) && param.getIsPublic().equals(0)) {
+                FsUserVideo video = fsUserVideoMapper.selectFsUserVideoByVideoId(String.valueOf(param.getVideoId()));
+                if (video == null) {
+                    return R.error("视频不存在");
+                }
+                // 优先从Redis缓存获取文件大小
+                String fileSizeRedisKey = "public:course:video:fileSize:" + param.getVideoId();
+                String cachedFileSize = redisCache.getCacheObject(fileSizeRedisKey);
+                if (StringUtils.isNotEmpty(cachedFileSize)) {
+                    fileSize = Long.parseLong(cachedFileSize);
+                } else if (StringUtils.isNotEmpty(video.getUrl())) {
+                    // 缓存未命中,通过视频URL的HEAD请求获取文件大小
+                    try {
+                        java.net.HttpURLConnection conn = (java.net.HttpURLConnection) new java.net.URL(video.getUrl()).openConnection();
+                        conn.setRequestMethod("HEAD");
+                        conn.setConnectTimeout(5000);
+                        conn.setReadTimeout(5000);
+                        int contentLength = conn.getContentLength();
+                        conn.disconnect();
+                        if (contentLength > 0) {
+                            fileSize = (long) contentLength;
+                            // 写入Redis缓存,7天过期
+                            redisCache.setCacheObject(fileSizeRedisKey, String.valueOf(fileSize), 7, java.util.concurrent.TimeUnit.DAYS);
+                        }
+                    } catch (Exception ex) {
+                        logger.warn("【公开课】通过URL获取文件大小失败, videoId: {}, url: {}, error: {}", param.getVideoId(), video.getUrl(), ex.getMessage());
+                    }
+                }
+            }else {
+                FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
+                if (video == null) {
+                    return R.error("视频不存在");
+                }
+                fileSize = video.getFileSize();
 //            Company company = companyMapper.selectCompanyById(param.getCompanyId());
 //            if (company == null) {
 //                return R.error("公司不存在");
 //            }
-            FsUserCourse fsUserCourse = fsUserCourseMapper.selectFsUserCourseByCourseId(param.getCourseId());
-            if (fsUserCourse != null) {
-                trafficLog.setProjectId(fsUserCourse.getProject());
+                FsUserCourse fsUserCourse = fsUserCourseMapper.selectFsUserCourseByCourseId(param.getCourseId());
+                if (fsUserCourse != null) {
+                    trafficLog.setProjectId(fsUserCourse.getProject());
+                }
             }
+
             BigDecimal result = param.getBufferRate().divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP);
-            BigDecimal longAsBigDecimal = BigDecimal.valueOf(video.getFileSize());
+            BigDecimal longAsBigDecimal = BigDecimal.valueOf(fileSize);
             long roundedResult = result.multiply(longAsBigDecimal).setScale(0, RoundingMode.HALF_UP).longValue();
             trafficLog.setInternetTraffic(roundedResult);
 

+ 1 - 0
fs-service/src/main/java/com/fs/course/vo/FsUserVideoListUVO.java

@@ -14,6 +14,7 @@ public class FsUserVideoListUVO {
     private String headImg;//3.发布者头像
     private String cover;//视频封面
     private String title;//4.第一行标题
+    private Long duration;//时长
     private String msg;//5.第二行内容
     private String state = "pause";//6.初始状态标志(不改)
     private Integer like = 0; //7.是否是自己喜欢,0不喜欢,1喜欢。默认不喜欢

+ 48 - 5
fs-service/src/main/java/com/fs/im/service/impl/OpenIMServiceImpl.java

@@ -77,7 +77,7 @@ public class OpenIMServiceImpl implements OpenIMService {
     /** IM好友关系缓存时间(秒) */
     private static final int IM_FRIEND_CACHE_SECONDS = 300;
     /** HTTP请求超时时间(毫秒) */
-    private static final int HTTP_TIMEOUT_MS = 10000;
+    private static final int HTTP_TIMEOUT_MS = 30000;
 
     @Autowired
     IMConfig imConfig;
@@ -1760,13 +1760,56 @@ public class OpenIMServiceImpl implements OpenIMService {
     @Override
     @Transactional
     public OpenImResponseDTO batchUrgeCourseTask(OpenImBatchMsgDTO openImBatchMsgDTO, List<FsImMsgSendDetail> imMsgSendDetailList) {
-        log.info("批量催课消息, 接收人数={}", openImBatchMsgDTO.getRecvIDs() != null ? openImBatchMsgDTO.getRecvIDs().size() : 0);
+        List<String> allRecvIds = openImBatchMsgDTO.getRecvIDs();
+        int totalSize = allRecvIds != null ? allRecvIds.size() : 0;
+        log.info("批量催课消息, 接收人数={}", totalSize);
         log.debug("批量催课消息详情: \n{}", JSON.toJSONString(openImBatchMsgDTO));
-        OpenImResponseDTO openImResponseDTO = openIMBatchSendMsg(openImBatchMsgDTO);
+
+        int BATCH_SIZE = 50;
+        OpenImResponseDTO finalResponseDTO = new OpenImResponseDTO();
+        int successCount = 0;
+        int failCount = 0;
+
+        for (int i = 0; i < totalSize; i += BATCH_SIZE) {
+            int end = Math.min(i + BATCH_SIZE, totalSize);
+            List<String> batchRecvIds = allRecvIds.subList(i, end);
+
+            // 为每个批次创建独立的DTO,避免修改原始对象
+            OpenImBatchMsgDTO batchDTO = new OpenImBatchMsgDTO();
+            batchDTO.setSendID(openImBatchMsgDTO.getSendID());
+            batchDTO.setRecvIDs(batchRecvIds);
+            batchDTO.setSessionType(openImBatchMsgDTO.getSessionType());
+            batchDTO.setContentType(openImBatchMsgDTO.getContentType());
+            batchDTO.setContent(openImBatchMsgDTO.getContent());
+            batchDTO.setSendTime(openImBatchMsgDTO.getSendTime());
+            batchDTO.setIsOnlineOnly(openImBatchMsgDTO.getIsOnlineOnly());
+            batchDTO.setNotOfflinePush(openImBatchMsgDTO.getNotOfflinePush());
+            batchDTO.setOfflinePushInfo(openImBatchMsgDTO.getOfflinePushInfo());
+            batchDTO.setIsSendAll(openImBatchMsgDTO.getIsSendAll());
+
+            OpenImResponseDTO responseDTO = openIMBatchSendMsg(batchDTO);
+
+            if (responseDTO != null && responseDTO.getErrCode() == 0) {
+                successCount += batchRecvIds.size();
+            } else {
+                failCount += batchRecvIds.size();
+                log.error("催课批次 {}/{} 发送失败:{}", i, end, responseDTO != null ? responseDTO.getErrMsg() : "unknown error");
+            }
+            finalResponseDTO = responseDTO;
+
+            // 每批之间休眠100ms,避免请求过快
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                break;
+            }
+        }
 
         // 修改发送记录
-        this.updateImMsgSendLog(openImBatchMsgDTO, imMsgSendDetailList, openImResponseDTO, "催课");
-        return openImResponseDTO;
+        this.updateImMsgSendLog(openImBatchMsgDTO, imMsgSendDetailList, finalResponseDTO, "催课");
+        finalResponseDTO.setErrMsg(String.format("催课发送完成:总数=%d, 成功=%d, 失败=%d", totalSize, successCount, failCount));
+        return finalResponseDTO;
     }
 
     @Override