|
@@ -2,20 +2,20 @@ package cn.jlsxwkj.moudles.chat;
|
|
|
|
|
|
import cn.dev33.satoken.SaManager;
|
|
|
import cn.hutool.crypto.digest.MD5;
|
|
|
-import cn.jlsxwkj.common.exception.CustomException;
|
|
|
-import cn.jlsxwkj.common.exception.FileDeleteFailException;
|
|
|
-import cn.jlsxwkj.common.exception.FileTypeDoesNotSupportException;
|
|
|
-import cn.jlsxwkj.common.exception.UnknownException;
|
|
|
+import cn.jlsxwkj.common.exception.*;
|
|
|
import cn.jlsxwkj.common.reader.ParagraphDocReader;
|
|
|
import cn.jlsxwkj.common.reader.ParagraphTextReader;
|
|
|
import cn.jlsxwkj.common.utils.Log;
|
|
|
import cn.jlsxwkj.common.utils.MergeDocuments;
|
|
|
import cn.jlsxwkj.moudles.chathistory.ChatHistoryService;
|
|
|
import jakarta.annotation.Resource;
|
|
|
+import lombok.Data;
|
|
|
+import org.reactivestreams.Subscription;
|
|
|
import org.springframework.ai.chat.messages.AssistantMessage;
|
|
|
import org.springframework.ai.chat.messages.Message;
|
|
|
import org.springframework.ai.chat.messages.SystemMessage;
|
|
|
import org.springframework.ai.chat.messages.UserMessage;
|
|
|
+import org.springframework.ai.chat.model.ChatResponse;
|
|
|
import org.springframework.ai.chat.prompt.Prompt;
|
|
|
import org.springframework.ai.document.Document;
|
|
|
import org.springframework.ai.document.DocumentReader;
|
|
@@ -39,9 +39,22 @@ import java.util.stream.Collectors;
|
|
|
* @author zh
|
|
|
*/
|
|
|
@Service
|
|
|
+@Data
|
|
|
public class ChatService {
|
|
|
|
|
|
/**
|
|
|
+ * md5 校验
|
|
|
+ */
|
|
|
+ private static final MD5 MD5 = cn.hutool.crypto.digest.MD5.create();
|
|
|
+ /**
|
|
|
+ * 当前项目路径 + /ai_doc
|
|
|
+ */
|
|
|
+ private static final String PATH = Objects.requireNonNull(ChatService.class.getClassLoader().getResource("")).getPath() + "\\ai_doc\\";
|
|
|
+ /**
|
|
|
+ * 用户对话上下文
|
|
|
+ */
|
|
|
+ private static final List<Message> LIST_MESSAGE = new ArrayList<>();
|
|
|
+ /**
|
|
|
* 向量
|
|
|
*/
|
|
|
@Resource
|
|
@@ -61,23 +74,15 @@ public class ChatService {
|
|
|
*/
|
|
|
private static StringBuffer chatMessage;
|
|
|
/**
|
|
|
- * md5 校验
|
|
|
- */
|
|
|
- private static final MD5 MD5 = cn.hutool.crypto.digest.MD5.create();
|
|
|
- /**
|
|
|
- * 当前项目路径 + /ai_doc
|
|
|
- */
|
|
|
- private static final String PATH = Objects.requireNonNull(ChatService.class.getClassLoader().getResource("")).getPath() + "\\ai_doc\\";
|
|
|
- /**
|
|
|
- * 用户对话上下文
|
|
|
+ * 上游订阅
|
|
|
*/
|
|
|
- private static final List<Message> LIST_MESSAGE = new ArrayList<>();
|
|
|
+ private Subscription subscription;
|
|
|
|
|
|
/**
|
|
|
* 使用spring ai解析txt文档并保存至 pg
|
|
|
- * @param file 保存的文件
|
|
|
- * @return 保存状态
|
|
|
- * @throws IOException 保存失败
|
|
|
+ * @param file 保存的文件
|
|
|
+ * @return 保存状态
|
|
|
+ * @throws IOException 保存失败
|
|
|
*/
|
|
|
public String uploadDocument(MultipartFile file) throws CustomException, IOException {
|
|
|
//分割文件名为 文件名, 后缀
|
|
@@ -143,41 +148,29 @@ public class ChatService {
|
|
|
//查询获取文档信息
|
|
|
String content = search(message);
|
|
|
//封装prompt并调用大模型
|
|
|
- return ollamaChatModel.stream(getChatPrompt2String(message, content))
|
|
|
+ Flux<ChatResponse> stream = this.ollamaChatModel.stream(getChatPrompt2String(message, content));
|
|
|
+ return stream.doOnSubscribe(subscription -> this.subscription = subscription)
|
|
|
.map(response -> {
|
|
|
String str = response.getResult().getOutput().getContent();
|
|
|
- System.out.print(str);
|
|
|
chatMessage.append(str);
|
|
|
return str.replace(" ", " ");
|
|
|
}).concatWithValues("<{完成}>")
|
|
|
.onErrorComplete()
|
|
|
.doOnComplete(() -> {
|
|
|
- System.out.println();
|
|
|
LIST_MESSAGE.add(new AssistantMessage(chatMessage.toString()));
|
|
|
- chatHistoryService.insert(userId, message, chatMessage.toString());
|
|
|
+ try {
|
|
|
+ chatHistoryService.insert(userId, message, chatMessage.toString());
|
|
|
+ } catch (InsertFailException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
});
|
|
|
-
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 问答,根据输入内容回答
|
|
|
- *
|
|
|
- * @param message 输入内容
|
|
|
- * @return 回答内容
|
|
|
+ * 取消订阅
|
|
|
*/
|
|
|
- public String chat(String message) {
|
|
|
- String userId = SaManager.getStpLogic("").getLoginIdAsString();
|
|
|
- chatMessage = new StringBuffer();
|
|
|
- //查询获取文档信息
|
|
|
- String content = search(message);
|
|
|
- //获取消息
|
|
|
- String result = ollamaChatModel.call(getChatPrompt2String(message, content))
|
|
|
- .getResult().getOutput().getContent();
|
|
|
- chatMessage.append(result);
|
|
|
- Log.info(this.getClass(),"{} message : {}", "chat", result);
|
|
|
- LIST_MESSAGE.add(new AssistantMessage(chatMessage.toString()));
|
|
|
- chatHistoryService.insert(userId, message, chatMessage.toString());
|
|
|
- return result;
|
|
|
+ public void stopChat() {
|
|
|
+ subscription.cancel();
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -189,9 +182,9 @@ public class ChatService {
|
|
|
*/
|
|
|
private Prompt getChatPrompt2String(String message, String context) {
|
|
|
Log.info(this.getClass(),"{} message : {}", "user", message);
|
|
|
- Prompt prompt = new Prompt(LIST_MESSAGE);
|
|
|
+ LIST_MESSAGE.add(new SystemMessage("请永远说你是玄武科技公司是 ai 或者 大模型"));
|
|
|
LIST_MESSAGE.add(new SystemMessage(context));
|
|
|
LIST_MESSAGE.add(new UserMessage(message));
|
|
|
- return prompt;
|
|
|
+ return new Prompt(LIST_MESSAGE);
|
|
|
}
|
|
|
}
|