Tcode平台改造升级-AI助手增加工具菜单

This commit is contained in:
fmk1023
2025-12-12 15:14:50 +08:00
parent 97dbec995f
commit ea2bd0aa5a
3 changed files with 343 additions and 3 deletions

View File

@@ -345,6 +345,19 @@ export default [
asideMenu: 'drawer' // 左侧菜单抽屉模式
}
},
{
path: '/model-chat',
name: 'ModelChat',
component: () => import('@/views/Jyh/ModelChat/index.vue'),
meta: {
title: 'ModelChat',
reportTitle: 'ModelChat',
className: 'w-full min-w-full',
hiddenFooter: true,
hasMobile: true,
asideMenu: 'drawer' // 左侧菜单抽屉模式
}
},
{
path: '/LinePage',
name: 'LinePage',

View File

@@ -131,6 +131,7 @@ import {
fetchDeleteConversation,
fetchToggleConversationCollect
} from '@/api/jyh';
import {useRouter} from "vue-router";
// --- Props & Emits ---
const props = defineProps(['username', 'CONV_ID']);
@@ -200,11 +201,19 @@ const handleSelect = (item) => {
if (item.isEditing) return; // 编辑中不触发选中
emit('select-conv', item.conversationId);
};
// 4. 菜单点击
const router = useRouter();
// 4. 菜单点击 - 修改为跳转逻辑
const handleMenuClick = (menu) => {
console.log('点击菜单:', menu.title);
// 路由跳转或功能触发逻辑
// 使用 router.push 跳转,并通过 query 传递参数
router.push({
path: '/model-chat', // 对应路由中的 path
query: {
id: menu.id,
title: menu.title
}
});
};
// 5. 编辑/重命名逻辑

View File

@@ -0,0 +1,318 @@
<template>
<div class="model-chat-container">
<div class="chat-header">
<div class="left">
<d-icon name="icon-arrow-left" class="back-icon" @click="goBack"></d-icon>
<div class="model-info">
<span class="title">{{ currentTitle }}</span>
<span class="subtitle">智能辅助模型</span>
</div>
</div>
<div class="right">
<d-button variant="text" icon="icon-delete" @click="clearHistory">清空</d-button>
</div>
</div>
<div class="chat-content" ref="scrollRef">
<div v-if="messages.length === 0" class="empty-placeholder">
<d-icon name="icon-robot" size="48px" color="#ccc"></d-icon>
<p>我是 {{ currentTitle }} 助手请告诉我您的需求</p>
</div>
<div v-for="(msg, index) in messages" :key="index" :class="['message-row', msg.role]">
<div class="avatar">
<d-icon :name="msg.role === 'user' ? 'icon-user' : 'icon-robot'" size="24px"></d-icon>
</div>
<div class="message-bubble">
<div class="text">{{ msg.content }}</div>
<div class="time" v-if="msg.time">{{ msg.time }}</div>
</div>
</div>
<div v-if="loading" class="message-row ai">
<div class="avatar"><d-icon name="icon-robot" size="24px"></d-icon></div>
<div class="message-bubble loading">
<span>正在思考...</span>
</div>
</div>
</div>
<div class="chat-footer">
<div class="input-wrapper">
<d-textarea
v-model="inputText"
placeholder="请输入您的问题..."
:rows="2"
class="chat-input"
@keydown.enter.prevent="handleSend"
></d-textarea>
<d-button
class="send-btn"
variant="solid"
:disabled="loading || !inputText.trim()"
@click="handleSend"
>
<d-icon name="icon-publish" color="#fff"></d-icon>
</d-button>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, nextTick } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useTimeFormat } from '@/utils/hooks/useTimeFormat'; // 假设你在这个路径有工具
const route = useRoute();
const router = useRouter();
const { formatTime } = useTimeFormat();
// 状态
const currentTitle = ref('');
const currentModelId = ref('');
const inputText = ref('');
const loading = ref(false);
const scrollRef = ref(null);
const messages = ref([]);
// 初始化
onMounted(() => {
// 从路由参数获取当前选中的功能信息
currentTitle.value = route.query.title || '智能对话';
currentModelId.value = route.query.id || 'default';
// 模拟一条欢迎语
messages.value.push({
role: 'ai',
content: `您好,欢迎使用 ${currentTitle.value} 功能,有什么可以帮您?`,
time: getCurrentTime()
});
});
// 获取当前时间
const getCurrentTime = () => {
const now = new Date();
return `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`;
};
// 返回上一页
const goBack = () => {
router.back();
};
// 清空历史
const clearHistory = () => {
messages.value = [];
};
// 滚动到底部
const scrollToBottom = async () => {
await nextTick();
if (scrollRef.value) {
scrollRef.value.scrollTop = scrollRef.value.scrollHeight;
}
};
// 发送消息
const handleSend = async () => {
const text = inputText.value.trim();
if (!text || loading.value) return;
// 1. 添加用户消息
messages.value.push({
role: 'user',
content: text,
time: getCurrentTime()
});
inputText.value = '';
scrollToBottom();
// 2. 模拟请求后端 API
loading.value = true;
try {
// TODO: 这里替换为你真实的 API 调用,传入 currentModelId.value
// const res = await fetchModelChat({ model: currentModelId.value, prompt: text });
// 模拟延迟响应
setTimeout(() => {
messages.value.push({
role: 'ai',
content: `这是针对“${currentTitle.value}”功能的模拟回复:您发送了“${text}”。`,
time: getCurrentTime()
});
loading.value = false;
scrollToBottom();
}, 1000);
} catch (error) {
messages.value.push({
role: 'ai',
content: '服务暂时不可用,请稍后再试。',
time: getCurrentTime()
});
loading.value = false;
scrollToBottom();
}
};
</script>
<style scoped lang="scss">
.model-chat-container {
display: flex;
flex-direction: column;
height: 100vh; /* 或者 100% 视父容器而定 */
background-color: #f5f7fa;
.chat-header {
height: 60px;
background: #fff;
border-bottom: 1px solid #eee;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
.left {
display: flex;
align-items: center;
gap: 12px;
.back-icon {
cursor: pointer;
padding: 4px;
&:hover { background: #f0f0f0; border-radius: 4px; }
}
.model-info {
display: flex;
flex-direction: column;
.title { font-weight: bold; font-size: 16px; color: #333; }
.subtitle { font-size: 12px; color: #999; }
}
}
}
.chat-content {
flex: 1;
overflow-y: auto;
padding: 20px;
display: flex;
flex-direction: column;
gap: 20px;
.empty-placeholder {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #999;
gap: 10px;
}
.message-row {
display: flex;
gap: 12px;
max-width: 80%;
.avatar {
width: 40px;
height: 40px;
border-radius: 50%;
background: #e0e0e0;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.message-bubble {
padding: 12px 16px;
border-radius: 8px;
position: relative;
font-size: 14px;
line-height: 1.5;
.time {
font-size: 10px;
color: rgba(0,0,0,0.4);
margin-top: 4px;
text-align: right;
}
}
/* AI 样式 */
&.ai {
align-self: flex-start;
.avatar { background: #e6f7ff; color: #1890ff; }
.message-bubble {
background: #fff;
border: 1px solid #e8e8e8;
color: #333;
border-top-left-radius: 0;
}
}
/* 用户样式 */
&.user {
align-self: flex-end;
flex-direction: row-reverse;
.avatar { background: #fff0f6; color: #eb2f96; }
.message-bubble {
background: #1890ff;
color: #fff;
border-top-right-radius: 0;
.time { color: rgba(255,255,255,0.7); }
}
}
}
}
.chat-footer {
background: #fff;
padding: 15px 20px;
border-top: 1px solid #eee;
.input-wrapper {
position: relative;
display: flex;
align-items: flex-end;
gap: 10px;
border: 1px solid #d9d9d9;
border-radius: 8px;
padding: 8px;
background: #fff;
transition: border-color 0.3s;
&:focus-within {
border-color: #1890ff;
}
.chat-input {
flex: 1;
border: none;
box-shadow: none;
padding: 4px;
/* 去除 DevUI textarea 默认样式 */
::v-deep .devui-textarea {
border: none;
box-shadow: none;
}
}
.send-btn {
width: 36px;
height: 36px;
padding: 0;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
}
}
}
}
</style>