update
This commit is contained in:
parent
c2b949919f
commit
30502d1c3e
@ -5,8 +5,8 @@ services:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: icrypto-web:1.0.13
|
||||
container_name: icrypto-web
|
||||
image: tradus-web:1.0.13
|
||||
container_name: tradus-web
|
||||
ports:
|
||||
- '6000:80'
|
||||
restart: unless-stopped
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||
/>
|
||||
<title>Crypto.AI - AI Agent for Web3</title>
|
||||
<title>tradus - AI Agent for trading</title>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
|
||||
466
src/App.vue
466
src/App.vue
@ -6,87 +6,141 @@ import { useUserStore } from './stores/user'
|
||||
const userStore = useUserStore()
|
||||
const isAuthenticated = computed(() => userStore.isAuthenticated)
|
||||
const userInfo = computed(() => userStore.userInfo)
|
||||
const showUserMenu = ref(false)
|
||||
const showMobileMenu = ref(false)
|
||||
|
||||
const handleLogout = () => {
|
||||
userStore.logout()
|
||||
if (window.location.pathname.includes('/user')) {
|
||||
window.location.href = '/'
|
||||
}
|
||||
showUserMenu.value = false
|
||||
showMobileMenu.value = false
|
||||
}
|
||||
|
||||
const toggleUserMenu = () => {
|
||||
showUserMenu.value = !showUserMenu.value
|
||||
const toggleMobileMenu = () => {
|
||||
showMobileMenu.value = !showMobileMenu.value
|
||||
}
|
||||
|
||||
// 点击其他地方关闭菜单
|
||||
const closeUserMenu = (event: MouseEvent) => {
|
||||
const closeMenus = (event: MouseEvent) => {
|
||||
const target = event.target as HTMLElement
|
||||
if (!target.closest('.user-section')) {
|
||||
showUserMenu.value = false
|
||||
if (!target.closest('.mobile-menu') && !target.closest('.menu-button')) {
|
||||
showMobileMenu.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
document.addEventListener('click', closeUserMenu)
|
||||
document.addEventListener('click', closeMenus)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
document.removeEventListener('click', closeUserMenu)
|
||||
document.removeEventListener('click', closeMenus)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 移动端菜单按钮 -->
|
||||
<button class="menu-button" @click="toggleMobileMenu">
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
fill="none"
|
||||
>
|
||||
<path d="M3 12h18M3 6h18M3 18h18" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<!-- 左侧栏 -->
|
||||
<aside class="sidebar">
|
||||
<aside class="sidebar" :class="{ 'sidebar-open': showMobileMenu }">
|
||||
<div class="sidebar-content">
|
||||
<!-- 网站标题 -->
|
||||
<div class="site-title">
|
||||
<span class="title-text">AI Trade</span>
|
||||
<span class="title-text">tradus</span>
|
||||
<div class="subtitle-text">AI for Trading</div>
|
||||
</div>
|
||||
<!-- Agent 列表 -->
|
||||
<div class="agent-list">
|
||||
<RouterLink to="/" class="agent-item">
|
||||
<span class="agent-icon">🏠</span>
|
||||
<RouterLink to="/" class="agent-item" @click="showMobileMenu = false">
|
||||
<svg
|
||||
class="agent-icon"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"
|
||||
/>
|
||||
</svg>
|
||||
<span class="agent-name">首页</span>
|
||||
</RouterLink>
|
||||
<RouterLink to="/ai-agent" class="agent-item">
|
||||
<span class="agent-icon">🤖</span>
|
||||
<RouterLink to="/ai-agent" class="agent-item" @click="showMobileMenu = false">
|
||||
<svg
|
||||
class="agent-icon"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
|
||||
/>
|
||||
</svg>
|
||||
<span class="agent-name">AI 助手</span>
|
||||
</RouterLink>
|
||||
</div>
|
||||
|
||||
<!-- 桌面端用户信息 -->
|
||||
<div class="desktop-user-info" v-if="isAuthenticated">
|
||||
<div class="user-info-box">
|
||||
<div class="user-avatar">
|
||||
<span>{{ userInfo?.nickname?.charAt(0) || 'U' }}</span>
|
||||
</div>
|
||||
<span class="user-nickname">{{ userInfo?.nickname }}</span>
|
||||
</div>
|
||||
<button class="logout-button" @click="handleLogout">退出登录</button>
|
||||
</div>
|
||||
<div class="desktop-user-info" v-else>
|
||||
<RouterLink to="/login" class="auth-link">登录</RouterLink>
|
||||
<RouterLink to="/register" class="auth-link">注册</RouterLink>
|
||||
</div>
|
||||
|
||||
<!-- 移动端用户信息 -->
|
||||
<div class="mobile-user-info" v-if="isAuthenticated">
|
||||
<div class="user-info-box">
|
||||
<div class="user-avatar">
|
||||
<span>{{ userInfo?.nickname?.charAt(0) || 'U' }}</span>
|
||||
</div>
|
||||
<span class="user-nickname">{{ userInfo?.nickname }}</span>
|
||||
</div>
|
||||
<button class="logout-button" @click="handleLogout">退出登录</button>
|
||||
</div>
|
||||
<div class="mobile-user-info" v-else>
|
||||
<RouterLink to="/login" class="mobile-auth-link" @click="showMobileMenu = false"
|
||||
>登录</RouterLink
|
||||
>
|
||||
<RouterLink to="/register" class="mobile-auth-link" @click="showMobileMenu = false"
|
||||
>注册</RouterLink
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- 遮罩层 -->
|
||||
<div class="sidebar-overlay" v-if="showMobileMenu" @click="showMobileMenu = false"></div>
|
||||
|
||||
<!-- 右侧对话区域 -->
|
||||
<main class="chat-container">
|
||||
<div class="chat-content">
|
||||
<RouterView />
|
||||
</div>
|
||||
|
||||
<!-- 用户信息区域 -->
|
||||
<div class="user-section" v-if="isAuthenticated">
|
||||
<div class="user-info-box" @click="toggleUserMenu">
|
||||
<div class="user-avatar">
|
||||
<span>{{ userInfo?.nickname?.charAt(0) || 'U' }}</span>
|
||||
</div>
|
||||
<span class="user-nickname">{{ userInfo?.nickname }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 用户菜单 -->
|
||||
<div v-if="showUserMenu" class="user-menu">
|
||||
<button class="menu-item" @click="handleLogout">退出登录</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="user-section">
|
||||
<div class="auth-buttons">
|
||||
<RouterLink to="/login" class="auth-link">登录</RouterLink>
|
||||
<RouterLink to="/register" class="auth-link register-link">注册</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
@ -94,22 +148,21 @@ onUnmounted(() => {
|
||||
<style>
|
||||
:root {
|
||||
--color-bg-primary: #ffffff;
|
||||
--color-bg-secondary: #f8f9fa;
|
||||
--color-bg-elevated: #ffffff;
|
||||
--color-bg-card: #f8f9fa;
|
||||
--color-bg-secondary: #f8fafc;
|
||||
--color-bg-hover: rgba(51, 85, 255, 0.04);
|
||||
--color-bg-active: rgba(51, 85, 255, 0.08);
|
||||
|
||||
--color-text-primary: #2c3e50;
|
||||
--color-text-secondary: #6c757d;
|
||||
--color-text-tertiary: #8c98a4;
|
||||
--color-text-disabled: #adb5bd;
|
||||
|
||||
--color-divider: rgba(0, 0, 0, 0.1);
|
||||
--color-border: rgba(0, 0, 0, 0.1);
|
||||
--color-border-hover: rgba(0, 0, 0, 0.2);
|
||||
--color-text-primary: #1e293b;
|
||||
--color-text-secondary: #64748b;
|
||||
--color-text-tertiary: #94a3b8;
|
||||
|
||||
--color-accent: #3355ff;
|
||||
--color-accent-hover: #2244ee;
|
||||
--color-accent-light: rgba(51, 85, 255, 0.1);
|
||||
--color-accent-hover: #4466ff;
|
||||
--color-accent-active: #2244ee;
|
||||
|
||||
--shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||||
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.07);
|
||||
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
|
||||
|
||||
--font-weight-light: 300;
|
||||
--font-weight-regular: 400;
|
||||
@ -156,8 +209,8 @@ body {
|
||||
.sidebar {
|
||||
width: var(--sidebar-width);
|
||||
height: 100vh;
|
||||
background-color: var(--color-bg-elevated);
|
||||
border-right: 1px solid var(--color-border);
|
||||
background-color: var(--color-bg-secondary);
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.06);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
@ -173,7 +226,7 @@ body {
|
||||
.site-title {
|
||||
padding: 2rem 1.5rem;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid var(--color-divider);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.title-text {
|
||||
@ -214,7 +267,7 @@ body {
|
||||
/* Agent 列表样式 */
|
||||
.agent-list {
|
||||
flex: 1;
|
||||
padding: 1rem;
|
||||
padding: 0.75rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
@ -226,28 +279,33 @@ body {
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
color: var(--color-text-primary);
|
||||
color: var(--color-text-secondary);
|
||||
text-decoration: none;
|
||||
border-radius: var(--border-radius);
|
||||
transition: background-color 0.2s ease;
|
||||
border-radius: 8px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.agent-item:hover {
|
||||
background-color: var(--color-bg-secondary);
|
||||
background-color: var(--color-bg-hover);
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.agent-item.router-link-active {
|
||||
background-color: var(--color-accent-light);
|
||||
background-color: var(--color-bg-active);
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.agent-icon {
|
||||
font-size: 1.25rem;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
flex-shrink: 0;
|
||||
stroke: currentColor;
|
||||
}
|
||||
|
||||
.agent-name {
|
||||
font-size: 0.95rem;
|
||||
font-weight: var(--font-weight-medium);
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
/* 修改用户信息区域样式 */
|
||||
@ -258,39 +316,48 @@ body {
|
||||
width: var(--sidebar-width);
|
||||
background-color: var(--color-bg-elevated);
|
||||
border-radius: 0;
|
||||
padding: 1rem;
|
||||
padding: 1.25rem;
|
||||
z-index: 100;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
border-top: 1px solid var(--color-divider);
|
||||
border: 1px solid var(--color-border);
|
||||
box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.user-section:hover {
|
||||
background-color: var(--color-bg-secondary);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.user-info-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
width: 2.75rem;
|
||||
height: 2.75rem;
|
||||
border-radius: 50%;
|
||||
background: var(--color-accent-light);
|
||||
background: var(--color-bg-hover);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1rem;
|
||||
font-size: 1.1rem;
|
||||
color: var(--color-accent);
|
||||
font-weight: bold;
|
||||
box-shadow: 0 2px 8px rgba(51, 85, 255, 0.2);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.user-section:hover .user-avatar {
|
||||
transform: scale(1.05);
|
||||
box-shadow: 0 4px 12px rgba(51, 85, 255, 0.3);
|
||||
}
|
||||
|
||||
.user-nickname {
|
||||
font-size: 0.95rem;
|
||||
font-size: 1rem;
|
||||
font-weight: var(--font-weight-medium);
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
@ -346,6 +413,19 @@ body {
|
||||
.subtitle-text {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.agent-item {
|
||||
padding: 0.875rem 1rem;
|
||||
}
|
||||
|
||||
.agent-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.agent-name {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* 右侧对话区域样式 */
|
||||
@ -412,27 +492,263 @@ body {
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* 移动端菜单按钮 */
|
||||
.menu-button {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 1rem;
|
||||
left: 1rem;
|
||||
z-index: 1000;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--color-text-primary);
|
||||
cursor: pointer;
|
||||
padding: 0.75rem;
|
||||
border-radius: var(--border-radius);
|
||||
background-color: var(--color-bg-secondary);
|
||||
border: 1px solid rgba(0, 0, 0, 0.06);
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.menu-button:hover {
|
||||
background-color: var(--color-bg-hover);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.menu-button:active {
|
||||
transform: translateY(0);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 遮罩层 */
|
||||
.sidebar-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
z-index: 90;
|
||||
backdrop-filter: blur(2px);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.sidebar-overlay.sidebar-open {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 移动端用户信息 */
|
||||
.mobile-user-info {
|
||||
display: none;
|
||||
padding: 1rem;
|
||||
border-top: 1px solid var(--color-border);
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.mobile-auth-link {
|
||||
display: block;
|
||||
padding: 0.75rem 1rem;
|
||||
color: var(--color-text-primary);
|
||||
text-decoration: none;
|
||||
border-radius: var(--border-radius);
|
||||
transition: all 0.2s ease;
|
||||
text-align: center;
|
||||
margin: 0.5rem 0;
|
||||
background-color: var(--color-bg-secondary);
|
||||
}
|
||||
|
||||
.mobile-auth-link:hover {
|
||||
background-color: var(--color-bg-elevated);
|
||||
}
|
||||
|
||||
.logout-button {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.75rem 1rem;
|
||||
margin-top: 1rem;
|
||||
background-color: var(--color-bg-hover);
|
||||
border: 1px solid rgba(0, 0, 0, 0.06);
|
||||
border-radius: var(--border-radius);
|
||||
color: var(--color-text-primary);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.logout-button:hover {
|
||||
background-color: var(--color-bg-active);
|
||||
border-color: var(--color-accent);
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
:root {
|
||||
--sidebar-width: 100%;
|
||||
.menu-button {
|
||||
display: block;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
left: -100%;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
transform: translateX(-100%);
|
||||
transition: transform 0.3s ease;
|
||||
bottom: 0;
|
||||
width: 80% !important;
|
||||
max-width: 300px;
|
||||
z-index: 1002;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
background-color: var(--color-bg-elevated);
|
||||
box-shadow: 4px 0 16px rgba(0, 0, 0, 0.1);
|
||||
transform: translateX(0);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.sidebar-open {
|
||||
transform: translateX(0);
|
||||
left: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.sidebar-overlay {
|
||||
display: block;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.mobile-user-info {
|
||||
display: block;
|
||||
animation: slideUp 0.3s ease;
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
from {
|
||||
transform: translateY(20px);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.user-section {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.chat-container {
|
||||
margin-left: 0;
|
||||
padding-top: 4rem;
|
||||
}
|
||||
|
||||
.agent-item {
|
||||
transform: translateX(-10px);
|
||||
opacity: 0;
|
||||
animation: slideIn 0.3s ease forwards;
|
||||
}
|
||||
|
||||
.agent-item:nth-child(1) {
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
|
||||
.agent-item:nth-child(2) {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
from {
|
||||
transform: translateX(-10px);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 桌面端用户信息样式 */
|
||||
.desktop-user-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1.25rem;
|
||||
margin-top: auto;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.06);
|
||||
background-color: var(--color-bg-secondary);
|
||||
}
|
||||
|
||||
.desktop-user-info .user-info-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.desktop-user-info .user-avatar {
|
||||
width: 2.75rem;
|
||||
height: 2.75rem;
|
||||
border-radius: 50%;
|
||||
background: var(--color-bg-hover);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1.1rem;
|
||||
color: var(--color-accent);
|
||||
font-weight: bold;
|
||||
box-shadow: 0 2px 8px rgba(51, 85, 255, 0.2);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.desktop-user-info .user-nickname {
|
||||
font-size: 1rem;
|
||||
font-weight: var(--font-weight-medium);
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.desktop-user-info .auth-link {
|
||||
display: block;
|
||||
padding: 0.75rem 1rem;
|
||||
color: var(--color-text-primary);
|
||||
text-decoration: none;
|
||||
border-radius: var(--border-radius);
|
||||
transition: all 0.2s ease;
|
||||
text-align: center;
|
||||
margin: 0.5rem 0;
|
||||
background-color: var(--color-bg-hover);
|
||||
}
|
||||
|
||||
.desktop-user-info .auth-link:hover {
|
||||
background-color: var(--color-bg-active);
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.desktop-user-info .logout-button {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.75rem 1rem;
|
||||
background-color: var(--color-bg-hover);
|
||||
border: 1px solid rgba(0, 0, 0, 0.06);
|
||||
border-radius: var(--border-radius);
|
||||
color: var(--color-text-primary);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.desktop-user-info .logout-button:hover {
|
||||
background-color: var(--color-bg-active);
|
||||
border-color: var(--color-accent);
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
/* 移动端适配 */
|
||||
@media (max-width: 768px) {
|
||||
.desktop-user-info {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.mobile-user-info {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -432,7 +432,7 @@ onUnmounted(() => {
|
||||
<style scoped>
|
||||
.ai-agent-view {
|
||||
width: 100%;
|
||||
height: calc(100vh - var(--header-height));
|
||||
height: 100%;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -580,6 +580,7 @@ onUnmounted(() => {
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
background-color: var(--color-bg-primary);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.chat-window {
|
||||
@ -591,12 +592,14 @@ onUnmounted(() => {
|
||||
margin: 0 auto;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.messages-container {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 2rem 0.5rem;
|
||||
padding-bottom: 2rem;
|
||||
scroll-behavior: smooth;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -683,12 +686,13 @@ onUnmounted(() => {
|
||||
.input-container {
|
||||
padding: 1.5rem 2rem;
|
||||
background-color: var(--color-bg-primary);
|
||||
border-top: 1px solid var(--color-border);
|
||||
width: 100%;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.input-wrapper {
|
||||
/* max-width: 48rem; */
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
@ -697,20 +701,19 @@ onUnmounted(() => {
|
||||
|
||||
.message-input {
|
||||
flex: 1;
|
||||
height: 3.5rem;
|
||||
min-height: 2.5rem;
|
||||
max-height: 8rem;
|
||||
padding: 0.75rem 1rem;
|
||||
padding-right: 3rem;
|
||||
height: 3rem;
|
||||
min-height: 3rem;
|
||||
max-height: 6rem;
|
||||
padding: 0.75rem 3rem 0.75rem 1rem;
|
||||
background-color: var(--color-bg-secondary);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius);
|
||||
color: var(--color-text-primary);
|
||||
font-size: 1rem;
|
||||
line-height: 1rem;
|
||||
line-height: 1.4;
|
||||
resize: none;
|
||||
outline: none;
|
||||
transition: border-color 0.2s ease;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.message-input::placeholder {
|
||||
@ -827,42 +830,79 @@ onUnmounted(() => {
|
||||
.agent-selector-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.5rem 1rem;
|
||||
background-color: var(--color-bg-elevated);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius);
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1.25rem;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid rgba(51, 85, 255, 0.2);
|
||||
border-radius: 12px;
|
||||
color: var(--color-text-primary);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 2px 8px rgba(51, 85, 255, 0.08);
|
||||
min-width: 160px;
|
||||
}
|
||||
|
||||
.agent-selector-button:hover {
|
||||
background-color: var(--color-bg-secondary);
|
||||
border-color: var(--color-accent);
|
||||
background-color: rgba(51, 85, 255, 0.04);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(51, 85, 255, 0.12);
|
||||
}
|
||||
|
||||
.agent-selector-button .agent-icon {
|
||||
font-size: 1.25rem;
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.agent-selector-button .agent-name {
|
||||
font-size: 0.95rem;
|
||||
color: var(--color-text-primary);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.agent-selector-button::after {
|
||||
content: '▼';
|
||||
font-size: 0.8rem;
|
||||
color: var(--color-accent);
|
||||
opacity: 0.8;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.agent-selector-menu {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
top: calc(100% + 0.5rem);
|
||||
right: 0;
|
||||
margin-top: 0.5rem;
|
||||
background-color: var(--color-bg-elevated);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--border-radius);
|
||||
min-width: 200px;
|
||||
max-width: 300px;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid rgba(51, 85, 255, 0.15);
|
||||
border-radius: 12px;
|
||||
min-width: 280px;
|
||||
max-width: 320px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||||
box-shadow: 0 4px 20px rgba(51, 85, 255, 0.15);
|
||||
animation: slideDown 0.2s ease;
|
||||
}
|
||||
|
||||
@keyframes slideDown {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.agent-menu-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
padding: 1rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
border-bottom: 1px solid rgba(51, 85, 255, 0.08);
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.agent-menu-item:last-child {
|
||||
@ -870,15 +910,23 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
.agent-menu-item:hover {
|
||||
background-color: var(--color-bg-secondary);
|
||||
background-color: rgba(51, 85, 255, 0.04);
|
||||
}
|
||||
|
||||
.agent-menu-item.active {
|
||||
background-color: var(--color-bg-secondary);
|
||||
background-color: rgba(51, 85, 255, 0.08);
|
||||
}
|
||||
|
||||
.agent-menu-item .agent-icon {
|
||||
font-size: 1.25rem;
|
||||
font-size: 1.5rem;
|
||||
color: var(--color-accent);
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: rgba(51, 85, 255, 0.08);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.agent-menu-item .agent-info {
|
||||
@ -887,50 +935,118 @@ onUnmounted(() => {
|
||||
}
|
||||
|
||||
.agent-menu-item .agent-name {
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-primary);
|
||||
margin-bottom: 0.25rem;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.agent-menu-item .agent-description {
|
||||
font-size: 0.75rem;
|
||||
font-size: 0.85rem;
|
||||
color: var(--color-text-secondary);
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.agent-loading {
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
/* 移动端适配 */
|
||||
@media (max-width: 768px) {
|
||||
.agent-selector {
|
||||
top: 0.5rem;
|
||||
.ai-agent-view {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.main-container {
|
||||
height: 100%;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
.messages-container {
|
||||
padding: 1rem 0.5rem;
|
||||
padding-bottom: calc(5rem + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.input-container {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 0.75rem;
|
||||
padding-bottom: calc(0.75rem + env(safe-area-inset-bottom));
|
||||
background-color: var(--color-bg-elevated);
|
||||
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
|
||||
z-index: 100;
|
||||
border-top: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
.input-wrapper {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.message-input {
|
||||
font-size: 16px; /* 防止 iOS 自动缩放 */
|
||||
padding: 0.6rem 2.5rem 0.6rem 0.75rem;
|
||||
min-height: 2.5rem;
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
.send-button {
|
||||
width: 1.8rem;
|
||||
height: 1.8rem;
|
||||
right: 0.5rem;
|
||||
bottom: 0.35rem;
|
||||
}
|
||||
|
||||
.send-icon {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.agent-selector {
|
||||
top: 0.75rem;
|
||||
right: 0.75rem;
|
||||
}
|
||||
|
||||
.agent-selector-button {
|
||||
padding: 0.6rem 1rem;
|
||||
min-width: 140px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.agent-selector-menu {
|
||||
min-width: 260px;
|
||||
max-width: calc(100vw - 2rem);
|
||||
right: -0.75rem;
|
||||
}
|
||||
|
||||
.agent-menu-item {
|
||||
padding: 0.875rem;
|
||||
}
|
||||
|
||||
.agent-menu-item .agent-icon {
|
||||
font-size: 1.25rem;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.agent-selector {
|
||||
max-height: 50px;
|
||||
.messages-container {
|
||||
padding: 0.75rem 0.5rem;
|
||||
padding-bottom: calc(4rem + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.agent-menu-item {
|
||||
padding: 0.4rem;
|
||||
min-width: 100px;
|
||||
.input-container {
|
||||
padding: 0.5rem;
|
||||
padding-bottom: calc(0.5rem + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.agent-name {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.message {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.input-field {
|
||||
font-size: 0.9rem;
|
||||
.message-content {
|
||||
padding: 0.75rem;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,8 +11,8 @@ const isAuthenticated = computed(() => userStore.isAuthenticated)
|
||||
<div class="home-view">
|
||||
<section class="hero-section">
|
||||
<div class="hero-content">
|
||||
<h1 class="hero-title"><span class="accent">AI Agent for Web3</span></h1>
|
||||
<p class="hero-subtitle">立刻加入,开启 Web3 + AI 新时代</p>
|
||||
<h1 class="hero-title"><span class="accent">Tradus</span></h1>
|
||||
<p class="hero-subtitle">AI Agent for trading</p>
|
||||
<div class="hero-actions">
|
||||
<!-- 未登录状态显示登录和注册按钮 -->
|
||||
<template v-if="!isAuthenticated">
|
||||
@ -48,11 +48,12 @@ const isAuthenticated = computed(() => userStore.isAuthenticated)
|
||||
|
||||
.hero-section {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
padding: 6rem 2rem;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
max-width: 900px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.hero-section::before {
|
||||
@ -62,7 +63,7 @@ const isAuthenticated = computed(() => userStore.isAuthenticated)
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: radial-gradient(circle at top right, rgba(59, 130, 246, 0.05), transparent 70%);
|
||||
background: radial-gradient(circle at top right, rgba(51, 85, 255, 0.03), transparent 70%);
|
||||
}
|
||||
|
||||
.hero-content {
|
||||
@ -71,14 +72,12 @@ const isAuthenticated = computed(() => userStore.isAuthenticated)
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
font-size: 3.5rem;
|
||||
font-size: 5rem;
|
||||
font-weight: 800;
|
||||
margin-bottom: 1.5rem;
|
||||
line-height: 1.2;
|
||||
background: linear-gradient(135deg, var(--color-accent) 0%, #3355ff 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
line-height: 1.1;
|
||||
letter-spacing: -0.02em;
|
||||
color: #3355ff;
|
||||
}
|
||||
|
||||
.accent {
|
||||
@ -89,21 +88,24 @@ const isAuthenticated = computed(() => userStore.isAuthenticated)
|
||||
.accent::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
bottom: 8px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 8px;
|
||||
background-color: var(--color-accent-light);
|
||||
height: 12px;
|
||||
background-color: rgba(51, 85, 255, 0.1);
|
||||
z-index: -1;
|
||||
border-radius: 4px;
|
||||
opacity: 0.3;
|
||||
border-radius: 6px;
|
||||
opacity: 0.5;
|
||||
transform: skewX(-12deg);
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 1.2rem;
|
||||
color: var(--color-text-secondary);
|
||||
font-size: 1.5rem;
|
||||
color: #6c757d;
|
||||
max-width: 700px;
|
||||
margin: 0 auto 3rem;
|
||||
margin: 0 auto 4rem;
|
||||
letter-spacing: -0.01em;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.hero-actions {
|
||||
@ -113,92 +115,120 @@ const isAuthenticated = computed(() => userStore.isAuthenticated)
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.discord-link {
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
||||
.discord-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
color: var(--color-text-secondary);
|
||||
text-decoration: none;
|
||||
font-size: 0.9rem;
|
||||
transition: color 0.2s ease;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.discord-text:hover {
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
.discord-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 0.8rem 1.6rem;
|
||||
border-radius: 6px;
|
||||
padding: 1rem 2rem;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
font-size: 1.1rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
border: none;
|
||||
transition: all 0.3s ease;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 160px;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #3355ff;
|
||||
color: white;
|
||||
font-weight: var(--font-weight-bold);
|
||||
border: none;
|
||||
box-shadow: 0 4px 6px rgba(51, 85, 255, 0.1);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #2244ee;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 5px 15px rgba(51, 85, 255, 0.3);
|
||||
box-shadow: 0 6px 12px rgba(51, 85, 255, 0.2);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: transparent;
|
||||
color: var(--color-text-primary);
|
||||
border: 1px solid var(--color-border);
|
||||
background-color: rgba(51, 85, 255, 0.1);
|
||||
color: #3355ff;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background-color: rgba(255, 255, 255, 0.05);
|
||||
background-color: rgba(51, 85, 255, 0.15);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.discord-link {
|
||||
margin-top: 4rem;
|
||||
opacity: 0.8;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.discord-link:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.discord-text {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
color: #6c757d;
|
||||
text-decoration: none;
|
||||
font-size: 1rem;
|
||||
transition: all 0.3s ease;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: 8px;
|
||||
background-color: rgba(108, 117, 125, 0.1);
|
||||
}
|
||||
|
||||
.discord-text:hover {
|
||||
color: #3355ff;
|
||||
background-color: rgba(51, 85, 255, 0.1);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.discord-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.hero-section {
|
||||
padding: 4rem 1.5rem;
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
font-size: 2.5rem;
|
||||
font-size: 3.5rem;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 1.25rem;
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 0.875rem 1.75rem;
|
||||
font-size: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.hero-actions {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.hero-section {
|
||||
padding: 2rem 1rem;
|
||||
min-width: 140px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.hero-title {
|
||||
font-size: 2rem;
|
||||
.hero-section {
|
||||
padding: 3rem 1rem;
|
||||
}
|
||||
|
||||
.hero-section {
|
||||
padding: 1.5rem 1rem;
|
||||
.hero-title {
|
||||
font-size: 2.75rem;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 1.1rem;
|
||||
margin-bottom: 2.5rem;
|
||||
}
|
||||
|
||||
.hero-actions {
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user