diff --git a/web/public/favicon-vue.ico b/web/public/favicon-vue.ico new file mode 100644 index 0000000..df36fcf Binary files /dev/null and b/web/public/favicon-vue.ico differ diff --git a/web/public/favicon.ico b/web/public/favicon.ico index df36fcf..f1ae864 100644 Binary files a/web/public/favicon.ico and b/web/public/favicon.ico differ diff --git a/web/src/App.vue b/web/src/App.vue index 19444e6..58309fa 100644 --- a/web/src/App.vue +++ b/web/src/App.vue @@ -1,15 +1,161 @@ - + +html, body, #app { + height: 100%; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; +} + +.app-container { + min-height: 100vh; + background: var(--bg-page); + max-width: 100%; +} + +/* 卡片通用样式 */ +.content-card { + background: var(--bg-card); + border-radius: 8px; + padding: 24px; + box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08); +} + +/* 页面标题样式 */ +.page-title { + font-size: 20px; + font-weight: 600; + color: var(--text-primary); + margin-bottom: 20px; + padding-bottom: 12px; + border-bottom: 1px solid var(--border-color); +} + +/* Section 标题 */ +.section-title { + font-size: 16px; + font-weight: 600; + color: var(--text-primary); + margin: 20px 0 16px; +} + +/* 按钮组样式 */ +.btn-group { + display: flex; + gap: 12px; + flex-wrap: wrap; +} + +/* 表格工具栏 */ +.table-toolbar { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 16px; + flex-wrap: wrap; + gap: 12px; +} + +/* Flex 布局工具类 */ +.flex-row { + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 12px; +} + +.flex-between { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 12px; +} + +/* Gap 间距 */ +.gap-sm { gap: 8px; } +.gap-md { gap: 12px; } +.gap-lg { gap: 16px; } + +/* 间距工具类 */ +.mt-sm { margin-top: 8px; } +.mt-md { margin-top: 16px; } +.mt-lg { margin-top: 24px; } +.mb-sm { margin-bottom: 8px; } +.mb-md { margin-bottom: 16px; } +.mb-lg { margin-bottom: 24px; } +.ml-sm { margin-left: 8px; } +.ml-md { margin-left: 12px; } +.ml-lg { margin-left: 16px; } +.mr-sm { margin-right: 8px; } +.mr-md { margin-right: 12px; } +.mr-lg { margin-right: 16px; } + +/* 文本工具类 */ +.text-primary { color: var(--text-primary); } +.text-success { color: var(--success-color); } +.text-warning { color: var(--warning-color); } +.text-danger { color: var(--danger-color); } +.text-info { color: var(--info-color); } + +/* 加载动画 */ +.loading-container { + display: flex; + justify-content: center; + align-items: center; + min-height: 200px; +} + +/* 空状态 */ +.empty-container { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 48px; + color: var(--text-secondary); +} + +/* 响应式 */ +@media (max-width: 768px) { + .content-card { + padding: 16px; + border-radius: 0; + } + + .hide-on-mobile { + display: none; + } +} + \ No newline at end of file diff --git a/web/src/views/AdminView.vue b/web/src/views/AdminView.vue index 1c70962..7206353 100644 --- a/web/src/views/AdminView.vue +++ b/web/src/views/AdminView.vue @@ -1,50 +1,224 @@ +.admin-header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 24px; + height: 60px; + background: var(--bg-header); + border-bottom: 1px solid var(--border-color); + position: sticky; + top: 0; + z-index: 100; +} + +.header-left { + display: flex; + align-items: center; +} + +.logo { + display: flex; + align-items: center; + gap: 10px; + color: var(--primary-color); + font-weight: 600; + font-size: 18px; +} + +.logo-text { + display: none; +} + +@media (min-width: 768px) { + .logo-text { + display: inline; + } +} + +.header-nav { + display: flex; + gap: 8px; +} + +.nav-item { + display: flex; + align-items: center; + gap: 6px; + padding: 8px 16px; + border-radius: 8px; + cursor: pointer; + color: var(--text-regular); + font-size: 14px; + transition: all 0.2s; +} + +.nav-item:hover { + background: var(--bg-page); + color: var(--text-primary); +} + +.nav-item.active { + background: var(--primary-color); + color: #fff; +} + +.header-right { + display: flex; + align-items: center; + gap: 12px; +} + +.admin-badge { + display: flex; + align-items: center; + gap: 6px; + padding: 6px 12px; + background: var(--danger-color); + color: #fff; + border-radius: 20px; + font-size: 13px; +} + +.admin-main { + flex: 1; + padding: 24px 48px; + max-width: 100%; + overflow-x: auto; +} + +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.2s ease; +} + +.fade-enter-from, +.fade-leave-to { + opacity: 0; +} + +@media (max-width: 768px) { + .admin-header { + padding: 0 16px; + flex-wrap: wrap; + height: auto; + padding: 12px 16px; + } + + .header-nav { + order: 3; + width: 100%; + margin-top: 12px; + overflow-x: auto; + } + + .nav-item { + padding: 8px 12px; + font-size: 13px; + } + + .nav-item span { + display: none; + } + + .admin-main { + padding: 16px; + } +} + \ No newline at end of file diff --git a/web/src/views/HomeView.vue b/web/src/views/HomeView.vue index e701f74..6818dcf 100644 --- a/web/src/views/HomeView.vue +++ b/web/src/views/HomeView.vue @@ -1,77 +1,275 @@ - \ No newline at end of file diff --git a/web/src/views/TokenDetailView.vue b/web/src/views/TokenDetailView.vue index b6aaccf..1cd4898 100644 --- a/web/src/views/TokenDetailView.vue +++ b/web/src/views/TokenDetailView.vue @@ -1,198 +1,533 @@ - \ No newline at end of file diff --git a/web/src/views/TokenManageView.vue b/web/src/views/TokenManageView.vue index e65aafb..3853f1c 100644 --- a/web/src/views/TokenManageView.vue +++ b/web/src/views/TokenManageView.vue @@ -1,304 +1,520 @@