Ver código fonte

1、优化代码

yys 1 mês atrás
pai
commit
abd2fc238d

+ 78 - 49
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -136,6 +136,8 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
     private Boolean isNewWxMerchant;
     private static final String registeredRealLink = "/pages_course/register.html?link=";
 
+    private static final BigDecimal HUNDRED = new BigDecimal("100");
+
     private static final String REDIS_KEY_PREFIX = "red_packet_config:";
 
     @Autowired
@@ -1325,68 +1327,95 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
             trafficLog.setCreateTime(new Date());
             BeanUtils.copyProperties(param, trafficLog);
 
-            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());
-                }
+            long fileSize = getVideoFileSize(param);
+            if (fileSize < 0) {
+                return R.error("视频不存在");
             }
+            setProjectIdIfNeeded(param, trafficLog);
 
-            BigDecimal result = param.getBufferRate().divide(new BigDecimal("100"), 4, RoundingMode.HALF_UP);
-            BigDecimal longAsBigDecimal = BigDecimal.valueOf(fileSize);
-            long roundedResult = result.multiply(longAsBigDecimal).setScale(0, RoundingMode.HALF_UP).longValue();
-            trafficLog.setInternetTraffic(roundedResult);
+            // 计算流量 = bufferRate / 100 * fileSize
+            long internetTraffic = param.getBufferRate()
+                    .multiply(BigDecimal.valueOf(fileSize))
+                    .divide(HUNDRED, 4, RoundingMode.HALF_UP)
+                    .setScale(0, RoundingMode.HALF_UP)
+                    .longValue();
+            trafficLog.setInternetTraffic(internetTraffic);
 
             if (StringUtils.isNotEmpty(trafficLog.getUuId())) {
                 fsPublicCourseTrafficLogMapper.insertOrUpdateTrafficLog(trafficLog);
-//                asyncDeductPublicCourseTraffic(company, trafficLog);
             }
         } catch (Exception e) {
-            e.printStackTrace();
             logger.error("【公开课插入或更新流量失败】参数: {}, 错误信息:{}", param, e.getMessage(), e);
             return R.error();
         }
         return R.ok();
     }
 
+    /**
+     * 获取视频文件大小
+     * 公开课视频(isPublic=0):从FsUserVideo获取,优先Redis缓存,未命中则HEAD请求并缓存
+     * 非公开课视频:从FsUserCourseVideo直接获取fileSize
+     * @return 文件大小,-1表示视频不存在
+     */
+    private long getVideoFileSize(FsUserCourseVideoFinishUParam param) {
+        if (ObjectUtil.isNotEmpty(param.getIsPublic()) && param.getIsPublic().equals(0)) {
+            FsUserVideo video = fsUserVideoMapper.selectFsUserVideoByVideoId(String.valueOf(param.getVideoId()));
+            if (video == null) {
+                return -1L;
+            }
+            return getPublicVideoFileSize(param.getVideoId(), video.getUrl());
+        } else {
+            FsUserCourseVideo video = fsUserCourseVideoMapper.selectFsUserCourseVideoByVideoId(param.getVideoId());
+            if (video == null) {
+                return -1L;
+            }
+            return video.getFileSize() != null ? video.getFileSize() : 0L;
+        }
+    }
+
+    /**
+     * 获取公开课视频文件大小,优先Redis缓存
+     */
+    private long getPublicVideoFileSize(Long videoId, String videoUrl) {
+        String fileSizeRedisKey = "public:course:video:fileSize:" + videoId;
+        String cachedFileSize = redisCache.getCacheObject(fileSizeRedisKey);
+        if (StringUtils.isNotEmpty(cachedFileSize)) {
+            return Long.parseLong(cachedFileSize);
+        }
+        // 缓存未命中,通过视频URL的HEAD请求获取文件大小
+        if (StringUtils.isEmpty(videoUrl)) {
+            return 0L;
+        }
+        try {
+            java.net.HttpURLConnection conn = (java.net.HttpURLConnection) new java.net.URL(videoUrl).openConnection();
+            conn.setRequestMethod("HEAD");
+            conn.setConnectTimeout(5000);
+            conn.setReadTimeout(5000);
+            int contentLength = conn.getContentLength();
+            conn.disconnect();
+            if (contentLength > 0) {
+                redisCache.setCacheObject(fileSizeRedisKey, String.valueOf(contentLength), 7, java.util.concurrent.TimeUnit.DAYS);
+                return contentLength;
+            }
+        } catch (Exception ex) {
+            logger.warn("【公开课】通过URL获取文件大小失败, videoId: {}, url: {}, error: {}", videoId, videoUrl, ex.getMessage());
+        }
+        return 0L;
+    }
+
+    /**
+     * 非公开课时设置projectId
+     */
+    private void setProjectIdIfNeeded(FsUserCourseVideoFinishUParam param, FsPublicCourseTrafficLog trafficLog) {
+        if (ObjectUtil.isNotEmpty(param.getIsPublic()) && param.getIsPublic().equals(0)) {
+            return;
+        }
+        FsUserCourse fsUserCourse = fsUserCourseMapper.selectFsUserCourseByCourseId(param.getCourseId());
+        if (fsUserCourse != null) {
+            trafficLog.setProjectId(fsUserCourse.getProject());
+        }
+    }
+
 //    public void asyncDeductPublicCourseTraffic(Company company, FsPublicCourseTrafficLog trafficLog) {
 //        try {
 //            FsPublicCourseTrafficLog existingLog = fsPublicCourseTrafficLogMapper.selectFsPublicCourseTrafficLogByUuId(trafficLog.getUuId());