mirror of
https://github.com/yangjian102621/geekai.git
synced 2026-02-19 21:04:27 +08:00
完善 SSE 功能
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
.chat-page {
|
||||
height: 100%;
|
||||
:deep (.el-message-box__message){
|
||||
:deep(.el-message-box__message){
|
||||
font-size: 18px !important
|
||||
}
|
||||
.newChat{
|
||||
|
||||
@@ -137,6 +137,7 @@ const props = defineProps({
|
||||
tokens: 0,
|
||||
model: '',
|
||||
icon: '',
|
||||
files: [],
|
||||
},
|
||||
},
|
||||
listStyle: {
|
||||
@@ -146,7 +147,7 @@ const props = defineProps({
|
||||
})
|
||||
const finalTokens = ref(props.data.tokens)
|
||||
const content = ref(processPrompt(props.data.content))
|
||||
const files = ref([])
|
||||
const files = ref(props.data.files)
|
||||
|
||||
// 定义emit事件
|
||||
const emit = defineEmits(['edit'])
|
||||
@@ -159,38 +160,6 @@ const processFiles = () => {
|
||||
if (!props.data.content) {
|
||||
return
|
||||
}
|
||||
|
||||
// 提取图片|文件链接
|
||||
const linkRegex = /(https?:\/\/\S+)/g
|
||||
const links = props.data.content.match(linkRegex)
|
||||
const urlPrefix = `${window.location.protocol}//${window.location.host}`
|
||||
if (links) {
|
||||
// 把本地链接转换为相对路径
|
||||
const _links = links.map((link) => {
|
||||
if (link.startsWith(urlPrefix)) {
|
||||
return link.replace(urlPrefix, '')
|
||||
}
|
||||
return link
|
||||
})
|
||||
// 合并数组并去重
|
||||
const urls = [...new Set([...links, ..._links])]
|
||||
httpPost('/api/upload/list', { urls: urls })
|
||||
.then((res) => {
|
||||
files.value = res.data.items
|
||||
|
||||
// for (let link of links) {
|
||||
// if (isExternalImg(link, files.value)) {
|
||||
// files.value.push({ url: link, ext: ".png" });
|
||||
// }
|
||||
// }
|
||||
})
|
||||
.catch(() => {})
|
||||
|
||||
// 替换图片|文件链接
|
||||
for (let link of links) {
|
||||
content.value = content.value.replace(link, '')
|
||||
}
|
||||
}
|
||||
content.value = md.render(content.value.trim())
|
||||
}
|
||||
const isExternalImg = (link, files) => {
|
||||
|
||||
@@ -1,22 +1,36 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="config-dialog"
|
||||
v-model="showDialog"
|
||||
:close-on-click-modal="true"
|
||||
:before-close="close"
|
||||
style="max-width: 600px"
|
||||
title="聊天配置"
|
||||
class="config-dialog"
|
||||
v-model="showDialog"
|
||||
:close-on-click-modal="true"
|
||||
:before-close="close"
|
||||
style="max-width: 600px"
|
||||
title="聊天配置"
|
||||
>
|
||||
<div class="chat-setting">
|
||||
<el-form :model="data" label-width="100px" label-position="left">
|
||||
<el-form-item label="聊天样式:">
|
||||
<el-radio-group v-model="data.style" @change="(val) => {store.setChatListStyle(val)}">
|
||||
<el-radio-group
|
||||
v-model="data.style"
|
||||
@change="
|
||||
(val) => {
|
||||
store.setChatListStyle(val)
|
||||
}
|
||||
"
|
||||
>
|
||||
<el-radio value="list">列表样式</el-radio>
|
||||
<el-radio value="chat">对话样式</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="流式输出:">
|
||||
<el-switch v-model="data.stream" @change="(val) => {store.setChatStream(val)}" />
|
||||
<el-switch
|
||||
v-model="data.stream"
|
||||
@change="
|
||||
(val) => {
|
||||
store.setChatStream(val)
|
||||
}
|
||||
"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="语音音色:">
|
||||
<el-select v-model="data.ttsModel" placeholder="请选择语音音色" @change="changeTTSModel">
|
||||
@@ -31,10 +45,10 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {computed, ref, onMounted} from "vue"
|
||||
import {useSharedStore} from "@/store/sharedata";
|
||||
import {httpGet} from "@/utils/http";
|
||||
const store = useSharedStore();
|
||||
import { computed, ref, onMounted } from 'vue'
|
||||
import { useSharedStore } from '@/store/sharedata'
|
||||
import { httpGet } from '@/utils/http'
|
||||
const store = useSharedStore()
|
||||
|
||||
const data = ref({
|
||||
style: store.chatListStyle,
|
||||
@@ -44,28 +58,28 @@ const data = ref({
|
||||
// eslint-disable-next-line no-undef
|
||||
const props = defineProps({
|
||||
show: Boolean,
|
||||
});
|
||||
})
|
||||
|
||||
const showDialog = computed(() => {
|
||||
return props.show
|
||||
})
|
||||
const emits = defineEmits(['hide']);
|
||||
const emits = defineEmits(['hide'])
|
||||
const close = function () {
|
||||
emits('hide', false);
|
||||
emits('hide', false)
|
||||
}
|
||||
const models = ref([]);
|
||||
const models = ref([])
|
||||
onMounted(() => {
|
||||
// 获取模型列表
|
||||
httpGet("/api/model/list?type=tts").then((res) => {
|
||||
models.value = res.data;
|
||||
if (!data.ttsModel) {
|
||||
store.setTtsModel(models.value[0].id);
|
||||
httpGet('/api/model/list?type=tts').then((res) => {
|
||||
models.value = res.data
|
||||
if (!data.ttsModel && models.value.length > 0) {
|
||||
store.setTtsModel(models.value[0].id)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const changeTTSModel = (item) => {
|
||||
store.setTtsModel(item);
|
||||
store.setTtsModel(item)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -73,4 +87,4 @@ const changeTTSModel = (item) => {
|
||||
.chat-setting {
|
||||
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -709,11 +709,6 @@ onMounted(() => {
|
||||
// 初始化数据
|
||||
const initData = async () => {
|
||||
try {
|
||||
// 获取用户信息
|
||||
const user = await checkSession()
|
||||
loginUser.value = user
|
||||
isLogin.value = true
|
||||
|
||||
// 获取角色列表
|
||||
const roleRes = await httpGet('/api/app/list')
|
||||
roles.value = roleRes.data
|
||||
@@ -728,6 +723,11 @@ const initData = async () => {
|
||||
modelID.value = models.value[0].id
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
const user = await checkSession()
|
||||
loginUser.value = user
|
||||
isLogin.value = true
|
||||
|
||||
// 获取聊天列表
|
||||
const chatRes = await httpGet('/api/chat/list')
|
||||
allChats.value = chatRes.data
|
||||
@@ -739,7 +739,7 @@ const initData = async () => {
|
||||
if (error.response?.status === 401) {
|
||||
isLogin.value = false
|
||||
} else {
|
||||
showMessageError('初始化数据失败:' + error.message)
|
||||
console.warn('初始化数据失败:' + error.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -762,20 +762,15 @@ const sendMessage = async function () {
|
||||
return false
|
||||
}
|
||||
|
||||
// 如果携带了文件,则串上文件地址
|
||||
let content = prompt.value
|
||||
if (files.value.length > 0) {
|
||||
content += files.value.map((file) => file.url).join(' ')
|
||||
}
|
||||
|
||||
// 追加消息
|
||||
chatData.value.push({
|
||||
type: 'prompt',
|
||||
id: randString(32),
|
||||
icon: loginUser.value.avatar,
|
||||
content: content,
|
||||
content: prompt.value,
|
||||
model: getModelValue(modelID.value),
|
||||
created_at: new Date().getTime() / 1000,
|
||||
files: files.value,
|
||||
})
|
||||
|
||||
// 添加空回复消息
|
||||
@@ -809,9 +804,10 @@ const sendMessage = async function () {
|
||||
role_id: roleId.value,
|
||||
model_id: modelID.value,
|
||||
chat_id: chatId.value,
|
||||
content: content,
|
||||
content: prompt.value,
|
||||
tools: toolSelected.value,
|
||||
stream: stream.value,
|
||||
files: files.value,
|
||||
}),
|
||||
openWhenHidden: true,
|
||||
onopen(response) {
|
||||
@@ -902,7 +898,7 @@ const sendMessage = async function () {
|
||||
ElMessage.error('发送消息失败,请重试')
|
||||
}
|
||||
|
||||
tmpChatTitle.value = content
|
||||
tmpChatTitle.value = prompt.value
|
||||
prompt.value = ''
|
||||
files.value = []
|
||||
row.value = 1
|
||||
|
||||
Reference in New Issue
Block a user