Ver Fonte

1、调整问题

yys há 3 semanas atrás
pai
commit
826369b7e1

+ 19 - 6
fs-service/src/main/java/com/fs/course/service/impl/FsUserCourseVideoServiceImpl.java

@@ -446,18 +446,31 @@ public class FsUserCourseVideoServiceImpl extends ServiceImpl<FsUserCourseVideoM
             }
 
         }
+        if (list == null) {
+            return Collections.emptyList();
+        }
         for (FsUserCourseVideoListUVO listUVO : list) {
             if (StringUtils.isNotEmpty(listUVO.getPackageJson())) {
                 List<CoursePackageDTO> packageDTOS = JSON.parseArray(listUVO.getPackageJson(), CoursePackageDTO.class);
+                if (CollectionUtils.isEmpty(packageDTOS)) {
+                    continue;
+                }
                 for (CoursePackageDTO packageDTO : packageDTOS) {
-                    // 将时间按 ":" 分割
-                    String[] parts = packageDTO.getDuration().split(":");
-                    // 提取小时和分钟
+                    if (packageDTO == null || StringUtils.isEmpty(packageDTO.getDuration())) {
+                        continue;
+                    }
+                    String duration = packageDTO.getDuration();
+                    if (!duration.contains(":")) {
+                        continue;
+                    }
+                    // 将时间按 ":" 分割(格式 HH:mm)
+                    String[] parts = duration.split(":");
+                    if (parts.length < 2) {
+                        continue;
+                    }
                     int hours = Integer.parseInt(parts[0]);
                     int minutes = Integer.parseInt(parts[1]);
-                    // 转换为秒
-                    int seconds = hours * 3600 + minutes * 60;
-                    packageDTO.setDuration(String.valueOf(seconds));
+                    packageDTO.setDuration(String.valueOf(hours * 3600 + minutes * 60));
                 }
                 listUVO.setPackageJson(JSON.toJSONString(packageDTOS));
             }

+ 5 - 3
fs-service/src/main/java/com/fs/his/service/impl/FsInquiryOrderReportServiceImpl.java

@@ -93,9 +93,11 @@ public class FsInquiryOrderReportServiceImpl implements IFsInquiryOrderReportSer
     public int insertFsInquiryOrderReport(FsInquiryOrderReport fsInquiryOrderReport)
     {
         fsInquiryOrderReport.setCreateTime(DateUtils.getNowDate());
-        FsDoctor drug =fsDoctorMapper.selectPackageFsDoctorType2Ids(2);
-        fsInquiryOrderReport.setDrugId(drug.getDoctorId());
-        fsInquiryOrderReport.setDrugDoctorSignUrl(drug.getSignUrl());
+        FsDoctor drug = fsDoctorMapper.selectPackageFsDoctorType2Ids(2);
+        if (drug != null) {
+            fsInquiryOrderReport.setDrugId(drug.getDoctorId());
+            fsInquiryOrderReport.setDrugDoctorSignUrl(drug.getSignUrl());
+        }
         return fsInquiryOrderReportMapper.insertFsInquiryOrderReport(fsInquiryOrderReport);
     }
 

+ 48 - 13
fs-service/src/main/java/com/fs/utils/VideoUtil.java

@@ -75,31 +75,66 @@ public class VideoUtil {
      * 提取缩略图
      */
     public static void extractFirstFrame(String videoPath, String outputImagePath) throws IOException, InterruptedException {
+        File videoFile = new File(videoPath);
+        if (!videoFile.exists()) {
+            throw new IOException("视频文件不存在: " + videoPath);
+        }
+
+        File outputFile = new File(outputImagePath);
+        File outputDir = outputFile.getParentFile();
+        if (outputDir != null && !outputDir.exists() && !outputDir.mkdirs()) {
+            throw new IOException("创建缩略图输出目录失败: " + outputDir.getAbsolutePath());
+        }
+
         String[] command = {
-                "ffmpeg",
-                "-ss", "00:00:01.000",  // 精准定位到第1秒
-                "-i", videoPath,        // 输入视频路径
-                "-vframes", "1",        // 只提取1帧
-                "-q:v", "2",            // 质量控制(2=高质量,范围1-31)
-                "-y",                   // 覆盖输出文件
-                outputImagePath         // 输出图片路径(如 cover.jpg)
+                resolveFfmpegCommand(),
+                "-i", videoPath,
+                "-frames:v", "1",
+                "-f", "image2",
+                "-update", "1",
+                "-q:v", "10",
+                "-y",
+                outputImagePath
         };
         ProcessBuilder processBuilder = new ProcessBuilder(command);
-        processBuilder.redirectErrorStream(true); // 将标准错误和标准输出合并
+        processBuilder.redirectErrorStream(true);
         Process process = processBuilder.start();
-//        process.waitFor();
 
-        // 处理进程的标准输出和错误流
+        StringBuilder output = new StringBuilder();
         try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
             String line;
             while ((line = reader.readLine()) != null) {
-                log.info(line); // 输出到控制台或日志
+                output.append(line).append(System.lineSeparator());
+                log.info(line);
             }
         }
 
         int exitCode = process.waitFor();
-        if (exitCode != 0 && exitCode != 1) {
-            throw new RuntimeException("FFmpeg 执行失败,退出代码:" + exitCode);
+        if (exitCode != 0) {
+            log.error("FFmpeg 提取缩略图失败, exitCode={}, videoPath={}, outputPath={}, output={}",
+                    exitCode, videoPath, outputImagePath, output);
+            throw new RuntimeException("FFmpeg 执行失败,退出代码:" + exitCode + ",输出:" + output);
+        }
+        if (!outputFile.exists() || outputFile.length() == 0) {
+            throw new RuntimeException("FFmpeg 执行完成但未生成缩略图: " + outputImagePath);
         }
     }
+
+    private static String resolveFfmpegCommand() {
+        if (isWindows()) {
+            String configuredPath = System.getenv("FFMPEG_PATH");
+            if (configuredPath != null && !configuredPath.trim().isEmpty()) {
+                File ffmpeg = new File(configuredPath.trim());
+                if (ffmpeg.exists()) {
+                    return ffmpeg.getAbsolutePath();
+                }
+            }
+            return "ffmpeg.exe";
+        }
+        return "ffmpeg";
+    }
+
+    private static boolean isWindows() {
+        return System.getProperty("os.name", "").toLowerCase().contains("win");
+    }
 }

+ 0 - 1
fs-user-app/src/main/java/com/fs/app/controller/CourseController.java

@@ -72,7 +72,6 @@ public class CourseController extends  AppBaseController{
         }
     }
 
-    @Cacheable(value = "getProductCateByPid", key = "#pid")
     @ApiOperation("获取子分类")
     @GetMapping("/getProductCateByPid")
     public R getProductCateByPid(@RequestParam(value="pid") Long pid){

+ 1 - 0
fs-user-app/src/main/java/com/fs/app/controller/PackageController.java

@@ -80,6 +80,7 @@ public class PackageController extends AppBaseController {
     public R getPackagCateList(FsPackageCateUParam param) {
         log.info("获取套餐分类: {} ",param);
         try {
+            param.setStatus(1);
             ObjectMapper objectMapper = new ObjectMapper();
             Long companyUserId = getCompanyUserId();
             CompanyUser companyUser=companyUserService.selectCompanyUserById(companyUserId);

+ 11 - 2
fs-user-app/src/main/java/com/fs/app/controller/TalentController.java

@@ -62,8 +62,8 @@ public class TalentController extends  AppBaseController{
     @Autowired
     private IFsVideoCollectionService fsVideoCollectionService;
 
-    private static final String VIDEO_UPLOAD_DIR = "C:\\fs\\uploadPath\\talent\\video";  // 上传目录
-    private static final String FRAME_OUTPUT_DIR = "C:\\fs\\uploadPath\\talent\\frame";  // 输出帧的目录
+    private static final String VIDEO_UPLOAD_DIR = System.getProperty("java.io.tmpdir") + File.separator + "fs_upload" + File.separator + "talent" + File.separator + "video";
+    private static final String FRAME_OUTPUT_DIR = System.getProperty("java.io.tmpdir") + File.separator + "fs_upload" + File.separator + "talent" + File.separator + "frame";
 
 
     @ApiOperation("获取指定达人详情")
@@ -180,6 +180,7 @@ public class TalentController extends  AppBaseController{
 
             //保存临时视频文件
             String videoFileName = System.currentTimeMillis() + "_" + originalFilename;
+            createDir(VIDEO_UPLOAD_DIR);
             File videoFile = new File(VIDEO_UPLOAD_DIR, videoFileName);
             file.transferTo(videoFile);
 
@@ -188,6 +189,7 @@ public class TalentController extends  AppBaseController{
 
             //提取第一帧作为缩略图
             String frameFileName = FilenameUtils.removeExtension(videoFileName) + "_frame.jpg";
+            createDir(FRAME_OUTPUT_DIR);
             File frameFile = new File(FRAME_OUTPUT_DIR, frameFileName);
             VideoUtil.extractFirstFrame(videoFile.getAbsolutePath(), frameFile.getAbsolutePath());
 
@@ -301,4 +303,11 @@ public class TalentController extends  AppBaseController{
         List<FsUserVideoTagsPVO> list = fsUserVideoTagsService.selectFsUserVideoTagsSubList();
         return AjaxResult.success(list);
     }
+
+    private void createDir(String path) {
+        File dir = new File(path);
+        if (!dir.exists() && !dir.mkdirs()) {
+            throw new OssException("创建目录失败: " + path);
+        }
+    }
 }