|
@@ -16,13 +16,14 @@ |
|
@@ -16,13 +16,14 @@ |
|
16
|
</div>
|
16
|
</div>
|
|
17
|
</div>
|
17
|
</div>
|
|
18
|
</div>
|
18
|
</div>
|
|
19
|
- <!-- 流式响应时显示的临时消息 -->
|
|
|
|
20
|
<div v-if="streamingMessage" class="message assistant">
|
19
|
<div v-if="streamingMessage" class="message assistant">
|
|
21
|
<div class="message-content">
|
20
|
<div class="message-content">
|
|
22
|
<div class="message-text" style="white-space: pre-wrap;">{{ streamingMessage }}</div>
|
21
|
<div class="message-text" style="white-space: pre-wrap;">{{ streamingMessage }}</div>
|
|
23
|
</div>
|
22
|
</div>
|
|
24
|
</div>
|
23
|
</div>
|
|
25
|
- <div v-if="loading" class="message assistant">
|
24
|
+
|
|
|
|
25
|
+
|
|
|
|
26
|
+ <div v-if="loading && !streamingMessage" class="message assistant">
|
|
26
|
<div class="message-content">
|
27
|
<div class="message-content">
|
|
27
|
<div class="message-text">思考中...</div>
|
28
|
<div class="message-text">思考中...</div>
|
|
28
|
</div>
|
29
|
</div>
|
|
@@ -38,12 +39,7 @@ |
|
@@ -38,12 +39,7 @@ |
|
38
|
<DownloadOutlined />
|
39
|
<DownloadOutlined />
|
|
39
|
<span class="btn-text">下载</span>
|
40
|
<span class="btn-text">下载</span>
|
|
40
|
</a-button>
|
41
|
</a-button>
|
|
41
|
- <a-button
|
|
|
|
42
|
- type="text"
|
|
|
|
43
|
- @click="closePreview"
|
|
|
|
44
|
- class="close-btn"
|
|
|
|
45
|
- title="关闭预览"
|
|
|
|
46
|
- >
|
42
|
+ <a-button type="text" @click="closePreview" class="close-btn" title="关闭预览">
|
|
47
|
<CloseOutlined />
|
43
|
<CloseOutlined />
|
|
48
|
</a-button>
|
44
|
</a-button>
|
|
49
|
</div>
|
45
|
</div>
|
|
@@ -70,7 +66,8 @@ |
|
@@ -70,7 +66,8 @@ |
|
70
|
v-for="(btn, index) in buttonList"
|
66
|
v-for="(btn, index) in buttonList"
|
|
71
|
:key="index"
|
67
|
:key="index"
|
|
72
|
class="action-button"
|
68
|
class="action-button"
|
|
73
|
- @click="sendButtonMessage(btn.buttonValues)"
|
69
|
+ @click="sendButtonMessage(btn)"
|
|
|
|
70
|
+ :disabled="buttonDisabled || loading"
|
|
74
|
>
|
71
|
>
|
|
75
|
{{ btn.buttonName }}
|
72
|
{{ btn.buttonName }}
|
|
76
|
</a-button>
|
73
|
</a-button>
|
|
@@ -100,10 +97,8 @@ |
|
@@ -100,10 +97,8 @@ |
|
100
|
<script lang="ts" name="zdy-rag-chat" setup>
|
97
|
<script lang="ts" name="zdy-rag-chat" setup>
|
|
101
|
import { ref, reactive, nextTick, onMounted, onBeforeUnmount } from 'vue';
|
98
|
import { ref, reactive, nextTick, onMounted, onBeforeUnmount } from 'vue';
|
|
102
|
import { sendMessage as apiSendMessage, getButtonList } from './ZdyRag.api';
|
99
|
import { sendMessage as apiSendMessage, getButtonList } from './ZdyRag.api';
|
|
103
|
-import { useMessage } from '/@/hooks/web/useMessage';
|
|
|
|
104
|
import { CloseOutlined, DownloadOutlined } from '@ant-design/icons-vue';
|
100
|
import { CloseOutlined, DownloadOutlined } from '@ant-design/icons-vue';
|
|
105
|
import * as pdfjsLib from 'pdfjs-dist';
|
101
|
import * as pdfjsLib from 'pdfjs-dist';
|
|
106
|
-import * as mammoth from 'mammoth';
|
|
|
|
107
|
import { renderAsync } from 'docx-preview';
|
102
|
import { renderAsync } from 'docx-preview';
|
|
108
|
|
103
|
|
|
109
|
// 设置PDF.js worker路径
|
104
|
// 设置PDF.js worker路径
|
|
@@ -134,7 +129,8 @@ const messages = reactive([ |
|
@@ -134,7 +129,8 @@ const messages = reactive([ |
|
134
|
|
129
|
|
|
135
|
const inputMessage = ref('');
|
130
|
const inputMessage = ref('');
|
|
136
|
const loading = ref(false);
|
131
|
const loading = ref(false);
|
|
137
|
-const streamingMessage = ref(''); // 流式响应消息
|
132
|
+const buttonDisabled = ref(false);
|
|
|
|
133
|
+const streamingMessage = ref('');
|
|
138
|
const messagesContainer = ref<HTMLElement>();
|
134
|
const messagesContainer = ref<HTMLElement>();
|
|
139
|
const previewContent = ref('');
|
135
|
const previewContent = ref('');
|
|
140
|
const previewType = ref('');
|
136
|
const previewType = ref('');
|
|
@@ -143,12 +139,10 @@ const currentFile = ref<any>(null); |
|
@@ -143,12 +139,10 @@ const currentFile = ref<any>(null); |
|
143
|
const pdfPreview = ref<HTMLElement>();
|
139
|
const pdfPreview = ref<HTMLElement>();
|
|
144
|
const docxPreview = ref<HTMLElement>();
|
140
|
const docxPreview = ref<HTMLElement>();
|
|
145
|
|
141
|
|
|
146
|
-// 发送消息
|
|
|
|
147
|
const sendMessage = async () => {
|
142
|
const sendMessage = async () => {
|
|
148
|
const text = inputMessage.value.trim();
|
143
|
const text = inputMessage.value.trim();
|
|
149
|
if (!text || loading.value) return;
|
144
|
if (!text || loading.value) return;
|
|
150
|
|
145
|
|
|
151
|
- // 添加用户消息
|
|
|
|
152
|
messages.push({
|
146
|
messages.push({
|
|
153
|
type: 'user',
|
147
|
type: 'user',
|
|
154
|
text: text,
|
148
|
text: text,
|
|
@@ -164,7 +158,6 @@ const sendMessage = async () => { |
|
@@ -164,7 +158,6 @@ const sendMessage = async () => { |
|
164
|
scrollToBottom();
|
158
|
scrollToBottom();
|
|
165
|
|
159
|
|
|
166
|
try {
|
160
|
try {
|
|
167
|
- // 创建最终消息对象
|
|
|
|
168
|
const newMessage = {
|
161
|
const newMessage = {
|
|
169
|
type: 'assistant',
|
162
|
type: 'assistant',
|
|
170
|
text: '',
|
163
|
text: '',
|
|
@@ -173,15 +166,15 @@ const sendMessage = async () => { |
|
@@ -173,15 +166,15 @@ const sendMessage = async () => { |
|
173
|
fileName: ''
|
166
|
fileName: ''
|
|
174
|
};
|
167
|
};
|
|
175
|
|
168
|
|
|
176
|
- // 调用API获取异步生成器
|
|
|
|
177
|
- const streamGenerator = await apiSendMessage({ questionText: text });
|
169
|
+ // 🚩调用API携带正确参数
|
|
|
|
170
|
+ const streamGenerator = await apiSendMessage({
|
|
|
|
171
|
+ questionText: text,
|
|
|
|
172
|
+ code: 'INPUT_SEND',
|
|
|
|
173
|
+ codeType: 0
|
|
|
|
174
|
+ });
|
|
178
|
|
175
|
|
|
179
|
- // 遍历异步生成器
|
|
|
|
180
|
for await (const chunk of streamGenerator) {
|
176
|
for await (const chunk of streamGenerator) {
|
|
181
|
if (chunk.token) {
|
177
|
if (chunk.token) {
|
|
182
|
- if (!streamingMessage.value){
|
|
|
|
183
|
- loading.value = false;
|
|
|
|
184
|
- }
|
|
|
|
185
|
streamingMessage.value += chunk.token;
|
178
|
streamingMessage.value += chunk.token;
|
|
186
|
newMessage.text += chunk.token;
|
179
|
newMessage.text += chunk.token;
|
|
187
|
scrollToBottom();
|
180
|
scrollToBottom();
|
|
@@ -192,10 +185,8 @@ const sendMessage = async () => { |
|
@@ -192,10 +185,8 @@ const sendMessage = async () => { |
|
192
|
}
|
185
|
}
|
|
193
|
}
|
186
|
}
|
|
194
|
|
187
|
|
|
195
|
- // 将流式消息添加到消息列表
|
|
|
|
196
|
messages.push(newMessage);
|
188
|
messages.push(newMessage);
|
|
197
|
streamingMessage.value = '';
|
189
|
streamingMessage.value = '';
|
|
198
|
-
|
|
|
|
199
|
} catch (error: any) {
|
190
|
} catch (error: any) {
|
|
200
|
console.error('发送消息失败:', error);
|
191
|
console.error('发送消息失败:', error);
|
|
201
|
messages.push({
|
192
|
messages.push({
|
|
@@ -211,25 +202,25 @@ const sendMessage = async () => { |
|
@@ -211,25 +202,25 @@ const sendMessage = async () => { |
|
211
|
}
|
202
|
}
|
|
212
|
};
|
203
|
};
|
|
213
|
|
204
|
|
|
214
|
-const sendButtonMessage = async (buttonValue: string) => {
|
|
|
|
215
|
- if (loading.value) return;
|
205
|
+const sendButtonMessage = async (btn: any) => {
|
|
|
|
206
|
+ if (loading.value || buttonDisabled.value) return;
|
|
216
|
|
207
|
|
|
217
|
// 添加用户消息
|
208
|
// 添加用户消息
|
|
218
|
messages.push({
|
209
|
messages.push({
|
|
219
|
type: 'user',
|
210
|
type: 'user',
|
|
220
|
- text: buttonValue,
|
211
|
+ text: btn.buttonValues, // 🚩使用 buttonValues 作为显示内容
|
|
221
|
similarity: null,
|
212
|
similarity: null,
|
|
222
|
fileBase64: null,
|
213
|
fileBase64: null,
|
|
223
|
fileName: null
|
214
|
fileName: null
|
|
224
|
});
|
215
|
});
|
|
225
|
|
216
|
|
|
226
|
loading.value = true;
|
217
|
loading.value = true;
|
|
|
|
218
|
+ buttonDisabled.value = true;
|
|
227
|
streamingMessage.value = '';
|
219
|
streamingMessage.value = '';
|
|
228
|
closePreview();
|
220
|
closePreview();
|
|
229
|
scrollToBottom();
|
221
|
scrollToBottom();
|
|
230
|
|
222
|
|
|
231
|
try {
|
223
|
try {
|
|
232
|
- // 创建最终消息对象
|
|
|
|
233
|
const newMessage = {
|
224
|
const newMessage = {
|
|
234
|
type: 'assistant',
|
225
|
type: 'assistant',
|
|
235
|
text: '',
|
226
|
text: '',
|
|
@@ -238,15 +229,15 @@ const sendButtonMessage = async (buttonValue: string) => { |
|
@@ -238,15 +229,15 @@ const sendButtonMessage = async (buttonValue: string) => { |
|
238
|
fileName: ''
|
229
|
fileName: ''
|
|
239
|
};
|
230
|
};
|
|
240
|
|
231
|
|
|
241
|
- // 调用API获取异步生成器
|
|
|
|
242
|
- const streamGenerator = await apiSendMessage({ questionText: buttonValue });
|
232
|
+ // 🚩调用API携带正确参数
|
|
|
|
233
|
+ const streamGenerator = await apiSendMessage({
|
|
|
|
234
|
+ questionText: btn.buttonValues,
|
|
|
|
235
|
+ code: btn.code,
|
|
|
|
236
|
+ codeType: 1
|
|
|
|
237
|
+ });
|
|
243
|
|
238
|
|
|
244
|
- // 遍历异步生成器
|
|
|
|
245
|
for await (const chunk of streamGenerator) {
|
239
|
for await (const chunk of streamGenerator) {
|
|
246
|
if (chunk.token) {
|
240
|
if (chunk.token) {
|
|
247
|
- if (!streamingMessage.value){
|
|
|
|
248
|
- loading.value = false;
|
|
|
|
249
|
- }
|
|
|
|
250
|
streamingMessage.value += chunk.token;
|
241
|
streamingMessage.value += chunk.token;
|
|
251
|
newMessage.text += chunk.token;
|
242
|
newMessage.text += chunk.token;
|
|
252
|
scrollToBottom();
|
243
|
scrollToBottom();
|
|
@@ -257,10 +248,8 @@ const sendButtonMessage = async (buttonValue: string) => { |
|
@@ -257,10 +248,8 @@ const sendButtonMessage = async (buttonValue: string) => { |
|
257
|
}
|
248
|
}
|
|
258
|
}
|
249
|
}
|
|
259
|
|
250
|
|
|
260
|
- // 将流式消息添加到消息列表
|
|
|
|
261
|
messages.push(newMessage);
|
251
|
messages.push(newMessage);
|
|
262
|
streamingMessage.value = '';
|
252
|
streamingMessage.value = '';
|
|
263
|
-
|
|
|
|
264
|
} catch (error: any) {
|
253
|
} catch (error: any) {
|
|
265
|
console.error('发送按钮消息失败:', error);
|
254
|
console.error('发送按钮消息失败:', error);
|
|
266
|
messages.push({
|
255
|
messages.push({
|
|
@@ -272,6 +261,7 @@ const sendButtonMessage = async (buttonValue: string) => { |
|
@@ -272,6 +261,7 @@ const sendButtonMessage = async (buttonValue: string) => { |
|
272
|
});
|
261
|
});
|
|
273
|
} finally {
|
262
|
} finally {
|
|
274
|
loading.value = false;
|
263
|
loading.value = false;
|
|
|
|
264
|
+ buttonDisabled.value = false;
|
|
275
|
scrollToBottom();
|
265
|
scrollToBottom();
|
|
276
|
}
|
266
|
}
|
|
277
|
};
|
267
|
};
|