可信代码库-AI大模型创建会话\会话列表\会话详情接口对接及前端功能开发
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
<div class="home-content">
|
||||
<div v-if="startChat" ref="conversationRef" class="conversation-area">
|
||||
<template v-for="(msg, idx) in messages" :key="idx">
|
||||
<McBubble v-if="msg.from === 'user'" :content="msg.content" :align="'right'" ></McBubble>
|
||||
<McBubble v-if="msg.role === 'user'" :content="msg.content" :align="'right'" ></McBubble>
|
||||
<McBubble v-else :loading="msg.loading ?? false" >
|
||||
<div class="think-toggle-btn" @click="toggleThink(idx)">
|
||||
<div class="flex align-middle">
|
||||
@@ -132,6 +132,16 @@
|
||||
<p>内容由AI生成,无法确保准确性和完整性,仅供参考:使用条款 隐私声明</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="back-in-btn">
|
||||
<div class="back-in-time-btn" @click="toggleHistory" :class="{ 'active': isHistoryVisible }">
|
||||
<i class="icon icon-history" title="查看历史"></i>
|
||||
</div>
|
||||
<div class="back-in-time-btn" @click="handleBackInTime">
|
||||
<i class="icon icon-operation-log" title="查看文档"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ViewHistoryAside ref="viewHistoryRef" :CONV_ID="CONV_ID" :username="username" v-show="isHistoryVisible" @select-conv="handleSelectConv"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -145,11 +155,14 @@ import WarningList from './components/WarningList.vue';
|
||||
import OssDetail from './components/OssDetail.vue';
|
||||
import Other from './components/Other.vue';
|
||||
import AIList from './components/AIList.vue';
|
||||
import ViewHistoryAside from './components/ViewHistoryAside/ViewHistoryAside.vue';
|
||||
import axios from 'axios';
|
||||
import { useDiscussGetUserInfo } from '@/api/discussion/hook';
|
||||
import { Message } from 'vue-devui/message';
|
||||
|
||||
// 获取当前用户信息 & 是否登录
|
||||
const { isLogin = false, userInfo = {}} = useDiscussGetUserInfo();
|
||||
const {username=''} = userInfo
|
||||
|
||||
const inputValue = ref('');
|
||||
const startChat = ref(false);
|
||||
@@ -164,6 +177,7 @@ const agentList = ref([
|
||||
{ label: 'InsCode', value: 'inscode' },
|
||||
]);
|
||||
const selectedAgent = ref(agentList.value[0]);
|
||||
|
||||
const aiModelAvatar = {
|
||||
imgSrc: 'https://matechat.gitcode.com/logo.svg',
|
||||
width: 32,
|
||||
@@ -182,13 +196,22 @@ const inputFootIcons = [
|
||||
|
||||
const messages = ref([]);
|
||||
|
||||
// 控制 ViewHistoryAside 组件的显示状态
|
||||
const isHistoryVisible = ref(false);
|
||||
|
||||
|
||||
// 切换 ViewHistoryAside 组件的显示与隐藏
|
||||
const toggleHistory = () => {
|
||||
isHistoryVisible.value =!isHistoryVisible.value;
|
||||
};
|
||||
|
||||
const onInputIconClick = (e) => {
|
||||
if (e.icon === 'icon-at') {
|
||||
inputValue.value += `@${selectedAgent.value.label}`;
|
||||
}
|
||||
};
|
||||
|
||||
const onSubmit = (e, answer = undefined) => {
|
||||
const onSubmit = async (e, answer = undefined) => {
|
||||
if(e === '') {
|
||||
return;
|
||||
}
|
||||
@@ -197,70 +220,163 @@ const onSubmit = (e, answer = undefined) => {
|
||||
startChat.value = true;
|
||||
}
|
||||
messages.value.push({
|
||||
from: 'user',
|
||||
role: 'user',
|
||||
content: e,
|
||||
avatarPosition: 'side-right',
|
||||
avatarConfig: { ...customerAvatar },
|
||||
});
|
||||
// getAIAnswer(answer ?? e);
|
||||
// 判断是否有会话id
|
||||
if(!CONV_ID.value) {
|
||||
// 调用创建会话接口
|
||||
await createConversation()
|
||||
}
|
||||
await getAIAnswer(e,1);
|
||||
nextTick(() => {
|
||||
conversationRef.value?.scrollTo({
|
||||
top: conversationRef.value.scrollHeight,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
});
|
||||
// getAIAnswer(answer ?? e);
|
||||
getAIAnswer(e,1);
|
||||
};
|
||||
|
||||
const VITE_AI_API_HOST = (import.meta as any).env.VITE_AI_API_HOST;
|
||||
|
||||
// AI对话接口对接
|
||||
const getAIAnswer = async (content) => {
|
||||
messages.value.push({
|
||||
from: 'ai-model',
|
||||
type: '',
|
||||
content: '',
|
||||
avatarPosition: 'side-left',
|
||||
avatarConfig: { ...aiModelAvatar },
|
||||
loading: true,
|
||||
});
|
||||
debugger
|
||||
if(!username) return Message.error('请先登录!')
|
||||
if(CONV_ID.value) {
|
||||
messages.value.push({
|
||||
role: 'ai-model',
|
||||
type: '',
|
||||
content: '',
|
||||
avatarPosition: 'side-left',
|
||||
avatarConfig: { ...aiModelAvatar },
|
||||
loading: true,
|
||||
});
|
||||
|
||||
const {data} = await axios.get(VITE_AI_API_HOST + '/api/v0/chat_use_sql?question='+content);
|
||||
const {text,type} = data;
|
||||
const response = await axios.post(`${VITE_AI_API_HOST}/api/v0/chat_use_sql`, {
|
||||
userId: username, // 使用 username 作为 userId
|
||||
conversationId: CONV_ID.value,
|
||||
question: content,
|
||||
});
|
||||
|
||||
if(type==='text') {
|
||||
messages.value[messages.value.length - 1].content = text;
|
||||
messages.value[messages.value.length - 1].loading = false;
|
||||
messages.value[messages.value.length - 1].type = 'text';
|
||||
} else if(type==='df') {
|
||||
messages.value[messages.value.length - 1].content = data[type];
|
||||
messages.value[messages.value.length - 1].loading = false;
|
||||
messages.value[messages.value.length - 1].type = 'df';
|
||||
if(response.data.type) {
|
||||
const {text,type} = response.data;
|
||||
|
||||
if(type==='text') {
|
||||
messages.value[messages.value.length - 1].content = text;
|
||||
messages.value[messages.value.length - 1].loading = false;
|
||||
messages.value[messages.value.length - 1].type = 'text';
|
||||
} else if(type==='df') {
|
||||
messages.value[messages.value.length - 1].content = response.data[type];
|
||||
messages.value[messages.value.length - 1].loading = false;
|
||||
messages.value[messages.value.length - 1].type = 'df';
|
||||
}
|
||||
} else {
|
||||
Message.warning('接口异常!')
|
||||
}
|
||||
// messages.value.push({
|
||||
// from: 'ai-model',
|
||||
// content: '',
|
||||
// avatarPosition: 'side-left',
|
||||
// avatarConfig: { ...aiModelAvatar },
|
||||
// loading: true,
|
||||
// });
|
||||
|
||||
// /* 模拟流式数据返回 */
|
||||
// setTimeout(async () => {
|
||||
// messages.value.at(-1).loading = false;
|
||||
// for (let i = 0; i < content.length;) {
|
||||
// await new Promise(r => setTimeout(r, 300 * Math.random()));
|
||||
// messages.value[messages.value.length - 1].content = content.slice(0, i += Math.random() * 10);
|
||||
// nextTick(() => {
|
||||
// conversationRef.value?.scrollTo({
|
||||
// top: conversationRef.value.scrollHeight
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
// }, 1000);
|
||||
} else {
|
||||
Message.error('请先创建会话!');
|
||||
}
|
||||
// messages.value.push({
|
||||
// from: 'ai-model',
|
||||
// content: '',
|
||||
// avatarPosition: 'side-left',
|
||||
// avatarConfig: { ...aiModelAvatar },
|
||||
// loading: true,
|
||||
// });
|
||||
};
|
||||
|
||||
// /* 模拟流式数据返回 */
|
||||
// setTimeout(async () => {
|
||||
// messages.value.at(-1).loading = false;
|
||||
// for (let i = 0; i < content.length;) {
|
||||
// await new Promise(r => setTimeout(r, 300 * Math.random()));
|
||||
// messages.value[messages.value.length - 1].content = content.slice(0, i += Math.random() * 10);
|
||||
// nextTick(() => {
|
||||
// conversationRef.value?.scrollTo({
|
||||
// top: conversationRef.value.scrollHeight
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
// }, 1000);
|
||||
const viewHistoryRef = ref(null);
|
||||
// 当前会话id
|
||||
const CONV_ID = ref('');
|
||||
// 创建对话接口
|
||||
const createConversation = async () => {
|
||||
try {
|
||||
if (!username) {
|
||||
Message.error('请先登录!');
|
||||
return;
|
||||
}
|
||||
const response = await axios.post(`${VITE_AI_API_HOST}/api/createConversation`, {
|
||||
userId: username,
|
||||
});
|
||||
debugger
|
||||
const createRes = response.data;
|
||||
|
||||
if (createRes&&createRes.conversationId) {
|
||||
CONV_ID.value = createRes.conversationId;
|
||||
console.log('创建会话成功,会话ID:', CONV_ID.value);
|
||||
nextTick(() => {
|
||||
// 刷新会话列表
|
||||
if (viewHistoryRef.value) {
|
||||
viewHistoryRef.value.getQuestionHistory(); // 调用子组件方法
|
||||
}
|
||||
})
|
||||
} else {
|
||||
Message.error('创建会话失败,未获取到会话ID');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('创建会话失败:', error);
|
||||
Message.error('创建会话失败,请重试');
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelectConv = (convId: string) => {
|
||||
CONV_ID.value = convId; // 更新为选中的会话 ID
|
||||
getConversationDetail(convId); // 调用详情接口
|
||||
};
|
||||
|
||||
// 定义获取会话详情的接口(根据实际接口调整)
|
||||
const getConversationDetail = async (convId: string) => {
|
||||
try {
|
||||
const response = await axios.get(`${VITE_AI_API_HOST}/api/conversationDetail`, {
|
||||
params: {
|
||||
userId: username,
|
||||
conversationId: convId,
|
||||
},
|
||||
});
|
||||
const detail = response.data;
|
||||
// 处理详情数据(如回显消息列表)
|
||||
handleDetailResponse(detail);
|
||||
} catch (error) {
|
||||
console.error('获取会话详情失败:', error);
|
||||
Message.error('获取会话详情失败,请重试');
|
||||
}
|
||||
};
|
||||
|
||||
// 处理详情数据(示例:更新消息列表)
|
||||
const handleDetailResponse = (detail: any) => {
|
||||
// 假设接口返回消息列表为 messagesList
|
||||
messages.value = detail.messages || [];
|
||||
startChat.value = true; // 显示聊天界面
|
||||
nextTick(() => {
|
||||
conversationRef.value?.scrollTo({
|
||||
top: conversationRef.value.scrollHeight,
|
||||
behavior: 'smooth',
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const onNewConvo = () => {
|
||||
startChat.value = false;
|
||||
messages.value = [];
|
||||
createConversation()
|
||||
};
|
||||
|
||||
const onItemClick = (item) => {
|
||||
@@ -660,4 +776,51 @@ onMounted(() => {
|
||||
text-align: left;
|
||||
|
||||
}
|
||||
|
||||
|
||||
.back-in-btn {
|
||||
position: fixed;
|
||||
left: 20px;
|
||||
bottom: 20px;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
|
||||
.active {
|
||||
background-color: #f0f0f0; /* 灰色背景 */
|
||||
}
|
||||
|
||||
.active .icon {
|
||||
transform: translateY(-4px); /* 图标上移4px */
|
||||
}
|
||||
|
||||
.back-in-time-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px;
|
||||
background-color: var(--el-color-primary);
|
||||
//color: white;
|
||||
border-radius: 20px;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
z-index: 999;
|
||||
transition: all 0.3s;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.back-in-time-btn:hover {
|
||||
background-color: var(--el-color-primary-light-3);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* 响应式调整 - 移动端隐藏或调整位置 */
|
||||
@media (max-width: 768px) {
|
||||
.back-in-time-btn {
|
||||
left: 10px;
|
||||
bottom: 10px;
|
||||
padding: 6px 12px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user