diff --git a/web-admin/src/App.vue b/web-admin/src/App.vue
index 0a00084..aa83cc9 100644
--- a/web-admin/src/App.vue
+++ b/web-admin/src/App.vue
@@ -6,6 +6,11 @@
diff --git a/web-admin/src/components/AiConfigQuickActions.vue b/web-admin/src/components/AiConfigQuickActions.vue
index d823b53..4790ae3 100644
--- a/web-admin/src/components/AiConfigQuickActions.vue
+++ b/web-admin/src/components/AiConfigQuickActions.vue
@@ -143,18 +143,19 @@ onMounted(() => {
align-items: center;
gap: 12px;
padding: 12px;
- border: 1px solid #e4e7ed;
- border-radius: 8px;
+ border: 1px solid rgba(255, 255, 255, 0.08);
+ border-radius: var(--ls-radius-md);
+ background: rgba(255, 255, 255, 0.02);
transition: all 0.3s;
&:hover {
- border-color: #409eff;
- background-color: #f0f9ff;
+ border-color: rgba(255, 171, 145, 0.28);
+ background: rgba(255, 171, 145, 0.06);
}
.action-icon {
font-size: 24px;
- color: #409eff;
+ color: var(--ls-accent-orange);
}
.action-content {
@@ -163,13 +164,13 @@ onMounted(() => {
.action-title {
font-size: 14px;
font-weight: 500;
- color: #333;
+ color: rgba(226, 232, 240, 0.92);
margin-bottom: 4px;
}
.action-desc {
font-size: 12px;
- color: #999;
+ color: rgba(226, 232, 240, 0.6);
}
}
}
diff --git a/web-admin/src/layouts/Layout.vue b/web-admin/src/layouts/Layout.vue
index 2ac3a53..e736a67 100644
--- a/web-admin/src/layouts/Layout.vue
+++ b/web-admin/src/layouts/Layout.vue
@@ -115,10 +115,14 @@ onMounted(() => {
diff --git a/web-admin/src/main.ts b/web-admin/src/main.ts
index 05dcea8..4898550 100644
--- a/web-admin/src/main.ts
+++ b/web-admin/src/main.ts
@@ -1,6 +1,11 @@
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
+/**
+ * 全局主题样式:
+ * - 仅覆盖样式,确保 web-admin 视觉风格与 life-script 对齐
+ */
+import './styles/life-script-theme.scss'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import App from './App.vue'
import router from './router'
diff --git a/web-admin/src/styles/life-script-theme.scss b/web-admin/src/styles/life-script-theme.scss
new file mode 100644
index 0000000..9d747bb
--- /dev/null
+++ b/web-admin/src/styles/life-script-theme.scss
@@ -0,0 +1,393 @@
+/**
+ * web-admin 全局主题(对齐 life-script 视觉风格)
+ *
+ * 目标:
+ * - 深色基底 + 玻璃拟态(glassmorphism)
+ * - 橙/蓝点缀色(accent)
+ * - 更大的圆角、更柔和的阴影、更一致的 hover/active 反馈
+ *
+ * 说明:
+ * - 仅做样式覆盖,不涉及任何业务逻辑与交互行为变更
+ * - 通过 CSS Variables 覆盖 Element Plus 主题变量,并对常用 el-* 组件做全局外观微调
+ */
+
+/* 使用国内镜像加载字体,避免 Google Fonts 访问超时(与 life-script 保持一致) */
+@import url('https://fonts.loli.net/css2?family=Noto+Serif+SC:wght@300;600&family=Noto+Sans+SC:wght@300;400;500&display=swap');
+
+:root {
+ /* ====== life-script tokens ====== */
+ --ls-bg: #0a0c10;
+ --ls-text: #e2e8f0;
+ --ls-text-muted: rgba(226, 232, 240, 0.7);
+
+ --ls-glass-bg: rgba(15, 17, 26, 0.4);
+ --ls-glass-bg-strong: rgba(15, 17, 26, 0.55);
+ --ls-glass-border: rgba(255, 255, 255, 0.08);
+ --ls-glass-border-strong: rgba(255, 255, 255, 0.14);
+ --ls-shadow: 0 20px 50px -12px rgba(0, 0, 0, 0.5);
+
+ --ls-accent-orange: #ffab91;
+ --ls-accent-blue: #81d4fa;
+
+ --ls-radius-xl: 32px;
+ --ls-radius-lg: 20px;
+ --ls-radius-md: 16px;
+
+ /* ====== Element Plus theme overrides(尽量使用官方变量名)====== */
+ --el-color-primary: var(--ls-accent-orange);
+ --el-color-success: #67c23a;
+ --el-color-warning: #e6a23c;
+ --el-color-danger: #f56c6c;
+ --el-color-info: var(--ls-accent-blue);
+
+ --el-bg-color: var(--ls-bg);
+ --el-bg-color-overlay: var(--ls-glass-bg-strong);
+ /**
+ * Element Plus 填充色:
+ * - 避免“白底控件”的观感,统一使用偏黑的玻璃面
+ */
+ --el-fill-color-blank: rgba(15, 17, 26, 0.28);
+ --el-fill-color-light: rgba(15, 17, 26, 0.34);
+ --el-fill-color: rgba(15, 17, 26, 0.40);
+ --el-fill-color-dark: rgba(15, 17, 26, 0.46);
+
+ --el-text-color-primary: var(--ls-text);
+ --el-text-color-regular: rgba(226, 232, 240, 0.85);
+ --el-text-color-secondary: rgba(226, 232, 240, 0.7);
+ --el-text-color-placeholder: rgba(226, 232, 240, 0.45);
+ --el-border-color: var(--ls-glass-border);
+ --el-border-color-light: rgba(255, 255, 255, 0.06);
+ --el-border-color-lighter: rgba(255, 255, 255, 0.05);
+ --el-border-color-extra-light: rgba(255, 255, 255, 0.04);
+
+ --el-border-radius-base: var(--ls-radius-md);
+ --el-border-radius-round: 999px;
+ --el-box-shadow-light: var(--ls-shadow);
+}
+
+* {
+ box-sizing: border-box;
+}
+
+html,
+body,
+#app {
+ height: 100%;
+}
+
+body {
+ margin: 0;
+ padding: 0;
+ overflow-x: hidden;
+ font-family: 'Noto Sans SC', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
+ -webkit-font-smoothing: antialiased;
+ color: var(--ls-text);
+ background-color: var(--ls-bg);
+}
+
+.font-serif {
+ font-family: 'Noto Serif SC', serif;
+}
+
+/* ====== 背景层(给整个后台一个 life-script 风格的氛围底)====== */
+#app {
+ background:
+ radial-gradient(1200px 800px at 10% 20%, rgba(255, 171, 145, 0.12), transparent 55%),
+ radial-gradient(900px 700px at 90% 10%, rgba(129, 212, 250, 0.10), transparent 50%),
+ radial-gradient(900px 700px at 70% 90%, rgba(255, 171, 145, 0.08), transparent 50%),
+ var(--ls-bg);
+}
+
+/* ====== 通用 glass 外观(与 life-script 对齐)====== */
+.glass-card,
+.el-card,
+.el-dialog,
+.el-message-box,
+.el-drawer {
+ background: var(--ls-glass-bg) !important;
+ border: 1px solid var(--ls-glass-border) !important;
+ border-radius: var(--ls-radius-xl) !important;
+ box-shadow: var(--ls-shadow) !important;
+ backdrop-filter: blur(25px) saturate(180%);
+ -webkit-backdrop-filter: blur(25px) saturate(180%);
+}
+
+.el-card__header {
+ border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
+}
+
+/* ====== 按钮(玻璃按钮/强调按钮)====== */
+.glass-btn,
+.el-button {
+ background: rgba(15, 17, 26, 0.35);
+ border: 1px solid rgba(255, 255, 255, 0.08);
+ color: var(--ls-text);
+ transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
+}
+
+.el-button:hover,
+.glass-btn:hover {
+ background: rgba(15, 17, 26, 0.25);
+ border-color: rgba(255, 255, 255, 0.18);
+ transform: translateY(-2px);
+}
+
+.el-button:active,
+.glass-btn:active {
+ transform: scale(0.98);
+}
+
+.el-button.is-disabled,
+.el-button.is-disabled:hover {
+ opacity: 0.5;
+ transform: none;
+}
+
+/* primary:用 life-script 的橙色作为主强调 */
+.el-button--primary {
+ background: rgba(255, 171, 145, 0.14) !important;
+ border-color: rgba(255, 171, 145, 0.35) !important;
+ color: var(--ls-accent-orange) !important;
+}
+.el-button--primary:hover {
+ background: var(--ls-accent-orange) !important;
+ color: #000 !important;
+ border-color: var(--ls-accent-orange) !important;
+}
+
+/* link 按钮在深色底上更清晰 */
+.el-button.is-link {
+ background: transparent !important;
+ border-color: transparent !important;
+}
+.el-button.is-link:hover {
+ background: rgba(255, 171, 145, 0.08) !important;
+ border-color: rgba(255, 171, 145, 0.12) !important;
+}
+
+/* ====== 输入框(glass-input 风格)====== */
+.glass-input,
+.el-input__wrapper,
+.el-textarea__inner {
+ background: rgba(0, 0, 0, 0.2) !important;
+ border: 1px solid rgba(255, 255, 255, 0.06) !important;
+ border-radius: var(--ls-radius-md) !important;
+ color: var(--ls-text) !important;
+ box-shadow: none !important;
+}
+
+.el-input__wrapper.is-focus,
+.el-textarea__inner:focus {
+ border-color: rgba(255, 171, 145, 0.55) !important;
+ box-shadow: 0 0 20px rgba(255, 171, 145, 0.10) !important;
+}
+
+.el-input__inner::placeholder,
+.el-textarea__inner::placeholder {
+ color: rgba(255, 255, 255, 0.35) !important;
+}
+
+/**
+ * 浏览器自动填充(尤其登录页)可能将输入框渲染为浅色/白底:
+ * - 强制覆盖为深色玻璃背景,避免出现白底
+ */
+input:-webkit-autofill,
+input:-webkit-autofill:hover,
+input:-webkit-autofill:focus,
+textarea:-webkit-autofill,
+textarea:-webkit-autofill:hover,
+textarea:-webkit-autofill:focus,
+select:-webkit-autofill,
+select:-webkit-autofill:hover,
+select:-webkit-autofill:focus {
+ -webkit-text-fill-color: var(--ls-text) !important;
+ box-shadow: 0 0 0 1000px rgba(0, 0, 0, 0.25) inset !important;
+ -webkit-box-shadow: 0 0 0 1000px rgba(0, 0, 0, 0.25) inset !important;
+ transition: background-color 9999s ease-out 0s;
+}
+
+/* ====== Tabs(border-card 默认面板偏白,统一改为深色玻璃)====== */
+.el-tabs--border-card {
+ background: var(--ls-glass-bg) !important;
+ border: 1px solid rgba(255, 255, 255, 0.06) !important;
+ border-radius: var(--ls-radius-xl) !important;
+ overflow: hidden;
+}
+
+.el-tabs--border-card > .el-tabs__header {
+ background: rgba(15, 17, 26, 0.35) !important;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
+}
+
+.el-tabs--border-card > .el-tabs__header .el-tabs__item {
+ color: rgba(226, 232, 240, 0.75) !important;
+}
+
+.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
+ color: var(--ls-accent-orange) !important;
+}
+
+.el-tabs__nav-wrap::after {
+ background-color: rgba(255, 255, 255, 0.06) !important;
+}
+
+.el-tabs__content {
+ background: transparent !important;
+}
+
+/* ====== Popper/Dropdown/Select/DatePicker 面板(避免白底)====== */
+.el-popper,
+.el-popper.is-light,
+.el-select__popper,
+.el-dropdown__popper,
+.el-autocomplete__popper,
+.el-tooltip__popper,
+.el-picker__popper {
+ background: rgba(15, 17, 26, 0.72) !important;
+ border: 1px solid rgba(255, 255, 255, 0.10) !important;
+ backdrop-filter: blur(25px) saturate(180%);
+ -webkit-backdrop-filter: blur(25px) saturate(180%);
+}
+
+.el-select-dropdown__item,
+.el-dropdown-menu__item {
+ color: rgba(226, 232, 240, 0.85) !important;
+}
+
+.el-select-dropdown__item.hover,
+.el-select-dropdown__item:hover,
+.el-dropdown-menu__item:hover {
+ background: rgba(255, 171, 145, 0.10) !important;
+}
+
+.el-select-dropdown__item.selected {
+ color: var(--ls-accent-orange) !important;
+}
+
+/* ====== 表格/分页(深色玻璃)====== */
+.el-table {
+ background: transparent !important;
+ color: var(--ls-text) !important;
+}
+.el-table th.el-table__cell {
+ background: rgba(255, 255, 255, 0.03) !important;
+ color: rgba(226, 232, 240, 0.85) !important;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
+}
+.el-table td.el-table__cell {
+ background: transparent !important;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.04) !important;
+}
+.el-table--striped .el-table__body tr.el-table__row--striped td.el-table__cell {
+ background: rgba(255, 255, 255, 0.02) !important;
+}
+.el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell {
+ background: rgba(255, 171, 145, 0.06) !important;
+}
+
+.el-pagination {
+ color: rgba(226, 232, 240, 0.85) !important;
+}
+
+/* ====== 弹窗(对话框/MessageBox)====== */
+.el-dialog__header {
+ margin-right: 0 !important;
+ border-bottom: 1px solid rgba(255, 255, 255, 0.06);
+}
+.el-dialog__title {
+ color: var(--ls-text) !important;
+}
+
+/* ====== Tag/Statistic 等小组件可读性 ====== */
+.el-tag {
+ /**
+ * Tag 在深色玻璃主题下默认背景会偏亮,导致“白底字段”观感:
+ * - 统一改为深色玻璃底
+ * - 不同 type 使用对应色系做文字/边框强调
+ */
+ background: rgba(15, 17, 26, 0.38) !important;
+ border: 1px solid rgba(255, 255, 255, 0.10) !important;
+ color: rgba(226, 232, 240, 0.85) !important;
+}
+
+/* Tag 颜色语义:保持可读性与 life-script 点缀风格一致 */
+.el-tag--primary {
+ background: rgba(255, 171, 145, 0.12) !important;
+ border-color: rgba(255, 171, 145, 0.28) !important;
+ color: var(--ls-accent-orange) !important;
+}
+
+.el-tag--success {
+ background: rgba(103, 194, 58, 0.12) !important;
+ border-color: rgba(103, 194, 58, 0.28) !important;
+ color: rgba(199, 255, 176, 0.95) !important;
+}
+
+.el-tag--warning {
+ background: rgba(230, 162, 60, 0.12) !important;
+ border-color: rgba(230, 162, 60, 0.28) !important;
+ color: rgba(255, 220, 160, 0.95) !important;
+}
+
+.el-tag--danger {
+ background: rgba(245, 108, 108, 0.12) !important;
+ border-color: rgba(245, 108, 108, 0.30) !important;
+ color: rgba(255, 190, 190, 0.95) !important;
+}
+
+.el-tag--info {
+ background: rgba(129, 212, 250, 0.10) !important;
+ border-color: rgba(129, 212, 250, 0.26) !important;
+ color: var(--ls-accent-blue) !important;
+}
+
+/* plain 模式也避免浅底 */
+.el-tag.is-plain {
+ background: rgba(15, 17, 26, 0.28) !important;
+}
+
+/* ====== Descriptions(详情展示默认也可能偏白)====== */
+.el-descriptions,
+.el-descriptions__body,
+.el-descriptions__table {
+ background: transparent !important;
+ color: var(--ls-text) !important;
+}
+
+.el-descriptions__cell {
+ background: rgba(15, 17, 26, 0.24) !important;
+ border-color: rgba(255, 255, 255, 0.06) !important;
+ color: rgba(226, 232, 240, 0.85) !important;
+}
+
+.el-descriptions__label {
+ color: rgba(226, 232, 240, 0.65) !important;
+}
+
+.el-descriptions__content {
+ color: rgba(226, 232, 240, 0.90) !important;
+}
+.el-statistic__head {
+ color: rgba(226, 232, 240, 0.7) !important;
+}
+.el-statistic__content {
+ color: var(--ls-text) !important;
+}
+
+/* ====== 滚动条(与 life-script 接近)====== */
+*::-webkit-scrollbar {
+ width: 4px;
+ height: 4px;
+}
+*::-webkit-scrollbar-track {
+ background: transparent;
+}
+*::-webkit-scrollbar-thumb {
+ background: rgba(255, 255, 255, 0.08);
+ border-radius: 10px;
+}
+*::-webkit-scrollbar-thumb:hover {
+ background: rgba(255, 255, 255, 0.15);
+}
+
+
diff --git a/web-admin/src/views/Dashboard.vue b/web-admin/src/views/Dashboard.vue
index 754bd91..42baa20 100644
--- a/web-admin/src/views/Dashboard.vue
+++ b/web-admin/src/views/Dashboard.vue
@@ -498,7 +498,7 @@ const updateUserChart = () => {
.page-title {
margin: 0;
font-size: 24px;
- color: #333;
+ color: var(--ls-text);
}
.dashboard-actions {
@@ -535,13 +535,13 @@ const updateUserChart = () => {
.stat-value {
font-size: 28px;
font-weight: bold;
- color: #333;
+ color: var(--ls-text);
margin-bottom: 5px;
}
.stat-label {
font-size: 14px;
- color: #999;
+ color: rgba(226, 232, 240, 0.65);
}
}
}
@@ -563,7 +563,7 @@ const updateUserChart = () => {
.nickname {
font-size: 14px;
font-weight: 500;
- color: #333;
+ color: rgba(226, 232, 240, 0.9);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
@@ -571,7 +571,7 @@ const updateUserChart = () => {
.username {
font-size: 12px;
- color: #999;
+ color: rgba(226, 232, 240, 0.6);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
diff --git a/web-admin/src/views/Login.vue b/web-admin/src/views/Login.vue
index e5d8a4d..410ff50 100644
--- a/web-admin/src/views/Login.vue
+++ b/web-admin/src/views/Login.vue
@@ -93,15 +93,33 @@ const handleLogin = async () => {
justify-content: center;
align-items: center;
min-height: 100vh;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+ background: var(--ls-bg);
+ position: relative;
+ overflow: hidden;
+}
+
+.login-container::before {
+ content: '';
+ position: absolute;
+ inset: -20%;
+ background:
+ radial-gradient(700px 500px at 20% 30%, rgba(255, 171, 145, 0.18), transparent 55%),
+ radial-gradient(650px 500px at 80% 20%, rgba(129, 212, 250, 0.14), transparent 55%),
+ radial-gradient(800px 600px at 60% 80%, rgba(255, 171, 145, 0.10), transparent 55%);
+ filter: blur(0px);
+ pointer-events: none;
}
.login-box {
width: 400px;
padding: 40px;
- background: #fff;
- border-radius: 10px;
- box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
+ background: var(--ls-glass-bg);
+ border: 1px solid var(--ls-glass-border);
+ border-radius: var(--ls-radius-xl);
+ box-shadow: var(--ls-shadow);
+ backdrop-filter: blur(25px) saturate(180%);
+ -webkit-backdrop-filter: blur(25px) saturate(180%);
+ position: relative;
}
.login-header {
@@ -110,13 +128,13 @@ const handleLogin = async () => {
h2 {
font-size: 24px;
- color: #333;
+ color: var(--ls-text);
margin-bottom: 10px;
}
p {
font-size: 14px;
- color: #999;
+ color: rgba(226, 232, 240, 0.7);
}
}
@@ -132,7 +150,7 @@ const handleLogin = async () => {
p {
font-size: 12px;
- color: #999;
+ color: rgba(226, 232, 240, 0.6);
}
}
diff --git a/web-admin/src/views/NotFound.vue b/web-admin/src/views/NotFound.vue
index 057574d..053f943 100644
--- a/web-admin/src/views/NotFound.vue
+++ b/web-admin/src/views/NotFound.vue
@@ -24,20 +24,20 @@ const goHome = () => {
justify-content: center;
align-items: center;
min-height: 100vh;
- background-color: #f0f2f5;
+ background-color: var(--ls-bg);
.content {
text-align: center;
h1 {
font-size: 120px;
- color: #409eff;
+ color: var(--ls-accent-orange);
margin-bottom: 20px;
}
p {
font-size: 24px;
- color: #666;
+ color: rgba(226, 232, 240, 0.75);
margin-bottom: 30px;
}
}
diff --git a/web-admin/src/views/admin/AdminList.vue b/web-admin/src/views/admin/AdminList.vue
index c374c24..e97dfed 100644
--- a/web-admin/src/views/admin/AdminList.vue
+++ b/web-admin/src/views/admin/AdminList.vue
@@ -296,7 +296,7 @@ onMounted(() => {
.page-title {
margin-bottom: 20px;
font-size: 24px;
- color: #333;
+ color: var(--ls-text);
}
.search-card {
diff --git a/web-admin/src/views/aiconfig/AiConfigList.vue b/web-admin/src/views/aiconfig/AiConfigList.vue
index 3506eee..402fecc 100644
--- a/web-admin/src/views/aiconfig/AiConfigList.vue
+++ b/web-admin/src/views/aiconfig/AiConfigList.vue
@@ -1581,7 +1581,7 @@ onMounted(() => {
.page-title {
margin-bottom: 20px;
font-size: 24px;
- color: #333;
+ color: var(--ls-text);
}
.search-card {
@@ -1614,8 +1614,9 @@ onMounted(() => {
.stats-row {
margin-bottom: 20px;
padding: 20px;
- background: #f8f9fa;
- border-radius: 8px;
+ background: rgba(255, 255, 255, 0.03);
+ border: 1px solid rgba(255, 255, 255, 0.06);
+ border-radius: var(--ls-radius-lg);
}
.pagination {
@@ -1627,7 +1628,7 @@ onMounted(() => {
.form-tip {
margin-left: 10px;
font-size: 12px;
- color: #999;
+ color: rgba(226, 232, 240, 0.6);
}
}
@@ -1635,8 +1636,8 @@ onMounted(() => {
.test-section {
h4 {
margin-bottom: 20px;
- color: #333;
- border-bottom: 2px solid #409eff;
+ color: var(--ls-text);
+ border-bottom: 2px solid rgba(255, 171, 145, 0.6);
padding-bottom: 8px;
}
@@ -1646,7 +1647,7 @@ onMounted(() => {
gap: 8px;
.info-icon {
- color: #909399;
+ color: rgba(226, 232, 240, 0.6);
cursor: help;
}
}
diff --git a/web-admin/src/views/dictionary/DictionaryForm.vue b/web-admin/src/views/dictionary/DictionaryForm.vue
index 24ffa05..2c5e791 100644
--- a/web-admin/src/views/dictionary/DictionaryForm.vue
+++ b/web-admin/src/views/dictionary/DictionaryForm.vue
@@ -69,7 +69,7 @@
diff --git a/web-admin/src/views/user/UserList.vue b/web-admin/src/views/user/UserList.vue
index 128e165..450f2e0 100644
--- a/web-admin/src/views/user/UserList.vue
+++ b/web-admin/src/views/user/UserList.vue
@@ -190,7 +190,7 @@ onMounted(() => {
.page-title {
margin-bottom: 20px;
font-size: 24px;
- color: #333;
+ color: var(--ls-text);
}
.search-card {