SGTY пре 2 месеци
родитељ
комит
55234788a8

+ 20 - 0
pom.xml

@@ -195,6 +195,26 @@
             <groupId>com.github.ben-manes.caffeine</groupId>
             <artifactId>caffeine</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>5.2.3</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml-schemas</artifactId>
+            <version>4.1.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.xmlbeans</groupId>
+            <artifactId>xmlbeans</artifactId>
+            <version>5.1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-collections4</artifactId>
+            <version>4.4</version>
+        </dependency>
 
     </dependencies>
     <dependencyManagement>

+ 0 - 0
src/main/java/com/qizhen/healsphere/49.急诊与灾难医学(第4版).docx


+ 39 - 0
src/main/java/com/qizhen/healsphere/TextValidator.java

@@ -0,0 +1,39 @@
+package com.qizhen.healsphere;
+
+import java.util.regex.Pattern;
+
+public class TextValidator {
+    public static boolean isValidText(String text) {
+        // 正则表达式解释:
+        // ^ 表示字符串的开始
+        // \\s* 表示0个或多个空白字符
+        // (\\.\\s+)* 表示0个或多个点号(`.`)后跟1个或多个空白字符
+        // [0-9]+ 表示1个或多个数字
+        // (\\s+\\.\\s*)? 表示0个或1个点号(`.`)前后跟1个或多个空白字符
+        // \\s* 表示0个或多个空白字符
+        // $ 表示字符串的结束
+        return Pattern.matches("^\\s*(\\.\\s+)*[0-9]+(\\s+\\.\\s*)?\\s*$", text);
+    }
+
+    public static void main(String[] args) {
+        String input1 = ".      27";
+        String input2 = "12       .   ";
+        String input3 = "     27    ";
+        String input4 = "27.";
+        String input5 = ".27.";
+        String input6 = "abc";
+        String input7 = "27.45";
+        String input8 = ".27 45.";
+        String input9 = "27 45.";
+
+        System.out.println(isValidText(input1)); // true
+        System.out.println(isValidText(input2)); // true
+        System.out.println(isValidText(input3)); // true
+        System.out.println(isValidText(input4)); // false
+        System.out.println(isValidText(input5)); // false
+        System.out.println(isValidText(input6)); // false
+        System.out.println(isValidText(input7)); // false
+        System.out.println(isValidText(input8)); // true
+        System.out.println(isValidText(input9)); // true
+    }
+}

+ 263 - 0
src/main/java/com/qizhen/healsphere/TxtSplitter.java

@@ -0,0 +1,263 @@
+package com.qizhen.healsphere;
+
+import com.alibaba.fastjson.JSONObject;
+import com.qizhen.healsphere.common.ai.QizhenAssistant;
+import com.qizhen.healsphere.util.FileCommonUtils;
+import org.apache.commons.lang3.StringUtils;
+import com.qizhen.healsphere.util.SentenceSplitter;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class TxtSplitter {
+    private static final int max_leng = 500;
+    private static final String JIE_PATTERN = "^第[零一二三四五六七八九十百千万0123456789]+节\\s+[^\n]+";
+    private static final String TITLE1_PATTERN = "^[零一二三四五六七八九十百千万]+\\s*、\\s*(.*)";
+    private static final String TITLE2_PATTERN = "^\\(([零一二三四五六七八九十百千万]+)\\)(.*)";
+    Pattern pageNumberCompile = Pattern.compile("^\\s*(\\.\\s+)*[0-9]+(\\s+\\.\\s*)?\\s*$");
+    public void splitTxtFile(String inputFilePath, String outputDirectory, String pattern) throws IOException {
+        File inputFile = new File(inputFilePath);
+        if (!inputFile.exists()) {
+            System.out.println("输入文件不存在: " + inputFilePath);
+            return;
+        }
+
+        // 检查目录是否存在,如果不存在则创建目录
+        File outputDir = new File(outputDirectory);
+        if (!outputDir.exists()) {
+            boolean isCreated = outputDir.mkdirs();
+            if (isCreated) {
+                //System.out.println("目录已创建: " + outputDirectory);
+            } else {
+                //System.out.println("目录创建失败: " + outputDirectory);
+                return;
+            }
+        }
+
+        StringBuilder currentChapter = new StringBuilder();
+        String currentChapterTitle = null;
+        Pattern compile = Pattern.compile(pattern);
+        try (BufferedReader reader = new BufferedReader(new FileReader(inputFile))) {
+            String line;
+            while ((line = reader.readLine()) != null) {
+                if (StringUtils.isNotEmpty(line) &&  pageNumberCompile.matcher(line).find()) {
+                    continue;
+                }
+                Matcher matcher = compile.matcher(line);
+                if (matcher.find()) {
+                    String tempTitle = matcher.group();
+                    if (currentChapterTitle == null) {
+                        currentChapterTitle = tempTitle;
+                        // 标题一样的话,不保存
+                    } else if (currentChapterTitle != null && !trim(currentChapterTitle).equals(trim(tempTitle))) {
+                        save(currentChapterTitle, currentChapter.toString(), outputDirectory);
+                        currentChapter.setLength(0); // Clear the StringBuilder
+                        currentChapterTitle = tempTitle;
+                    }
+                }
+                if (StringUtils.isNotEmpty(line)) {
+                    currentChapter.append(line).append("\n");
+                }
+            }
+            save(currentChapterTitle, currentChapter.toString(), outputDirectory);
+        }
+    }
+    public static final String appId = "e1de7dfc-afdb-48e4-b0f8-4fcecea09643";
+    private static int saveTxt(String inputFilePath, String outputDirectory, int i, File inputFile, StringBuilder merge,String title) throws IOException {
+        String fileName = FileCommonUtils.getFileNameWithoutExtension(inputFilePath) + "_split_" + i + ".txt";
+        File outputFile = new File(outputDirectory, fileName);
+
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile))) {
+            String s = inputFile.getParent().replace("E:\\project\\vscode\\", "").replaceAll("\\\\", " ,");
+            if(StringUtils.isNotEmpty(title)){
+                writer.write("本切片内容来自:"+s+","+title+"\n");
+            }else{
+                writer.write("本切片内容来自:"+s+"\n");
+            }
+            writer.write(merge.toString());
+
+          /*  String response = QizhenAssistant.call(appId, QizhenAssistant.getConversationId(appId), merge.toString());
+            String answer = JSONObject.parseObject(response).getString("answer");
+            writer.write("\n\n"+answer);*/
+            merge.setLength(0);
+        }
+        return i;
+    }
+
+    private void save(String chapterTitle, String chapterContents, String outputDirectory) throws IOException {
+        if (StringUtils.isEmpty(chapterTitle)) {
+            return;
+        }
+        String fileName = FileCommonUtils.sanitizeFileName(chapterTitle);
+        String fileNameEXt = fileName + ".txt";
+        if (!outputDirectory.endsWith("\\")) {
+            outputDirectory += "\\";
+        }
+        outputDirectory += fileName + "\\";
+        File outputFile = new File(outputDirectory, fileNameEXt);
+        // 检查目录是否存在,如果不存在则创建目录
+        File directory = new File(outputDirectory);
+        if (!directory.exists()) {
+            boolean isCreated = directory.mkdirs();
+            if (isCreated) {
+                //System.out.println("目录已创建: " + outputDirectory);
+            } else {
+                //System.out.println("目录创建失败: " + outputDirectory);
+                return;
+            }
+        }
+
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile))) {
+            writer.write(chapterContents);
+        }
+    }
+
+    private String trim(String text) {
+        return text.replaceAll("\\s+", "");
+    }
+
+    public static void main(String[] args) {
+        split(false,JIE_PATTERN);
+        split(false,TITLE1_PATTERN);
+        split(true,TITLE2_PATTERN);
+    }
+    private static void split(boolean split,String pattern) {
+        String inputDirectoryPath = "E:\\project\\vscode\\《急诊与灾难医学(第4版)》\\"; // 修改为目录路径
+        //String inputDirectoryPath = "E:\\project\\vscode\\《急诊与灾难医学(第4版)》\\"; // 修改为目录路径
+        File inputDirectory = new File(inputDirectoryPath);
+        traverse(inputDirectory, split,pattern);
+    }
+
+    private static void traverse(File dir, boolean split,String pattern) {
+        boolean hasSubDir = false;
+        File[] files = dir.listFiles();
+        if (files == null) {
+            return;
+        }
+        // 第一阶段:检测是否存在子目录
+        for (File file : files) {
+            if (file.isDirectory()) {
+                hasSubDir = true;
+                break; // 发现子目录立即中断循环
+            }
+        }
+
+        // 第二阶段:根据检测结果处理
+        if (hasSubDir) {
+            // 存在子目录时递归遍历
+            for (File file : files) {
+                if (file.isDirectory()) {
+                    traverse(file, split,pattern);
+                }
+            }
+        } else {
+            TxtSplitter txtSplitter = new TxtSplitter();
+            // 无子目录时处理txt文件
+            for (File file : files) {
+                if (file.getName().toLowerCase().endsWith(".txt")) {
+                    //System.out.println("发现文本文件: " + file.getName());
+                    String inputFilePath = file.getAbsolutePath();
+                    try {
+                        // 调用splitTxtFile方法
+                        if (!split) {
+                            txtSplitter.splitTxtFile(inputFilePath, file.getParent(), pattern);
+                        } else {
+                            txtSplitter.splitTxtFileByPattern(inputFilePath, file.getParent(), pattern);
+                        }
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+    }
+
+    public void splitTxtFileByPattern(String inputFilePath, String outputDirectory, String pattern) throws IOException {
+        File inputFile = new File(inputFilePath);
+        if (!inputFile.exists()) {
+            System.out.println("输入文件不存在: " + inputFilePath);
+            return;
+        }
+
+        // 检查目录是否存在,如果不存在则创建目录
+        File outputDir = new File(outputDirectory);
+        if (!outputDir.exists()) {
+            boolean isCreated = outputDir.mkdirs();
+            if (isCreated) {
+                //System.out.println("目录已创建: " + outputDirectory);
+            } else {
+                //System.out.println("目录创建失败: " + outputDirectory);
+                return;
+            }
+        }
+
+        List<String> paragraphs = new ArrayList<>();
+        StringBuilder currentParagraph = new StringBuilder();
+        Pattern compile = Pattern.compile(pattern);
+        try (BufferedReader reader = new BufferedReader(new FileReader(inputFile))) {
+            String line;
+            while ((line = reader.readLine()) != null) {
+                Matcher matcher = compile.matcher(line);
+                if (matcher.find()) {
+                    //找到了新的一段,且上一段内容超过了最大长度的1/4则保存,并清空
+                    if (currentParagraph.length() > 0) {
+                        paragraphs.add(currentParagraph.toString());
+                        currentParagraph.setLength(0); // Clear the StringBuilder
+                    }
+                }
+                currentParagraph.append(line).append("\n");
+            }
+            if (currentParagraph.length() > 0) {
+                paragraphs.add(currentParagraph.toString());
+            }
+        }
+        StringBuilder merge = new StringBuilder();
+        int i = 0;
+        String lastTitle = "";
+        String title = "";
+        for (int j=0;j< paragraphs.size();j++) {
+            String temp = paragraphs.get(j);
+            Matcher matcher = compile.matcher(temp);
+
+            boolean finded = matcher.find();
+            if(finded){
+                lastTitle = title;
+                title = matcher.group();
+            }
+            if (merge.length() + temp.length() > max_leng) {
+                //因为merge没有超过最大长度的1/3,说明是temp超过最大长度的2/3,所以切割temp
+                //System.out.println(temp);
+                List<String> sentences = SentenceSplitter.splitSentences(temp);
+                for (String sentence : sentences) {
+                    if ((merge.length() + sentence.length()) > max_leng) {
+                        saveTxt(inputFilePath, outputDirectory, i++, inputFile, merge,title);
+                        merge.append(sentence);
+                    } else {
+                        merge.append(sentence);
+                    }
+                }
+                merge.append("\n");
+            } else {
+                boolean onlyTitle = finded && trim(temp).equals(title);
+                //如果temp是标题,且merge+temp超过最大长度的1/3,则merge保存,再追加temp,以保证标题不会出现在切片的末尾
+                if (onlyTitle && (merge.length() + temp.length()) > max_leng / 3) {
+                    saveTxt(inputFilePath, outputDirectory, i++, inputFile, merge,lastTitle);
+                }
+                if(temp.length()>merge.length()){
+                    lastTitle = title;
+                }
+                merge.append(temp);
+            }
+
+            //超过最大长度的1/3则直接保存或是最后的片段
+            if (merge.length() > max_leng / 3) {
+                saveTxt(inputFilePath, outputDirectory, i++, inputFile, merge,lastTitle);
+            }else if(j==paragraphs.size()-1){
+                saveTxt(inputFilePath, outputDirectory, i++, inputFile, merge,StringUtils.isNotEmpty(title)?title:lastTitle);
+            }
+        }
+    }
+}

+ 126 - 0
src/main/java/com/qizhen/healsphere/WordSplitter.java

@@ -0,0 +1,126 @@
+package com.qizhen.healsphere;
+
+import com.qizhen.healsphere.util.FileCommonUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.xwpf.usermodel.*;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class WordSplitter {
+
+    private static final String ZHANG_PATTERN = "^第[零一二三四五六七八九十百千万0123456789]+章\\s+[^\\n]+";
+    public void splitWordDocument(String inputFilePath, String outputDirectory,String pattern) throws IOException {
+        System.out.println(inputFilePath+"==="+outputDirectory+"==="+pattern);
+        XWPFDocument document = new XWPFDocument(new FileInputStream(inputFilePath));
+        StringBuilder currentChapter = new StringBuilder();
+        String currentChapterTitle = null;
+        Pattern compile = Pattern.compile(pattern);
+        for (IBodyElement element : document.getBodyElements()) {
+            if (element instanceof XWPFParagraph) {
+                XWPFParagraph paragraph = (XWPFParagraph) element;
+                String text = paragraph.getText();
+                Matcher matcher = compile.matcher(text);
+                boolean isAppendTitle = false;
+                if (matcher.find()) {
+                    String tempTitle = matcher.group();
+                    //标题一样的话,不保存
+                    if (currentChapterTitle == null) {
+                        currentChapterTitle = tempTitle;
+                        isAppendTitle = true;
+                    } else if (currentChapterTitle != null && !trim(currentChapterTitle).equals(trim(tempTitle))) {
+                        save(currentChapterTitle, currentChapter.toString(), outputDirectory);
+                        currentChapter.setLength(0); // Clear the StringBuilder
+                        currentChapterTitle = tempTitle;
+                        isAppendTitle = true;
+                    }
+                }
+                String trimText = trim(text);
+                if (StringUtils.isNotEmpty(text) && (isAppendTitle || !trim(currentChapterTitle).equals(trimText))
+                        && !"本章数字资源".equals(trimText)) {
+                    currentChapter.append(text).append("\n");
+                }
+
+            } /*else if (element instanceof XWPFTable) {
+                // Handle tables if necessary
+                currentChapter.append(element.toString()).append("\n");
+            }*/
+        }
+        save(currentChapterTitle, currentChapter.toString(), outputDirectory);
+        document.close();
+    }
+
+    private void save(String chapterTitle, String chapterContents, String outputDirectory) throws IOException {
+        if (StringUtils.isEmpty(chapterTitle)) {
+            return;
+        }
+        String fileName = FileCommonUtils.sanitizeFileName(chapterTitle);
+        String fileNameEXt = fileName + ".txt";
+        outputDirectory += fileName + "\\";
+        File outputFile = new File(outputDirectory, fileNameEXt);
+        // 检查目录是否存在,如果不存在则创建目录
+        File directory = new File(outputDirectory);
+        if (!directory.exists()) {
+            boolean isCreated = directory.mkdirs();
+            if (isCreated) {
+                System.out.println("目录已创建: " + outputDirectory);
+            } else {
+                System.out.println("目录创建失败: " + outputDirectory);
+                return;
+            }
+        }
+        try (BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile))) {
+            writer.write(chapterContents);
+        }
+    }
+
+    private String trim(String text) {
+        return text.replaceAll("\\s+", "");
+    }
+
+
+    public static void removeHeadersAndFooters(String inputFilePath, String outputFilePath) {
+        try (FileInputStream fis = new FileInputStream(inputFilePath);
+             XWPFDocument document = new XWPFDocument(fis)) {
+
+            // 删除所有页眉
+            for (XWPFHeader header : document.getHeaderList()) {
+                List<XWPFParagraph> paragraphs = header.getParagraphs();
+                for (int i = paragraphs.size() - 1; i >= 0; i--) {
+                    header.removeParagraph(paragraphs.get(i));
+                }
+            }
+
+            // 删除所有页脚
+            for (XWPFFooter footer : document.getFooterList()) {
+                List<XWPFParagraph> paragraphs = footer.getParagraphs();
+                for (int i = paragraphs.size() - 1; i >= 0; i--) {
+                    footer.removeParagraph(paragraphs.get(i));
+                }
+            }
+
+            // 保存修改后的文档
+            try (FileOutputStream fos = new FileOutputStream(outputFilePath)) {
+                document.write(fos);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    public static void main(String[] args) {
+        WordSplitter wordSplitter1 = new WordSplitter();
+        String inputFilePath = "E:\\project\\vscode\\急诊与灾难医学(第4版).docx";
+        String outputDirectory = "E:\\project\\vscode\\《急诊与灾难医学(第4版)》\\";
+        try {
+            //removeHeadersAndFooters(inputFilePath, outputFilePath);
+            wordSplitter1.splitWordDocument(inputFilePath, outputDirectory,ZHANG_PATTERN);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 3 - 6
src/main/java/com/qizhen/healsphere/common/ai/DeepSeekUtil.java

@@ -32,8 +32,8 @@ public class DeepSeekUtil {
         // 构建请求体
         Map<String, Object> requestBody = new HashMap<>();
 
-        requestBody.put("model", "deepseek-v3");
-        //requestBody.put("model", "deepseek-r1");
+        //requestBody.put("model", "deepseek-v3");
+        requestBody.put("model", "deepseek-r1");
         //requestBody.put("model", "ernie-3.5-8k");
 
         //app-VUPQ3Rq1
@@ -69,10 +69,7 @@ public class DeepSeekUtil {
                 "    \"头孢菌素类\",  \n" +
                 "    \"大环内酯类\"\n" +
                 "]\n";*/
-        String des = "你是一个资深的医学专家,请回答:地塞米松是否是急性上呼吸道感染的治疗药物?请回答是或者否。\n" +
-                "#示例\n" +
-                "输入:急性中毒是否酒精中毒的分期?\n" +
-                "输出:是";
+        String des = "“子宫内膜息肉”相关手术有哪些?";
 
         System.out.println(DeepSeekUtil.getChatResponse(des));
     }

+ 10 - 5
src/main/java/com/qizhen/healsphere/common/ai/Knowlege.java

@@ -27,10 +27,15 @@ public class Knowlege {
     private String chunk;
 
     public static void main(String[] args) {
-        String a = "别名\t的别称或别名有哪些(请更加严格的遵照文献原文,不要把子类名称当做别称给我)" +
-                "常伴随的症状\t常伴随的症状有哪些症状" +
-                "常见病因\t的常见病因有哪些" +
-                "常见疾病\t常见于哪些疾病" +
-                "症状的子类或分类(按性质、特点等细分)\t的症状子类或症状分类有哪些症状";
+        String a = "并发症\t的并发症有哪些疾病" +
+                ",常见并发症\t的常见并发症或常并发的疾病有哪些疾病" +
+                ",提示病情加重或进展的检查指标\t的相关检查中可以提示病情加重或进展的指标变化有哪些" +
+                ",早期预警指标\t疾病早期的诊疗过程或病程中出现哪些体检指标的异常或临床症状的恶化,可能提示疾病进一步进展、加重或恶化" +
+                ",病因\t的病因或常见病因有哪些病因或致病原因" +
+                ",危险因素\t的危险因素有哪些危险因素(不要病因)" +
+                ",遗传方式\t的遗传方式有哪些遗传方式(如果该病无遗传方式,可回答“无”)" +
+                ",遗传基因\t的遗传基因名称有哪些遗传基因名称" +
+                ",诱因\t的诱因或诱发因素或常见诱因有哪些诱因" +
+                ",出院标准\t的出院标准有哪些";
     }
 }

+ 26 - 17
src/main/java/com/qizhen/healsphere/common/ai/QizhenAssistant.java

@@ -23,14 +23,14 @@ public class QizhenAssistant {
         try {
             return getAnswer(userInput, conversationId, appId, tuili);
         } catch (Exception e) {
-            e.printStackTrace();
             retry++;
-            if (retry >= 2) {
+            if (retry >= 20) {
                 Map<String, String> map = new HashMap<>();
                 map.put("answer", "failed");
                 return map;
             }
             return getAnswer(userInput, conversationId, appId, tuili);
+
         }
     }
 
@@ -50,20 +50,8 @@ public class QizhenAssistant {
     }
 
     private static Map<String, String> getAnswer(String userInput, String conversationId, String appId, boolean tuili) {
+        String resposne = call(appId, conversationId, userInput);
         Map<String, String> map = new HashMap<>();
-        JSONObject json = new JSONObject();
-        json.put("app_id", appId);
-        json.put("conversation_id", conversationId);
-        json.put("query", userInput);
-        json.put("stream", false);
-
-        HttpRequest request = HttpUtil.createRequest(Method.POST, "https://qianfan.baidubce.com/v2/app/conversation/runs")
-                .header("X-Appbuilder-Authorization", "Bearer bce-v3/ALTAK-MyGbNEA18oT3boS2nOga1/d8b5057f7842f59b2c64971d8d077fe724d0aed5")
-                .header("Content-Type", "application/json")
-                .body(json.toJSONString()).timeout(60 * 1000);
-        ;
-        long l = System.currentTimeMillis();
-        String resposne = request.execute().body();
         String answer = JSONObject.parseObject(resposne).getString("answer");
         if (answer.contains(noAnswer)) {
             map.put("answer", noAnswer);
@@ -114,7 +102,6 @@ public class QizhenAssistant {
             map.put("references", "[]");
         }
 
-        System.out.println((System.currentTimeMillis() - l) / 1000 + userInput);
         return map;
     }
 
@@ -123,7 +110,7 @@ public class QizhenAssistant {
         json.put("app_id", appId);
         //json.put("app_id", "454b1634-91ad-4dde-9d2f-f9a3302fdcbe");
         HttpRequest request = HttpUtil.createRequest(Method.POST, "https://qianfan.baidubce.com/v2/app/conversation")
-                .header("X-Appbuilder-Authorization", "Bearer bce-v3/ALTAK-MyGbNEA18oT3boS2nOga1/d8b5057f7842f59b2c64971d8d077fe724d0aed5")
+                .header("Authorization", "Bearer bce-v3/ALTAK-MyGbNEA18oT3boS2nOga1/d8b5057f7842f59b2c64971d8d077fe724d0aed5")
                 .header("Content-Type", "application/json")
                 .body(json.toJSONString());
         ;
@@ -131,4 +118,26 @@ public class QizhenAssistant {
         return JSONObject.parseObject(resposne).getString("conversation_id");
     }
 
+    public static String call(String appId, String conversationId, String userInput){
+        JSONObject json = new JSONObject();
+        json.put("app_id", appId);
+        json.put("conversation_id", conversationId);
+        json.put("query", userInput);
+        json.put("stream", false);
+
+
+        HttpRequest request = HttpUtil.createRequest(Method.POST, "https://qianfan.baidubce.com/v2/app/conversation/runs")
+                .header("Authorization", "Bearer bce-v3/ALTAK-MyGbNEA18oT3boS2nOga1/d8b5057f7842f59b2c64971d8d077fe724d0aed5")
+                .header("Content-Type", "application/json")
+                .body(json.toJSONString()).timeout(120 * 1000);
+        long l = System.currentTimeMillis();
+        String resposne = request.execute().body();
+        System.out.println(userInput.length());
+        long ct = (System.currentTimeMillis() - l) / 1000;
+        System.out.println(ct);
+        System.out.println(userInput.length()/ct);
+        System.out.println("===========================");
+        return resposne;
+    }
+
 }

+ 4 - 0
src/main/java/com/qizhen/healsphere/repository/mapper/KgEdgesMapper.java

@@ -3,6 +3,7 @@ package com.qizhen.healsphere.repository.mapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.qizhen.healsphere.repository.mapper.entity.KgEdges;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 /**
  * <p>
@@ -24,4 +25,7 @@ public interface KgEdgesMapper extends BaseMapper<KgEdges> {
 
     // 分页查询
     List<KgEdge> selectKgEdgesByPage(@Param("pageSize") int pageSize, @Param("offset") int offset);*/
+
+    boolean update1(@Param("oldId") int oldId, @Param("newId") int newId);
+    boolean update2(@Param("oldId") int oldId, @Param("newId") int newId);
 }

+ 64 - 0
src/main/java/com/qizhen/healsphere/util/FileCommonUtils.java

@@ -0,0 +1,64 @@
+package com.qizhen.healsphere.util;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class FileCommonUtils {
+
+    // 定义允许的字符集,这里只允许字母、数字、下划线、连字符和汉字
+    private static final String ALLOWED_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-\\u4e00-\\u9fa5、";
+
+    /**
+     * 清理文件名中的特殊字符
+     *
+     * @param originalFileName 原始文件名
+     * @return 清理后的文件名
+     */
+    public static String sanitizeFileName(String originalFileName) {
+        if (originalFileName == null) {
+            return null;
+        }
+
+        StringBuilder sanitizedFileName = new StringBuilder();
+        for (char c : originalFileName.toCharArray()) {
+            if (isAllowedChar(c)) {
+                sanitizedFileName.append(c);
+            }
+        }
+
+        return sanitizedFileName.toString();
+    }
+
+    /**
+     * 检查字符是否在允许的字符集中
+     *
+     * @param c 字符
+     * @return 如果字符在允许的字符集中,返回true;否则返回false
+     */
+    private static boolean isAllowedChar(char c) {
+        return ALLOWED_CHARS.indexOf(c) != -1 || (c >= '\u4e00' && c <= '\u9fa5');
+    }
+
+
+    /**
+     * 从文件路径中提取文件名(不包括目录和扩展名)
+     *
+     * @param filePath 文件路径
+     * @return 文件名(不包括目录和扩展名)
+     */
+    public static String getFileNameWithoutExtension(String filePath) {
+        Path path = Paths.get(filePath);
+        String fileName = path.getFileName().toString();
+        int dotIndex = fileName.lastIndexOf('.');
+        if (dotIndex == -1) {
+            return fileName; // 没有扩展名
+        }
+        return fileName.substring(0, dotIndex);
+    }
+
+    public static void main(String[] args) {
+        String filePath = "E:\\project\\demo\\example.txt";
+        String fileNameWithoutExtension = getFileNameWithoutExtension(filePath);
+        System.out.println("File Name Without Extension: " + fileNameWithoutExtension);
+    }
+}

+ 62 - 0
src/main/java/com/qizhen/healsphere/util/SentenceSplitter.java

@@ -0,0 +1,62 @@
+package com.qizhen.healsphere.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class SentenceSplitter {
+
+    /**
+     * 将一段话中的每句话拆分出来,支持中英文混合。
+     *
+     * @param text 输入的文本
+     * @return 拆分后的句子列表
+     */
+    public static List<String> splitSentences(String text) {
+        List<String> sentences = new ArrayList<>();
+        // 定义正则表达式,匹配中英文句子分隔符
+        String regex = "[。!?]+";
+        Pattern pattern = Pattern.compile(regex);
+        Matcher matcher = pattern.matcher(text);
+
+        int start = 0;
+        while (matcher.find()) {
+            int end = matcher.end();
+            // 包含句子分隔符和可能的换行符
+            String sentence = text.substring(start, end).trim();
+            // 检查句子分隔符后面是否有换行符
+            if (end < text.length() && text.charAt(end) == '\n') {
+                sentence += "\n";
+            }
+            if (!sentence.isEmpty()) {
+                sentences.add(sentence);
+            }
+            start = end;
+        }
+
+        // 添加最后一段未匹配到分隔符的内容,保留可能的换行符
+        if (start < text.length()) {
+            String lastSentence = text.substring(start).trim();
+            if (!lastSentence.isEmpty()) {
+                sentences.add(lastSentence);
+            }
+        }
+
+        return sentences;
+    }
+
+    public static void main(String[] args) {
+        // 测试用例
+        String input = "(一)热度与热程\n" +
+                "通常将发热程度分为:①低热:37.3~38℃;②中等度热:38.1~39℃;③高热:39.1~41℃;④超高 热:41℃以上。\n" +
+                "热程是指发热病程持续的时间。通常按发热持续的时间将其分为急性发热和长期发热,而急性 发热在急诊最为常见。";
+        List<String> result = splitSentences(input);
+
+        // 输出结果
+        for (String sentence : result) {
+            System.out.println(sentence);
+            System.out.println("=========");
+        }
+    }
+}

+ 1 - 1
src/main/resources/application.yml

@@ -1,6 +1,6 @@
 spring:
   profiles:
-    active: local
+    active: test
   application:
     name: healsphere
   jackson:

+ 13 - 0
src/main/resources/mapper/mysql/KgEdgesMapper.xml

@@ -19,6 +19,19 @@
         VALUES (#{id}, #{src_id}, #{dest_id}, #{name}, #{status}, #{category}, #{version})
     </insert>
 
+    <!-- 更新 -->
+    <update id="update1">
+        UPDATE kg_edges
+        SET dest_id=#{newId},version='1.1'
+        WHERE dest_id = #{oldId}
+    </update>
+
+    <update id="update2">
+        UPDATE kg_edges
+        SET src_id=#{newId},version='1.1'
+        WHERE src_id = #{oldId}
+    </update>
+
     <!-- 更新 -->
     <update id="updateKgEdge" parameterType="com.qizhen.healsphere.repository.mapper.entity.KgEdges">
         UPDATE kg_edge

+ 127 - 0
src/test/java/com/qizhen/healsphere/DataExtractTest.java

@@ -0,0 +1,127 @@
+package com.qizhen.healsphere;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.qizhen.healsphere.common.ai.Knowlege;
+import com.qizhen.healsphere.common.ai.QizhenAssistant;
+import com.qizhen.healsphere.repository.neo4j.entity.BaseEntity;
+import com.qizhen.healsphere.service.EntityService;
+import com.qizhen.healsphere.service.RelationshipService;
+import com.qizhen.healsphere.util.FileCommonUtils;
+import com.qizhen.healsphere.web.vo.CreateEntityVO;
+import com.qizhen.healsphere.web.vo.RelationshipVO;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.util.CollectionUtils;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * 是否空腹及归大类
+ */
+@RunWith(SpringRunner.class)
+@ComponentScan(basePackages = {"com.qizhen.healsphere.model", "com.qizhen.healsphere.repository"})
+@SpringBootTest
+public class DataExtractTest {
+    public static final String appId = "e1de7dfc-afdb-48e4-b0f8-4fcecea09643";
+
+    //public static final String appId = "9da5da63-29a1-4c59-ad0b-f1f3c737924a";
+
+    //public static final String inputDirectoryPath = "E:\\project\\vscode\\《急诊与灾难医学(第4版)》\\第二章急性发热\\"; // 修改为目录路径
+    public static final String inputDirectoryPath = "E:\\project\\vscode\\《急诊与灾难医学(第4版)》\\第五章心悸与心律失常\\"; // 修改为目录路径
+    public static void main(String[] args) {
+
+        //String inputDirectoryPath = "E:\\project\\vscode\\《急诊与灾难医学(第4版)》\\"; // 修改为目录路径
+        File inputDirectory = new File(inputDirectoryPath);
+        // 无子目录时处理txt文件
+        workbook = new HSSFWorkbook();//这里也可以设置sheet的Name
+        sheet = workbook.createSheet();
+        traverse(inputDirectory);
+    }
+    static HSSFWorkbook workbook;
+    static  HSSFSheet sheet = null;
+
+    public static int rows = 0;
+    private static void traverse(File dir) {
+        boolean hasSubDir = false;
+        File[] files = dir.listFiles();
+        if (files == null) {
+            return;
+        }
+        // 第一阶段:检测是否存在子目录
+        for (File file : files) {
+            if (file.isDirectory()) {
+                hasSubDir = true;
+                break; // 发现子目录立即中断循环
+            }
+        }
+
+        // 第二阶段:根据检测结果处理
+        if (hasSubDir) {
+            // 存在子目录时递归遍历
+            for (File file : files) {
+                if (file.isDirectory()) {
+                    traverse(file);
+                }
+            }
+        } else {
+            for (File file : files) {
+                if (file.getName().toLowerCase().endsWith(".txt") && file.getName().toLowerCase().contains("_split_")) {
+                    //System.out.println("发现文本文件: " + file.getName());
+                    String inputFilePath = file.getAbsolutePath();
+                    inputFilePath = inputFilePath.replace("E:\\project\\vscode", "");
+                    StringBuilder sb = new StringBuilder();
+                    try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
+                        String line;
+                        int i = 0;
+                        while ((line = reader.readLine()) != null) {
+                            if(i>0) {
+                                sb.append(line+"\n");
+                            }
+                            i++;
+                        }
+                        System.out.println(sb.toString());
+                        String response = QizhenAssistant.call(appId,QizhenAssistant.getConversationId(appId),sb.toString());
+                        System.out.println(response);
+                        HSSFRow row = sheet.createRow(rows++);
+                        row.createCell(0).setCellValue(response == null ? "" : JSONObject.parseObject(response).getString("answer"));
+                        row.createCell(1).setCellValue(sb.toString());
+                        row.createCell(2).setCellValue(inputFilePath);
+                        save(FileCommonUtils.getFileNameWithoutExtension(inputDirectoryPath));
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+    }
+
+    private static synchronized void save(String fileName) {
+        try {
+            fileName="C:\\Users\\17664\\Desktop\\"+fileName+".xlsx";
+            //文档输出
+            FileOutputStream out = new FileOutputStream(new File(fileName));
+            workbook.write(out);
+            out.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+}

+ 18 - 5
src/test/java/com/qizhen/healsphere/DataWriteTest31.java

@@ -40,8 +40,8 @@ public class DataWriteTest31 {
     RelationshipService relationshipService;
     @Autowired
     EntityService entityService;
-
-    private static boolean selfCheck = false;
+    private static int maxCount= 10;
+    private static boolean selfCheck = true;
     private static String urlExcelPath = "C:\\Users\\17664\\Desktop\\疾病.xlsx";
 
     @Test
@@ -124,10 +124,18 @@ public class DataWriteTest31 {
     public static void main(String[] args) throws Exception {
 
         String accessToken = BaidubceUtil.getAccessToken();
-        String propertyStr = "就诊科室\t有哪些“相关科室”或“就诊科室”或“所属科室”(有多个科室时,选相关性最高的,最多给我三个科室)?";
-
-        saveExel(propertyStr, accessToken,"就诊科室");
+        String propertyStr = "并发症\t的并发症有哪些疾病" +
+                ",常见并发症\t的常见并发症或常并发的疾病有哪些疾病" +
+                ",提示病情加重或进展的检查指标\t的相关检查中可以提示病情加重或进展的指标变化有哪些" +
+                ",早期预警指标\t疾病早期的诊疗过程或病程中出现哪些体检指标的异常或临床症状的恶化,可能提示疾病进一步进展、加重或恶化" +
+                ",病因\t的病因或常见病因有哪些病因或致病原因" +
+                ",危险因素\t的危险因素有哪些危险因素(不要病因)" +
+                ",遗传方式\t的遗传方式有哪些遗传方式(如果该病无遗传方式,可回答“无”)" +
+                ",遗传基因\t的遗传基因名称有哪些遗传基因名称" +
+                ",诱因\t的诱因或诱发因素或常见诱因有哪些诱因" +
+                ",出院标准\t的出院标准有哪些";
 
+        saveExel(propertyStr, accessToken,"old");
     }
 
     static HSSFWorkbook workbook;
@@ -189,6 +197,11 @@ public class DataWriteTest31 {
                 Sheet urlSheet = urlWorkbook.getSheetAt(0);
 
                 for (int rowNum = 0; rowNum <= urlSheet.getLastRowNum(); rowNum++) {
+                    if (maxCount > 0) {
+                        if (rowNum >= maxCount) {
+                            break;
+                        }
+                    }
                 try {
                     Row row = urlSheet.getRow(rowNum);
                     String disease = row.getCell(0).getStringCellValue();

+ 349 - 0
src/test/java/com/qizhen/healsphere/DataWriteTestDSR1.java

@@ -0,0 +1,349 @@
+package com.qizhen.healsphere;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.qizhen.healsphere.common.ai.BaidubceUtil;
+import com.qizhen.healsphere.common.ai.Knowlege;
+import com.qizhen.healsphere.common.ai.QizhenAssistant;
+import com.qizhen.healsphere.repository.neo4j.entity.BaseEntity;
+import com.qizhen.healsphere.service.EntityService;
+import com.qizhen.healsphere.service.RelationshipService;
+import com.qizhen.healsphere.web.vo.CreateEntityVO;
+import com.qizhen.healsphere.web.vo.RelationshipVO;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.util.CollectionUtils;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+@RunWith(SpringRunner.class)
+@ComponentScan(basePackages = {"com.qizhen.healsphere.model","com.qizhen.healsphere.repository"})
+@SpringBootTest
+public class DataWriteTestDSR1 {
+    @Autowired
+    RelationshipService relationshipService;
+    @Autowired
+    EntityService entityService;
+    private static int maxCount= 10;
+    private static boolean selfCheck = true;
+    private static String urlExcelPath = "C:\\Users\\17664\\Desktop\\疾病.xlsx";
+
+    @Test
+    public void writeNeo4j() {
+        String startLabel = "疾病";
+        String propertyStr = "并发症\t的并发症有哪些疾病";
+        String[] properties = propertyStr.split(",");
+        workbook = new HSSFWorkbook();//这里也可以设置sheet的Name
+        String fileName = "temp";//
+        HSSFSheet sheet = workbook.createSheet(fileName);
+        int rows = 0;
+        for(String property:properties){
+            String[] split = property.split("\t");
+            if(split.length<2){
+                continue;
+            }
+            String endLabel = split[0];
+            List<Knowlege> data = getData(BaidubceUtil.getAccessToken(), property);
+            if(!CollectionUtils.isEmpty(data)) {
+
+                for (Knowlege temp:data) {
+                    HSSFRow row = sheet.createRow(rows++);
+                    row.createCell(0).setCellValue(temp.getEntity() == null ? "" : temp.getEntity());
+                    row.createCell(1).setCellValue(temp.getProperty() == null ? "" : temp.getProperty());
+                    row.createCell(2).setCellValue(temp.getValue() == null ? "" : temp.getValue());
+                    row.createCell(3).setCellValue(temp.getQuestion() == null ? "" : temp.getQuestion());
+                    row.createCell(4).setCellValue(temp.getAnswer() == null ? "" : temp.getAnswer());
+                    row.createCell(5).setCellValue(temp.getChunk() == null ? "" : temp.getChunk());
+                    row.createCell(6).setCellValue(temp.getRefenrece() == null ? "" : temp.getRefenrece());
+                }
+                save(fileName);
+
+                for (Knowlege temp:data) {
+                    String value = temp.getValue();
+                    if(StringUtils.isBlank(value)){
+                        continue;
+                    }
+                    try{
+                        JSONArray jsonArray = JSONArray.parseArray(value);
+                        BaseEntity startEntity = createNoExists(startLabel, temp.getEntity());
+                        long startId = startEntity.getId();
+                        List<RelationshipVO> relationshipList = new ArrayList<>();
+                        for(int i=0;i<jsonArray.size();i++){
+                            String name = jsonArray.getString(i);
+                            if(StringUtils.isEmpty(name)){
+                                continue;
+                            }
+                            BaseEntity endEntity =  createNoExists(endLabel, name);
+                            Long endId = endEntity.getId();
+                            RelationshipVO relationshipVO = new RelationshipVO();
+                            relationshipVO.setStartId(startId);
+                            relationshipVO.setEndId(endId);
+                            relationshipVO.setStartLabel(startLabel);
+                            relationshipVO.setEndLabel(endLabel);
+                            relationshipVO.setRelationshipType(startLabel+"相关"+endLabel);
+                            relationshipList.add(relationshipVO);
+                        }
+                        if(!CollectionUtils.isEmpty(relationshipList)) {
+                            System.out.println( relationshipService.createRelationship(relationshipList));
+                        }
+                    }catch (Exception e){
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+    }
+
+    private BaseEntity createNoExists(String labelName, String name) {
+        BaseEntity nodeByName = entityService.findNodeByName(labelName, name);
+        if(Objects.nonNull(nodeByName)){//节点不存在
+            return nodeByName;
+        }
+        CreateEntityVO createEntity = new CreateEntityVO();
+        createEntity.setName(name);
+        createEntity.setLabel(labelName);
+        return entityService.create(createEntity);
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        String accessToken = BaidubceUtil.getAccessToken();
+        String propertyStr = "并发症\t的并发症有哪些疾病" +
+                ",提示病情加重或进展的检查指标\t的相关检查中可以提示病情加重或进展的指标变化有哪些" +
+                ",早期预警指标\t疾病早期的诊疗过程或病程中出现哪些体检指标的异常或临床症状的恶化,可能提示疾病进一步进展、加重或恶化" +
+                ",病因\t的病因或常见病因有哪些病因或致病原因" +
+                ",危险因素\t的危险因素有哪些危险因素(不要病因)" +
+                ",遗传方式\t的遗传方式有哪些遗传方式(如果该病无遗传方式,可回答“无”)" +
+                ",遗传基因\t的遗传基因名称有哪些遗传基因名称" +
+                ",诱因\t的诱因或诱发因素或常见诱因有哪些诱因" +
+                ",出院标准\t的出院标准有哪些";
+
+        saveExel(propertyStr, accessToken,"new");
+    }
+
+    static HSSFWorkbook workbook;
+    static Long totalCount = 0l;
+    static Long successCount = 0l;
+    static Long failCount = 0l;
+    static Long unkonwCount = 0l;
+    private static void saveExel(String propertyStr, String accessToken,String fileName) {
+        String[] properties = propertyStr.split(",");
+        workbook = new HSSFWorkbook();//这里也可以设置sheet的Name
+        HSSFSheet sheet = workbook.createSheet(fileName);
+        int rows = 0;
+        for(String property:properties){
+            List<Knowlege> data = getData(accessToken, property);
+            if(!CollectionUtils.isEmpty(data)) {
+                for (Knowlege temp:data) {
+                    HSSFRow row = sheet.createRow(rows++);
+                    row.createCell(0).setCellValue(temp.getEntity() == null ? "" : temp.getEntity());
+                    row.createCell(1).setCellValue(temp.getProperty() == null ? "" : temp.getProperty());
+                    row.createCell(2).setCellValue(temp.getValue() == null ? "" : temp.getValue());
+                    row.createCell(3).setCellValue(temp.getQuestion() == null ? "" : temp.getQuestion());
+                    row.createCell(4).setCellValue(temp.getAnswer() == null ? "" : temp.getAnswer());
+                    row.createCell(5).setCellValue(temp.getChunk() == null ? "" : temp.getChunk());
+                    row.createCell(6).setCellValue(temp.getRefenrece() == null ? "" : temp.getRefenrece());
+                }
+            }
+
+            String successRate = String.format("%.2f", Double.valueOf(successCount)/ Double.valueOf(totalCount));
+            String unkonwRate = String.format("%.2f", Double.valueOf(unkonwCount)/ Double.valueOf(totalCount));
+            sheet.getRow(rows-1).createCell(7).setCellValue(successRate);
+            sheet.getRow(rows-1).createCell(8).setCellValue(unkonwRate);
+            save(fileName);
+            totalCount = 0l;
+            successCount = 0l;
+            failCount = 0l;
+            unkonwCount = 0l;
+        }
+    }
+
+    private static synchronized void save(String fileName) {
+        try {
+            fileName="C:\\Users\\17664\\Desktop\\"+fileName+System.currentTimeMillis()+".xlsx";
+            //文档输出
+            FileOutputStream out = new FileOutputStream(new File(fileName));
+            workbook.write(out);
+            out.close();
+            System.out.println(fileName + "存储完毕");
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static List<Knowlege> getData(String accessToken,String property) {
+        List<Knowlege> list = new ArrayList<>();
+        try {
+            String appId= "7cba6286-643f-467c-96c0-9528d10ef593";
+                InputStream fis = new FileInputStream(urlExcelPath);
+                Workbook urlWorkbook = new XSSFWorkbook(fis);
+                Sheet urlSheet = urlWorkbook.getSheetAt(0);
+
+                for (int rowNum = 0; rowNum <= urlSheet.getLastRowNum(); rowNum++) {
+                    if (maxCount > 0) {
+                        if (rowNum >= maxCount) {
+                            break;
+                        }
+                    }
+                try {
+                    Row row = urlSheet.getRow(rowNum);
+                    String disease = row.getCell(0).getStringCellValue();
+                    if(StringUtils.isEmpty(disease)){
+                        continue;
+                    }
+                    disease = disease.trim();
+                    String[] split = property.split("\t");
+                    if(split.length<2){
+                        continue;
+                    }
+                    String quetionParty = split[1];
+                    String relation = split[0];
+                    String question = disease + quetionParty + "?";
+
+                    Map<String, String> result = QizhenAssistant.getChatResponse(question, QizhenAssistant.getConversationId(appId),appId);
+                    String answer = result.get("answer");
+                    String references = result.get("references");
+                    String defaultReferences = result.get("defaultReferences");
+                    String chatResponse = "";
+                    if (!("failed".equals(answer) || answer.contains(QizhenAssistant.noAnswer))) {
+                        String format = "你是专门处理医学领域文本的关系抽取专家。你将在指定的文本中抽取其中“"+disease+"的"+relation+"”。\n" +
+                                "\n" +
+                                "#要求\n" +
+                                "1、抽取的结果将以JSON数组的形式呈现。每个抽取的“"+relation+"”高度简洁、高度概括,不要要描述性的文字,文字尽量保持在12个字符以内!\n" +
+                                "\n" +
+                                "#示例1\n" +
+                                "以抽取“分期”为例\n" +
+                                "文本:\n" +
+                                "肱骨骨折如果是**肱骨头坏死**则有Cruess分期,包括I期、Ⅱ期、Ⅲ期、IV期、V期^[1]^。\n" +
+                                "\n" +
+                                "如果是肱骨近端骨折则有Neer分型和AO分型^[3]^。\n" +
+                                "输出:[\"Cruess分期I期\",\"Cruess分期Ⅱ期\",\"Cruess分期Ⅲ期\",\"Cruess分期IV期\",\"Cruess分期V期\"]\n" +
+                                "\n" +
+                                "#示例2\n" +
+                                "以抽取“是否传染病”为例\n" +
+                                "文本:\n" +
+                                "**是**^[2][4][6]^。\n" +
+                                "\n" +
+                                "输出:[\"是\"]\n\n"+
+                                "2、没有可抽取的“"+relation+"”,则返回空json数组。\n" +
+                                "\n" +
+                                "本次抽取的文本如下:\n\n";
+
+                        String zhiling = format+ answer;
+                        System.out.println(zhiling);
+                        chatResponse = BaidubceUtil.getChatResponse(zhiling, accessToken);
+                        //chatResponse = BaidubceUtil2.getChatResponse(zhiling);
+                        chatResponse = filte(chatResponse);
+                        JSONArray jsonResult = new JSONArray();
+                        if(!StringUtils.isBlank(chatResponse)){
+                            try{
+                                JSONArray jsonArray = JSONArray.parseArray(chatResponse);
+                                JSONArray referenceJA = JSONArray.parseArray(references);
+                                for(int t=0;t<jsonArray.size();t++){
+                                    String name = jsonArray.getString(t);
+                                    JSONObject temp = new JSONObject();
+                                    temp.put("name", name);
+                                    JSONArray tempReferenceJA = new JSONArray();
+                                    for(int r=0;r<referenceJA.size();r++){
+                                        JSONObject referenceJO = referenceJA.getJSONObject(r);
+                                        String content = referenceJO.getString("content");
+                                        String contentFilted = content.replaceAll("\\s+", "");
+                                        if(contentFilted.contains(name)){
+                                            //JSONObject clone = referenceJO.clone();
+                                            tempReferenceJA.add(referenceJO.getString("title"));
+                                        }
+                                    }
+                                    if(selfCheck) {
+                                        String llmQuestion = "你是一个资深的医学专家,请用“是”、“否”和“不确定”回答用户的问题回答。\n" +
+                                                "\n" +
+                                                "#要求\n" +
+                                                "1、只回答“是”、“否”和“不确定”,不要有额外的信息。\n" +
+                                                "\n" +
+                                                "#示例\n" +
+                                                "用户输入:急性上呼吸道感染的治疗药物是否包括“利巴韦林”?\n" +
+                                                "输出:是\n\n" +
+                                                "请回答:" + disease + "的" + relation + "是否包括“" + name + "”?";
+                                        String llmAnswer = BaidubceUtil.getChatResponse(llmQuestion, accessToken);
+                                        totalCount++;
+                                        temp.put("LLM-question", llmQuestion);
+                                        temp.put("LLM-answer", llmAnswer);
+                                        if (!StringUtils.isEmpty(llmAnswer) && llmAnswer.length() < 7) {
+                                            if (llmAnswer.contains("是")) {
+                                                successCount++;
+                                            } else if (llmAnswer.contains("否")) {
+                                                failCount++;
+                                            }
+                                        } else {
+                                            unkonwCount++;
+                                        }
+                                    }
+                                    temp.put("reference", tempReferenceJA);
+                                    if(tempReferenceJA.size()<1){
+                                        temp.put("defaultReferences", defaultReferences);
+                                    }
+                                    jsonResult.add(temp);
+                                }
+                            }catch (Exception e){
+                                System.out.println("######"+chatResponse);
+                                e.printStackTrace();
+                                continue;
+                            }
+                        }
+                        addNode(disease, relation, chatResponse,jsonResult.toJSONString(), answer, question, result, list);
+                    }else {
+                        addNode(disease, relation, "","", answer, question, result, list);
+                    }
+
+                }catch (Exception e){
+                    System.out.println("抽取三元组失败!");
+                    e.printStackTrace();
+                }
+            }
+            return list;
+        } catch (Exception e) {
+            System.out.println("未知错误!");
+            e.printStackTrace();
+        }finally {
+            return list;
+        }
+    }
+
+    private static void addNode(String disease, String property, String chatResponse,String refences, String answer, String question, Map<String, String> result, List<Knowlege> list) {
+        Knowlege knowlege = new Knowlege();
+        knowlege.setEntity(disease);
+        knowlege.setProperty(property);
+        knowlege.setValue(chatResponse);
+        knowlege.setAnswer(answer);
+        knowlege.setQuestion(question);
+        knowlege.setChunk(result.get("references"));
+        knowlege.setRefenrece(refences);
+        list.add(knowlege);
+    }
+
+    private static String filte(String chatResponse) {
+        if (chatResponse.startsWith("```json")) {
+            chatResponse = chatResponse.substring(7);
+        }
+        if (chatResponse.endsWith("```")) {
+            chatResponse = chatResponse.substring(0, chatResponse.length() - 3);
+        }
+        return chatResponse;
+    }
+}
+

+ 347 - 0
src/test/java/com/qizhen/healsphere/DataWriteTestDSV3.java

@@ -0,0 +1,347 @@
+package com.qizhen.healsphere;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.qizhen.healsphere.common.ai.BaidubceUtil;
+import com.qizhen.healsphere.common.ai.Knowlege;
+import com.qizhen.healsphere.common.ai.QizhenAssistant;
+import com.qizhen.healsphere.repository.neo4j.entity.BaseEntity;
+import com.qizhen.healsphere.service.EntityService;
+import com.qizhen.healsphere.service.RelationshipService;
+import com.qizhen.healsphere.web.vo.CreateEntityVO;
+import com.qizhen.healsphere.web.vo.RelationshipVO;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.util.CollectionUtils;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+@RunWith(SpringRunner.class)
+@ComponentScan(basePackages = {"com.qizhen.healsphere.model","com.qizhen.healsphere.repository"})
+@SpringBootTest
+public class DataWriteTestDSV3 {
+    @Autowired
+    RelationshipService relationshipService;
+    @Autowired
+    EntityService entityService;
+    private static int maxCount= 10;
+    private static boolean selfCheck = true;
+    private static String urlExcelPath = "C:\\Users\\17664\\Desktop\\疾病.xlsx";
+
+    @Test
+    public void writeNeo4j() {
+        String startLabel = "疾病";
+        String propertyStr = "并发症\t的并发症有哪些疾病";
+        String[] properties = propertyStr.split(",");
+        workbook = new HSSFWorkbook();//这里也可以设置sheet的Name
+        String fileName = "temp";//
+        HSSFSheet sheet = workbook.createSheet(fileName);
+        int rows = 0;
+        for(String property:properties){
+            String[] split = property.split("\t");
+            if(split.length<2){
+                continue;
+            }
+            String endLabel = split[0];
+            List<Knowlege> data = getData(BaidubceUtil.getAccessToken(), property);
+            if(!CollectionUtils.isEmpty(data)) {
+
+                for (Knowlege temp:data) {
+                    HSSFRow row = sheet.createRow(rows++);
+                    row.createCell(0).setCellValue(temp.getEntity() == null ? "" : temp.getEntity());
+                    row.createCell(1).setCellValue(temp.getProperty() == null ? "" : temp.getProperty());
+                    row.createCell(2).setCellValue(temp.getValue() == null ? "" : temp.getValue());
+                    row.createCell(3).setCellValue(temp.getQuestion() == null ? "" : temp.getQuestion());
+                    row.createCell(4).setCellValue(temp.getAnswer() == null ? "" : temp.getAnswer());
+                    row.createCell(5).setCellValue(temp.getChunk() == null ? "" : temp.getChunk());
+                    row.createCell(6).setCellValue(temp.getRefenrece() == null ? "" : temp.getRefenrece());
+                }
+                save(fileName);
+
+                for (Knowlege temp:data) {
+                    String value = temp.getValue();
+                    if(StringUtils.isBlank(value)){
+                        continue;
+                    }
+                    try{
+                        JSONArray jsonArray = JSONArray.parseArray(value);
+                        BaseEntity startEntity = createNoExists(startLabel, temp.getEntity());
+                        long startId = startEntity.getId();
+                        List<RelationshipVO> relationshipList = new ArrayList<>();
+                        for(int i=0;i<jsonArray.size();i++){
+                            String name = jsonArray.getString(i);
+                            if(StringUtils.isEmpty(name)){
+                                continue;
+                            }
+                            BaseEntity endEntity =  createNoExists(endLabel, name);
+                            Long endId = endEntity.getId();
+                            RelationshipVO relationshipVO = new RelationshipVO();
+                            relationshipVO.setStartId(startId);
+                            relationshipVO.setEndId(endId);
+                            relationshipVO.setStartLabel(startLabel);
+                            relationshipVO.setEndLabel(endLabel);
+                            relationshipVO.setRelationshipType(startLabel+"相关"+endLabel);
+                            relationshipList.add(relationshipVO);
+                        }
+                        if(!CollectionUtils.isEmpty(relationshipList)) {
+                            System.out.println( relationshipService.createRelationship(relationshipList));
+                        }
+                    }catch (Exception e){
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+    }
+
+    private BaseEntity createNoExists(String labelName, String name) {
+        BaseEntity nodeByName = entityService.findNodeByName(labelName, name);
+        if(Objects.nonNull(nodeByName)){//节点不存在
+            return nodeByName;
+        }
+        CreateEntityVO createEntity = new CreateEntityVO();
+        createEntity.setName(name);
+        createEntity.setLabel(labelName);
+        return entityService.create(createEntity);
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        String accessToken = BaidubceUtil.getAccessToken();
+        String propertyStr = "并发症\t的并发症有哪些疾病" +
+                ",常见并发症\t的常见并发症或常并发的疾病有哪些疾病" +
+                ",提示病情加重或进展的检查指标\t的相关检查中可以提示病情加重或进展的指标变化有哪些" +
+                ",早期预警指标\t疾病早期的诊疗过程或病程中出现哪些体检指标的异常或临床症状的恶化,可能提示疾病进一步进展、加重或恶化" +
+                ",病因\t的病因或常见病因有哪些病因或致病原因" +
+                ",危险因素\t的危险因素有哪些危险因素(不要病因)" +
+                ",遗传方式\t的遗传方式有哪些遗传方式(如果该病无遗传方式,可回答“无”)" +
+                ",遗传基因\t的遗传基因名称有哪些遗传基因名称" +
+                ",诱因\t的诱因或诱发因素或常见诱因有哪些诱因" +
+                ",出院标准\t的出院标准有哪些";
+        saveExel(propertyStr, accessToken,"v3");
+    }
+
+    static HSSFWorkbook workbook;
+    static Long totalCount = 0l;
+    static Long successCount = 0l;
+    static Long failCount = 0l;
+    static Long unkonwCount = 0l;
+    private static void saveExel(String propertyStr, String accessToken,String fileName) {
+        String[] properties = propertyStr.split(",");
+        workbook = new HSSFWorkbook();//这里也可以设置sheet的Name
+        HSSFSheet sheet = workbook.createSheet(fileName);
+        int rows = 0;
+        for(String property:properties){
+            List<Knowlege> data = getData(accessToken, property);
+            if(!CollectionUtils.isEmpty(data)) {
+                for (Knowlege temp:data) {
+                    HSSFRow row = sheet.createRow(rows++);
+                    row.createCell(0).setCellValue(temp.getEntity() == null ? "" : temp.getEntity());
+                    row.createCell(1).setCellValue(temp.getProperty() == null ? "" : temp.getProperty());
+                    row.createCell(2).setCellValue(temp.getValue() == null ? "" : temp.getValue());
+                    row.createCell(3).setCellValue(temp.getQuestion() == null ? "" : temp.getQuestion());
+                    row.createCell(4).setCellValue(temp.getAnswer() == null ? "" : temp.getAnswer());
+                    row.createCell(5).setCellValue(temp.getChunk() == null ? "" : temp.getChunk());
+                    row.createCell(6).setCellValue(temp.getRefenrece() == null ? "" : temp.getRefenrece());
+                }
+            }
+
+            String successRate = String.format("%.2f", Double.valueOf(successCount)/ Double.valueOf(totalCount));
+            String unkonwRate = String.format("%.2f", Double.valueOf(unkonwCount)/ Double.valueOf(totalCount));
+            sheet.getRow(rows-1).createCell(7).setCellValue(successRate);
+            sheet.getRow(rows-1).createCell(8).setCellValue(unkonwRate);
+            save(fileName);
+            totalCount = 0l;
+            successCount = 0l;
+            failCount = 0l;
+            unkonwCount = 0l;
+        }
+    }
+
+    private static synchronized void save(String fileName) {
+        try {
+            fileName="C:\\Users\\17664\\Desktop\\"+fileName+System.currentTimeMillis()+".xlsx";
+            //文档输出
+            FileOutputStream out = new FileOutputStream(new File(fileName));
+            workbook.write(out);
+            out.close();
+            System.out.println(fileName + "存储完毕");
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static List<Knowlege> getData(String accessToken,String property) {
+        List<Knowlege> list = new ArrayList<>();
+        try {
+            String appId= "5d271a65-754b-460a-9f9b-28b566d40538";
+                InputStream fis = new FileInputStream(urlExcelPath);
+                Workbook urlWorkbook = new XSSFWorkbook(fis);
+                Sheet urlSheet = urlWorkbook.getSheetAt(0);
+
+                for (int rowNum = 0; rowNum <= urlSheet.getLastRowNum(); rowNum++) {
+                    if (maxCount > 0) {
+                        if (rowNum >= maxCount) {
+                            break;
+                        }
+                    }
+                try {
+                    Row row = urlSheet.getRow(rowNum);
+                    String disease = row.getCell(0).getStringCellValue();
+                    if(StringUtils.isEmpty(disease)){
+                        continue;
+                    }
+                    disease = disease.trim();
+                    String[] split = property.split("\t");
+                    if(split.length<2){
+                        continue;
+                    }
+                    String quetionParty = split[1];
+                    String relation = split[0];
+                    String question = disease + quetionParty + "?";
+
+                    Map<String, String> result = QizhenAssistant.getChatResponse(question, QizhenAssistant.getConversationId(appId),appId);
+                    String answer = result.get("answer");
+                    String references = result.get("references");
+                    String defaultReferences = result.get("defaultReferences");
+                    String chatResponse = "";
+                    if (!("failed".equals(answer) || answer.contains(QizhenAssistant.noAnswer))) {
+                        String format = "你是专门处理医学领域文本的关系抽取专家。你将在指定的文本中抽取其中“"+disease+"的"+relation+"”。\n" +
+                                "\n" +
+                                "#要求\n" +
+                                "1、抽取的结果将以JSON数组的形式呈现。每个抽取的“"+relation+"”高度简洁、高度概括,不要要描述性的文字,文字尽量保持在12个字符以内!\n" +
+                                "\n" +
+                                "#示例1\n" +
+                                "以抽取“分期”为例\n" +
+                                "文本:\n" +
+                                "肱骨骨折如果是**肱骨头坏死**则有Cruess分期,包括I期、Ⅱ期、Ⅲ期、IV期、V期^[1]^。\n" +
+                                "\n" +
+                                "如果是肱骨近端骨折则有Neer分型和AO分型^[3]^。\n" +
+                                "输出:[\"Cruess分期I期\",\"Cruess分期Ⅱ期\",\"Cruess分期Ⅲ期\",\"Cruess分期IV期\",\"Cruess分期V期\"]\n" +
+                                "\n" +
+                                "#示例2\n" +
+                                "以抽取“是否传染病”为例\n" +
+                                "文本:\n" +
+                                "**是**^[2][4][6]^。\n" +
+                                "\n" +
+                                "输出:[\"是\"]\n\n"+
+                                "2、没有可抽取的“"+relation+"”,则返回空json数组。\n" +
+                                "\n" +
+                                "本次抽取的文本如下:\n\n";
+
+                        String zhiling = format+ answer;
+                        System.out.println(zhiling);
+                        chatResponse = BaidubceUtil.getChatResponse(zhiling, accessToken);
+                        chatResponse = filte(chatResponse);
+                        JSONArray jsonResult = new JSONArray();
+                        if(!StringUtils.isBlank(chatResponse)){
+                            try{
+                                JSONArray jsonArray = JSONArray.parseArray(chatResponse);
+                                JSONArray referenceJA = JSONArray.parseArray(references);
+                                for(int t=0;t<jsonArray.size();t++){
+                                    String name = jsonArray.getString(t);
+                                    JSONObject temp = new JSONObject();
+                                    temp.put("name", name);
+                                    JSONArray tempReferenceJA = new JSONArray();
+                                    for(int r=0;r<referenceJA.size();r++){
+                                        JSONObject referenceJO = referenceJA.getJSONObject(r);
+                                        String content = referenceJO.getString("content");
+                                        String contentFilted = content.replaceAll("\\s+", "");
+                                        if(contentFilted.contains(name)){
+                                            //JSONObject clone = referenceJO.clone();
+                                            tempReferenceJA.add(referenceJO.getString("title"));
+                                        }
+                                    }
+                                    if(selfCheck) {
+                                        String llmQuestion = "你是一个资深的医学专家,请用“是”、“否”和“不确定”回答用户的问题回答。\n" +
+                                                "\n" +
+                                                "#要求\n" +
+                                                "1、只回答“是”、“否”和“不确定”,不要有额外的信息。\n" +
+                                                "\n" +
+                                                "#示例\n" +
+                                                "用户输入:急性上呼吸道感染的治疗药物是否包括“利巴韦林”?\n" +
+                                                "输出:是\n\n" +
+                                                "请回答:" + disease + "的" + relation + "是否包括“" + name + "”?";
+                                        String llmAnswer = BaidubceUtil.getChatResponse(llmQuestion, accessToken);
+                                        totalCount++;
+                                        temp.put("LLM-question", llmQuestion);
+                                        temp.put("LLM-answer", llmAnswer);
+                                        if (!StringUtils.isEmpty(llmAnswer) && llmAnswer.length() < 7) {
+                                            if (llmAnswer.contains("是")) {
+                                                successCount++;
+                                            } else if (llmAnswer.contains("否")) {
+                                                failCount++;
+                                            }
+                                        } else {
+                                            unkonwCount++;
+                                        }
+                                    }
+                                    temp.put("reference", tempReferenceJA);
+                                    if(tempReferenceJA.size()<1){
+                                        temp.put("defaultReferences", defaultReferences);
+                                    }
+                                    jsonResult.add(temp);
+                                }
+                            }catch (Exception e){
+                                System.out.println("######"+chatResponse);
+                                e.printStackTrace();
+                                continue;
+                            }
+                        }
+                        addNode(disease, relation, chatResponse,jsonResult.toJSONString(), answer, question, result, list);
+                    }else {
+                        addNode(disease, relation, "","", answer, question, result, list);
+                    }
+                }catch (Exception e){
+                    System.out.println("抽取三元组失败!");
+                    e.printStackTrace();
+                }
+            }
+            return list;
+        } catch (Exception e) {
+            System.out.println("未知错误!");
+            e.printStackTrace();
+        }finally {
+            return list;
+        }
+    }
+
+    private static void addNode(String disease, String property, String chatResponse,String refences, String answer, String question, Map<String, String> result, List<Knowlege> list) {
+        Knowlege knowlege = new Knowlege();
+        knowlege.setEntity(disease);
+        knowlege.setProperty(property);
+        knowlege.setValue(chatResponse);
+        knowlege.setAnswer(answer);
+        knowlege.setQuestion(question);
+        knowlege.setChunk(result.get("references"));
+        knowlege.setRefenrece(refences);
+        list.add(knowlege);
+    }
+
+    private static String filte(String chatResponse) {
+        if (chatResponse.startsWith("```json")) {
+            chatResponse = chatResponse.substring(7);
+        }
+        if (chatResponse.endsWith("```")) {
+            chatResponse = chatResponse.substring(0, chatResponse.length() - 3);
+        }
+        return chatResponse;
+    }
+}
+

+ 98 - 0
src/test/java/com/qizhen/healsphere/DeletedDataTest.java

@@ -0,0 +1,98 @@
+package com.qizhen.healsphere;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.qizhen.healsphere.repository.mapper.KgEdgesMapper;
+import com.qizhen.healsphere.repository.mapper.KgNodesMapper;
+import com.qizhen.healsphere.repository.mapper.KgSchemasMapper;
+import com.qizhen.healsphere.repository.mapper.entity.KgEdges;
+import com.qizhen.healsphere.repository.mapper.entity.KgNodes;
+import com.qizhen.healsphere.repository.mapper.entity.KgSchemas;
+import com.qizhen.healsphere.repository.neo4j.BaseRelationshipRepository;
+import com.qizhen.healsphere.repository.neo4j.entity.BaseEntity;
+import com.qizhen.healsphere.repository.neo4j.entity.Edge;
+import com.qizhen.healsphere.util.DataMigrationUtil;
+import com.qizhen.healsphere.util.IcdRelationCreator;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.util.CollectionUtils;
+
+import java.sql.Wrapper;
+import java.util.HashMap;
+import java.util.List;
+
+@RunWith(SpringRunner.class)
+@ComponentScan(basePackages = {"com.qizhen.healsphere"})
+@SpringBootTest
+public class DeletedDataTest {
+    String version = "1.1";
+    @Autowired
+    BaseRelationshipRepository baseRelationshipRepository;
+
+    @Autowired
+    KgNodesMapper kgNodesMapper;
+
+    @Autowired
+    KgEdgesMapper kgEdgesMapper;
+
+    @Autowired
+    KgSchemasMapper kgSchemasMapper;
+
+    @Autowired
+    DataMigrationUtil dataMigrationUtil;
+
+    @Autowired
+    private IcdRelationCreator icdRelationCreator;
+
+    @Test
+    public void migrateData() {
+
+        String relationships = "Vectors";
+        String[] split = relationships.split(",");
+        for(String relationship:split) {
+            HashMap<String, Object> columnMap = new HashMap<>();
+            columnMap.put("category", relationship);
+            List<KgNodes> kgNodes = kgNodesMapper.selectByMap(columnMap);
+            if(CollectionUtil.isEmpty(kgNodes)) {
+                continue;
+            }
+            for(KgNodes temp:kgNodes) {
+                columnMap = new HashMap<>();
+                columnMap.put("src_id", temp.getId());
+                System.out.println(kgEdgesMapper.deleteByMap(columnMap));
+                columnMap = new HashMap<>();
+                columnMap.put("dest_id", temp.getId());
+                System.out.println(kgEdgesMapper.deleteByMap(columnMap));
+
+                System.out.println(kgNodesMapper.deleteById(temp.getId()));
+            }
+        }
+    }
+
+    @Test
+    public void mergeData() {
+
+        HashMap<String, Object> columnMap = new HashMap<>();
+        columnMap.put("category", "药品");
+        List<KgNodes> kgNodes = kgNodesMapper.selectByMap(columnMap);
+        for(KgNodes temp:kgNodes) {
+            columnMap = new HashMap<>();
+            columnMap.put("name", temp.getName());
+            List<KgNodes> drugs = kgNodesMapper.selectByMap(columnMap);
+            if(!CollectionUtils.isEmpty(drugs)){
+                if(drugs.size()>1){
+                    System.out.println(1111);
+                }
+                kgEdgesMapper.update1(temp.getId(), drugs.get(0).getId());
+                kgEdgesMapper.update2(temp.getId(), drugs.get(0).getId());
+            }else{
+                temp.setCategory("Drug");
+                kgNodesMapper.updateById(temp);
+            }
+        }
+    }
+}

+ 62 - 0
src/test/java/com/qizhen/healsphere/ExplainAssistant.java

@@ -0,0 +1,62 @@
+package com.qizhen.healsphere;
+
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.http.Method;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.qizhen.healsphere.common.ai.QizhenAssistant;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ExplainAssistant {
+
+    public static String getConversationId(String appId) {
+        JSONObject json = new JSONObject();
+        json.put("app_id", appId);
+        //json.put("app_id", "454b1634-91ad-4dde-9d2f-f9a3302fdcbe");
+        HttpRequest request = HttpUtil.createRequest(Method.POST, "https://qianfan.baidubce.com/v2/app/conversation")
+                .header("Authorization", "Bearer bce-v3/ALTAK-MyGbNEA18oT3boS2nOga1/d8b5057f7842f59b2c64971d8d077fe724d0aed5")
+                .header("Content-Type", "application/json")
+                .body(json.toJSONString());
+        ;
+        String resposne = request.execute().body();
+        return JSONObject.parseObject(resposne).getString("conversation_id");
+    }
+
+    public static String call(String appId, String conversationId, String userInput){
+        JSONObject json = new JSONObject();
+        json.put("app_id", appId);
+        json.put("conversation_id", conversationId);
+        json.put("query", userInput);
+        json.put("stream", false);
+
+
+        HttpRequest request = HttpUtil.createRequest(Method.POST, "https://qianfan.baidubce.com/v2/app/conversation/runs")
+                .header("Authorization", "Bearer bce-v3/ALTAK-MyGbNEA18oT3boS2nOga1/d8b5057f7842f59b2c64971d8d077fe724d0aed5")
+                .header("Content-Type", "application/json")
+                .body(json.toJSONString()).timeout(120 * 1000);
+        long l = System.currentTimeMillis();
+        String resposne = request.execute().body();
+        System.out.println(userInput.length());
+        long ct = (System.currentTimeMillis() - l) / 1000;
+        System.out.println(ct);
+        System.out.println(userInput.length()/ct);
+        System.out.println("===========================");
+        return resposne;
+    }
+
+    public static void main(String[] args) {
+        String appId = "03a62954-9bb0-4abe-9c7e-b7555cd3c2a0";
+        String response =  ExplainAssistant.call(appId,ExplainAssistant.getConversationId(appId),"Haemophilus parainfluenzae,Streptococcus australis");
+        System.out.println(response);
+        System.out.println(JSONObject.parseObject(response).getString("answer"));
+    }
+
+}

+ 33 - 13
src/test/java/com/qizhen/healsphere/MigrateDataTest.java

@@ -19,6 +19,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.util.CollectionUtils;
 
 import java.util.HashMap;
 import java.util.List;
@@ -49,19 +50,43 @@ public class MigrateDataTest {
     @Autowired
     private DrugRelationCreator drugRelationCreator;
 
+    @Test
+    public void mergeData() {
+
+        HashMap<String, Object> columnMap = new HashMap<>();
+        columnMap.put("category", "药品");
+        List<KgNodes> kgNodes = kgNodesMapper.selectByMap(columnMap);
+        for(KgNodes temp:kgNodes) {
+            columnMap = new HashMap<>();
+            columnMap.put("name", temp.getName());
+            columnMap.put("category", "Drug");
+            List<KgNodes> drugs = kgNodesMapper.selectByMap(columnMap);
+            if(!CollectionUtils.isEmpty(drugs)){
+                if(drugs.size()>1){
+                    System.out.println(1111);
+                }
+                kgEdgesMapper.update1(temp.getId(), drugs.get(0).getId());
+                kgEdgesMapper.update2(temp.getId(), drugs.get(0).getId());
+            }else{
+                temp.setCategory("Drug");
+                kgNodesMapper.updateById(temp);
+            }
+        }
+    }
+
     @Test
     public void migrateData() {
 
-        String endLabels = "剂型,规格";
+        String endLabels = "ICD10编码";
         String[] split = endLabels.split(",");
-        String startLabel = "药品";
+        String startLabel = "疾病";
         addIfNotExist(startLabel);
         for(String endLabel:split) {
-            String relationship = startLabel + "相关" + endLabel;
+            String relationship = "疾病相关ICD10临床2.0编码";
             String name = "";
 
 
-            List<Edge> edges = baseRelationshipRepository.triples(startLabel, relationship, startLabel+endLabel);
+            List<Edge> edges = baseRelationshipRepository.triples(startLabel, relationship, endLabel);
             if (CollectionUtil.isEmpty(edges)) {
                 continue;
             }
@@ -103,9 +128,9 @@ public class MigrateDataTest {
     @Test
     public void migrateDataByExist() {
 
-        String relationships = "常见疾病";
+        String relationships = "禁忌症";
         String[] split = relationships.split(",");
-        String startLabel = "症状";
+        String startLabel = "辅助检查";
         String endLabel = "疾病";
         addIfNotExist(startLabel);
         for(String relationship:split) {
@@ -143,14 +168,9 @@ public class MigrateDataTest {
 
     @Test
     public void migrateDataBySelf() {
-/*        String propertyStr = "别名##症状\t“#症状#”此处作为一种“症状”,“#症状#”的别称或别名有哪些(请更加严格的遵照文献原文,不要把子类名称当做别称给我)" +
-                ",常伴随的症状##症状\t“#症状#”此处作为一种“症状”,“#症状#”常伴随的症状有哪些症状" +
-                ",常见疾病##疾病\t“#症状#”此处作为一种“症状”,“#症状#”常见于哪些疾病" +
-                ",子类或分类##症状\t“#症状#”此处作为一种“症状”,“#症状#”的症状子类或症状分类有哪些症状(答案必须包含“#症状#”几个字,否则不提取)";*/
-
-        String relationships = "别名,常伴随的症状,子类或分类";
+        String relationships = "英文名称";
         String[] split = relationships.split(",");
-        String startLabel = "症状";
+        String startLabel = "辅助检查";
         String endLabel = startLabel;
         addIfNotExist(startLabel);
         for(String relationship:split) {