增加流式返回的开关

This commit is contained in:
aixianling
2024-08-27 18:00:04 +08:00
parent 155366d92e
commit 8b724e52b3
2 changed files with 45 additions and 12 deletions

View File

@@ -5,6 +5,7 @@ import {mapState} from "vuex";
import AiDrag from "../basic/AiDrag.vue"; import AiDrag from "../basic/AiDrag.vue";
import AiLocateDialog from "../tools/AiLocateDialog.vue"; import AiLocateDialog from "../tools/AiLocateDialog.vue";
import AiUploader from "../basic/AiUploader.vue"; import AiUploader from "../basic/AiUploader.vue";
import {$checkJson} from "../../lib/js/utils";
export default { export default {
name: "AiCopilot", name: "AiCopilot",
@@ -137,8 +138,8 @@ export default {
else this.$message.error("最多上传一个文件") else this.$message.error("最多上传一个文件")
}, },
sendMessage(message, isSSE = false) { sendMessage(message, isSSE = false) {
if (isSSE) { if (isSSE || localStorage.getItem("isSSE")) {
const {content, sdkFileUrl} = message const {content, sdkFileUrl, appId} = message
const body = { const body = {
inputs: {}, inputs: {},
query: content, query: content,
@@ -149,21 +150,29 @@ export default {
return new Promise(resolve => this.http.post("/sse/chat-messages", body, { return new Promise(resolve => this.http.post("/sse/chat-messages", body, {
withoutToken: 1, headers: { withoutToken: 1, headers: {
Accept: 'text/event-stream', Accept: 'text/event-stream',
Authorization: "Bearer app-DRXYELe63911kx7F9RvKUonf" Authorization: `Bearer ${appId}`
}, },
onDownloadProgress: evt => { onDownloadProgress: evt => {
evt.target.responseText.split("data:").forEach(data => { evt.target.responseText.split(/(data|event):/).forEach(data => {
if (data.trim()) { if ($checkJson(data.trim())) {
const res = JSON.parse(data.trim()) const res = JSON.parse(data.trim())
if (this.history.at(-1).userType != 1) {
this.history.push({userType: 1, content: "", workflow: []})
}
const last = this.history.at(-1)
if (res.event == "node_started") {
last.workflow = ["el-icon-loading", res.data.title]
} else if (res.event == "node_finished") {
last.workflow = ["el-icon-finished", res.data.title]
}
const chunk = res.answer?.trim() const chunk = res.answer?.trim()
if (!!chunk) { if (!!chunk) {
if (this.history.at(-1).userType != 1) { if (!last.content?.includes(chunk)) last.content += chunk
this.history.push({userType: 1, content: chunk}) }
} else if (!this.history.at(-1).content?.includes(chunk)) { if (res.event == "message_end") {
this.history.at(-1).content += chunk last.workflow = ""
} resolve()
} }
if (res.event == "message_end") resolve()
} }
}) })
} }

View File

@@ -5,6 +5,10 @@
<img v-if="item.userType!=2" class="avatar" :src="avatar(item)" alt=""/> <img v-if="item.userType!=2" class="avatar" :src="avatar(item)" alt=""/>
<div style="max-width: max(calc(100% - 140px), 220px)"> <div style="max-width: max(calc(100% - 140px), 220px)">
<div class="content" v-html="markdown(item.content)"/> <div class="content" v-html="markdown(item.content)"/>
<div v-if="item.workflow&&item.workflow.length>0" class="process flex">
<i :class="item.workflow[0]"/>
<div v-html="item.workflow[1]"/>
</div>
<div class="attachments pointer el-icon-paperclip" v-if="item.fileName" v-text="item.fileName" @click="handleDownload(item)"/> <div class="attachments pointer el-icon-paperclip" v-if="item.fileName" v-text="item.fileName" @click="handleDownload(item)"/>
</div> </div>
</div> </div>
@@ -56,7 +60,7 @@ export default {
mounted() { mounted() {
const {hljs, markdownit} = window const {hljs, markdownit} = window
this.md = markdownit({ this.md = markdownit({
breaks: true, breaks: true, linkify: true, html: true,
highlight: function (str, lang) { highlight: function (str, lang) {
if (lang && hljs.getLanguage(lang)) { if (lang && hljs.getLanguage(lang)) {
try { try {
@@ -175,6 +179,26 @@ export default {
margin-right: 2px; margin-right: 2px;
} }
} }
:deep(.process) {
font-size: 12px;
gap: 4px;
& > i {
display: flex;
align-items: center;
gap: 4px;
&:before {
font-size: 16px;
color: $primaryColor;
&.el-icon-finished {
color: $successColor;
}
}
}
}
} }
.avatar { .avatar {