Compare commits
3 Commits
feature/ds
...
feature/zo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
011c28d945 | ||
|
|
ff5355855f | ||
|
|
aff9233ce2 |
64
src/renderer/api/ConversationApi.ts
Normal file
64
src/renderer/api/ConversationApi.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
/* eslint-disable */
|
||||
// @ts-ignore
|
||||
import { getRequest, postRequest, ResponseModel } from '@utils/request'
|
||||
|
||||
/** 创建会话 创建会话创建会话 GET /agent/assistant/createConversation */
|
||||
export interface CreateConversationResponse {
|
||||
conversationId: string
|
||||
}
|
||||
|
||||
export const createConversation = async () => {
|
||||
const res: ResponseModel = await getRequest('/agent/assistant/createConversation')
|
||||
return res.data as CreateConversationResponse
|
||||
}
|
||||
|
||||
/** 获取会话列表 获取会话列表获取会话列表 POST /agent/assistant/conversationList */
|
||||
export interface ConversationListRequest {
|
||||
pageSize: number
|
||||
pageNum: number
|
||||
conversationId?: string
|
||||
}
|
||||
|
||||
export interface ConversationListResponse {
|
||||
records: Array<ConversationListRecords>
|
||||
total: number
|
||||
size: number
|
||||
current: number
|
||||
optimizeCountSql: boolean
|
||||
searchCount: boolean
|
||||
}
|
||||
|
||||
export interface ConversationListRecords {
|
||||
conversationTitle: string
|
||||
conversationId: string
|
||||
}
|
||||
|
||||
export interface ConversationMessageListResponse {
|
||||
records: Array<ConversationMessageListRecords>
|
||||
total: number
|
||||
size: number
|
||||
current: number
|
||||
optimizeCountSql: boolean
|
||||
searchCount: boolean
|
||||
}
|
||||
|
||||
export interface ConversationMessageListRecords {
|
||||
messageId: string
|
||||
conversationId: string
|
||||
messageType: string
|
||||
messageContent: string
|
||||
messageDisplay: string
|
||||
messageSenderId: string
|
||||
messageSenderRole: string
|
||||
messageTime: string
|
||||
}
|
||||
|
||||
export const getConversationList = async (params: ConversationListRequest) => {
|
||||
const res: ResponseModel = await postRequest('/agent/assistant/conversationList', params)
|
||||
return res.data as ConversationListResponse
|
||||
}
|
||||
|
||||
export const conversationMessageList = async (params: ConversationListRequest) => {
|
||||
const res: ResponseModel = await postRequest('/agent/assistant/conversationMessageList', params)
|
||||
return res.data as ConversationMessageListResponse
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<header class="title-bar flex items-start justify-between h-[40px]">
|
||||
<header class="flex items-start justify-between h-[40px]">
|
||||
<div class="title-bar-main flex-auto">
|
||||
<slot>{{ title ?? '' }}</slot>
|
||||
</div>
|
||||
@@ -69,8 +69,4 @@ function handleClose() {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.title-bar {
|
||||
background-color: rgba(239, 246, 255, 0.8);
|
||||
}
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div class="bg h-screen flex flex-col">
|
||||
<div class="bg-color h-screen flex flex-col">
|
||||
<header-bar>
|
||||
<drag-region class="w-full" />
|
||||
</header-bar>
|
||||
|
||||
<main class="bg-[#f7f9fc] box-border w-full h-[calc(100vh-40px)] flex pt-[8px] pb-[8px] pl-[8px] ">
|
||||
<main class="box-border w-full h-[calc(100vh-40px)] flex pt-[8px] pb-[8px] pl-[8px] ">
|
||||
<div class="flex-1 flex">
|
||||
<slot />
|
||||
</div>
|
||||
@@ -17,3 +17,8 @@
|
||||
<script setup lang="ts" name="Layout">
|
||||
import SideMenus from '@renderer/components/SideMenus/index.vue'
|
||||
</script>
|
||||
<style scoped>
|
||||
.bg-color {
|
||||
background: linear-gradient(180deg, #EFF6FF 0%, #F5F7FA 40%);
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,7 @@
|
||||
import axios from 'axios'
|
||||
import cache from '@utils/cache'
|
||||
import errorCode from '@constant/errorCode'
|
||||
import { ElNotification , ElMessageBox, ElMessage } from 'element-plus'
|
||||
import { ElNotification, ElMessageBox, ElMessage } from 'element-plus'
|
||||
import { Session } from '@renderer/utils/storage'
|
||||
import { tansParams } from '@utils/tansParams'
|
||||
|
||||
@@ -87,12 +87,13 @@ instance.interceptors.request.use(
|
||||
// 添加响应拦截器
|
||||
instance.interceptors.response.use(
|
||||
(res) => {
|
||||
console.log(`🚀 ~ response: \n url:${res.config.url} \n params:${JSON.stringify(res.config.params)} \n data:\n ${JSON.stringify(res.data)}`)
|
||||
// 未设置状态码则默认成功状态
|
||||
const code = res.data.code || 200
|
||||
// 获取错误信息
|
||||
const msg = (errorCode as any)[code] || res.data.msg || errorCode['default']
|
||||
// 二进制数据则直接返回
|
||||
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
|
||||
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
|
||||
return res.data
|
||||
}
|
||||
if (code === 401) {
|
||||
@@ -103,10 +104,10 @@ instance.interceptors.response.use(
|
||||
// useUserStore().logOut().then(() => {
|
||||
// location.href = '/index'
|
||||
// })
|
||||
}).catch(() => {
|
||||
isRelogin.show = false
|
||||
})
|
||||
}
|
||||
}).catch(() => {
|
||||
isRelogin.show = false
|
||||
})
|
||||
}
|
||||
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
|
||||
} else if (code === 500) {
|
||||
ElMessage({ message: msg, type: 'error' })
|
||||
@@ -118,7 +119,7 @@ instance.interceptors.response.use(
|
||||
ElNotification.error({ title: msg })
|
||||
return Promise.reject('error')
|
||||
} else {
|
||||
return Promise.resolve(res.data)
|
||||
return Promise.resolve(res.data)
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
@@ -138,4 +139,34 @@ instance.interceptors.response.use(
|
||||
}
|
||||
)
|
||||
|
||||
// 封装基于 request 的 POST 请求(
|
||||
export const postRequest = <ResponseModel>(url: string, data?: any, options?: any): Promise<ResponseModel> => {
|
||||
return instance.request({
|
||||
url,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
data,
|
||||
...(options || {}),
|
||||
}) as Promise<ResponseModel>
|
||||
}
|
||||
|
||||
// 封装基于 request 的 GET 请求
|
||||
export const getRequest = <ResponseModel>(url: string, params?: any, options?: any): Promise<ResponseModel> => {
|
||||
return instance.request({
|
||||
url,
|
||||
method: 'GET',
|
||||
params,
|
||||
...(options || {}),
|
||||
}) as Promise<ResponseModel>
|
||||
}
|
||||
|
||||
export default instance
|
||||
|
||||
/// 响应模型
|
||||
export interface ResponseModel {
|
||||
code: number;
|
||||
msg: string | null;
|
||||
data: any | null;
|
||||
};
|
||||
@@ -20,7 +20,7 @@
|
||||
<ChatAvatar v-if="msg.messageRole === MessageRole.AI" :src="aiAvatar" />
|
||||
|
||||
<!-- 自己 发的消息 -->
|
||||
<ChatRoleMe v-if="msg.messageRole === MessageRole.ME" :msg="msg" >
|
||||
<ChatRoleMe v-if="msg.messageRole === MessageRole.ME" :msg="msg">
|
||||
<template #header>
|
||||
<!-- 名字和时间 -->
|
||||
<ChatNameTime :showReverse="true" />
|
||||
@@ -46,8 +46,8 @@
|
||||
</template>
|
||||
</ChatRoleAI>
|
||||
|
||||
<!-- User avatar -->
|
||||
<ChatAvatar v-if="msg.messageRole === MessageRole.ME" :src="userAvatar" />
|
||||
<!-- User avatar -->
|
||||
<ChatAvatar v-if="msg.messageRole === MessageRole.ME" :src="userAvatar" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -88,10 +88,13 @@ import { Session } from '../../utils/storage';
|
||||
|
||||
import userAvatar from '@assets/images/login/user_icon.png';
|
||||
import aiAvatar from '@assets/images/login/blue_logo.png';
|
||||
import { createConversation, conversationMessageList } from '../../api/ConversationApi';
|
||||
import { ElMessage, ElLoading } from 'element-plus'
|
||||
|
||||
// 支持外部通过 prop 控制是否为引导页
|
||||
const props = defineProps({
|
||||
guide: { type: Boolean, default: true }
|
||||
guide: { type: Boolean, default: true },
|
||||
conversationId: { type: String, default: '' }
|
||||
});
|
||||
const emit = defineEmits(['update:guide']);
|
||||
|
||||
@@ -108,6 +111,7 @@ watch(isGuidePage, (v) => {
|
||||
if (v) {
|
||||
// 当切换到引导页时,重置/清理会话状态
|
||||
resetConversation();
|
||||
createConversationRequest();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -121,10 +125,19 @@ const inputMessage = ref("");
|
||||
/// 发送消息中标志
|
||||
const isSendingMessage = ref(false);
|
||||
|
||||
/// agentId 首页接口中获取 1953462165250859010
|
||||
const agentId = ref("1");
|
||||
/// agentId 首页接口中获取 1953462165250859011
|
||||
const agentId = ref("1953462165250859011");
|
||||
/// 会话ID 历史数据接口中获取
|
||||
const conversationId = ref("");
|
||||
const conversationId = ref(props.conversationId);
|
||||
|
||||
// 监听 conversationId prop 变化,只有当有值时(选择历史消息)才请求消息列表
|
||||
watch(() => props.conversationId, (newId) => {
|
||||
if (newId) {
|
||||
conversationId.value = newId;
|
||||
loadConversationMessages(newId);
|
||||
}
|
||||
});
|
||||
|
||||
// 会话进行中标志
|
||||
const isSessionActive = ref(false);
|
||||
/// 指令通用消息类型
|
||||
@@ -261,11 +274,12 @@ onMounted(() => {
|
||||
});
|
||||
|
||||
// token存在,初始化数据
|
||||
const initHandler = () => {
|
||||
const initHandler = async () => {
|
||||
console.log("initHandler");
|
||||
const token = getAccessToken();
|
||||
if (!token) return;
|
||||
initWebSocket();
|
||||
await createConversationRequest();
|
||||
await initWebSocket();
|
||||
};
|
||||
|
||||
const getAccessToken = () => {
|
||||
@@ -280,6 +294,38 @@ const checkToken = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
// 调用接口创建新会话
|
||||
const createConversationRequest = async (): Promise<string | null> => {
|
||||
const res = await createConversation();
|
||||
if (res && res.conversationId) {
|
||||
conversationId.value = res.conversationId;
|
||||
console.log("创建新会话,ID:", conversationId.value);
|
||||
return res.conversationId;
|
||||
} else {
|
||||
console.log("创建会话失败,接口返回异常");
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// 加载历史会话消息
|
||||
const loadConversationMessages = async (convId: string) => {
|
||||
try {
|
||||
const res = await conversationMessageList({ conversationId: convId, pageSize: 50, pageNum: 1 });
|
||||
// 将消息转换为 ChatMessage 格式
|
||||
chatMsgList.value = res.records.map((msg: any) => ({
|
||||
messageId: msg.messageId,
|
||||
messageRole: msg.messageSenderRole === 'user' ? MessageRole.ME : MessageRole.AI,
|
||||
messageContent: msg.messageContent,
|
||||
finished: true, // 历史消息已完成
|
||||
}));
|
||||
console.log("加载历史消息:", chatMsgList.value);
|
||||
// 加载历史消息后滚动到底部
|
||||
nextTick(() => scrollToBottom());
|
||||
} catch (error) {
|
||||
console.error("加载历史消息失败:", error);
|
||||
}
|
||||
};
|
||||
|
||||
/// =============对话↓================
|
||||
// 初始化WebSocket
|
||||
const initWebSocket = async () => {
|
||||
@@ -475,10 +521,7 @@ const sendMessage = async (message: string, isInstruct: boolean = false) => {
|
||||
if (!isWsConnected()) {
|
||||
console.log("WebSocket未连接,尝试重新连接...");
|
||||
// 显示加载提示
|
||||
// uni.showLoading({
|
||||
// title: "正在连接服务器...",
|
||||
// });
|
||||
|
||||
const loadingInstance = ElLoading.service({ fullscreen: true, text: '正在连接服务器...' });
|
||||
// 尝试重新初始化WebSocket连接
|
||||
try {
|
||||
await initWebSocket();
|
||||
@@ -487,31 +530,22 @@ const sendMessage = async (message: string, isInstruct: boolean = false) => {
|
||||
|
||||
// 检查连接是否成功建立
|
||||
if (!isWsConnected()) {
|
||||
// uni.hideLoading();
|
||||
// uni.showToast({
|
||||
// title: "连接服务器失败,请稍后重试",
|
||||
// icon: "none",
|
||||
// });
|
||||
loadingInstance.close();
|
||||
ElMessage({ message: '连接服务器失败,请稍后重试', type: 'error' })
|
||||
console.error("重新连接WebSocket后仍未连接成功");
|
||||
return;
|
||||
}
|
||||
// uni.hideLoading();
|
||||
loadingInstance.close();
|
||||
} catch (error) {
|
||||
loadingInstance.close();
|
||||
console.error("重新连接WebSocket失败:", error);
|
||||
// uni.hideLoading();
|
||||
// uni.showToast({
|
||||
// title: "连接服务器失败,请稍后重试",
|
||||
// icon: "none",
|
||||
// });
|
||||
ElMessage({ message: '连接服务器失败,请稍后重试', type: 'error' })
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (isSessionActive.value) {
|
||||
// uni.showToast({
|
||||
// title: "请等待当前回复完成",
|
||||
// icon: "none",
|
||||
// });
|
||||
ElMessage({ message: '当前会话正在进行中,请等待回复完成', type: 'warning' })
|
||||
console.warn("当前会话正在进行中,请等待回复完成");
|
||||
return;
|
||||
}
|
||||
@@ -801,5 +835,4 @@ const resetConversation = () => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
@@ -5,130 +5,79 @@
|
||||
<div class="font-bold text-gray-80">YINIAN</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center m-2 bg-white rounded-lg p-2.5 border-[##E5E8EE] shadow-sm text-center" @click="addNewChat">
|
||||
<div class="flex justify-center m-2 bg-white rounded-lg p-2.5 border-[#E5E8EE] shadow-sm text-center"
|
||||
@click="addNewChat">
|
||||
<RiAddLine /> 新对话
|
||||
</div>
|
||||
|
||||
<div class="overflow-y-auto p-2 ">
|
||||
<section v-for="(group, index) in groups" :key="group.title" class="mb-3">
|
||||
<div class="flex items-center justify-between text-sm text-gray-500" @click="selectGroupKey(index)">
|
||||
<span>{{ group.title }}</span>
|
||||
<RiArrowDownSLine v-show="group.selected" color="rgba(153,160,174,1)" />
|
||||
<RiArrowRightSLine v-show="!group.selected" color="rgba(153,160,174,1)" />
|
||||
</div>
|
||||
|
||||
<ul class="list-none mt-1.5" v-if="group.selected">
|
||||
<li v-for="item in group.items" :key="item.id" @click="selectedHistoryMessage(item.id)" :class="[
|
||||
<ul class="list-none">
|
||||
<li v-for="item in groups" :key="item.conversationId" @click="selectedHistoryMessage(item.conversationId)"
|
||||
:class="[
|
||||
'flex items-center gap-2 p-2 text-gray-600 rounded-lg cursor-pointer transition-colors',
|
||||
item.id === selectedId ? 'bg-white shadow-sm border-[##E5E8EE]' : 'hover:bg-gray-50'
|
||||
item.conversationId === selectedConversationId ? 'bg-white shadow-sm border-[#E5E8EE] py-1.5 relative z-10' : 'hover:bg-gray-200'
|
||||
]">
|
||||
<span class="w-2 h-2 rounded-full bg-[#BEDBFF] flex-none"></span>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="truncate text-sm">{{ item.title }}</div>
|
||||
</div>
|
||||
<button v-if="item.id === selectedId"
|
||||
class="bg-transparent border-0 text-gray-500 text-lg px-1 py-0">…</button>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
<span class="w-2 h-2 rounded-full bg-[#BEDBFF] flex-none"></span>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="truncate text-sm">{{ item.conversationId }}</div>
|
||||
</div>
|
||||
<button v-if="item.conversationId === selectedConversationId"
|
||||
class="bg-transparent border-0 text-gray-500 text-lg px-1 py-0">…</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, defineEmits } from 'vue'
|
||||
import { ref, onMounted, defineEmits } from 'vue'
|
||||
import { RiAddLine, RiArrowRightSLine, RiArrowDownSLine } from '@remixicon/vue'
|
||||
import { getConversationList } from '../../api/ConversationApi';
|
||||
|
||||
interface HistoryMessage {
|
||||
conversationId: string;
|
||||
conversationTitle: string;
|
||||
}
|
||||
|
||||
/// 记录选择的历史消息ID
|
||||
const selectedId = ref<number | null>(2)
|
||||
const selectedConversationId = ref<string>('')
|
||||
|
||||
/// 历史消息分组数据
|
||||
const groups = ref([
|
||||
{
|
||||
title: '近3天',
|
||||
selected: false,
|
||||
items: [
|
||||
{ id: 1, title: '这是一段对话' },
|
||||
{ id: 2, title: '这是一段对话' },
|
||||
{ id: 3, title: '这是一段对话这是一段对话这是一段对话' },
|
||||
{ id: 4, title: '这是一段对话这是一段对话' },
|
||||
{ id: 5, title: '这是一段对话这是一段对话' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '近7天',
|
||||
selected: false,
|
||||
items: [
|
||||
{ id: 6, title: '这是一段对话' },
|
||||
{ id: 7, title: '这是一段对话' },
|
||||
{ id: 8, title: '这是一段对话这是一段对话' },
|
||||
{ id: 9, title: '这是一段对话这是一段对话' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '近15天',
|
||||
selected: false,
|
||||
items: [
|
||||
{ id: 10, title: '这是一段对话' },
|
||||
{ id: 11, title: '这是一段对话' },
|
||||
{ id: 12, title: '这是一段对话这是一段对话这是一段对话' },
|
||||
{ id: 13, title: '这是一段对话这是一段对话' },
|
||||
{ id: 14, title: '这是一段对话这是一段对话' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '近30天',
|
||||
selected: false,
|
||||
items: [
|
||||
{ id: 15, title: '这是一段对话' },
|
||||
{ id: 16, title: '这是一段对话' },
|
||||
{ id: 17, title: '这是一段对话这是一段对话' },
|
||||
{ id: 18, title: '这是一段对话这是一段对话' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '近60天',
|
||||
selected: false,
|
||||
items: [
|
||||
{ id: 19, title: '这是一段对话' },
|
||||
{ id: 20, title: '这是一段对话' },
|
||||
{ id: 21, title: '这是一段对话这是一段对话这是一段对话' },
|
||||
{ id: 22, title: '这是一段对话这是一段对话' },
|
||||
{ id: 23, title: '这是一段对话这是一段对话' }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: '近90天',
|
||||
selected: false,
|
||||
items: [
|
||||
{ id: 24, title: '这是一段对话' },
|
||||
{ id: 25, title: '这是一段对话' },
|
||||
{ id: 26, title: '这是一段对话这是一段对话' },
|
||||
{ id: 27, title: '这是一段对话这是一段对话' }
|
||||
]
|
||||
}
|
||||
])
|
||||
const groups = ref<Array<HistoryMessage>>([])
|
||||
|
||||
/// 选择历史消息
|
||||
const selectedHistoryMessage = (id: number) => {
|
||||
selectedId.value = id
|
||||
}
|
||||
|
||||
/// 选择分组展开/收起
|
||||
const selectGroupKey = (index: number) => {
|
||||
groups.value.forEach((group, i) => {
|
||||
if (i === index) {
|
||||
group.selected = !group.selected
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// TODO: 添加新对话
|
||||
const emit = defineEmits(['new-chat'])
|
||||
/// 定义事件
|
||||
const emit = defineEmits(['new-chat', 'select-chat'])
|
||||
|
||||
/// 添加新对话
|
||||
const addNewChat = () => {
|
||||
console.log('add new chat')
|
||||
// 触发新对话事件
|
||||
emit('new-chat')
|
||||
// 清空选择的历史消息ID
|
||||
selectedConversationId.value = ''
|
||||
// 获取最新的历史会话列表
|
||||
getHistoryConversationList()
|
||||
}
|
||||
|
||||
/// 选择历史消息
|
||||
const selectedHistoryMessage = (conversationId: string) => {
|
||||
selectedConversationId.value = conversationId
|
||||
emit('select-chat', conversationId)
|
||||
}
|
||||
|
||||
/// 页面加载时获取历史会话列表
|
||||
onMounted(() => {
|
||||
getHistoryConversationList()
|
||||
})
|
||||
|
||||
/// 获取历史会话列表
|
||||
const getHistoryConversationList = async () => {
|
||||
const list = await getConversationList({ pageSize: 20, pageNum: 1 })
|
||||
if (!list || !list.records) return;
|
||||
groups.value.push(...list.records.map((item: any) => ({
|
||||
conversationId: item.conversationId,
|
||||
conversationTitle: item.conversationTitle
|
||||
})))
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<layout>
|
||||
<div class="flex h-full w-full flex-col md:flex-row ">
|
||||
<ChatHistory class="flex-none w-50" @new-chat="guide = true" />
|
||||
<div class="flex h-full w-full flex-col md:flex-row">
|
||||
<ChatHistory class="flex-none w-50" @new-chat="guide = true" @select-chat="handleSelectChat" />
|
||||
<div class="flex-1 mr-2 overflow-hidden bg-white rounded-xl">
|
||||
<ChatBox v-model:guide="guide" />
|
||||
<ChatBox v-model:guide="guide" :conversationId="selectedConversationId" />
|
||||
</div>
|
||||
<TaskList />
|
||||
</div>
|
||||
@@ -15,6 +15,15 @@ import TaskList from '@renderer/components/TaskList/index.vue'
|
||||
import ChatHistory from './ChatHistory.vue'
|
||||
import ChatBox from './ChatBox.vue'
|
||||
import { ref } from 'vue'
|
||||
/// 是否显示引导页
|
||||
const guide = ref(true)
|
||||
/// 选择的历史会话ID
|
||||
const selectedConversationId = ref('')
|
||||
|
||||
/// 选择历史会话
|
||||
const handleSelectChat = (conversationId: string) => {
|
||||
guide.value = false;
|
||||
selectedConversationId.value = conversationId;
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user