增加流式返回的开关
This commit is contained in:
@@ -5,6 +5,7 @@ import {mapState} from "vuex";
|
||||
import AiDrag from "../basic/AiDrag.vue";
|
||||
import AiLocateDialog from "../tools/AiLocateDialog.vue";
|
||||
import AiUploader from "../basic/AiUploader.vue";
|
||||
import {$checkJson} from "../../lib/js/utils";
|
||||
|
||||
export default {
|
||||
name: "AiCopilot",
|
||||
@@ -137,8 +138,8 @@ export default {
|
||||
else this.$message.error("最多上传一个文件")
|
||||
},
|
||||
sendMessage(message, isSSE = false) {
|
||||
if (isSSE) {
|
||||
const {content, sdkFileUrl} = message
|
||||
if (isSSE || localStorage.getItem("isSSE")) {
|
||||
const {content, sdkFileUrl, appId} = message
|
||||
const body = {
|
||||
inputs: {},
|
||||
query: content,
|
||||
@@ -149,21 +150,29 @@ export default {
|
||||
return new Promise(resolve => this.http.post("/sse/chat-messages", body, {
|
||||
withoutToken: 1, headers: {
|
||||
Accept: 'text/event-stream',
|
||||
Authorization: "Bearer app-DRXYELe63911kx7F9RvKUonf"
|
||||
Authorization: `Bearer ${appId}`
|
||||
},
|
||||
onDownloadProgress: evt => {
|
||||
evt.target.responseText.split("data:").forEach(data => {
|
||||
if (data.trim()) {
|
||||
evt.target.responseText.split(/(data|event):/).forEach(data => {
|
||||
if ($checkJson(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()
|
||||
if (!!chunk) {
|
||||
if (this.history.at(-1).userType != 1) {
|
||||
this.history.push({userType: 1, content: chunk})
|
||||
} else if (!this.history.at(-1).content?.includes(chunk)) {
|
||||
this.history.at(-1).content += chunk
|
||||
}
|
||||
if (!last.content?.includes(chunk)) last.content += chunk
|
||||
}
|
||||
if (res.event == "message_end") {
|
||||
last.workflow = ""
|
||||
resolve()
|
||||
}
|
||||
if (res.event == "message_end") resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
<img v-if="item.userType!=2" class="avatar" :src="avatar(item)" alt=""/>
|
||||
<div style="max-width: max(calc(100% - 140px), 220px)">
|
||||
<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>
|
||||
</div>
|
||||
@@ -56,7 +60,7 @@ export default {
|
||||
mounted() {
|
||||
const {hljs, markdownit} = window
|
||||
this.md = markdownit({
|
||||
breaks: true,
|
||||
breaks: true, linkify: true, html: true,
|
||||
highlight: function (str, lang) {
|
||||
if (lang && hljs.getLanguage(lang)) {
|
||||
try {
|
||||
@@ -175,6 +179,26 @@ export default {
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user