mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-12-27 10:35:58 +08:00
支持按次收费的 OpenAI 实时语音通话功能
This commit is contained in:
@@ -3,21 +3,15 @@
|
||||
<el-container>
|
||||
<el-aside>
|
||||
<div class="media-page">
|
||||
<!-- <el-button @click="_newChat" color="#21aa93">
|
||||
<el-button @click="_newChat" type="primary" style="margin-bottom: 10px">
|
||||
<el-icon style="margin-right: 5px">
|
||||
<Plus/>
|
||||
<Plus />
|
||||
</el-icon>
|
||||
新建对话
|
||||
</el-button> -->
|
||||
</el-button>
|
||||
|
||||
<div class="search-box">
|
||||
<el-input
|
||||
v-model="chatName"
|
||||
placeholder="搜索会话"
|
||||
@keyup="searchChat($event)"
|
||||
style=""
|
||||
class="search-input"
|
||||
>
|
||||
<el-input v-model="chatName" placeholder="搜索会话" @keyup="searchChat($event)" style="" class="search-input">
|
||||
<template #prefix>
|
||||
<el-icon class="el-input__icon">
|
||||
<Search />
|
||||
@@ -28,14 +22,7 @@
|
||||
|
||||
<div class="content" :style="{ height: leftBoxHeight + 'px' }">
|
||||
<el-row v-for="chat in chatList" :key="chat.chat_id">
|
||||
<div
|
||||
:class="
|
||||
chat.chat_id === chatId
|
||||
? 'chat-list-item active'
|
||||
: 'chat-list-item'
|
||||
"
|
||||
@click="loadChat(chat)"
|
||||
>
|
||||
<div :class="chat.chat_id === chatId ? 'chat-list-item active' : 'chat-list-item'" @click="loadChat(chat)">
|
||||
<el-image :src="chat.icon" class="avatar" />
|
||||
<span class="chat-title-input" v-if="chat.edit">
|
||||
<el-input
|
||||
@@ -52,34 +39,23 @@
|
||||
|
||||
<span class="chat-opt">
|
||||
<el-dropdown trigger="click">
|
||||
<span
|
||||
class="el-dropdown-link"
|
||||
@click="stopPropagation($event)"
|
||||
>
|
||||
<span class="el-dropdown-link" @click="stopPropagation($event)">
|
||||
<el-icon><More /></el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
:icon="Edit"
|
||||
@click="editChatTitle(chat)"
|
||||
>重命名</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item :icon="Edit" @click="editChatTitle(chat)">重命名</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
:icon="Delete"
|
||||
style="
|
||||
--el-text-color-regular: var(--el-color-danger);
|
||||
--el-dropdown-menuItem-hover-fill: #f8e1de;
|
||||
--el-dropdown-menuItem-hover-color: var(
|
||||
--el-color-danger
|
||||
);
|
||||
--el-dropdown-menuItem-hover-color: var(--el-color-danger);
|
||||
"
|
||||
@click="removeChat(chat)"
|
||||
>删除</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item :icon="Share" @click="shareChat(chat)"
|
||||
>分享</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item :icon="Share" @click="shareChat(chat)">分享</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
@@ -90,31 +66,14 @@
|
||||
</div>
|
||||
|
||||
<div class="tool-box">
|
||||
<el-button type="primary" size="small" @click="clearAllChats">
|
||||
<i class="iconfont icon-clear"></i> 清除所有对话
|
||||
</el-button>
|
||||
<el-button type="primary" size="small" @click="clearAllChats"> <i class="iconfont icon-clear"></i> 清除所有对话 </el-button>
|
||||
</div>
|
||||
</el-aside>
|
||||
<el-main
|
||||
v-loading="loading"
|
||||
element-loading-background="rgba(122, 122, 122, 0.3)"
|
||||
>
|
||||
<el-main v-loading="loading" element-loading-background="rgba(122, 122, 122, 0.3)">
|
||||
<div class="chat-container">
|
||||
<div class="chat-config">
|
||||
<el-select
|
||||
v-model="roleId"
|
||||
filterable
|
||||
placeholder="角色"
|
||||
@change="_newChat"
|
||||
class="role-select"
|
||||
style="width: 150px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in roles"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
>
|
||||
<el-select v-model="roleId" filterable placeholder="角色" @change="_newChat" class="role-select" style="width: 150px">
|
||||
<el-option v-for="item in roles" :key="item.id" :label="item.name" :value="item.id">
|
||||
<div class="role-option">
|
||||
<el-image :src="item.icon"></el-image>
|
||||
<span>{{ item.name }}</span>
|
||||
@@ -122,43 +81,21 @@
|
||||
</el-option>
|
||||
</el-select>
|
||||
|
||||
<el-select
|
||||
v-model="modelID"
|
||||
filterable
|
||||
placeholder="模型"
|
||||
@change="_newChat"
|
||||
:disabled="disableModel"
|
||||
style="width: 150px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in models"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
>
|
||||
<el-select v-model="modelID" filterable placeholder="模型" @change="_newChat" :disabled="disableModel" style="width: 150px">
|
||||
<el-option v-for="item in models" :key="item.id" :label="item.name" :value="item.id">
|
||||
<span>{{ item.name }}</span>
|
||||
<el-tag
|
||||
style="margin-left: 5px; position: relative; top: -2px"
|
||||
type="info"
|
||||
size="small"
|
||||
>{{ item.power }}算力
|
||||
</el-tag>
|
||||
<el-tag style="margin-left: 5px; position: relative; top: -2px" type="info" size="small">{{ item.power }}算力 </el-tag>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<div class="flex-center">
|
||||
<el-dropdown :hide-on-click="false" trigger="click">
|
||||
<span class="setting"
|
||||
><i class="iconfont icon-plugin"></i
|
||||
></span>
|
||||
<span class="setting"><i class="iconfont icon-plugin"></i></span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu class="tools-dropdown">
|
||||
<el-checkbox-group v-model="toolSelected">
|
||||
<el-dropdown-item v-for="item in tools" :key="item.id">
|
||||
<el-checkbox :value="item.id" :label="item.label" />
|
||||
<el-tooltip
|
||||
:content="item.description"
|
||||
placement="right"
|
||||
>
|
||||
<el-tooltip :content="item.description" placement="right">
|
||||
<el-icon><InfoFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</el-dropdown-item>
|
||||
@@ -175,27 +112,13 @@
|
||||
|
||||
<div>
|
||||
<div id="container" :style="{ height: mainWinHeight + 'px' }">
|
||||
<div
|
||||
class="chat-box"
|
||||
id="chat-box"
|
||||
:style="{ height: chatBoxHeight + 'px' }"
|
||||
>
|
||||
<div class="chat-box" id="chat-box" :style="{ height: chatBoxHeight + 'px' }">
|
||||
<div v-if="showHello">
|
||||
<welcome @send="autofillPrompt" />
|
||||
</div>
|
||||
<div v-for="item in chatData" :key="item.id" v-else>
|
||||
<chat-prompt
|
||||
v-if="item.type === 'prompt'"
|
||||
:data="item"
|
||||
:list-style="listStyle"
|
||||
/>
|
||||
<chat-reply
|
||||
v-else-if="item.type === 'reply'"
|
||||
:data="item"
|
||||
@regen="reGenerate"
|
||||
:read-only="false"
|
||||
:list-style="listStyle"
|
||||
/>
|
||||
<chat-prompt v-if="item.type === 'prompt'" :data="item" :list-style="listStyle" />
|
||||
<chat-reply v-else-if="item.type === 'reply'" :data="item" @regen="reGenerate" :read-only="false" :list-style="listStyle" />
|
||||
</div>
|
||||
|
||||
<back-top :right="30" :bottom="155" />
|
||||
@@ -248,66 +171,34 @@
|
||||
</textarea>
|
||||
</div>
|
||||
<div class="flex-between">
|
||||
<div @click="_newChat" class="flex-center add-new">
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
content="新建会话"
|
||||
>
|
||||
<el-icon><CirclePlusFilled /></el-icon>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="flex little-btns">
|
||||
<span class="send-btn tool-item-btn">
|
||||
<!-- showStopGenerate -->
|
||||
<el-button
|
||||
type="info"
|
||||
v-if="showStopGenerate"
|
||||
@click="stopGenerate"
|
||||
plain
|
||||
>
|
||||
<el-icon>
|
||||
<VideoPause />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-button
|
||||
@click="sendMessage"
|
||||
style="color: #754ff6"
|
||||
v-else
|
||||
>
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
content="发送"
|
||||
>
|
||||
<el-icon><Promotion /></el-icon>
|
||||
</el-tooltip>
|
||||
</el-button>
|
||||
</span>
|
||||
<div class="flex-center little-btns">
|
||||
<span class="tool-item-btn" @click="realtimeChat">
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
content="实时语音对话"
|
||||
>
|
||||
<el-tooltip class="box-item" effect="dark" :content="'实时语音对话,每次消耗' + config.advance_voice_power + '算力'">
|
||||
<i class="iconfont icon-mic-bold"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
|
||||
<span class="tool-item-btn" v-if="isLogin">
|
||||
<el-tooltip
|
||||
class="box-item"
|
||||
effect="dark"
|
||||
content="上传附件"
|
||||
>
|
||||
<file-select
|
||||
v-if="isLogin"
|
||||
:user-id="loginUser.id"
|
||||
@selected="insertFile"
|
||||
/>
|
||||
<el-tooltip class="box-item" effect="dark" content="上传附件">
|
||||
<file-select v-if="isLogin" :user-id="loginUser.id" @selected="insertFile" />
|
||||
</el-tooltip>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex little-btns">
|
||||
<span class="send-btn tool-item-btn">
|
||||
<!-- showStopGenerate -->
|
||||
<el-button type="info" v-if="showStopGenerate" @click="stopGenerate" plain>
|
||||
<el-icon>
|
||||
<VideoPause />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
<el-button @click="sendMessage" style="color: #754ff6" v-else>
|
||||
<el-tooltip class="box-item" effect="dark" content="发送">
|
||||
<el-icon><Promotion /></el-icon>
|
||||
</el-tooltip>
|
||||
</el-button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -322,28 +213,21 @@
|
||||
</el-main>
|
||||
</el-container>
|
||||
|
||||
<el-dialog
|
||||
v-model="showNotice"
|
||||
:show-close="true"
|
||||
class="notice-dialog"
|
||||
title="网站公告"
|
||||
>
|
||||
<el-dialog v-model="showNotice" :show-close="true" class="notice-dialog" title="网站公告">
|
||||
<div class="notice">
|
||||
<div v-html="notice"></div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="notShow" type="primary"
|
||||
>我知道了,不再显示</el-button
|
||||
>
|
||||
<el-button @click="notShow" type="primary">我知道了,不再显示</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<ChatSetting :show="showChatSetting" @hide="showChatSetting = false" />
|
||||
|
||||
<el-dialog
|
||||
<!-- <el-dialog
|
||||
v-model="showConversationDialog"
|
||||
title="实时语音通话"
|
||||
:before-close="hangUp"
|
||||
@@ -353,6 +237,17 @@
|
||||
ref="conversationRef"
|
||||
:height="dialogHeight + 'px'"
|
||||
/>
|
||||
</el-dialog> -->
|
||||
|
||||
<el-dialog v-model="showConversationDialog" title="实时语音通话" :fullscreen="true">
|
||||
<div v-loading="!frameLoaded">
|
||||
<iframe
|
||||
style="width: 100%; height: calc(100vh - 100px); border: none"
|
||||
:src="voiceChatUrl"
|
||||
@load="frameLoaded = true"
|
||||
allow="microphone *;camera *;"
|
||||
></iframe>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
@@ -360,18 +255,7 @@
|
||||
import { nextTick, onMounted, onUnmounted, ref, watch } from "vue";
|
||||
import ChatPrompt from "@/components/ChatPrompt.vue";
|
||||
import ChatReply from "@/components/ChatReply.vue";
|
||||
import {
|
||||
Delete,
|
||||
Edit,
|
||||
InfoFilled,
|
||||
More,
|
||||
Plus,
|
||||
CirclePlusFilled,
|
||||
Promotion,
|
||||
Search,
|
||||
Share,
|
||||
VideoPause
|
||||
} from "@element-plus/icons-vue";
|
||||
import { Delete, Edit, InfoFilled, More, Plus, Promotion, Search, Share, VideoPause } from "@element-plus/icons-vue";
|
||||
import "highlight.js/styles/a11y-dark.css";
|
||||
import { isMobile, randString, removeArrayItem, UUID } from "@/utils/libs";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
@@ -385,8 +269,7 @@ import FileSelect from "@/components/FileSelect.vue";
|
||||
import FileList from "@/components/FileList.vue";
|
||||
import ChatSetting from "@/components/ChatSetting.vue";
|
||||
import BackTop from "@/components/BackTop.vue";
|
||||
import { showMessageError } from "@/utils/dialog";
|
||||
import RealtimeConversation from "@/components/RealtimeConversation.vue";
|
||||
import { closeLoading, showLoading, showMessageError } from "@/utils/dialog";
|
||||
|
||||
const title = ref("GeekAI-智能助手");
|
||||
const models = ref([]);
|
||||
@@ -415,6 +298,8 @@ const store = useSharedStore();
|
||||
const row = ref(1);
|
||||
const showChatSetting = ref(false);
|
||||
const listStyle = ref(store.chatListStyle);
|
||||
const config = ref({ advance_voice_power: 0 });
|
||||
const voiceChatUrl = ref("");
|
||||
watch(
|
||||
() => store.chatListStyle,
|
||||
(newValue) => {
|
||||
@@ -460,7 +345,8 @@ if (!chatId.value) {
|
||||
// 获取系统配置
|
||||
getSystemInfo()
|
||||
.then((res) => {
|
||||
title.value = res.data.title;
|
||||
config.value = res.data;
|
||||
title.value = config.value.title;
|
||||
})
|
||||
.catch((e) => {
|
||||
ElMessage.error("获取系统配置失败:" + e.message);
|
||||
@@ -470,7 +356,7 @@ const md = require("markdown-it")({
|
||||
breaks: true,
|
||||
html: true,
|
||||
linkify: true,
|
||||
typographer: true
|
||||
typographer: true,
|
||||
});
|
||||
// 获取系统公告
|
||||
httpGet("/api/config/get?key=notice")
|
||||
@@ -539,7 +425,7 @@ onMounted(() => {
|
||||
id: randString(32),
|
||||
icon: chatRole["icon"],
|
||||
prompt: prePrompt,
|
||||
content: data.body
|
||||
content: data.body,
|
||||
});
|
||||
isNewMsg.value = false;
|
||||
lineBuffer.value = data.body;
|
||||
@@ -561,16 +447,14 @@ onMounted(() => {
|
||||
httpPost("/api/chat/tokens", {
|
||||
text: "",
|
||||
model: getModelValue(modelID.value),
|
||||
chat_id: chatId.value
|
||||
chat_id: chatId.value,
|
||||
})
|
||||
.then((res) => {
|
||||
reply["created_at"] = new Date().getTime();
|
||||
reply["tokens"] = res.data;
|
||||
// 将聊天框的滚动条滑动到最底部
|
||||
nextTick(() => {
|
||||
document
|
||||
.getElementById("chat-box")
|
||||
.scrollTo(0, document.getElementById("chat-box").scrollHeight);
|
||||
document.getElementById("chat-box").scrollTo(0, document.getElementById("chat-box").scrollHeight);
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
@@ -584,9 +468,7 @@ onMounted(() => {
|
||||
}
|
||||
// 将聊天框的滚动条滑动到最底部
|
||||
nextTick(() => {
|
||||
document
|
||||
.getElementById("chat-box")
|
||||
.scrollTo(0, document.getElementById("chat-box").scrollHeight);
|
||||
document.getElementById("chat-box").scrollTo(0, document.getElementById("chat-box").scrollHeight);
|
||||
localStorage.setItem("chat_id", chatId.value);
|
||||
});
|
||||
});
|
||||
@@ -687,8 +569,8 @@ const resizeElement = function () {
|
||||
// mainWinHeight.value = window.innerHeight;
|
||||
|
||||
// leftBoxHeight.value = window.innerHeight - 90 - 45 - 82;
|
||||
// leftBoxHeight.value = window.innerHeight - 90 - 82;
|
||||
leftBoxHeight.value = window.innerHeight - 90 - 50;
|
||||
leftBoxHeight.value = window.innerHeight - 90 - 90;
|
||||
// leftBoxHeight.value = window.innerHeight - 90 - 50;
|
||||
};
|
||||
|
||||
const _newChat = () => {
|
||||
@@ -714,10 +596,7 @@ const newChat = () => {
|
||||
disableModel.value = true;
|
||||
}
|
||||
// 已有新开的会话
|
||||
if (
|
||||
newChatItem.value !== null &&
|
||||
newChatItem.value["role_id"] === roles.value[0]["role_id"]
|
||||
) {
|
||||
if (newChatItem.value !== null && newChatItem.value["role_id"] === roles.value[0]["role_id"]) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -735,7 +614,7 @@ const newChat = () => {
|
||||
model_id: modelID.value,
|
||||
title: "",
|
||||
edit: false,
|
||||
removing: false
|
||||
removing: false,
|
||||
};
|
||||
showStopGenerate.value = false;
|
||||
loadChatHistory(chatId.value);
|
||||
@@ -796,7 +675,7 @@ const editConfirm = function (chat) {
|
||||
|
||||
httpPost("/api/chat/update", {
|
||||
chat_id: chat.chat_id,
|
||||
title: tmpChatTitle.value
|
||||
title: tmpChatTitle.value,
|
||||
})
|
||||
.then(() => {
|
||||
chat.title = tmpChatTitle.value;
|
||||
@@ -811,18 +690,14 @@ const removeChat = function (chat) {
|
||||
ElMessageBox.confirm(`该操作会删除"${chat.title}"`, "删除聊天", {
|
||||
confirmButtonText: "删除",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
type: "warning",
|
||||
})
|
||||
.then(() => {
|
||||
httpGet("/api/chat/remove?chat_id=" + chat.chat_id)
|
||||
.then(() => {
|
||||
chatList.value = removeArrayItem(
|
||||
chatList.value,
|
||||
chat,
|
||||
function (e1, e2) {
|
||||
return e1.id === e2.id;
|
||||
}
|
||||
);
|
||||
chatList.value = removeArrayItem(chatList.value, chat, function (e1, e2) {
|
||||
return e1.id === e2.id;
|
||||
});
|
||||
// 重置会话
|
||||
_newChat();
|
||||
})
|
||||
@@ -845,9 +720,7 @@ const enableInput = () => {
|
||||
|
||||
const onInput = (e) => {
|
||||
// 根据输入的内容自动计算输入框的行数
|
||||
const lineHeight = parseFloat(
|
||||
window.getComputedStyle(inputRef.value).lineHeight
|
||||
);
|
||||
const lineHeight = parseFloat(window.getComputedStyle(inputRef.value).lineHeight);
|
||||
textHeightRef.value.style.width = inputRef.value.clientWidth + "px"; // 设定宽度和 textarea 相同
|
||||
const lines = Math.floor(textHeightRef.value.clientHeight / lineHeight);
|
||||
inputRef.value.scrollTo(0, inputRef.value.scrollHeight);
|
||||
@@ -914,13 +787,11 @@ const sendMessage = function () {
|
||||
icon: loginUser.value.avatar,
|
||||
content: content,
|
||||
model: getModelValue(modelID.value),
|
||||
created_at: new Date().getTime() / 1000
|
||||
created_at: new Date().getTime() / 1000,
|
||||
});
|
||||
|
||||
nextTick(() => {
|
||||
document
|
||||
.getElementById("chat-box")
|
||||
.scrollTo(0, document.getElementById("chat-box").scrollHeight);
|
||||
document.getElementById("chat-box").scrollTo(0, document.getElementById("chat-box").scrollHeight);
|
||||
});
|
||||
|
||||
showHello.value = false;
|
||||
@@ -935,8 +806,8 @@ const sendMessage = function () {
|
||||
chat_id: chatId.value,
|
||||
content: content,
|
||||
tools: toolSelected.value,
|
||||
stream: stream.value
|
||||
}
|
||||
stream: stream.value,
|
||||
},
|
||||
})
|
||||
);
|
||||
tmpChatTitle.value = content;
|
||||
@@ -954,7 +825,7 @@ const clearAllChats = function () {
|
||||
dangerouslyUseHTMLString: true,
|
||||
showClose: true,
|
||||
closeOnClickModal: false,
|
||||
center: false
|
||||
center: false,
|
||||
})
|
||||
.then(() => {
|
||||
httpGet("/api/chat/clear")
|
||||
@@ -987,7 +858,7 @@ const loadChatHistory = function (chatId) {
|
||||
type: "reply",
|
||||
id: randString(32),
|
||||
icon: _role["icon"],
|
||||
content: _role["hello_msg"]
|
||||
content: _role["hello_msg"],
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -1000,9 +871,7 @@ const loadChatHistory = function (chatId) {
|
||||
}
|
||||
|
||||
nextTick(() => {
|
||||
document
|
||||
.getElementById("chat-box")
|
||||
.scrollTo(0, document.getElementById("chat-box").scrollHeight);
|
||||
document.getElementById("chat-box").scrollTo(0, document.getElementById("chat-box").scrollHeight);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
@@ -1027,7 +896,7 @@ const reGenerate = function (prompt) {
|
||||
type: "prompt",
|
||||
id: randString(32),
|
||||
icon: loginUser.value.avatar,
|
||||
content: text
|
||||
content: text,
|
||||
});
|
||||
store.socket.conn.send(
|
||||
JSON.stringify({
|
||||
@@ -1039,8 +908,8 @@ const reGenerate = function (prompt) {
|
||||
chat_id: chatId.value,
|
||||
content: text,
|
||||
tools: toolSelected.value,
|
||||
stream: stream.value
|
||||
}
|
||||
stream: stream.value,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
@@ -1055,11 +924,7 @@ const searchChat = function (e) {
|
||||
if (e.keyCode === 13) {
|
||||
const items = [];
|
||||
for (let i = 0; i < allChats.value.length; i++) {
|
||||
if (
|
||||
allChats.value[i].title
|
||||
.toLowerCase()
|
||||
.indexOf(chatName.value.toLowerCase()) !== -1
|
||||
) {
|
||||
if (allChats.value[i].title.toLowerCase().indexOf(chatName.value.toLowerCase()) !== -1) {
|
||||
items.push(allChats.value[i]);
|
||||
}
|
||||
}
|
||||
@@ -1073,12 +938,7 @@ const shareChat = (chat) => {
|
||||
return ElMessage.error("请先选中一个会话");
|
||||
}
|
||||
|
||||
const url =
|
||||
location.protocol +
|
||||
"//" +
|
||||
location.host +
|
||||
"/chat/export?chat_id=" +
|
||||
chat.chat_id;
|
||||
const url = location.protocol + "//" + location.host + "/chat/export?chat_id=" + chat.chat_id;
|
||||
window.open(url, "_blank");
|
||||
};
|
||||
|
||||
@@ -1102,31 +962,36 @@ const insertFile = (file) => {
|
||||
files.value.push(file);
|
||||
};
|
||||
const removeFile = (file) => {
|
||||
files.value = removeArrayItem(
|
||||
files.value,
|
||||
file,
|
||||
(v1, v2) => v1.url === v2.url
|
||||
);
|
||||
files.value = removeArrayItem(files.value, file, (v1, v2) => v1.url === v2.url);
|
||||
};
|
||||
|
||||
// 实时语音对话
|
||||
const showConversationDialog = ref(false);
|
||||
const conversationRef = ref(null);
|
||||
const dialogHeight = ref(window.innerHeight - 75);
|
||||
// const conversationRef = ref(null);
|
||||
// const dialogHeight = ref(window.innerHeight - 75);
|
||||
const frameLoaded = ref(false);
|
||||
const realtimeChat = () => {
|
||||
if (!isLogin.value) {
|
||||
store.setShowLoginDialog(true);
|
||||
return;
|
||||
}
|
||||
showConversationDialog.value = true;
|
||||
nextTick(() => {
|
||||
conversationRef.value.connect();
|
||||
});
|
||||
};
|
||||
const hangUp = () => {
|
||||
showConversationDialog.value = false;
|
||||
conversationRef.value.hangUp();
|
||||
showLoading("正在连接...");
|
||||
httpPost("/api/realtime/voice")
|
||||
.then((res) => {
|
||||
voiceChatUrl.value = res.data;
|
||||
showConversationDialog.value = true;
|
||||
closeLoading();
|
||||
})
|
||||
.catch((e) => {
|
||||
showMessageError("连接失败:" + e.message);
|
||||
closeLoading();
|
||||
});
|
||||
};
|
||||
|
||||
// const hangUp = () => {
|
||||
// showConversationDialog.value = false;
|
||||
// conversationRef.value.hangUp();
|
||||
// };
|
||||
</script>
|
||||
|
||||
<style scoped lang="stylus">
|
||||
|
||||
Reference in New Issue
Block a user