AIChat.ts 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. import { defineStore } from 'pinia';
  2. import { useUserStore } from './user';
  3. export const useAIChat = defineStore({
  4. id: 'ai-chat',
  5. state: (): {
  6. /** 会话历史 */
  7. sessionHistory: {
  8. id: string;
  9. user_id: string;
  10. agent: string;
  11. title: string;
  12. title_type: string;
  13. version: number;
  14. current_message_id: number;
  15. inserted_at: string;
  16. updated_at: string;
  17. }[];
  18. /** 消息历史 */
  19. messageHistory: {
  20. id: string; // 唯一标识(可用时间戳生成)
  21. type: 'user' | 'system' | 'response';
  22. content: string;
  23. /** 深度思考时的文本 */
  24. contentR1: string;
  25. timestamp: number; // 排序依据
  26. }[];
  27. /** 当前会话ID */
  28. currentSessionID: string;
  29. /** 当前会话是否有流正在传输 */
  30. streaming: boolean;
  31. /** 当前会话是否启用 deepseekR1 模型 */
  32. deepseekR1Enable: boolean;
  33. /** 当前用户ID */
  34. userID: string;
  35. } => {
  36. const userid = useUserStore().getUserInfo.id as string;
  37. return {
  38. sessionHistory: [],
  39. messageHistory: [],
  40. currentSessionID: '',
  41. streaming: false,
  42. deepseekR1Enable: false,
  43. userID: userid,
  44. };
  45. },
  46. getters: {
  47. getMessageHistory: (state) => {
  48. return state.messageHistory.sort((a, b) => a.timestamp - b.timestamp);
  49. },
  50. },
  51. actions: {
  52. /** 创建新会话 */
  53. async createSession() {
  54. const response = await fetch('http://182.92.126.35:6005/sessions/create', {
  55. method: 'post',
  56. headers: {
  57. 'Content-Type': 'application/json',
  58. },
  59. body: JSON.stringify({
  60. user_id: this.userID,
  61. }),
  62. });
  63. const data = await response.json();
  64. this.currentSessionID = data.id;
  65. this.messageHistory = [];
  66. },
  67. /** 根据当前会话,创建聊天流,流里的数据将会更新到消息历史中 */
  68. async createStream(question: string, onUpdate?: any) {
  69. this.streaming = true;
  70. this.messageHistory.push({
  71. id: `user_${Date.now()}`,
  72. type: 'user',
  73. content: question,
  74. contentR1: '',
  75. timestamp: Date.now(),
  76. });
  77. try {
  78. // 发送 POST 请求
  79. const response = await fetch('http://182.92.126.35:6005/chat_stream', {
  80. method: 'POST',
  81. headers: {
  82. 'Content-Type': 'application/json',
  83. },
  84. body: JSON.stringify({
  85. chat_session_id: this.currentSessionID,
  86. prompt: question,
  87. ref_file_ids: [],
  88. thinking_enabled: this.deepseekR1Enable,
  89. }),
  90. });
  91. // 检查响应是否成功
  92. if (!response.ok || !response.body) {
  93. throw new Error('Network response was not ok');
  94. }
  95. // 获取可读流
  96. const reader = response.body.getReader();
  97. // 创建一条新的消息对象
  98. const newMessage = {
  99. id: `response_${Date.now()}`,
  100. type: 'response' as any,
  101. content: '',
  102. contentR1: '',
  103. timestamp: Date.now(),
  104. };
  105. // 将新消息添加到消息列表
  106. this.messageHistory.push(newMessage);
  107. // 读取流式数据
  108. while (true) {
  109. const { done, value } = await reader.read();
  110. if (done) {
  111. break;
  112. }
  113. // 将流数据转换为字符串
  114. const chunk = new TextDecoder().decode(value);
  115. // 使用正则表达式匹配完整的 JSON 对象
  116. const jsonRegex = /{.*?}/g;
  117. const matches = chunk.match(jsonRegex);
  118. if (!matches) continue;
  119. matches.forEach((match) => {
  120. const data = JSON.parse(match);
  121. // 找到当前消息对象并更新 content
  122. const targetMessage = this.messageHistory.find((msg) => msg.id === newMessage.id);
  123. if (!targetMessage) return;
  124. if (data.type === 'text') {
  125. targetMessage.content += data.content; // 追加内容
  126. }
  127. if (data.type === 'thinking') {
  128. targetMessage.contentR1 += data.content;
  129. }
  130. if (typeof onUpdate === 'function') {
  131. onUpdate(value);
  132. }
  133. });
  134. }
  135. } catch (error) {
  136. // 请求失败时设置系统消息
  137. this.messageHistory.push({
  138. id: `system_${Date.now()}`,
  139. type: 'system',
  140. content: '系统异常,请稍后再试',
  141. contentR1: '',
  142. timestamp: Date.now(),
  143. });
  144. } finally {
  145. this.streaming = false;
  146. }
  147. },
  148. /** 创建会话的标题 */
  149. async createSessionTitle(title: string) {
  150. await fetch('http://182.92.126.35:6005/sessions/title', {
  151. method: 'post',
  152. headers: {
  153. 'Content-Type': 'application/json',
  154. },
  155. body: JSON.stringify({
  156. chat_session_id: this.currentSessionID,
  157. prompt: title,
  158. }),
  159. });
  160. },
  161. /** 修改会话的标题 */
  162. async changeSessionTitle(title: string, id: string) {
  163. try {
  164. const response = await fetch('http://182.92.126.35:6005/sessions/change_title', {
  165. method: 'POST',
  166. headers: {
  167. 'Content-Type': 'application/json',
  168. },
  169. body: JSON.stringify({
  170. chat_session_id: id,
  171. new_title: title,
  172. }),
  173. });
  174. if (!response.ok) {
  175. throw new Error('Network response was not ok');
  176. }
  177. this.sessionHistory.forEach((session) => {
  178. if (session.id === id) {
  179. session.title = title;
  180. }
  181. });
  182. } catch (error) {
  183. console.error('保存失败:', error);
  184. }
  185. },
  186. /** 获取会话历史 */
  187. async getSessionHistory() {
  188. const response = await fetch(`http://182.92.126.35:6005/sessions`, {
  189. method: 'post',
  190. headers: {
  191. 'Content-Type': 'application/json',
  192. },
  193. body: JSON.stringify({
  194. user_id: this.userID,
  195. }),
  196. });
  197. const data = await response.json();
  198. this.sessionHistory = data.chat_sessions;
  199. },
  200. /** 获取会话历史 */
  201. async getSessionHistoryByID(id: string) {
  202. const response = await fetch(`http://182.92.126.35:6005/sessions/history_chat/?chat_session_id=${id}`, {
  203. method: 'get',
  204. headers: {
  205. 'Content-Type': 'application/json',
  206. },
  207. });
  208. const data = await response.json();
  209. if (data.chat_messages.length === 0) return;
  210. this.currentSessionID = id;
  211. this.messageHistory = data.chat_messages.map((item: any) => {
  212. if (item.role === 'user') {
  213. // role== user 用户提问
  214. return {
  215. id: `user_${Date.now()}`,
  216. type: 'user',
  217. content: item.content,
  218. contentR1: '',
  219. timestamp: Date.now(),
  220. };
  221. } else {
  222. // role== assistant 机器回答
  223. return {
  224. id: `system_${Date.now()}`,
  225. type: 'system',
  226. content: item.content,
  227. contentR1: item.thinking_content,
  228. timestamp: Date.now(),
  229. };
  230. }
  231. });
  232. },
  233. /** 发出问题 */
  234. async sendQuestion(question: string, onUpdate?: any) {
  235. if (this.currentSessionID === '') {
  236. await this.createSession();
  237. this.createSessionTitle(question);
  238. this.createStream(question, onUpdate);
  239. } else {
  240. this.createSessionTitle(question);
  241. this.createStream(question, onUpdate);
  242. }
  243. },
  244. },
  245. });