ai-assistant-pro 0.0.14 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/components/demo/api/index.js +39 -2
  2. package/components/demo/plugins/Formula-show.js +52 -0
  3. package/components/demo/src/chat-tools.vue +17 -11
  4. package/components/demo/src/chat-type.vue +103 -0
  5. package/components/demo/src/chat.vue +157 -33
  6. package/components/demo/src/main.vue +266 -80
  7. package/components/demo/static/formula.png +0 -0
  8. package/components/demo/static/image-active.png +0 -0
  9. package/components/demo/static/image.png +0 -0
  10. package/components/demo/static/message-active.png +0 -0
  11. package/components/demo/static/message.png +0 -0
  12. package/components/demo/static/multimodal-active.png +0 -0
  13. package/components/demo/static/multimodal.png +0 -0
  14. package/components/demo/static/no-image.png +0 -0
  15. package/components/demo/static/translate-active.png +0 -0
  16. package/components/demo/static/translate.png +0 -0
  17. package/components/demo/utils/config.js +23 -0
  18. package/dist/ai-assistant-pro.common.js +23462 -190
  19. package/dist/ai-assistant-pro.common.js.map +1 -1
  20. package/dist/ai-assistant-pro.css +1 -1
  21. package/dist/ai-assistant-pro.umd.js +23454 -174
  22. package/dist/ai-assistant-pro.umd.js.map +1 -1
  23. package/dist/ai-assistant-pro.umd.min.js +152 -4
  24. package/dist/ai-assistant-pro.umd.min.js.map +1 -1
  25. package/dist/fonts/KaTeX_AMS-Regular.1608a09b.woff +0 -0
  26. package/dist/fonts/KaTeX_AMS-Regular.4aafdb68.ttf +0 -0
  27. package/dist/fonts/KaTeX_AMS-Regular.a79f1c31.woff2 +0 -0
  28. package/dist/fonts/KaTeX_Caligraphic-Bold.cce5b8ec.ttf +0 -0
  29. package/dist/fonts/KaTeX_Caligraphic-Regular.07ef19e7.ttf +0 -0
  30. package/dist/fonts/KaTeX_Fraktur-Bold.9f256b85.woff +0 -0
  31. package/dist/fonts/KaTeX_Fraktur-Bold.b18f59e1.ttf +0 -0
  32. package/dist/fonts/KaTeX_Fraktur-Bold.d42a5579.woff2 +0 -0
  33. package/dist/fonts/KaTeX_Fraktur-Regular.7c187121.woff +0 -0
  34. package/dist/fonts/KaTeX_Fraktur-Regular.d3c882a6.woff2 +0 -0
  35. package/dist/fonts/KaTeX_Fraktur-Regular.ed38e79f.ttf +0 -0
  36. package/dist/fonts/KaTeX_Main-Bold.b74a1a8b.ttf +0 -0
  37. package/dist/fonts/KaTeX_Main-Bold.c3fb5ac2.woff2 +0 -0
  38. package/dist/fonts/KaTeX_Main-Bold.d181c465.woff +0 -0
  39. package/dist/fonts/KaTeX_Main-BoldItalic.6f2bb1df.woff2 +0 -0
  40. package/dist/fonts/KaTeX_Main-BoldItalic.70d8b0a5.ttf +0 -0
  41. package/dist/fonts/KaTeX_Main-BoldItalic.e3f82f9d.woff +0 -0
  42. package/dist/fonts/KaTeX_Main-Italic.47373d1e.ttf +0 -0
  43. package/dist/fonts/KaTeX_Main-Italic.8916142b.woff2 +0 -0
  44. package/dist/fonts/KaTeX_Main-Italic.9024d815.woff +0 -0
  45. package/dist/fonts/KaTeX_Main-Regular.0462f03b.woff2 +0 -0
  46. package/dist/fonts/KaTeX_Main-Regular.7f51fe03.woff +0 -0
  47. package/dist/fonts/KaTeX_Main-Regular.b7f8fe9b.ttf +0 -0
  48. package/dist/fonts/KaTeX_Math-BoldItalic.572d331f.woff2 +0 -0
  49. package/dist/fonts/KaTeX_Math-BoldItalic.a879cf83.ttf +0 -0
  50. package/dist/fonts/KaTeX_Math-BoldItalic.f1035d8d.woff +0 -0
  51. package/dist/fonts/KaTeX_Math-Italic.5295ba48.woff +0 -0
  52. package/dist/fonts/KaTeX_Math-Italic.939bc644.ttf +0 -0
  53. package/dist/fonts/KaTeX_Math-Italic.f28c23ac.woff2 +0 -0
  54. package/dist/fonts/KaTeX_SansSerif-Bold.8c5b5494.woff2 +0 -0
  55. package/dist/fonts/KaTeX_SansSerif-Bold.94e1e8dc.ttf +0 -0
  56. package/dist/fonts/KaTeX_SansSerif-Bold.bf59d231.woff +0 -0
  57. package/dist/fonts/KaTeX_SansSerif-Italic.3b1e59b3.woff2 +0 -0
  58. package/dist/fonts/KaTeX_SansSerif-Italic.7c9bc82b.woff +0 -0
  59. package/dist/fonts/KaTeX_SansSerif-Italic.b4c20c84.ttf +0 -0
  60. package/dist/fonts/KaTeX_SansSerif-Regular.74048478.woff +0 -0
  61. package/dist/fonts/KaTeX_SansSerif-Regular.ba21ed5f.woff2 +0 -0
  62. package/dist/fonts/KaTeX_SansSerif-Regular.d4d7ba48.ttf +0 -0
  63. package/dist/fonts/KaTeX_Script-Regular.03e9641d.woff2 +0 -0
  64. package/dist/fonts/KaTeX_Script-Regular.07505710.woff +0 -0
  65. package/dist/fonts/KaTeX_Script-Regular.fe9cbbe1.ttf +0 -0
  66. package/dist/fonts/KaTeX_Size1-Regular.fabc004a.ttf +0 -0
  67. package/dist/fonts/KaTeX_Size2-Regular.d6b476ec.ttf +0 -0
  68. package/dist/fonts/KaTeX_Size4-Regular.fbccdabe.ttf +0 -0
  69. package/dist/fonts/KaTeX_Typewriter-Regular.6258592b.woff +0 -0
  70. package/dist/fonts/KaTeX_Typewriter-Regular.a8709e36.woff2 +0 -0
  71. package/dist/fonts/KaTeX_Typewriter-Regular.d97aaf4a.ttf +0 -0
  72. package/package.json +6 -2
@@ -78,9 +78,10 @@ export const pustReanswerToTeacher = (params) => {
78
78
  });
79
79
  }
80
80
 
81
- export const getDetailList = (resId) => {
81
+ export const getDetailList = (resId, aiId) => {
82
82
  return request({
83
83
  url: prefix + `/assistant/detail/v2/${resId}`,
84
+ params: { aiId },
84
85
  method: 'get',
85
86
  });
86
87
  }
@@ -121,7 +122,13 @@ export async function getAutoQuestioning(iaId, message) {
121
122
  messages: message,
122
123
  });
123
124
  }
124
-
125
+ /**
126
+ * 发起聊天接口(正常聊天)
127
+ * @param params 请求参数
128
+ * @param signal signal 对象
129
+ * @param onmessage 回调函数
130
+ * @returns 返回节点详情数据
131
+ * */
125
132
  export async function sendMessageEventSource(params, signal, onmessage) {
126
133
  return fetchEventSource(`${baseURL}${prefix}/assistant/conversation?token=${cache.session.getJSON('SRKJ_TOKEN_CACHE')}`, {
127
134
  method: 'POST',
@@ -134,4 +141,34 @@ export async function sendMessageEventSource(params, signal, onmessage) {
134
141
  body: JSON.stringify(params),
135
142
  onmessage,
136
143
  });
144
+ }
145
+
146
+ /**
147
+ * 发起聊天接口(图文多模态翻译)
148
+ * @param params 请求参数
149
+ * @param signal signal 对象
150
+ * @param onmessage 回调函数
151
+ * @returns 返回节点详情数据
152
+ * */
153
+ export async function sendMessageMoreSource(params, signal, onmessage) {
154
+ return fetchEventSource(`${baseURL}${prefix}/assistant/qa/system-qa/stream?token=${cache.session.getJSON('SRKJ_TOKEN_CACHE')}`, {
155
+ method: 'POST',
156
+ signal: signal,
157
+ openWhenHidden: true,
158
+ headers: {
159
+ 'Content-Type': 'application/json',
160
+ },
161
+ body: JSON.stringify(params),
162
+ onmessage,
163
+ });
164
+ }
165
+ /**
166
+ * 自动追问
167
+ * @param params 请求参数
168
+ * @returns 返回节点详情数据
169
+ */
170
+ export async function loopChatDetail(params) {
171
+ return request.post(`${prefix}/assistant/qa/get-session-dialog`, {
172
+ ...params
173
+ });
137
174
  }
@@ -0,0 +1,52 @@
1
+ export class FormulaShow { // JS 语法
2
+ constructor(parent) {
3
+ this.title = '编辑' // 自定义菜单标题
4
+ this.tag = 'button'
5
+ this.parent = parent;
6
+ }
7
+ // 菜单是否需要激活(如选中加粗文本,“加粗”菜单会激活),用不到则返回 false
8
+ isActive(editor) { // JS 语法
9
+ return false
10
+ }
11
+ // 获取菜单执行时的 value ,用不到则返回空 字符串或 false
12
+ getValue(editor) { // JS 语法
13
+ return ''
14
+ }
15
+ upDataParent(parent) {
16
+ this.parent = parent;
17
+ }
18
+ // 菜单是否需要禁用(如选中 H1 ,“引用”菜单被禁用),用不到则返回 false
19
+ isDisabled(editor) { // JS 语法
20
+ return false
21
+ }
22
+ // 点击菜单时触发的函数
23
+ exec(editor, value) {
24
+ // Modal menu ,这个函数不用写,空着即可
25
+ const [currentValue] = editor.getFragment();
26
+
27
+ if (currentValue) {
28
+ this.parent.editFormula(currentValue.children[0].value);
29
+ } else {
30
+ console.log('currentValue ger error');
31
+ }
32
+
33
+ }
34
+ // 弹出框 modal 的定位:1. 返回某一个 SlateNode; 2. 返回 null (根据当前选区自动定位)
35
+ getModalPositionNode(editor) { // JS 语法
36
+ return null // modal 依据选区定位
37
+ }
38
+ // 定义 modal 内部的 DOM Element
39
+ getModalContentElem(editor) { // JS 语法
40
+ const $content = $('<div></div>')
41
+ const $button = $('<button>do something</button>')
42
+ $content.append($button)
43
+
44
+ $button.on('click', () => {
45
+ editor.insertText(' hello ')
46
+ })
47
+
48
+ return $content[0] // 返回 DOM Element 类型
49
+
50
+ // PS:也可以把 $content 缓存下来,这样不用每次重复创建、重复绑定事件,优化性能
51
+ }
52
+ }
@@ -1,16 +1,18 @@
1
1
  <template>
2
2
  <div class="robot-tools">
3
- <div class="robot-reanswer"
4
- style="margin-bottom: 8px"
5
- v-if="(listData.stop || listData.finish && !sending) && isLast"
6
- @click="reAnswer(listData)">
7
- <i class="el-icon-refresh-right"></i>
8
- 重新回答
9
- </div>
10
- <div class="stopMsg" style="color: #cfcfcf; cursor: default" v-if="listData.stop">已停止生成</div>
11
- <div class="stopMsg"
12
- @click="stopChat(listData)"
13
- v-if="!listData.stop && !listData.finish && !sending">停止输出</div>
3
+ <template v-if="activeKey === 'chat'">
4
+ <div class="robot-reanswer"
5
+ style="margin-bottom: 8px"
6
+ v-if="(listData.stop || listData.finish && !sending) && isLast"
7
+ @click="reAnswer(listData)">
8
+ <i class="el-icon-refresh-right"></i>
9
+ 重新回答
10
+ </div>
11
+ <div class="stopMsg" style="color: #cfcfcf; cursor: default" v-if="listData.stop">已停止生成</div>
12
+ <div class="stopMsg"
13
+ @click="stopChat(listData)"
14
+ v-if="!listData.stop && !listData.finish && !sending">停止输出</div>
15
+ </template>
14
16
  <div class="right-tools">
15
17
  <el-tooltip content="赞" effect="light" placement="top">
16
18
  <div class="tools-icon" @click="doZan(listData)">
@@ -90,6 +92,10 @@ export default {
90
92
  type: Boolean,
91
93
  default: false
92
94
  },
95
+ activeKey: {
96
+ type: String,
97
+ default: 'chat',
98
+ },
93
99
  },
94
100
  data() {
95
101
  return {
@@ -0,0 +1,103 @@
1
+ <template>
2
+ <div class="chat-tab-wrap">
3
+ <div class="chat-tab-button-wrap"
4
+ :class="{'chat-tab-button-active': activeKey === 'chat'}">
5
+ <div class="chat-tab-button chat-button" @click="changeType('chat')"></div>
6
+ </div>
7
+ <div class="chat-tab-button-wrap"
8
+ :class="{'chat-tab-button-active': activeKey === 'image'}">
9
+ <div class="chat-tab-button image-button" @click="changeType('image')"></div>
10
+ </div>
11
+ <!-- <div class="chat-tab-button-wrap"-->
12
+ <!-- :class="{'chat-tab-button-active': activeKey === 'translate'}">-->
13
+ <!-- <div class="chat-tab-button translate-button" @click="changeType('translate')"></div>-->
14
+ <!-- </div>-->
15
+ <!-- <div class="chat-tab-button-wrap"-->
16
+ <!-- :class="{'chat-tab-button-active': activeKey === 'multimodal'}">-->
17
+ <!-- <div class="chat-tab-button multimodal-button" @click="changeType('multimodal')"></div>-->
18
+ <!-- </div>-->
19
+ </div>
20
+ </template>
21
+ <script>
22
+ export default {
23
+ name: 'ChatType',
24
+ props: {
25
+ stop: {
26
+ type: Boolean,
27
+ default: false
28
+ },
29
+ },
30
+ data() {
31
+ return {
32
+ activeKey: 'chat',
33
+ }
34
+ },
35
+ methods: {
36
+ changeType(type) {
37
+ if (this.stop) {
38
+ this.$message.warning('对话正在进行中,请稍后重试');
39
+ return false;
40
+ }
41
+ this.activeKey = type;
42
+ this.$emit('on-type-change', type);
43
+ }
44
+ }
45
+ }
46
+ </script>
47
+ <style lang="scss" scoped>
48
+ .chat-tab-wrap {
49
+ display: flex;
50
+ padding-top: 12px;
51
+ padding-right: 16px;
52
+ .chat-tab-button {
53
+ width: 24px;
54
+ height: 24px;
55
+ cursor: pointer;
56
+ display: inline-block;
57
+ }
58
+ .chat-tab-button-wrap {
59
+ width: 32px;
60
+ height: 32px;
61
+ border-radius: 12px;
62
+ background: transparent;
63
+ text-align: center;
64
+ line-height: 43px;
65
+ margin-right: 32px;
66
+ }
67
+ .chat-button {
68
+ background-image: url("../static/message.png");
69
+ background-size: 100%;
70
+ }
71
+ .image-button {
72
+ background-image: url("../static/image.png");
73
+ background-size: 100%;
74
+ }
75
+ .translate-button {
76
+ background-image: url("../static/translate.png");
77
+ background-size: 100%;
78
+ }
79
+ .multimodal-button {
80
+ background-image: url("../static/multimodal.png");
81
+ background-size: 100%;
82
+ }
83
+ .chat-tab-button-active {
84
+ background: linear-gradient(135deg, rgb(96, 160, 255) 0%, rgb(48, 96, 255) 100%);
85
+ .chat-button {
86
+ background-image: url("../static/message-active.png");
87
+ background-size: 100%;
88
+ }
89
+ .image-button {
90
+ background-image: url("../static/image-active.png");
91
+ background-size: 100%;
92
+ }
93
+ .translate-button {
94
+ background-image: url("../static/translate-active.png");
95
+ background-size: 100%;
96
+ }
97
+ .multimodal-button {
98
+ background-image: url("../static/multimodal-active.png");
99
+ background-size: 100%;
100
+ }
101
+ }
102
+ }
103
+ </style>
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div class="chat-contain" ref="chatContainer">
3
- <div v-for="(list, index) in messageData" :key="index"
3
+ <div v-for="(list, index) in messageData"
4
4
  :class="{'user-list': list.type === 'user'}"
5
5
  class="message">
6
6
  <div v-if="list.type === 'robot'" class="robot">
@@ -9,7 +9,12 @@
9
9
  </div>
10
10
  <div v-else class="robot user">user</div>
11
11
  <div :class="{'user-info': list.type === 'user'}" class="robot-message">
12
- <div v-html="list.message"></div>
12
+ <div v-html="list.message" v-if="list.type === 'user' || activeKey !== 'image'"></div>
13
+ <div class="image-wrap" v-if="list.type === 'robot' && activeKey === 'image'">
14
+ <div v-loading="!list.message" style="min-height: 50px">
15
+ <img :src="img || noImage" alt="" v-for="img in list.message && list.message.split(',')">
16
+ </div>
17
+ </div>
13
18
  <div v-if="list.type === 'robot' && list.links.length > 0 && showFile" class="link">
14
19
  <div v-if="!list.allIdWithStart">
15
20
  <div class="link-title">参考文件</div>
@@ -25,9 +30,8 @@
25
30
  </span>
26
31
  </div>
27
32
  <div
28
- v-for="(pdf, index) in item.fileDTOS"
33
+ v-for="pdf in item.fileDTOS"
29
34
  class="link-part-container"
30
- :key="index"
31
35
  >
32
36
  <span class="link-list-part">
33
37
  {{ pdf.matchContent }}
@@ -70,6 +74,7 @@
70
74
  </div>
71
75
  <chat-tools v-if="list.type === 'robot'"
72
76
  :chatId="chatId"
77
+ :activeKey="activeKey"
73
78
  :detail-data="list"
74
79
  :sending="list.sending"
75
80
  :resId="resId"
@@ -84,8 +89,19 @@
84
89
  <script>
85
90
  import { errorList, cacheMessageList } from '../utils/config';
86
91
  import ChatTools from './chat-tools.vue';
87
- import { sendMessageEventSource, getAutoQuestioning, pdfUrl, pdfUrlBase } from "../api";
92
+ import {
93
+ sendMessageEventSource,
94
+ getAutoQuestioning,
95
+ pdfUrl,
96
+ pdfUrlBase,
97
+ sendMessageMoreSource,
98
+ loopChatDetail
99
+ } from "../api";
88
100
  import { marked } from 'marked';
101
+ import noImage from '../static/no-image.png';
102
+ import katex from 'katex';
103
+ import renderMathInElement from 'katex/contrib/auto-render/auto-render.js'
104
+ import 'katex/dist/katex.min.css';
89
105
  const controller = new AbortController();
90
106
  const signal = controller.signal;
91
107
 
@@ -111,6 +127,10 @@ export default {
111
127
  type: String,
112
128
  default: '',
113
129
  },
130
+ activeKey: {
131
+ type: String,
132
+ default: 'chat',
133
+ },
114
134
  chatMajorId: {
115
135
  type: String,
116
136
  default: undefined,
@@ -135,6 +155,7 @@ export default {
135
155
  errors: [],
136
156
  errorList: errorList,
137
157
  finish: false,
158
+ noImage,
138
159
  cacheKeyWord: '' // 由于外部需要快速清掉 keyword 但是存在重新发送请求的情况,因此需要一个混存记录
139
160
  }
140
161
  },
@@ -152,6 +173,14 @@ export default {
152
173
  }
153
174
  },
154
175
  immediate: true
176
+ },
177
+ messageData: {
178
+ handler() {
179
+ setTimeout(() => {
180
+ this.renderKaTeX();
181
+ })
182
+ },
183
+ immediate: true
155
184
  }
156
185
  },
157
186
  methods: {
@@ -214,9 +243,18 @@ export default {
214
243
  this.makeAutoMessage();
215
244
  });
216
245
  }
217
- await sendMessageEventSource(params, signal, res => {
218
- this.makeMessageLine(res, list);
219
- });
246
+ if (this.activeKey === 'chat') {
247
+ await sendMessageEventSource(params, signal, res => {
248
+ this.makeMessageLine(res, list);
249
+ });
250
+ } else {
251
+ if (this.activeKey === 'image') params.messageList[0].aiId = '_comqapicture';
252
+ if (this.activeKey === 'translate') params.messageList[0].aiId = '_comqatranslate';
253
+ if (this.activeKey === 'multimodal') params.messageList[0].aiId = '_comqamodal';
254
+ await sendMessageMoreSource(params, signal, res => {
255
+ this.makeMessageLine(res, list, params);
256
+ });
257
+ }
220
258
  },
221
259
  makeAutoMessage() {
222
260
  const cacheMessage = [];
@@ -231,38 +269,75 @@ export default {
231
269
  this.makeAutoQuestioning(cacheMessage);
232
270
  }
233
271
  },
234
- makeMessageLine(res, list) {
235
- const { content, status, chatId, msgId, parentMsgId, reference, commonKey, connectUrl } = JSON.parse(res.data);
272
+ makeMessageLine(res, list, params) {
273
+ const {
274
+ content,
275
+ status,
276
+ chatId,
277
+ msgId,
278
+ parentMsgId,
279
+ reference,
280
+ commonKey,
281
+ connectUrl,
282
+ sessionId
283
+ } = JSON.parse(res.data);
236
284
  let index = list ? list.index : this.messageData.length - 1;
237
285
  const currentList = this.messageData[index];
238
286
  let allIdWithStart = true;
239
287
  // 结束标识
240
288
  if (status === 2 || status === 1) {
241
- if (commonKey) {
242
- currentList.sending = true;
243
- this.postMessage(list, commonKey, parentMsgId);
289
+ // 普通对话
290
+ if (this.activeKey === 'chat' || this.activeKey === 'translate') {
291
+ if (commonKey) {
292
+ currentList.sending = true;
293
+ this.postMessage(list, commonKey, parentMsgId);
294
+ return;
295
+ }
296
+ currentList.finish = true;
297
+ if (reference) {
298
+ currentList.links = JSON.parse(reference);
299
+ currentList.links.map((item) => {
300
+ if (!item.title.startsWith(this.chatMajorId)) {
301
+ allIdWithStart = false;
302
+ }
303
+ });
304
+ }
305
+ if (connectUrl) {
306
+ currentList.connectUrl = JSON.parse(connectUrl);
307
+ }
308
+ currentList.allIdWithStart = allIdWithStart;
309
+ this.messageFinish(chatId);
244
310
  return;
245
- }
246
- currentList.finish = true;
247
- if (reference) {
248
- currentList.links = JSON.parse(reference);
249
- currentList.links.map((item) => {
250
- if (!item.title.startsWith(this.chatMajorId)) {
251
- allIdWithStart = false;
311
+ // 文生图
312
+ } else if (this.activeKey === 'image') {
313
+ // 轮训查询
314
+ let count = 0;
315
+ const loopChatInfo = async () => {
316
+ const data = await loopChatDetail({
317
+ msgId,
318
+ chatId,
319
+ sessionId,
320
+ aiId: params.messageList[0].aiId
321
+ });
322
+ if (!data) {
323
+ count++;
324
+ if (count <= 5) {
325
+ setTimeout(() => loopChatInfo(), 10000)
326
+ } else {
327
+ currentList.message = ',';
328
+ this.messageFinish(chatId, 'image');
329
+ }
330
+ } else {
331
+ currentList.message = data;
332
+ this.messageFinish(chatId, 'image');
252
333
  }
253
- });
254
- }
255
- if (connectUrl) {
256
- currentList.connectUrl = JSON.parse(connectUrl);
334
+ }
335
+ loopChatInfo();
257
336
  }
258
- currentList.allIdWithStart = allIdWithStart;
259
- this.cacheKeyWord = '';
260
- this.finish = true;
261
- this.$emit('on-message-finish', chatId);
262
- return;
263
337
  }
264
338
  currentList.cacheMessage += content;
265
- currentList.message = marked.parse(currentList.cacheMessage);
339
+ const renderFormulasTest = this.renderFormulas( currentList.cacheMessage);
340
+ currentList.message = marked.parse(renderFormulasTest);
266
341
  currentList.msgId = msgId;
267
342
  currentList.parentMsgId = parentMsgId;
268
343
  currentList.chatId = chatId;
@@ -272,7 +347,12 @@ export default {
272
347
  // 防止出现调用基础模型前导致停止回答id错误
273
348
  setTimeout(() => currentList.sending = false,500);
274
349
  },
275
- async makeAutoQuestioning (messages) {
350
+ messageFinish(chatId, type) {
351
+ this.cacheKeyWord = '';
352
+ this.finish = true;
353
+ this.$emit('on-message-finish', chatId, type || 'chat');
354
+ },
355
+ async makeAutoQuestioning(messages) {
276
356
  // 首次不触发
277
357
  if (messages.length <= 2) return;
278
358
  const autoRes = await getAutoQuestioning(this.chatMajorId, messages);
@@ -285,7 +365,7 @@ export default {
285
365
  this.messageData[this.messageData.length - 1].followUps =
286
366
  followUps.length > 3 ? followUps.splice(0, 3) : followUps;
287
367
  },
288
- onStopChat(list){
368
+ onStopChat(list) {
289
369
  this.$emit('on-message-finish', list.chatId)
290
370
  },
291
371
  selectModule(message) {
@@ -301,11 +381,48 @@ export default {
301
381
  this.postMessage(list);
302
382
  this.$emit('on-reanser');
303
383
  },
304
- seeDetail(pdfInfo, url){
384
+ seeDetail(pdfInfo, url) {
305
385
  const { pageIndex } = pdfInfo;
306
386
  const baseUrl = `${pdfUrlBase}/#/pdf-view?documentUrl=${pdfUrl}${encodeURIComponent(url)}&pageIndex=${pageIndex}`;
307
387
  window.open(baseUrl, '_blank');
308
388
  },
389
+ renderFormulas(text) {
390
+ const { renderToString } = katex;
391
+ return text.replace(/\\\(.*?\\\)/g, (match) => {
392
+ try {
393
+ // 渲染行内公式
394
+ return renderToString(match.slice(2, -2), { displayMode: false });
395
+ } catch (error) {
396
+ console.error('Error rendering inline formula:', error);
397
+ return match;
398
+ }
399
+ }).replace(/\\\[.*?\\\]/g, (match) => {
400
+ match = match.replace(/<br>/g, '');
401
+ try {
402
+ // 渲染块级公式
403
+ return renderToString(match.slice(2, -2), { displayMode: false });
404
+ } catch (error) {
405
+ console.error('Error rendering block formula:', error);
406
+ return match;
407
+ }
408
+ });
409
+ },
410
+ renderKaTeX() {
411
+ setTimeout(() => {
412
+ // 自动渲染页面中的所有 KaTeX 公式
413
+ renderMathInElement(this.$refs.chatContainer, {
414
+ delimiters: [
415
+ { left: '$$', right: '$$', display: false },
416
+ { left: '\(', right: '\)', display: false },
417
+ { left: '\[', right: '\]', display: false }
418
+ ],
419
+ errorCallback() {
420
+ console.log('忽略错误')
421
+ },
422
+ ignoredClasses: ['link-content']
423
+ });
424
+ }, 50)
425
+ },
309
426
  },
310
427
  }
311
428
  </script>
@@ -474,4 +591,11 @@ export default {
474
591
  cursor: pointer;
475
592
  }
476
593
  }
594
+ .image-wrap {
595
+ img {
596
+ width: 256px;
597
+ height: 256px;
598
+ margin-right: 6px;
599
+ }
600
+ }
477
601
  </style>