web/src/views/AIAgentView.vue
2025-04-25 11:22:36 +08:00

411 lines
9.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { ref } from 'vue'
const activeAgent = ref('crypto-doctor')
const userInput = ref('')
const chatHistory = ref([
{
role: 'assistant',
content:
'你好!我是加密项目医生,可以帮你分析任何加密项目的健康状况。请告诉我你想了解的项目名称或合约地址。',
},
])
const sendMessage = () => {
if (!userInput.value.trim()) return
// 添加用户消息到历史记录
chatHistory.value.push({
role: 'user',
content: userInput.value,
})
// 模拟AI回复实际项目中这里应该调用后端API
setTimeout(() => {
if (activeAgent.value === 'crypto-doctor') {
chatHistory.value.push({
role: 'assistant',
content:
'我正在分析这个项目,这可能需要一些时间。基于初步分析,我建议关注以下几个方面:\n\n1. 团队背景和透明度\n2. 代码审计情况\n3. 项目活跃度和发展\n4. 代币分配机制\n5. 市场流动性\n\n您想了解哪方面的详细信息',
})
} else {
chatHistory.value.push({
role: 'assistant',
content:
'根据最近的市场数据和技术指标分析,我注意到该代币的趋势如下:\n\n- 价格走势:呈现上升通道,但接近阻力位\n- 交易量:逐渐增加,表明兴趣上升\n- RSI指标当前处于60左右未进入超买区域\n- MACD短期均线刚刚穿过长期均线形成黄金交叉\n\n需要注意的是市场可能受到宏观经济因素的影响。您希望了解更多具体的技术指标分析吗',
})
}
userInput.value = ''
}, 1000)
}
const switchAgent = (agent: string) => {
activeAgent.value = agent
chatHistory.value = [
{
role: 'assistant',
content:
agent === 'crypto-doctor'
? '你好!我是加密项目医生,可以帮你分析任何加密项目的健康状况。请告诉我你想了解的项目名称或合约地址。'
: '你好!我是币种技术分析师,可以为你提供币种的技术面分析和趋势预测。请告诉我你想分析的币种名称或代号。',
},
]
}
</script>
<template>
<div class="ai-agent-view">
<h1 class="page-title">AI Agent</h1>
<p class="page-description">智能AI助手为您提供加密项目分析和技术指标解读</p>
<div class="agent-container">
<div class="agent-sidebar">
<div class="agent-selector">
<button
class="agent-option"
:class="{ active: activeAgent === 'crypto-doctor' }"
@click="switchAgent('crypto-doctor')"
>
<span class="agent-icon">🔍</span>
<div class="agent-info">
<h3>加密项目医生</h3>
<p>项目风险分析与评估</p>
</div>
</button>
<button
class="agent-option"
:class="{ active: activeAgent === 'technical-analysis' }"
@click="switchAgent('technical-analysis')"
>
<span class="agent-icon">📊</span>
<div class="agent-info">
<h3>币种技术分析</h3>
<p>技术指标与趋势预测</p>
</div>
</button>
</div>
<div class="sidebar-info">
<h3>使用提示</h3>
<ul class="tips-list">
<li>提供详细的项目信息以获得更准确的分析</li>
<li>可以直接输入合约地址进行分析</li>
<li>分析结果仅供参考不构成投资建议</li>
</ul>
</div>
</div>
<div class="chat-container">
<div class="chat-header">
<h2>{{ activeAgent === 'crypto-doctor' ? '加密项目医生' : '币种技术分析' }}</h2>
</div>
<div class="chat-messages">
<div
v-for="(message, index) in chatHistory"
:key="index"
class="message"
:class="{
'user-message': message.role === 'user',
'ai-message': message.role === 'assistant',
}"
>
<div class="message-content">
<p v-for="(line, i) in message.content.split('\n')" :key="i">
{{ line }}
</p>
</div>
</div>
</div>
<div class="chat-input">
<input
type="text"
v-model="userInput"
@keyup.enter="sendMessage"
placeholder="输入项目名称、合约地址或问题..."
class="input-field"
/>
<button class="send-button" @click="sendMessage">发送</button>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.ai-agent-view {
width: 100%;
padding: 0;
}
.page-title {
font-size: 2.2rem;
font-weight: 700;
margin-bottom: 0.5rem;
}
.page-description {
color: var(--color-text-secondary);
margin-bottom: 2rem;
}
.agent-container {
display: flex;
gap: 1.5rem;
height: calc(80vh - 100px);
min-height: 500px;
width: 100%;
}
.agent-sidebar {
width: 300px;
background-color: var(--color-bg-card);
border-radius: var(--border-radius);
padding: 1.5rem;
display: flex;
flex-direction: column;
border: 1px solid var(--color-border);
}
.agent-selector {
display: flex;
flex-direction: column;
gap: 1rem;
margin-bottom: 2rem;
}
.agent-option {
display: flex;
align-items: center;
gap: 0.8rem;
padding: 1rem;
border-radius: var(--border-radius);
background-color: var(--color-bg-primary);
border: 1px solid transparent;
cursor: pointer;
transition: all 0.2s ease;
text-align: left;
}
.agent-option:hover {
border-color: var(--color-border);
}
.agent-option.active {
border-color: var(--color-accent);
background-color: var(--color-accent-light);
}
.agent-icon {
font-size: 1.8rem;
}
.agent-info h3 {
font-size: 1rem;
font-weight: 600;
margin-bottom: 0.2rem;
color: rgba(255, 255, 255, 0.9);
}
.agent-info p {
font-size: 0.9rem;
color: var(--color-text-secondary);
}
.agent-option.active .agent-info h3 {
color: var(--color-accent-hover);
}
.sidebar-info {
margin-top: auto;
padding-top: 1rem;
border-top: 1px solid var(--color-border);
}
.sidebar-info h3 {
font-size: 1rem;
margin-bottom: 0.8rem;
}
.tips-list {
list-style-type: none;
padding: 0;
}
.tips-list li {
color: var(--color-text-secondary);
font-size: 0.9rem;
margin-bottom: 0.5rem;
padding-left: 1rem;
position: relative;
}
.tips-list li::before {
content: '•';
position: absolute;
left: 0;
color: var(--color-accent);
}
.chat-container {
flex: 1;
display: flex;
flex-direction: column;
background-color: var(--color-bg-card);
border-radius: var(--border-radius);
overflow: hidden;
border: 1px solid var(--color-border);
}
.chat-header {
padding: 1rem 1.5rem;
border-bottom: 1px solid var(--color-border);
}
.chat-header h2 {
font-size: 1.2rem;
font-weight: 600;
}
.chat-messages {
flex: 1;
overflow-y: auto;
padding: 1.5rem;
display: flex;
flex-direction: column;
gap: 1rem;
}
.message {
max-width: 80%;
padding: 1rem;
border-radius: var(--border-radius);
position: relative;
}
.user-message {
align-self: flex-end;
background-color: var(--color-accent);
color: white;
}
.ai-message {
align-self: flex-start;
background-color: var(--color-bg-primary);
border: 1px solid var(--color-border);
}
.message-content p {
margin-bottom: 0.5rem;
}
.message-content p:last-child {
margin-bottom: 0;
}
.chat-input {
display: flex;
padding: 1rem 1.5rem;
border-top: 1px solid var(--color-border);
}
.input-field {
flex: 1;
padding: 0.8rem 1rem;
border-radius: var(--border-radius);
border: 1px solid var(--color-border);
background-color: var(--color-bg-primary);
color: var(--color-text-primary);
font-size: 1rem;
}
.input-field:focus {
border-color: var(--color-accent);
box-shadow: 0 0 0 2px var(--color-accent-light);
outline: none;
}
.send-button {
background-color: var(--color-accent);
color: var(--color-bg-primary);
border: none;
border-radius: var(--border-radius);
padding: 0 1.2rem;
margin-left: 0.8rem;
font-weight: var(--font-weight-bold);
cursor: pointer;
transition: background-color 0.2s ease;
}
.send-button:hover {
background-color: var(--color-accent-hover);
}
.btn-connect,
.btn-primary,
.btn-secondary {
color: var(--color-bg-primary);
font-weight: var(--font-weight-medium);
}
@media (max-width: 1024px) {
.agent-container {
flex-direction: row;
flex-wrap: wrap;
}
.agent-sidebar {
width: 250px;
}
.chat-container {
flex-basis: calc(100% - 270px);
}
}
@media (max-width: 768px) {
.agent-container {
flex-direction: column;
height: auto;
}
.agent-sidebar {
width: 100%;
height: auto;
padding: 1rem;
}
.agent-selector {
flex-direction: row;
flex-wrap: wrap;
margin-bottom: 1rem;
}
.agent-option {
flex: 1;
min-width: 140px;
flex-direction: column;
text-align: center;
}
.agent-info h3 {
font-size: 0.9rem;
}
.agent-info p {
display: none;
}
.sidebar-info {
display: none;
}
.chat-container {
height: 70vh;
flex-basis: 100%;
}
}
</style>