refactor: 更新 logo 图标并调整布局
- 将 logo 图标从 logo.png 更改为 xiaoyugan.png -调整了多个组件的布局结构 - 更新了部分样式,如按钮、文本等
This commit is contained in:
2
package-lock.json
generated
2
package-lock.json
generated
@@ -7,7 +7,7 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "xyzw-token-manager",
|
"name": "xyzw-token-manager",
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"license": "MIT",
|
"license": "CC-BY-NC-SA-4.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vicons/ionicons5": "^0.12.0",
|
"@vicons/ionicons5": "^0.12.0",
|
||||||
"@vicons/material": "^0.12.0",
|
"@vicons/material": "^0.12.0",
|
||||||
|
|||||||
@@ -5,13 +5,13 @@
|
|||||||
<div class="nav-container">
|
<div class="nav-container">
|
||||||
<div class="nav-brand">
|
<div class="nav-brand">
|
||||||
<img
|
<img
|
||||||
src="/icons/logo.png"
|
src="/icons/xiaoyugan.png"
|
||||||
alt="XYZW"
|
alt="XYZW"
|
||||||
class="brand-logo"
|
class="brand-logo"
|
||||||
>
|
>
|
||||||
<span class="brand-text">XYZW 控制台</span>
|
<span class="brand-text">XYZW 控制台</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="nav-menu">
|
<div class="nav-menu">
|
||||||
<router-link
|
<router-link
|
||||||
to="/dashboard"
|
to="/dashboard"
|
||||||
@@ -62,15 +62,15 @@
|
|||||||
<span>个人设置</span>
|
<span>个人设置</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="nav-user">
|
<div class="nav-user">
|
||||||
<n-dropdown
|
<n-dropdown
|
||||||
:options="userMenuOptions"
|
:options="userMenuOptions"
|
||||||
@select="handleUserAction"
|
@select="handleUserAction"
|
||||||
>
|
>
|
||||||
<div class="user-info">
|
<div class="user-info">
|
||||||
<n-avatar
|
<n-avatar
|
||||||
size="medium"
|
size="medium"
|
||||||
fallback-src="/icons/xiaoyugan.png"
|
fallback-src="/icons/xiaoyugan.png"
|
||||||
/>
|
/>
|
||||||
<span class="username">{{ tokenStore.selectedToken?.name || '未选择Token' }}</span>
|
<span class="username">{{ tokenStore.selectedToken?.name || '未选择Token' }}</span>
|
||||||
@@ -92,14 +92,14 @@
|
|||||||
<p>今天是 {{ currentDate }},继续您的游戏管理之旅吧</p>
|
<p>今天是 {{ currentDate }},继续您的游戏管理之旅吧</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="welcome-actions">
|
<div class="welcome-actions">
|
||||||
<n-button
|
<n-button
|
||||||
type="primary"
|
type="primary"
|
||||||
size="large"
|
size="large"
|
||||||
@click="router.push('/game-features')"
|
@click="router.push('/game-features')"
|
||||||
>
|
>
|
||||||
进入游戏功能
|
进入游戏功能
|
||||||
</n-button>
|
</n-button>
|
||||||
<n-button
|
<n-button
|
||||||
size="large"
|
size="large"
|
||||||
@click="router.push('/tokens')"
|
@click="router.push('/tokens')"
|
||||||
>
|
>
|
||||||
@@ -147,7 +147,7 @@
|
|||||||
快速操作
|
快速操作
|
||||||
</h2>
|
</h2>
|
||||||
<div class="actions-grid">
|
<div class="actions-grid">
|
||||||
<div
|
<div
|
||||||
v-for="action in quickActions"
|
v-for="action in quickActions"
|
||||||
:key="action.id"
|
:key="action.id"
|
||||||
class="action-card"
|
class="action-card"
|
||||||
@@ -178,12 +178,12 @@
|
|||||||
刷新
|
刷新
|
||||||
</n-button>
|
</n-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="recentActivities.length"
|
v-if="recentActivities.length"
|
||||||
class="activity-list"
|
class="activity-list"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-for="activity in recentActivities"
|
v-for="activity in recentActivities"
|
||||||
:key="activity.id"
|
:key="activity.id"
|
||||||
class="activity-item"
|
class="activity-item"
|
||||||
@@ -204,7 +204,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
class="empty-activity"
|
class="empty-activity"
|
||||||
@@ -222,10 +222,10 @@ import { ref, computed, onMounted } from 'vue'
|
|||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { useMessage } from 'naive-ui'
|
import { useMessage } from 'naive-ui'
|
||||||
import { useTokenStore } from '@/stores/tokenStore'
|
import { useTokenStore } from '@/stores/tokenStore'
|
||||||
import {
|
import {
|
||||||
Home,
|
Home,
|
||||||
PersonCircle,
|
PersonCircle,
|
||||||
Cube,
|
Cube,
|
||||||
Settings,
|
Settings,
|
||||||
ChevronDown,
|
ChevronDown,
|
||||||
Ribbon,
|
Ribbon,
|
||||||
@@ -428,7 +428,7 @@ const formatTime = (timestamp) => {
|
|||||||
const minutes = Math.floor(diff / (1000 * 60))
|
const minutes = Math.floor(diff / (1000 * 60))
|
||||||
const hours = Math.floor(diff / (1000 * 60 * 60))
|
const hours = Math.floor(diff / (1000 * 60 * 60))
|
||||||
const days = Math.floor(diff / (1000 * 60 * 60 * 24))
|
const days = Math.floor(diff / (1000 * 60 * 60 * 24))
|
||||||
|
|
||||||
if (days > 0) {
|
if (days > 0) {
|
||||||
return `${days}天前`
|
return `${days}天前`
|
||||||
} else if (hours > 0) {
|
} else if (hours > 0) {
|
||||||
@@ -512,12 +512,12 @@ onMounted(async () => {
|
|||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: all var(--transition-fast);
|
transition: all var(--transition-fast);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: var(--bg-tertiary);
|
background: var(--bg-tertiary);
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
background: var(--primary-color-light);
|
background: var(--primary-color-light);
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
@@ -536,7 +536,7 @@ onMounted(async () => {
|
|||||||
border-radius: var(--border-radius-medium);
|
border-radius: var(--border-radius-medium);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background var(--transition-fast);
|
transition: background var(--transition-fast);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: var(--bg-tertiary);
|
background: var(--bg-tertiary);
|
||||||
}
|
}
|
||||||
@@ -579,7 +579,7 @@ onMounted(async () => {
|
|||||||
font-weight: var(--font-weight-bold);
|
font-weight: var(--font-weight-bold);
|
||||||
margin-bottom: var(--spacing-sm);
|
margin-bottom: var(--spacing-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-size: var(--font-size-lg);
|
font-size: var(--font-size-lg);
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
@@ -609,7 +609,7 @@ onMounted(async () => {
|
|||||||
padding: var(--spacing-lg);
|
padding: var(--spacing-lg);
|
||||||
box-shadow: var(--shadow-light);
|
box-shadow: var(--shadow-light);
|
||||||
transition: all var(--transition-normal);
|
transition: all var(--transition-normal);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
box-shadow: var(--shadow-medium);
|
box-shadow: var(--shadow-medium);
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
@@ -620,7 +620,7 @@ onMounted(async () => {
|
|||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
margin-bottom: var(--spacing-md);
|
margin-bottom: var(--spacing-md);
|
||||||
|
|
||||||
:deep(svg) {
|
:deep(svg) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -643,11 +643,11 @@ onMounted(async () => {
|
|||||||
.stat-change {
|
.stat-change {
|
||||||
font-size: var(--font-size-sm);
|
font-size: var(--font-size-sm);
|
||||||
font-weight: var(--font-weight-medium);
|
font-weight: var(--font-weight-medium);
|
||||||
|
|
||||||
&.positive {
|
&.positive {
|
||||||
color: var(--success-color);
|
color: var(--success-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.negative {
|
&.negative {
|
||||||
color: var(--error-color);
|
color: var(--error-color);
|
||||||
}
|
}
|
||||||
@@ -678,7 +678,7 @@ onMounted(async () => {
|
|||||||
box-shadow: var(--shadow-light);
|
box-shadow: var(--shadow-light);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all var(--transition-normal);
|
transition: all var(--transition-normal);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
box-shadow: var(--shadow-medium);
|
box-shadow: var(--shadow-medium);
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
@@ -690,7 +690,7 @@ onMounted(async () => {
|
|||||||
height: 40px;
|
height: 40px;
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
margin-bottom: var(--spacing-md);
|
margin-bottom: var(--spacing-md);
|
||||||
|
|
||||||
:deep(svg) {
|
:deep(svg) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -704,7 +704,7 @@ onMounted(async () => {
|
|||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
margin-bottom: var(--spacing-xs);
|
margin-bottom: var(--spacing-xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
font-size: var(--font-size-sm);
|
font-size: var(--font-size-sm);
|
||||||
@@ -739,7 +739,7 @@ onMounted(async () => {
|
|||||||
padding: var(--spacing-md);
|
padding: var(--spacing-md);
|
||||||
border-radius: var(--border-radius-medium);
|
border-radius: var(--border-radius-medium);
|
||||||
transition: background var(--transition-fast);
|
transition: background var(--transition-fast);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: var(--bg-tertiary);
|
background: var(--bg-tertiary);
|
||||||
}
|
}
|
||||||
@@ -753,22 +753,22 @@ onMounted(async () => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
&.success {
|
&.success {
|
||||||
background: rgba(24, 160, 88, 0.1);
|
background: rgba(24, 160, 88, 0.1);
|
||||||
color: var(--success-color);
|
color: var(--success-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.warning {
|
&.warning {
|
||||||
background: rgba(240, 160, 32, 0.1);
|
background: rgba(240, 160, 32, 0.1);
|
||||||
color: var(--warning-color);
|
color: var(--warning-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.info {
|
&.info {
|
||||||
background: rgba(32, 128, 240, 0.1);
|
background: rgba(32, 128, 240, 0.1);
|
||||||
color: var(--info-color);
|
color: var(--info-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(svg) {
|
:deep(svg) {
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
@@ -801,7 +801,7 @@ onMounted(async () => {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-grid {
|
.stats-grid {
|
||||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
}
|
}
|
||||||
@@ -811,30 +811,30 @@ onMounted(async () => {
|
|||||||
.dashboard-main {
|
.dashboard-main {
|
||||||
padding: var(--spacing-md);
|
padding: var(--spacing-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-menu {
|
.nav-menu {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.welcome-section {
|
.welcome-section {
|
||||||
padding: var(--spacing-xl);
|
padding: var(--spacing-xl);
|
||||||
}
|
}
|
||||||
|
|
||||||
.welcome-text h1 {
|
.welcome-text h1 {
|
||||||
font-size: var(--font-size-2xl);
|
font-size: var(--font-size-2xl);
|
||||||
}
|
}
|
||||||
|
|
||||||
.welcome-actions {
|
.welcome-actions {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats-grid {
|
.stats-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions-grid {
|
.actions-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -6,35 +6,35 @@
|
|||||||
<div class="nav-content">
|
<div class="nav-content">
|
||||||
<div class="nav-brand">
|
<div class="nav-brand">
|
||||||
<img
|
<img
|
||||||
src="/icons/logo.png"
|
src="/icons/xiaoyugan.png"
|
||||||
alt="XYZW"
|
alt="XYZW"
|
||||||
class="brand-logo"
|
class="brand-logo"
|
||||||
>
|
>
|
||||||
<span class="brand-text">XYZW 游戏管理系统</span>
|
<span class="brand-text">XYZW 游戏管理系统</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="nav-actions">
|
<div class="nav-actions">
|
||||||
<template v-if="!authStore.isAuthenticated">
|
<template v-if="!authStore.isAuthenticated">
|
||||||
<n-button
|
<n-button
|
||||||
text
|
text
|
||||||
type="primary"
|
type="primary"
|
||||||
size="large"
|
size="large"
|
||||||
@click="router.push('/login')"
|
@click="router.push('/login')"
|
||||||
>
|
>
|
||||||
登录
|
登录
|
||||||
</n-button>
|
</n-button>
|
||||||
<n-button
|
<n-button
|
||||||
type="primary"
|
type="primary"
|
||||||
size="large"
|
size="large"
|
||||||
@click="router.push('/register')"
|
@click="router.push('/register')"
|
||||||
>
|
>
|
||||||
注册
|
注册
|
||||||
</n-button>
|
</n-button>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<n-button
|
<n-button
|
||||||
type="primary"
|
type="primary"
|
||||||
size="large"
|
size="large"
|
||||||
@click="router.push('/dashboard')"
|
@click="router.push('/dashboard')"
|
||||||
>
|
>
|
||||||
进入控制台
|
进入控制台
|
||||||
@@ -59,18 +59,18 @@
|
|||||||
让游戏变得更简单,让管理变得更高效
|
让游戏变得更简单,让管理变得更高效
|
||||||
</p>
|
</p>
|
||||||
<div class="hero-actions">
|
<div class="hero-actions">
|
||||||
<n-button
|
<n-button
|
||||||
type="primary"
|
type="primary"
|
||||||
size="large"
|
size="large"
|
||||||
class="hero-button"
|
class="hero-button"
|
||||||
@click="router.push(authStore.isAuthenticated ? '/dashboard' : '/register')"
|
@click="router.push(authStore.isAuthenticated ? '/dashboard' : '/register')"
|
||||||
>
|
>
|
||||||
{{ authStore.isAuthenticated ? '进入控制台' : '立即开始' }}
|
{{ authStore.isAuthenticated ? '进入控制台' : '立即开始' }}
|
||||||
</n-button>
|
</n-button>
|
||||||
<n-button
|
<n-button
|
||||||
text
|
text
|
||||||
type="primary"
|
type="primary"
|
||||||
size="large"
|
size="large"
|
||||||
class="hero-button"
|
class="hero-button"
|
||||||
@click="scrollToFeatures"
|
@click="scrollToFeatures"
|
||||||
>
|
>
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
</n-button>
|
</n-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="hero-visual">
|
<div class="hero-visual">
|
||||||
<div class="feature-cards">
|
<div class="feature-cards">
|
||||||
<div
|
<div
|
||||||
@@ -114,11 +114,11 @@
|
|||||||
为您提供全方位的游戏管理解决方案
|
为您提供全方位的游戏管理解决方案
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="features-grid">
|
<div class="features-grid">
|
||||||
<div
|
<div
|
||||||
v-for="feature in features"
|
v-for="feature in features"
|
||||||
:key="feature.id"
|
:key="feature.id"
|
||||||
class="feature-item"
|
class="feature-item"
|
||||||
>
|
>
|
||||||
<div class="feature-icon">
|
<div class="feature-icon">
|
||||||
@@ -162,7 +162,7 @@
|
|||||||
<div class="footer-content">
|
<div class="footer-content">
|
||||||
<div class="footer-brand">
|
<div class="footer-brand">
|
||||||
<img
|
<img
|
||||||
src="/icons/logo.png"
|
src="/icons/xiaoyugan.png"
|
||||||
alt="XYZW"
|
alt="XYZW"
|
||||||
class="footer-logo"
|
class="footer-logo"
|
||||||
>
|
>
|
||||||
@@ -199,12 +199,12 @@
|
|||||||
import { ref, onMounted } from 'vue'
|
import { ref, onMounted } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { useAuthStore } from '@/stores/auth'
|
import { useAuthStore } from '@/stores/auth'
|
||||||
import {
|
import {
|
||||||
PersonCircle,
|
PersonCircle,
|
||||||
Cube,
|
Cube,
|
||||||
Ribbon,
|
Ribbon,
|
||||||
Home,
|
Home,
|
||||||
Settings
|
Settings
|
||||||
} from '@vicons/ionicons5'
|
} from '@vicons/ionicons5'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@@ -272,8 +272,8 @@ const stats = ref([
|
|||||||
// 滚动到功能区域
|
// 滚动到功能区域
|
||||||
const scrollToFeatures = () => {
|
const scrollToFeatures = () => {
|
||||||
if (featuresSection.value) {
|
if (featuresSection.value) {
|
||||||
featuresSection.value.scrollIntoView({
|
featuresSection.value.scrollIntoView({
|
||||||
behavior: 'smooth'
|
behavior: 'smooth'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -399,7 +399,7 @@ onMounted(() => {
|
|||||||
border-radius: var(--border-radius-large);
|
border-radius: var(--border-radius-large);
|
||||||
padding: var(--spacing-lg);
|
padding: var(--spacing-lg);
|
||||||
transition: all var(--transition-normal);
|
transition: all var(--transition-normal);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
transform: translateY(-4px);
|
transform: translateY(-4px);
|
||||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
|
||||||
@@ -411,7 +411,7 @@ onMounted(() => {
|
|||||||
height: 48px;
|
height: 48px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
margin-bottom: var(--spacing-md);
|
margin-bottom: var(--spacing-md);
|
||||||
|
|
||||||
:deep(svg) {
|
:deep(svg) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -468,7 +468,7 @@ onMounted(() => {
|
|||||||
padding: var(--spacing-xl);
|
padding: var(--spacing-xl);
|
||||||
border-radius: var(--border-radius-large);
|
border-radius: var(--border-radius-large);
|
||||||
transition: all var(--transition-normal);
|
transition: all var(--transition-normal);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
transform: translateY(-4px);
|
transform: translateY(-4px);
|
||||||
box-shadow: var(--shadow-heavy);
|
box-shadow: var(--shadow-heavy);
|
||||||
@@ -480,7 +480,7 @@ onMounted(() => {
|
|||||||
height: 64px;
|
height: 64px;
|
||||||
margin: 0 auto var(--spacing-lg);
|
margin: 0 auto var(--spacing-lg);
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
|
|
||||||
:deep(svg) {
|
:deep(svg) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -564,7 +564,7 @@ onMounted(() => {
|
|||||||
.footer-link {
|
.footer-link {
|
||||||
color: rgba(255, 255, 255, 0.8);
|
color: rgba(255, 255, 255, 0.8);
|
||||||
transition: color var(--transition-fast);
|
transition: color var(--transition-fast);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
@@ -583,23 +583,23 @@ onMounted(() => {
|
|||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-title {
|
.hero-title {
|
||||||
font-size: 2.5rem;
|
font-size: 2.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-actions {
|
.hero-actions {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-content {
|
.footer-content {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: var(--spacing-lg);
|
gap: var(--spacing-lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-actions {
|
.nav-actions {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: var(--spacing-xs);
|
gap: var(--spacing-xs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="brand">
|
<div class="brand">
|
||||||
<img
|
<img
|
||||||
src="/icons/logo.png"
|
src="/icons/xiaoyugan.png"
|
||||||
alt="XYZW"
|
alt="XYZW"
|
||||||
class="brand-logo"
|
class="brand-logo"
|
||||||
>
|
>
|
||||||
@@ -87,8 +87,8 @@
|
|||||||
</n-divider>
|
</n-divider>
|
||||||
|
|
||||||
<div class="social-login">
|
<div class="social-login">
|
||||||
<n-button
|
<n-button
|
||||||
size="large"
|
size="large"
|
||||||
class="social-button"
|
class="social-button"
|
||||||
@click="handleSocialLogin('qq')"
|
@click="handleSocialLogin('qq')"
|
||||||
>
|
>
|
||||||
@@ -99,9 +99,9 @@
|
|||||||
</template>
|
</template>
|
||||||
QQ登录
|
QQ登录
|
||||||
</n-button>
|
</n-button>
|
||||||
|
|
||||||
<n-button
|
<n-button
|
||||||
size="large"
|
size="large"
|
||||||
class="social-button"
|
class="social-button"
|
||||||
@click="handleSocialLogin('wechat')"
|
@click="handleSocialLogin('wechat')"
|
||||||
>
|
>
|
||||||
@@ -133,7 +133,7 @@
|
|||||||
<h2>为什么选择 XYZW?</h2>
|
<h2>为什么选择 XYZW?</h2>
|
||||||
<p>专业的游戏管理平台,让游戏变得更轻松</p>
|
<p>专业的游戏管理平台,让游戏变得更轻松</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="features-list">
|
<div class="features-list">
|
||||||
<div
|
<div
|
||||||
v-for="feature in features"
|
v-for="feature in features"
|
||||||
@@ -237,7 +237,7 @@ const handleLogin = async () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await loginFormRef.value.validate()
|
await loginFormRef.value.validate()
|
||||||
|
|
||||||
const result = await authStore.login({
|
const result = await authStore.login({
|
||||||
username: loginForm.username,
|
username: loginForm.username,
|
||||||
password: loginForm.password,
|
password: loginForm.password,
|
||||||
@@ -246,7 +246,7 @@ const handleLogin = async () => {
|
|||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
message.success('登录成功')
|
message.success('登录成功')
|
||||||
|
|
||||||
// 跳转到dashboard或之前访问的页面
|
// 跳转到dashboard或之前访问的页面
|
||||||
const redirect = router.currentRoute.value.query.redirect || '/dashboard'
|
const redirect = router.currentRoute.value.query.redirect || '/dashboard'
|
||||||
router.push(redirect)
|
router.push(redirect)
|
||||||
@@ -370,7 +370,7 @@ onMounted(() => {
|
|||||||
.social-button {
|
.social-button {
|
||||||
height: 44px;
|
height: 44px;
|
||||||
border: 1px solid var(--border-light);
|
border: 1px solid var(--border-light);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: var(--primary-color);
|
border-color: var(--primary-color);
|
||||||
}
|
}
|
||||||
@@ -379,7 +379,7 @@ onMounted(() => {
|
|||||||
.register-prompt {
|
.register-prompt {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
|
|
||||||
span {
|
span {
|
||||||
margin-right: var(--spacing-sm);
|
margin-right: var(--spacing-sm);
|
||||||
}
|
}
|
||||||
@@ -394,13 +394,13 @@ onMounted(() => {
|
|||||||
.showcase-header {
|
.showcase-header {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: var(--spacing-xl);
|
margin-bottom: var(--spacing-xl);
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: var(--font-size-3xl);
|
font-size: var(--font-size-3xl);
|
||||||
font-weight: var(--font-weight-bold);
|
font-weight: var(--font-weight-bold);
|
||||||
margin-bottom: var(--spacing-md);
|
margin-bottom: var(--spacing-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-size: var(--font-size-lg);
|
font-size: var(--font-size-lg);
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
@@ -423,7 +423,7 @@ onMounted(() => {
|
|||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
transition: all var(--transition-normal);
|
transition: all var(--transition-normal);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
transform: translateX(8px);
|
transform: translateX(8px);
|
||||||
background: rgba(255, 255, 255, 0.15);
|
background: rgba(255, 255, 255, 0.15);
|
||||||
@@ -435,7 +435,7 @@ onMounted(() => {
|
|||||||
height: 48px;
|
height: 48px;
|
||||||
color: white;
|
color: white;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|
||||||
:deep(svg) {
|
:deep(svg) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -444,13 +444,13 @@ onMounted(() => {
|
|||||||
|
|
||||||
.feature-content {
|
.feature-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
font-size: var(--font-size-lg);
|
font-size: var(--font-size-lg);
|
||||||
font-weight: var(--font-weight-semibold);
|
font-weight: var(--font-weight-semibold);
|
||||||
margin-bottom: var(--spacing-sm);
|
margin-bottom: var(--spacing-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
line-height: var(--line-height-relaxed);
|
line-height: var(--line-height-relaxed);
|
||||||
@@ -515,11 +515,11 @@ onMounted(() => {
|
|||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.features-showcase {
|
.features-showcase {
|
||||||
order: -1;
|
order: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.showcase-header h2 {
|
.showcase-header h2 {
|
||||||
font-size: var(--font-size-2xl);
|
font-size: var(--font-size-2xl);
|
||||||
}
|
}
|
||||||
@@ -529,26 +529,26 @@ onMounted(() => {
|
|||||||
.login-container {
|
.login-container {
|
||||||
padding: var(--spacing-md);
|
padding: var(--spacing-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-card {
|
.login-card {
|
||||||
padding: var(--spacing-xl);
|
padding: var(--spacing-xl);
|
||||||
}
|
}
|
||||||
|
|
||||||
.brand-title {
|
.brand-title {
|
||||||
font-size: var(--font-size-xl);
|
font-size: var(--font-size-xl);
|
||||||
}
|
}
|
||||||
|
|
||||||
.social-login {
|
.social-login {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.feature-item {
|
.feature-item {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.decoration-circle {
|
.decoration-circle {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<div class="brand">
|
<div class="brand">
|
||||||
<img
|
<img
|
||||||
src="/icons/logo.png"
|
src="/icons/xiaoyugan.png"
|
||||||
alt="XYZW"
|
alt="XYZW"
|
||||||
class="brand-logo"
|
class="brand-logo"
|
||||||
>
|
>
|
||||||
@@ -209,12 +209,12 @@ const handleRegister = async () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await registerFormRef.value.validate()
|
await registerFormRef.value.validate()
|
||||||
|
|
||||||
if (!registerForm.agreeTerms) {
|
if (!registerForm.agreeTerms) {
|
||||||
message.warning('请先同意服务条款和隐私政策')
|
message.warning('请先同意服务条款和隐私政策')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await authStore.register({
|
const result = await authStore.register({
|
||||||
username: registerForm.username,
|
username: registerForm.username,
|
||||||
email: registerForm.email,
|
email: registerForm.email,
|
||||||
@@ -299,7 +299,7 @@ const handleRegister = async () => {
|
|||||||
|
|
||||||
.form-options {
|
.form-options {
|
||||||
margin-bottom: var(--spacing-xl);
|
margin-bottom: var(--spacing-xl);
|
||||||
|
|
||||||
:deep(.n-checkbox) {
|
:deep(.n-checkbox) {
|
||||||
line-height: var(--line-height-relaxed);
|
line-height: var(--line-height-relaxed);
|
||||||
}
|
}
|
||||||
@@ -315,7 +315,7 @@ const handleRegister = async () => {
|
|||||||
.login-prompt {
|
.login-prompt {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
|
|
||||||
span {
|
span {
|
||||||
margin-right: var(--spacing-sm);
|
margin-right: var(--spacing-sm);
|
||||||
}
|
}
|
||||||
@@ -325,9 +325,9 @@ const handleRegister = async () => {
|
|||||||
.register-card {
|
.register-card {
|
||||||
padding: var(--spacing-xl);
|
padding: var(--spacing-xl);
|
||||||
}
|
}
|
||||||
|
|
||||||
.brand-title {
|
.brand-title {
|
||||||
font-size: var(--font-size-xl);
|
font-size: var(--font-size-xl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<div class="header-content">
|
<div class="header-content">
|
||||||
<img
|
<img
|
||||||
src="/icons/logo.png"
|
src="/icons/xiaoyugan.png"
|
||||||
alt="XYZW"
|
alt="XYZW"
|
||||||
class="brand-logo"
|
class="brand-logo"
|
||||||
>
|
>
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
</n-alert>
|
</n-alert>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<n-form
|
<n-form
|
||||||
ref="importFormRef"
|
ref="importFormRef"
|
||||||
:model="importForm"
|
:model="importForm"
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
|
||||||
<n-form-item
|
<n-form-item
|
||||||
label="Base64 Token"
|
label="Base64 Token"
|
||||||
path="base64Token"
|
path="base64Token"
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
clearable
|
clearable
|
||||||
/>
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
|
||||||
<!-- 可选信息 -->
|
<!-- 可选信息 -->
|
||||||
<n-collapse>
|
<n-collapse>
|
||||||
<n-collapse-item
|
<n-collapse-item
|
||||||
@@ -82,7 +82,7 @@
|
|||||||
placeholder="服务器名称"
|
placeholder="服务器名称"
|
||||||
/>
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
|
||||||
<n-form-item label="等级">
|
<n-form-item label="等级">
|
||||||
<n-input-number
|
<n-input-number
|
||||||
v-model:value="importForm.level"
|
v-model:value="importForm.level"
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
placeholder="角色等级"
|
placeholder="角色等级"
|
||||||
/>
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
|
||||||
<n-form-item label="职业">
|
<n-form-item label="职业">
|
||||||
<n-select
|
<n-select
|
||||||
v-model:value="importForm.profession"
|
v-model:value="importForm.profession"
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
placeholder="选择职业"
|
placeholder="选择职业"
|
||||||
/>
|
/>
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
|
|
||||||
<n-form-item label="WebSocket URL (可选)">
|
<n-form-item label="WebSocket URL (可选)">
|
||||||
<n-input
|
<n-input
|
||||||
v-model:value="importForm.wsUrl"
|
v-model:value="importForm.wsUrl"
|
||||||
@@ -114,7 +114,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</n-collapse-item>
|
</n-collapse-item>
|
||||||
</n-collapse>
|
</n-collapse>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
<n-button
|
<n-button
|
||||||
type="primary"
|
type="primary"
|
||||||
@@ -128,7 +128,7 @@
|
|||||||
</template>
|
</template>
|
||||||
导入Token
|
导入Token
|
||||||
</n-button>
|
</n-button>
|
||||||
|
|
||||||
<n-button
|
<n-button
|
||||||
v-if="tokenStore.hasTokens"
|
v-if="tokenStore.hasTokens"
|
||||||
size="large"
|
size="large"
|
||||||
@@ -160,7 +160,7 @@
|
|||||||
</template>
|
</template>
|
||||||
添加Token
|
添加Token
|
||||||
</n-button>
|
</n-button>
|
||||||
|
|
||||||
<n-dropdown
|
<n-dropdown
|
||||||
:options="bulkOptions"
|
:options="bulkOptions"
|
||||||
@select="handleBulkAction"
|
@select="handleBulkAction"
|
||||||
@@ -174,13 +174,13 @@
|
|||||||
</n-dropdown>
|
</n-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tokens-grid">
|
<div class="tokens-grid">
|
||||||
<div
|
<div
|
||||||
v-for="token in tokenStore.gameTokens"
|
v-for="token in tokenStore.gameTokens"
|
||||||
:key="token.id"
|
:key="token.id"
|
||||||
class="token-card"
|
class="token-card"
|
||||||
:class="{
|
:class="{
|
||||||
active: token.id === tokenStore.selectedTokenId,
|
active: token.id === tokenStore.selectedTokenId,
|
||||||
connected: getConnectionStatus(token.id) === 'connected'
|
connected: getConnectionStatus(token.id) === 'connected'
|
||||||
}"
|
}"
|
||||||
@@ -206,7 +206,7 @@
|
|||||||
>{{ token.profession }}</span>
|
>{{ token.profession }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<n-dropdown
|
<n-dropdown
|
||||||
:options="getTokenActions(token)"
|
:options="getTokenActions(token)"
|
||||||
@@ -220,24 +220,24 @@
|
|||||||
</n-dropdown>
|
</n-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="token-display">
|
<div class="token-display">
|
||||||
<span class="token-label">Token:</span>
|
<span class="token-label">Token:</span>
|
||||||
<code class="token-value">{{ maskToken(token.token) }}</code>
|
<code class="token-value">{{ maskToken(token.token) }}</code>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="connection-status">
|
<div class="connection-status">
|
||||||
<div class="status-indicator">
|
<div class="status-indicator">
|
||||||
<span
|
<span
|
||||||
class="status-dot"
|
class="status-dot"
|
||||||
:class="getConnectionStatus(token.id)"
|
:class="getConnectionStatus(token.id)"
|
||||||
/>
|
/>
|
||||||
<span class="status-text">
|
<span class="status-text">
|
||||||
{{ getConnectionStatusText(token.id) }}
|
{{ getConnectionStatusText(token.id) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<n-button
|
<n-button
|
||||||
size="small"
|
size="small"
|
||||||
:type="getConnectionStatus(token.id) === 'connected' ? 'warning' : 'primary'"
|
:type="getConnectionStatus(token.id) === 'connected' ? 'warning' : 'primary'"
|
||||||
@@ -246,7 +246,7 @@
|
|||||||
{{ getConnectionStatus(token.id) === 'connected' ? '断开' : '连接' }}
|
{{ getConnectionStatus(token.id) === 'connected' ? '断开' : '连接' }}
|
||||||
</n-button>
|
</n-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="token-timestamps">
|
<div class="token-timestamps">
|
||||||
<div class="timestamp-item">
|
<div class="timestamp-item">
|
||||||
<span class="timestamp-label">创建:</span>
|
<span class="timestamp-label">创建:</span>
|
||||||
@@ -258,7 +258,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="token.id === tokenStore.selectedTokenId"
|
v-if="token.id === tokenStore.selectedTokenId"
|
||||||
class="card-footer"
|
class="card-footer"
|
||||||
@@ -342,7 +342,7 @@
|
|||||||
<n-input v-model:value="editForm.wsUrl" />
|
<n-input v-model:value="editForm.wsUrl" />
|
||||||
</n-form-item>
|
</n-form-item>
|
||||||
</n-form>
|
</n-form>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<div class="modal-actions">
|
<div class="modal-actions">
|
||||||
<n-button @click="showEditModal = false">
|
<n-button @click="showEditModal = false">
|
||||||
@@ -442,11 +442,11 @@ const bulkOptions = [
|
|||||||
// 方法
|
// 方法
|
||||||
const handleImport = async () => {
|
const handleImport = async () => {
|
||||||
if (!importFormRef.value) return
|
if (!importFormRef.value) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await importFormRef.value.validate()
|
await importFormRef.value.validate()
|
||||||
isImporting.value = true
|
isImporting.value = true
|
||||||
|
|
||||||
const result = tokenStore.importBase64Token(
|
const result = tokenStore.importBase64Token(
|
||||||
importForm.name,
|
importForm.name,
|
||||||
importForm.base64Token,
|
importForm.base64Token,
|
||||||
@@ -457,7 +457,7 @@ const handleImport = async () => {
|
|||||||
wsUrl: importForm.wsUrl
|
wsUrl: importForm.wsUrl
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
message.success(result.message)
|
message.success(result.message)
|
||||||
resetImportForm()
|
resetImportForm()
|
||||||
@@ -503,7 +503,7 @@ const getConnectionStatusText = (tokenId) => {
|
|||||||
|
|
||||||
const toggleConnection = (token) => {
|
const toggleConnection = (token) => {
|
||||||
const status = getConnectionStatus(token.id)
|
const status = getConnectionStatus(token.id)
|
||||||
|
|
||||||
if (status === 'connected') {
|
if (status === 'connected') {
|
||||||
tokenStore.closeWebSocketConnection(token.id)
|
tokenStore.closeWebSocketConnection(token.id)
|
||||||
message.info('WebSocket连接已断开')
|
message.info('WebSocket连接已断开')
|
||||||
@@ -552,10 +552,10 @@ const editToken = (token) => {
|
|||||||
|
|
||||||
const saveEdit = async () => {
|
const saveEdit = async () => {
|
||||||
if (!editFormRef.value || !editingToken.value) return
|
if (!editFormRef.value || !editingToken.value) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await editFormRef.value.validate()
|
await editFormRef.value.validate()
|
||||||
|
|
||||||
tokenStore.updateToken(editingToken.value.id, {
|
tokenStore.updateToken(editingToken.value.id, {
|
||||||
name: editForm.name,
|
name: editForm.name,
|
||||||
server: editForm.server,
|
server: editForm.server,
|
||||||
@@ -563,7 +563,7 @@ const saveEdit = async () => {
|
|||||||
profession: editForm.profession,
|
profession: editForm.profession,
|
||||||
wsUrl: editForm.wsUrl
|
wsUrl: editForm.wsUrl
|
||||||
})
|
})
|
||||||
|
|
||||||
message.success('Token信息已更新')
|
message.success('Token信息已更新')
|
||||||
showEditModal.value = false
|
showEditModal.value = false
|
||||||
editingToken.value = null
|
editingToken.value = null
|
||||||
@@ -627,12 +627,12 @@ const exportTokens = () => {
|
|||||||
const data = tokenStore.exportTokens()
|
const data = tokenStore.exportTokens()
|
||||||
const dataStr = JSON.stringify(data, null, 2)
|
const dataStr = JSON.stringify(data, null, 2)
|
||||||
const dataBlob = new Blob([dataStr], { type: 'application/json' })
|
const dataBlob = new Blob([dataStr], { type: 'application/json' })
|
||||||
|
|
||||||
const link = document.createElement('a')
|
const link = document.createElement('a')
|
||||||
link.href = URL.createObjectURL(dataBlob)
|
link.href = URL.createObjectURL(dataBlob)
|
||||||
link.download = `tokens_backup_${new Date().toISOString().split('T')[0]}.json`
|
link.download = `tokens_backup_${new Date().toISOString().split('T')[0]}.json`
|
||||||
link.click()
|
link.click()
|
||||||
|
|
||||||
message.success('Token数据已导出')
|
message.success('Token数据已导出')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
message.error('导出失败')
|
message.error('导出失败')
|
||||||
@@ -709,7 +709,7 @@ const goToDashboard = () => {
|
|||||||
// 生命周期
|
// 生命周期
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
tokenStore.initTokenStore()
|
tokenStore.initTokenStore()
|
||||||
|
|
||||||
// 如果没有token,显示导入表单
|
// 如果没有token,显示导入表单
|
||||||
if (!tokenStore.hasTokens) {
|
if (!tokenStore.hasTokens) {
|
||||||
showImportForm.value = true
|
showImportForm.value = true
|
||||||
@@ -782,7 +782,7 @@ onMounted(() => {
|
|||||||
.card-header {
|
.card-header {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: var(--spacing-xl);
|
margin-bottom: var(--spacing-xl);
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -792,16 +792,16 @@ onMounted(() => {
|
|||||||
font-size: var(--font-size-xl);
|
font-size: var(--font-size-xl);
|
||||||
margin-bottom: var(--spacing-sm);
|
margin-bottom: var(--spacing-sm);
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
margin: 0 0 var(--spacing-md) 0;
|
margin: 0 0 var(--spacing-md) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.help-info {
|
.help-info {
|
||||||
margin-top: var(--spacing-md);
|
margin-top: var(--spacing-md);
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
||||||
code {
|
code {
|
||||||
background: rgba(24, 160, 88, 0.1);
|
background: rgba(24, 160, 88, 0.1);
|
||||||
color: var(--success-color);
|
color: var(--success-color);
|
||||||
@@ -838,7 +838,7 @@ onMounted(() => {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: var(--spacing-xl);
|
margin-bottom: var(--spacing-xl);
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
font-size: var(--font-size-xl);
|
font-size: var(--font-size-xl);
|
||||||
@@ -863,17 +863,17 @@ onMounted(() => {
|
|||||||
padding: var(--spacing-lg);
|
padding: var(--spacing-lg);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all var(--transition-normal);
|
transition: all var(--transition-normal);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
box-shadow: var(--shadow-medium);
|
box-shadow: var(--shadow-medium);
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
border-color: var(--primary-color);
|
border-color: var(--primary-color);
|
||||||
box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1);
|
box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.connected {
|
&.connected {
|
||||||
border-left: 4px solid var(--success-color);
|
border-left: 4px solid var(--success-color);
|
||||||
}
|
}
|
||||||
@@ -956,15 +956,15 @@ onMounted(() => {
|
|||||||
height: 8px;
|
height: 8px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: var(--text-tertiary);
|
background: var(--text-tertiary);
|
||||||
|
|
||||||
&.connected {
|
&.connected {
|
||||||
background: var(--success-color);
|
background: var(--success-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.connecting {
|
&.connecting {
|
||||||
background: var(--warning-color);
|
background: var(--warning-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.error {
|
&.error {
|
||||||
background: var(--error-color);
|
background: var(--error-color);
|
||||||
}
|
}
|
||||||
@@ -1022,23 +1022,23 @@ onMounted(() => {
|
|||||||
.container {
|
.container {
|
||||||
padding: 0 var(--spacing-md);
|
padding: 0 var(--spacing-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tokens-grid {
|
.tokens-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.optional-fields {
|
.optional-fields {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-header {
|
.section-header {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: var(--spacing-md);
|
gap: var(--spacing-md);
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.token-timestamps {
|
.token-timestamps {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user