From 4ebaecee17409d138a732b8126c515064644edc5 Mon Sep 17 00:00:00 2001
From: xueqingkun <xueqingkun@126.com>
Date: Thu, 25 Jan 2024 14:03:35 +0800
Subject: [PATCH] =?UTF-8?q?manage:=20add=20=E7=97=85=E4=BE=8B=E7=AD=94?=
 =?UTF-8?q?=E6=A1=88=E8=A7=86=E9=A2=91=E8=B5=84=E6=BA=90=E6=9C=8D=E5=8A=A1?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 virtual-patient-manage/pom.xml                |   3 +-
 .../AnswerVideoResourceController.java        |  26 ++++
 .../service/AnswerVideoResourceService.java   |  14 ++
 .../impl/OfflineAnswerVideoResource.java      | 143 ++++++++++++++++++
 .../VirtualPatientManageApplicationTests.java |  19 ++-
 5 files changed, 196 insertions(+), 9 deletions(-)
 create mode 100644 virtual-patient-manage/src/main/java/com/supervision/manage/controller/medicalrec/AnswerVideoResourceController.java
 create mode 100644 virtual-patient-manage/src/main/java/com/supervision/manage/service/AnswerVideoResourceService.java
 create mode 100644 virtual-patient-manage/src/main/java/com/supervision/manage/service/impl/OfflineAnswerVideoResource.java

diff --git a/virtual-patient-manage/pom.xml b/virtual-patient-manage/pom.xml
index 1953e7f4..fd512d90 100644
--- a/virtual-patient-manage/pom.xml
+++ b/virtual-patient-manage/pom.xml
@@ -71,8 +71,7 @@
 		<dependency>
 			<groupId>org.apache.poi</groupId>
 			<artifactId>poi-ooxml</artifactId>
-			<version>4.1.2</version>
-			<scope>test</scope>
+			<version>${poi-ooxml.version}</version>
 		</dependency>
     </dependencies>
 
diff --git a/virtual-patient-manage/src/main/java/com/supervision/manage/controller/medicalrec/AnswerVideoResourceController.java b/virtual-patient-manage/src/main/java/com/supervision/manage/controller/medicalrec/AnswerVideoResourceController.java
new file mode 100644
index 00000000..dd006963
--- /dev/null
+++ b/virtual-patient-manage/src/main/java/com/supervision/manage/controller/medicalrec/AnswerVideoResourceController.java
@@ -0,0 +1,26 @@
+package com.supervision.manage.controller.medicalrec;
+
+import com.supervision.manage.service.AnswerVideoResourceService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@Api(tags = "病历管理")
+@RestController
+@RequestMapping("/answerVideo")
+@RequiredArgsConstructor
+public class AnswerVideoResourceController {
+
+    private final AnswerVideoResourceService answerVideoResourceService;
+
+    @ApiOperation("初步诊断下拉列表联想(这个接口查询所有疾病,包含复合疾病)")
+    @GetMapping("/preGenerationMedicalAnswerVideo")
+    public void preGenerationMedicalAnswerVideo(String medicalId) {
+         answerVideoResourceService.preGenerationMedicalAnswerVideo(medicalId);
+    }
+}
diff --git a/virtual-patient-manage/src/main/java/com/supervision/manage/service/AnswerVideoResourceService.java b/virtual-patient-manage/src/main/java/com/supervision/manage/service/AnswerVideoResourceService.java
new file mode 100644
index 00000000..bd0b134f
--- /dev/null
+++ b/virtual-patient-manage/src/main/java/com/supervision/manage/service/AnswerVideoResourceService.java
@@ -0,0 +1,14 @@
+package com.supervision.manage.service;
+
+
+/**
+ * @Description: 病例答案视频资源服务
+ **/
+public interface AnswerVideoResourceService {
+
+    /**
+     * 预生成病例答案视频
+     * @param medicalId 疾病id
+     */
+    void preGenerationMedicalAnswerVideo(String medicalId);
+}
diff --git a/virtual-patient-manage/src/main/java/com/supervision/manage/service/impl/OfflineAnswerVideoResource.java b/virtual-patient-manage/src/main/java/com/supervision/manage/service/impl/OfflineAnswerVideoResource.java
new file mode 100644
index 00000000..81b70470
--- /dev/null
+++ b/virtual-patient-manage/src/main/java/com/supervision/manage/service/impl/OfflineAnswerVideoResource.java
@@ -0,0 +1,143 @@
+package com.supervision.manage.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.date.TimeInterval;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.lang.Pair;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONUtil;
+import cn.hutool.poi.excel.ExcelReader;
+import cn.hutool.poi.excel.ExcelUtil;
+import com.supervision.manage.service.AnswerVideoResourceService;
+import com.supervision.model.AskPatientAnswer;
+import com.supervision.model.AskTemplateQuestionLibrary;
+import com.supervision.model.FileResource;
+import com.supervision.service.AskPatientAnswerService;
+import com.supervision.service.AskTemplateQuestionLibraryService;
+import com.supervision.service.FileResourceService;
+import com.supervision.util.MinioUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * 离线视频资源
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class OfflineAnswerVideoResource implements AnswerVideoResourceService {
+
+    @Value("${answer.offline.videoPath}")
+    private String videoPath;
+
+    @Value("${answer.offline.indexFile}")
+    private String indexFile;
+
+    @Value("${answer.offline.videoSuffix}")
+    private String videoSuffix;
+
+    private final AskPatientAnswerService askPatientAnswerService;
+
+    private final AskTemplateQuestionLibraryService askTemplateQuestionLibraryService;
+
+    private final FileResourceService fileResourceService;
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void preGenerationMedicalAnswerVideo(String medicalId) {
+
+        // 1. 获取视频文件,及视频内容
+        List<Pair<String, File>> videoFileAndContent = getVideoFileAndContent(videoPath,indexFile,videoSuffix);
+        if (CollUtil.isEmpty(videoFileAndContent)){
+            log.info("getVideoFileAndContent result is empty");
+            return;
+        }
+
+        //2. 填充数据库中疾病问诊的资源id
+        Map<String, AskPatientAnswer> patientAnserMap = askPatientAnswerService.lambdaQuery().eq(AskPatientAnswer::getMedicalId, medicalId).list()
+                .stream().collect(Collectors.toMap(answer -> StrUtil.trim(answer.getAnswer()), answer -> answer));
+        // 问诊模板数据
+        List<AskTemplateQuestionLibrary> askTemplateQuestionLibraryList = askTemplateQuestionLibraryService.lambdaQuery().list();
+        List<String> resourceIds = new ArrayList<>();
+        try {
+            for (Pair<String, File> pair : videoFileAndContent) {
+                AskPatientAnswer askPatientAnswer = patientAnserMap.get(pair.getKey());
+                if (Objects.nonNull(askPatientAnswer)){
+                    String resourceId = saveResource(pair.getValue());
+                    askPatientAnswer.setAnswerResourceId(resourceId);
+                    resourceIds.add(resourceId);
+                    askPatientAnswerService.updateById(askPatientAnswer);
+                    log.info("update askPatientAnswer:{}", JSONUtil.toJsonStr(askPatientAnswer));
+                }else {
+                    //todo: 获取模板中的数据
+                }
+            }
+        } catch (Exception e) {
+            // 文件处理过程中出现异常,删除文件
+            log.error("preGenerationMedicalAnswerVideo:生成文件失败",e);
+            for (String resourceId : resourceIds) {
+                try {
+                    MinioUtil.deleteObject(resourceId);
+                } catch (Exception ex) {
+                    log.info("删除资源失败:{}", resourceId);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * 保存资源
+     * @param file file
+     * @return 资源id
+     * @throws Exception
+     */
+    private String saveResource(File file) throws Exception {
+        String resourceId = MinioUtil.uploadFile(Files.newInputStream(file.toPath()));
+
+        FileResource fileResource = new FileResource();
+        fileResource.setMinioId(resourceId);
+        fileResource.setFileType(FileUtil.getMimeType(file.toPath()));
+        fileResource.setFileSize(FileUtil.size(file));
+        fileResourceService.save(fileResource);
+        return fileResource.getId();
+    }
+
+
+    /**
+     * 获取视频文件及内容
+     * @param videoPath 视频存放路径
+     * @return  pair.getKey():视频内容 pair.getValue():视频文件对象
+     */
+    List<Pair<String, File>> getVideoFileAndContent(String videoPath, String indexFileName, String videoSuffix){
+
+        log.info("preGenerationMedicalAnswerVideo: 开始读取excel表格中数据{}",String.join(File.separator,videoPath,indexFileName));
+        TimeInterval timer = DateUtil.timer();
+        try (ExcelReader reader = ExcelUtil.getReader(FileUtil.file(String.join(File.separator,videoPath,indexFileName)))){
+            List<Map<String, Object>> allMapList = reader.readAll();
+            log.info("preGenerationMedicalAnswerVideo: 读取excel表格中数据耗时:{} s", timer.intervalSecond());
+
+            return allMapList.stream().map(map -> {
+                String answerText = MapUtil.getStr(map, "A(answer)");
+                String fileName = MapUtil.getStr(map, "知识库A-ID\n[病征]");
+                if (StrUtil.isEmpty(answerText) || StrUtil.isEmpty(fileName)) {
+                    log.info("文件内容不完整:answerText:{},fileName:{}", answerText, fileName);
+                    return null;
+                }
+                return Pair.of(answerText, FileUtil.file(String.join(File.separator,videoPath,fileName)+videoSuffix));
+            }).filter(Objects::nonNull).collect(Collectors.toList());
+        }
+    }
+}
diff --git a/virtual-patient-manage/src/test/java/com/supervision/manage/VirtualPatientManageApplicationTests.java b/virtual-patient-manage/src/test/java/com/supervision/manage/VirtualPatientManageApplicationTests.java
index 8ecbcd69..f2ee40b3 100644
--- a/virtual-patient-manage/src/test/java/com/supervision/manage/VirtualPatientManageApplicationTests.java
+++ b/virtual-patient-manage/src/test/java/com/supervision/manage/VirtualPatientManageApplicationTests.java
@@ -7,25 +7,20 @@ import cn.hutool.core.lang.Pair;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.json.JSONUtil;
-import cn.hutool.log.Log;
 import cn.hutool.poi.excel.ExcelReader;
 import cn.hutool.poi.excel.ExcelUtil;
-import com.supervision.manage.service.AskQuestionLibraryManageService;
-import com.supervision.manage.service.DiseasePhysicalManageService;
+import com.supervision.manage.service.AnswerVideoResourceService;
 import com.supervision.model.AskPatientAnswer;
 import com.supervision.model.AskTemplateQuestionLibrary;
 import com.supervision.service.AskPatientAnswerService;
 import com.supervision.service.AskTemplateQuestionLibraryService;
 import com.supervision.util.MinioUtil;
-import com.supervision.vo.manage.DiseasePhysicalLocationNodeVo;
 import lombok.extern.slf4j.Slf4j;
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.util.*;
@@ -41,10 +36,20 @@ class VirtualPatientManageApplicationTests {
     @Autowired
     private AskTemplateQuestionLibraryService askTemplateQuestionLibraryService;
 
+    @Autowired
+    private AnswerVideoResourceService answerVideoResourceService;
+
+
 
+    @Test
+    void preGenerationMedicalAnswerVideoTest() throws IOException {
+
+        answerVideoResourceService.preGenerationMedicalAnswerVideo("ww");
+        System.out.println("ssss");
+    }
 
     @Test
-    void generateVideo(){
+    void preGenerationMedicalAnswerVideo(){
 
         String medicalId = "ww";