From 910d54b4c99900669c5d90f7d5d7a1db14370be9 Mon Sep 17 00:00:00 2001
From: liu <liujiatong112@163.com>
Date: Thu, 30 May 2024 16:31:43 +0800
Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4AI=E5=B7=A5=E5=85=B7=E7=B1=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 pom.xml                                       |   9 ++
 virtual-patient-common/pom.xml                |   6 +
 .../java/com/supervision/util/AiChatUtil.java | 106 ++++++++++++++++++
 virtual-patient-graph/pom.xml                 |   5 +
 .../nebula/config/NebulaGraphProperties.java  |   2 +
 .../nebula/config/NebulaSession.java          |   1 +
 .../src/main/resources/bootstrap-dev.yml      |   8 +-
 virtual-patient-manage/pom.xml                |   1 +
 virtual-patient-web/pom.xml                   |  17 ---
 9 files changed, 134 insertions(+), 21 deletions(-)
 create mode 100644 virtual-patient-common/src/main/java/com/supervision/util/AiChatUtil.java

diff --git a/pom.xml b/pom.xml
index 83db33ae..30abbfd0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -56,11 +56,20 @@
         <lock4j.version>2.2.5</lock4j.version>
         <minio.version>8.5.7</minio.version>
         <okhttp.version>4.9.0</okhttp.version>
+        <springboot.ai>1.0.3</springboot.ai>
     </properties>
 
     <dependencyManagement>
         <dependencies>
 
+            <dependency>
+                <groupId>io.springboot.ai</groupId>
+                <artifactId>spring-ai-bom</artifactId>
+                <version>${springboot.ai}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
             <dependency>
                 <groupId>org.springframework.cloud</groupId>
                 <artifactId>spring-cloud-starter-bootstrap</artifactId>
diff --git a/virtual-patient-common/pom.xml b/virtual-patient-common/pom.xml
index c9f86858..8727129f 100644
--- a/virtual-patient-common/pom.xml
+++ b/virtual-patient-common/pom.xml
@@ -36,6 +36,12 @@
             <artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
         </dependency>
 
+        <!--        引入ollama的依赖.版本号来自于 dependencyManagement中 spring-ai-bom中的版本号.-->
+        <dependency>
+            <groupId>io.springboot.ai</groupId>
+            <artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
+        </dependency>
+
 
         <dependency>
             <groupId>org.springframework.boot</groupId>
diff --git a/virtual-patient-common/src/main/java/com/supervision/util/AiChatUtil.java b/virtual-patient-common/src/main/java/com/supervision/util/AiChatUtil.java
new file mode 100644
index 00000000..f578be45
--- /dev/null
+++ b/virtual-patient-common/src/main/java/com/supervision/util/AiChatUtil.java
@@ -0,0 +1,106 @@
+package com.supervision.util;
+
+import cn.hutool.core.thread.ThreadUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.ai.chat.ChatResponse;
+import org.springframework.ai.chat.messages.Message;
+import org.springframework.ai.chat.messages.UserMessage;
+import org.springframework.ai.chat.prompt.Prompt;
+import org.springframework.ai.ollama.OllamaChatClient;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.*;
+
+@Slf4j
+public class AiChatUtil {
+
+    public static final ExecutorService chatExecutor = ThreadUtil.newFixedExecutor(5, 0, "chat", new ThreadPoolExecutor.CallerRunsPolicy());
+
+    public static final OllamaChatClient chatClient = SpringBeanUtil.getBean(OllamaChatClient.class);
+
+    /**
+     * 单轮对话
+     *
+     * @param chat 对话的内容
+     * @return jsonObject
+     */
+    public Optional<JSONObject> chat(String chat) {
+        Prompt prompt = new Prompt(List.of(new UserMessage(chat)));
+        Future<String> submit = chatExecutor.submit(new ChatTask(chatClient, prompt));
+        try {
+            return Optional.of(JSONUtil.parseObj(submit.get()));
+        } catch (ExecutionException | InterruptedException e) {
+            log.error("调用大模型生成失败");
+        }
+        return Optional.empty();
+    }
+
+    /**
+     * 支持多轮对话,自定义消息
+     *
+     * @param messageList 消息列表
+     * @return jsonObject
+     */
+    public Optional<JSONObject> chat(List<Message> messageList) {
+        Prompt prompt = new Prompt(messageList);
+        Future<String> submit = chatExecutor.submit(new ChatTask(chatClient, prompt));
+        try {
+            return Optional.of(JSONUtil.parseObj(submit.get()));
+        } catch (ExecutionException | InterruptedException e) {
+            log.error("调用大模型生成失败");
+        }
+        return Optional.empty();
+    }
+
+    /**
+     * 支持序列化的方式
+     *
+     * @param messageList 消息列表
+     * @param clazz       需要序列化的对象
+     * @param <T>         需要序列化的对象的泛型
+     * @return 对应对象类型, 不支持列表类型
+     */
+    public <T> Optional<T> chat(List<Message> messageList, Class<T> clazz) {
+        Prompt prompt = new Prompt(messageList);
+        Future<String> submit = chatExecutor.submit(new ChatTask(chatClient, prompt));
+        try {
+            String s = submit.get();
+            return Optional.ofNullable(JSONUtil.toBean(s, clazz));
+        } catch (ExecutionException | InterruptedException e) {
+            log.error("调用大模型生成失败");
+        }
+        return Optional.empty();
+    }
+
+    /**
+     * 支持序列化的方式的对话
+     *
+     * @param chat  对话的消息
+     * @param clazz 需要序列化的对象
+     * @param <T>   需要序列化的对象的泛型
+     * @return 对应对象类型, 不支持列表类型
+     */
+    public <T> Optional<T> chat(String chat, Class<T> clazz) {
+        Prompt prompt = new Prompt(List.of(new UserMessage(chat)));
+        Future<String> submit = chatExecutor.submit(new ChatTask(chatClient, prompt));
+        try {
+            String s = submit.get();
+            return Optional.ofNullable(JSONUtil.toBean(s, clazz));
+        } catch (ExecutionException | InterruptedException e) {
+            log.error("调用大模型生成失败");
+        }
+        return Optional.empty();
+    }
+
+    private record ChatTask(OllamaChatClient chatClient, Prompt prompt) implements Callable<String> {
+        @Override
+        public String call() {
+            ChatResponse call = chatClient.call(prompt);
+            return call.getResult().getOutput().getContent();
+        }
+    }
+
+}
diff --git a/virtual-patient-graph/pom.xml b/virtual-patient-graph/pom.xml
index b3b9038a..c5ec6ced 100644
--- a/virtual-patient-graph/pom.xml
+++ b/virtual-patient-graph/pom.xml
@@ -32,6 +32,11 @@
             </exclusions>
         </dependency>
 
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-bootstrap</artifactId>
+        </dependency>
+
 
         <dependency>
             <groupId>org.springframework.cloud</groupId>
diff --git a/virtual-patient-graph/src/main/java/com/supervision/nebula/config/NebulaGraphProperties.java b/virtual-patient-graph/src/main/java/com/supervision/nebula/config/NebulaGraphProperties.java
index 62356097..cff38346 100644
--- a/virtual-patient-graph/src/main/java/com/supervision/nebula/config/NebulaGraphProperties.java
+++ b/virtual-patient-graph/src/main/java/com/supervision/nebula/config/NebulaGraphProperties.java
@@ -4,6 +4,7 @@ import lombok.Data;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
 
 /**
  * @author fulin
@@ -12,6 +13,7 @@ import org.springframework.context.annotation.Configuration;
 @ConfigurationProperties(prefix = "nebula")
 @EnableConfigurationProperties(NebulaGraphProperties.class)
 @Data
+@Primary
 public class NebulaGraphProperties {
 
     private String username;
diff --git a/virtual-patient-graph/src/main/java/com/supervision/nebula/config/NebulaSession.java b/virtual-patient-graph/src/main/java/com/supervision/nebula/config/NebulaSession.java
index 05fb80e2..0b453438 100644
--- a/virtual-patient-graph/src/main/java/com/supervision/nebula/config/NebulaSession.java
+++ b/virtual-patient-graph/src/main/java/com/supervision/nebula/config/NebulaSession.java
@@ -13,6 +13,7 @@ import org.springframework.stereotype.Component;
 @RequiredArgsConstructor
 public class NebulaSession {
 
+
     private final NebulaGraphProperties nebulaGraphProperties;
 
     @Bean
diff --git a/virtual-patient-graph/src/main/resources/bootstrap-dev.yml b/virtual-patient-graph/src/main/resources/bootstrap-dev.yml
index b43e8800..8463777d 100644
--- a/virtual-patient-graph/src/main/resources/bootstrap-dev.yml
+++ b/virtual-patient-graph/src/main/resources/bootstrap-dev.yml
@@ -2,9 +2,9 @@ spring:
   cloud:
     nacos:
       config:
-        server-addr: 192.168.10.137:8848
+        server-addr: 192.168.10.138:8848
         file-extension: yml
-        namespace: b9eea377-79ec-4ba5-9cc2-354f7bd5181e
+        namespace: 0a75e42d-26fe-4ee6-a460-f1738845cf4d
       discovery:
-        server-addr: 192.168.10.137:8848
-        namespace: b9eea377-79ec-4ba5-9cc2-354f7bd5181e
+        server-addr: 192.168.10.138:8848
+        namespace: 0a75e42d-26fe-4ee6-a460-f1738845cf4d
diff --git a/virtual-patient-manage/pom.xml b/virtual-patient-manage/pom.xml
index 5fbb47ba..0893d8b8 100644
--- a/virtual-patient-manage/pom.xml
+++ b/virtual-patient-manage/pom.xml
@@ -37,6 +37,7 @@
 			</exclusions>
 		</dependency>
 
+
 		<!-- 操作视频流 -->
 		<dependency>
 			<groupId>org.bytedeco</groupId>
diff --git a/virtual-patient-web/pom.xml b/virtual-patient-web/pom.xml
index ec5797b6..5b122db4 100644
--- a/virtual-patient-web/pom.xml
+++ b/virtual-patient-web/pom.xml
@@ -34,11 +34,6 @@
             </exclusions>
         </dependency>
 
-        <dependency>
-            <groupId>org.springframework.cloud</groupId>
-            <artifactId>spring-cloud-starter-bootstrap</artifactId>
-        </dependency>
-
 
         <dependency>
             <groupId>com.alibaba.cloud</groupId>
@@ -116,18 +111,6 @@
 
     </dependencies>
 
-    <dependencyManagement>
-        <dependencies>
-            <dependency>
-                <groupId>io.springboot.ai</groupId>
-                <artifactId>spring-ai-bom</artifactId>
-                <version>1.0.3</version>
-                <type>pom</type>
-                <scope>import</scope>
-            </dependency>
-        </dependencies>
-    </dependencyManagement>
-
     <build>
         <plugins>
             <plugin>