refactor(ClientView): 重构客户端视图界面样式和组件结构
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 38s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 1m25s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 1m31s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 1m25s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 1m46s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 1m15s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 1m40s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 1m39s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 1m49s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 1m27s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 1m56s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 1m16s
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 38s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 1m25s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 1m31s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 1m25s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 1m46s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 1m15s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 1m40s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 1m39s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 1m49s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 1m27s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 1m56s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 1m16s
- 替换 naive-ui 组件为自定义玻璃态设计组件 - 添加粒子动画背景效果 - 优化页面布局结构和响应式设计 - 移除未使用的 NCard、NTable、NStatistic 等组件导入 - 重构规则表格和插件列表的展示方式 - 更新模态框标题和简化配置表单 - 调整头部导航和底部栏样式 - 优化卡片组件的视觉效果和交互反馈
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import {
|
||||
NCard, NButton, NSpace, NTag, NGrid, NGi, NEmpty, NSpin, NIcon,
|
||||
NAlert, useMessage, useDialog
|
||||
NTag, NIcon, useMessage, useDialog
|
||||
} from 'naive-ui'
|
||||
import { CloudDownloadOutline, RefreshOutline, ServerOutline } from '@vicons/ionicons5'
|
||||
import {
|
||||
@@ -88,109 +87,140 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="settings-view">
|
||||
<div class="page-header">
|
||||
<h2>系统设置</h2>
|
||||
<p>管理服务端配置和系统更新</p>
|
||||
<div class="settings-page">
|
||||
<!-- Particles -->
|
||||
<div class="particles">
|
||||
<div class="particle particle-1"></div>
|
||||
<div class="particle particle-2"></div>
|
||||
<div class="particle particle-3"></div>
|
||||
</div>
|
||||
|
||||
<n-spin :show="loading">
|
||||
<!-- 当前版本信息 -->
|
||||
<n-card title="版本信息" class="settings-card">
|
||||
<template #header-extra>
|
||||
<n-icon size="20" color="#6366f1"><ServerOutline /></n-icon>
|
||||
</template>
|
||||
<n-grid v-if="versionInfo" :cols="6" :x-gap="16" responsive="screen" cols-s="2" cols-m="3">
|
||||
<n-gi>
|
||||
<div class="info-item">
|
||||
<span class="label">版本号</span>
|
||||
<span class="value">{{ versionInfo.version }}</span>
|
||||
</div>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<div class="info-item">
|
||||
<span class="label">Git 提交</span>
|
||||
<span class="value">{{ versionInfo.git_commit?.slice(0, 8) || 'N/A' }}</span>
|
||||
</div>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<div class="info-item">
|
||||
<span class="label">构建时间</span>
|
||||
<span class="value">{{ versionInfo.build_time || 'N/A' }}</span>
|
||||
</div>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<div class="info-item">
|
||||
<span class="label">Go 版本</span>
|
||||
<span class="value">{{ versionInfo.go_version }}</span>
|
||||
</div>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<div class="info-item">
|
||||
<span class="label">操作系统</span>
|
||||
<span class="value">{{ versionInfo.os }}</span>
|
||||
</div>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<div class="info-item">
|
||||
<span class="label">架构</span>
|
||||
<span class="value">{{ versionInfo.arch }}</span>
|
||||
</div>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
<n-empty v-else description="加载中..." />
|
||||
</n-card>
|
||||
<div class="settings-content">
|
||||
<!-- Header -->
|
||||
<div class="page-header">
|
||||
<h1 class="page-title">系统设置</h1>
|
||||
<p class="page-subtitle">管理服务端配置和系统更新</p>
|
||||
</div>
|
||||
|
||||
<!-- 服务端更新 -->
|
||||
<n-card title="服务端更新" class="settings-card">
|
||||
<template #header-extra>
|
||||
<n-button size="small" :loading="checkingServer" @click="handleCheckServerUpdate">
|
||||
<template #icon><n-icon><RefreshOutline /></n-icon></template>
|
||||
<!-- Version Info Card -->
|
||||
<div class="glass-card">
|
||||
<div class="card-header">
|
||||
<h3>版本信息</h3>
|
||||
<n-icon size="20" color="#a78bfa"><ServerOutline /></n-icon>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div v-if="loading" class="loading-state">加载中...</div>
|
||||
<div v-else-if="versionInfo" class="info-grid">
|
||||
<div class="info-item">
|
||||
<span class="info-label">版本号</span>
|
||||
<span class="info-value">{{ versionInfo.version }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">Git 提交</span>
|
||||
<span class="info-value mono">{{ versionInfo.git_commit?.slice(0, 8) || 'N/A' }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">构建时间</span>
|
||||
<span class="info-value">{{ versionInfo.build_time || 'N/A' }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">Go 版本</span>
|
||||
<span class="info-value">{{ versionInfo.go_version }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">操作系统</span>
|
||||
<span class="info-value">{{ versionInfo.os }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="info-label">架构</span>
|
||||
<span class="info-value">{{ versionInfo.arch }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="empty-state">无法加载版本信息</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Server Update Card -->
|
||||
<div class="glass-card">
|
||||
<div class="card-header">
|
||||
<h3>服务端更新</h3>
|
||||
<button class="glass-btn small" :disabled="checkingServer" @click="handleCheckServerUpdate">
|
||||
<n-icon size="14"><RefreshOutline /></n-icon>
|
||||
检查更新
|
||||
</n-button>
|
||||
</template>
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div v-if="!serverUpdate" class="empty-state">
|
||||
点击检查更新按钮查看是否有新版本
|
||||
</div>
|
||||
<template v-else>
|
||||
<div v-if="serverUpdate.available" class="update-alert success">
|
||||
发现新版本 {{ serverUpdate.latest }},当前版本 {{ serverUpdate.current }}
|
||||
</div>
|
||||
<div v-else class="update-alert info">
|
||||
当前已是最新版本 {{ serverUpdate.current }}
|
||||
</div>
|
||||
|
||||
<n-empty v-if="!serverUpdate" description="点击检查更新按钮查看是否有新版本" />
|
||||
|
||||
<template v-else>
|
||||
<n-alert v-if="serverUpdate.available" type="success" style="margin-bottom: 16px;">
|
||||
发现新版本 {{ serverUpdate.latest }},当前版本 {{ serverUpdate.current }}
|
||||
</n-alert>
|
||||
<n-alert v-else type="info" style="margin-bottom: 16px;">
|
||||
当前已是最新版本 {{ serverUpdate.current }}
|
||||
</n-alert>
|
||||
|
||||
<n-space vertical :size="12">
|
||||
<div v-if="serverUpdate.download_url">
|
||||
<p style="margin: 0 0 8px 0; color: #666;">
|
||||
下载文件: {{ serverUpdate.asset_name }}
|
||||
<n-tag size="small" style="margin-left: 8px;">{{ formatBytes(serverUpdate.asset_size) }}</n-tag>
|
||||
</p>
|
||||
<div v-if="serverUpdate.download_url" class="download-info">
|
||||
下载文件: {{ serverUpdate.asset_name }}
|
||||
<n-tag size="small" style="margin-left: 8px;">{{ formatBytes(serverUpdate.asset_size) }}</n-tag>
|
||||
</div>
|
||||
|
||||
<div v-if="serverUpdate.release_note" class="release-note">
|
||||
<p style="margin: 0 0 4px 0; color: #666; font-size: 12px;">更新日志:</p>
|
||||
<span class="note-label">更新日志:</span>
|
||||
<pre>{{ serverUpdate.release_note }}</pre>
|
||||
</div>
|
||||
|
||||
<n-button
|
||||
<button
|
||||
v-if="serverUpdate.available && serverUpdate.download_url"
|
||||
type="primary"
|
||||
:loading="updatingServer"
|
||||
class="glass-btn primary"
|
||||
:disabled="updatingServer"
|
||||
@click="handleApplyServerUpdate"
|
||||
>
|
||||
<template #icon><n-icon><CloudDownloadOutline /></n-icon></template>
|
||||
<n-icon size="16"><CloudDownloadOutline /></n-icon>
|
||||
下载并更新服务端
|
||||
</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-card>
|
||||
</n-spin>
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.settings-view {
|
||||
.settings-page {
|
||||
min-height: calc(100vh - 108px);
|
||||
background: linear-gradient(135deg, #1e1b4b 0%, #312e81 30%, #4c1d95 60%, #581c87 100%);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
padding: 32px;
|
||||
}
|
||||
|
||||
.particles {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.particle {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0.05));
|
||||
animation: float-particle 20s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.particle-1 { width: 250px; height: 250px; top: -80px; right: -50px; }
|
||||
.particle-2 { width: 180px; height: 180px; bottom: 10%; left: 5%; animation-delay: -7s; }
|
||||
.particle-3 { width: 120px; height: 120px; top: 50%; right: 15%; animation-delay: -12s; }
|
||||
|
||||
@keyframes float-particle {
|
||||
0%, 100% { transform: translate(0, 0) scale(1); opacity: 0.3; }
|
||||
50% { transform: translate(-20px, -60px) scale(0.95); opacity: 0.4; }
|
||||
}
|
||||
|
||||
.settings-content {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
@@ -199,52 +229,169 @@ onMounted(() => {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.page-header h2 {
|
||||
.page-title {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: white;
|
||||
margin: 0 0 8px 0;
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: #1f2937;
|
||||
}
|
||||
|
||||
.page-header p {
|
||||
.page-subtitle {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
margin: 0;
|
||||
color: #6b7280;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.settings-card {
|
||||
margin-bottom: 16px;
|
||||
/* Glass Card */
|
||||
.glass-card {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border-radius: 16px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card-header h3 {
|
||||
margin: 0;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* Info Grid */
|
||||
.info-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.info-grid { grid-template-columns: repeat(2, 1fr); }
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 8px 0;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.info-item .label {
|
||||
.info-label {
|
||||
font-size: 12px;
|
||||
color: #9ca3af;
|
||||
margin-bottom: 4px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.info-item .value {
|
||||
.info-value {
|
||||
font-size: 14px;
|
||||
color: #1f2937;
|
||||
color: white;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.info-value.mono {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
/* States */
|
||||
.loading-state, .empty-state {
|
||||
text-align: center;
|
||||
padding: 32px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/* Update Alert */
|
||||
.update-alert {
|
||||
padding: 12px 16px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 16px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.update-alert.success {
|
||||
background: rgba(52, 211, 153, 0.15);
|
||||
border: 1px solid rgba(52, 211, 153, 0.3);
|
||||
color: #34d399;
|
||||
}
|
||||
|
||||
.update-alert.info {
|
||||
background: rgba(96, 165, 250, 0.15);
|
||||
border: 1px solid rgba(96, 165, 250, 0.3);
|
||||
color: #60a5fa;
|
||||
}
|
||||
|
||||
/* Download Info */
|
||||
.download-info {
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
font-size: 13px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
/* Release Note */
|
||||
.release-note {
|
||||
max-height: 150px;
|
||||
overflow-y: auto;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.note-label {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.release-note pre {
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
font-size: 12px;
|
||||
color: #374151;
|
||||
background: #f9fafb;
|
||||
color: rgba(255, 255, 255, 0.7);
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
padding: 12px;
|
||||
border-radius: 6px;
|
||||
border-radius: 8px;
|
||||
max-height: 150px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* Glass Button */
|
||||
.glass-btn {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
border-radius: 8px;
|
||||
padding: 8px 16px;
|
||||
color: white;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.glass-btn:hover:not(:disabled) {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.glass-btn:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.glass-btn.small {
|
||||
padding: 6px 12px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.glass-btn.primary {
|
||||
background: linear-gradient(135deg, #60a5fa 0%, #a78bfa 100%);
|
||||
border: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user