后台管理系统优化
This commit is contained in:
@@ -6,6 +6,11 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
/**
|
||||||
|
* 全局基础样式(仅样式,不涉及业务逻辑)
|
||||||
|
* - 由 life-script-theme.scss 提供主题变量与 Element Plus 覆盖
|
||||||
|
* - 这里保留基础 reset 与高度设置
|
||||||
|
*/
|
||||||
* {
|
* {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@@ -14,6 +19,6 @@
|
|||||||
|
|
||||||
html, body, #app {
|
html, body, #app {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
font-family: 'Noto Sans SC', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -143,18 +143,19 @@ onMounted(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
border: 1px solid #e4e7ed;
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||||
border-radius: 8px;
|
border-radius: var(--ls-radius-md);
|
||||||
|
background: rgba(255, 255, 255, 0.02);
|
||||||
transition: all 0.3s;
|
transition: all 0.3s;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: #409eff;
|
border-color: rgba(255, 171, 145, 0.28);
|
||||||
background-color: #f0f9ff;
|
background: rgba(255, 171, 145, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-icon {
|
.action-icon {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
color: #409eff;
|
color: var(--ls-accent-orange);
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-content {
|
.action-content {
|
||||||
@@ -163,13 +164,13 @@ onMounted(() => {
|
|||||||
.action-title {
|
.action-title {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #333;
|
color: rgba(226, 232, 240, 0.92);
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-desc {
|
.action-desc {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #999;
|
color: rgba(226, 232, 240, 0.6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,10 +115,14 @@ onMounted(() => {
|
|||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.layout-container {
|
.layout-container {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
background-color: #304156;
|
background: var(--ls-glass-bg);
|
||||||
|
border-right: 1px solid var(--ls-glass-border);
|
||||||
|
backdrop-filter: blur(25px) saturate(180%);
|
||||||
|
-webkit-backdrop-filter: blur(25px) saturate(180%);
|
||||||
transition: width 0.3s;
|
transition: width 0.3s;
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
@@ -127,25 +131,30 @@ onMounted(() => {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #fff;
|
color: var(--ls-text);
|
||||||
background-color: #2b3a4b;
|
background: rgba(255, 255, 255, 0.02);
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-menu) {
|
:deep(.el-menu) {
|
||||||
border-right: none;
|
border-right: none;
|
||||||
background-color: #304156;
|
background: transparent;
|
||||||
|
|
||||||
.el-menu-item,
|
.el-menu-item,
|
||||||
.el-sub-menu__title {
|
.el-sub-menu__title {
|
||||||
color: #bfcbd9;
|
color: rgba(226, 232, 240, 0.75);
|
||||||
|
border-radius: 14px;
|
||||||
|
margin: 6px 10px;
|
||||||
|
height: 44px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: #263445;
|
background: rgba(255, 255, 255, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.is-active {
|
&.is-active {
|
||||||
background-color: #409eff;
|
background: rgba(255, 171, 145, 0.08);
|
||||||
color: #fff;
|
border: 1px solid rgba(255, 171, 145, 0.20);
|
||||||
|
color: var(--ls-accent-orange) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -155,17 +164,21 @@ onMounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: #fff;
|
background: var(--ls-glass-bg);
|
||||||
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
|
||||||
|
box-shadow: none;
|
||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
|
backdrop-filter: blur(25px) saturate(180%);
|
||||||
|
-webkit-backdrop-filter: blur(25px) saturate(180%);
|
||||||
|
|
||||||
.header-left {
|
.header-left {
|
||||||
.collapse-icon {
|
.collapse-icon {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
color: rgba(226, 232, 240, 0.85);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: #409eff;
|
color: var(--ls-accent-orange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,6 +189,7 @@ onMounted(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
color: rgba(226, 232, 240, 0.9);
|
||||||
|
|
||||||
.username {
|
.username {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
@@ -185,7 +199,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.main-content {
|
.main-content {
|
||||||
background-color: #f0f2f5;
|
background: transparent;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import ElementPlus from 'element-plus'
|
import ElementPlus from 'element-plus'
|
||||||
import 'element-plus/dist/index.css'
|
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 * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import router from './router'
|
import router from './router'
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -498,7 +498,7 @@ const updateUserChart = () => {
|
|||||||
.page-title {
|
.page-title {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
color: #333;
|
color: var(--ls-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-actions {
|
.dashboard-actions {
|
||||||
@@ -535,13 +535,13 @@ const updateUserChart = () => {
|
|||||||
.stat-value {
|
.stat-value {
|
||||||
font-size: 28px;
|
font-size: 28px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #333;
|
color: var(--ls-text);
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-label {
|
.stat-label {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #999;
|
color: rgba(226, 232, 240, 0.65);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -563,7 +563,7 @@ const updateUserChart = () => {
|
|||||||
.nickname {
|
.nickname {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #333;
|
color: rgba(226, 232, 240, 0.9);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
@@ -571,7 +571,7 @@ const updateUserChart = () => {
|
|||||||
|
|
||||||
.username {
|
.username {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #999;
|
color: rgba(226, 232, 240, 0.6);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
|||||||
@@ -93,15 +93,33 @@ const handleLogin = async () => {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-height: 100vh;
|
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 {
|
.login-box {
|
||||||
width: 400px;
|
width: 400px;
|
||||||
padding: 40px;
|
padding: 40px;
|
||||||
background: #fff;
|
background: var(--ls-glass-bg);
|
||||||
border-radius: 10px;
|
border: 1px solid var(--ls-glass-border);
|
||||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
|
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 {
|
.login-header {
|
||||||
@@ -110,13 +128,13 @@ const handleLogin = async () => {
|
|||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
color: #333;
|
color: var(--ls-text);
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #999;
|
color: rgba(226, 232, 240, 0.7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +150,7 @@ const handleLogin = async () => {
|
|||||||
|
|
||||||
p {
|
p {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #999;
|
color: rgba(226, 232, 240, 0.6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -24,20 +24,20 @@ const goHome = () => {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background-color: #f0f2f5;
|
background-color: var(--ls-bg);
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 120px;
|
font-size: 120px;
|
||||||
color: #409eff;
|
color: var(--ls-accent-orange);
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
color: #666;
|
color: rgba(226, 232, 240, 0.75);
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ onMounted(() => {
|
|||||||
.page-title {
|
.page-title {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
color: #333;
|
color: var(--ls-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-card {
|
.search-card {
|
||||||
|
|||||||
@@ -1581,7 +1581,7 @@ onMounted(() => {
|
|||||||
.page-title {
|
.page-title {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
color: #333;
|
color: var(--ls-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-card {
|
.search-card {
|
||||||
@@ -1614,8 +1614,9 @@ onMounted(() => {
|
|||||||
.stats-row {
|
.stats-row {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
background: #f8f9fa;
|
background: rgba(255, 255, 255, 0.03);
|
||||||
border-radius: 8px;
|
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||||
|
border-radius: var(--ls-radius-lg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination {
|
.pagination {
|
||||||
@@ -1627,7 +1628,7 @@ onMounted(() => {
|
|||||||
.form-tip {
|
.form-tip {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #999;
|
color: rgba(226, 232, 240, 0.6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1635,8 +1636,8 @@ onMounted(() => {
|
|||||||
.test-section {
|
.test-section {
|
||||||
h4 {
|
h4 {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
color: #333;
|
color: var(--ls-text);
|
||||||
border-bottom: 2px solid #409eff;
|
border-bottom: 2px solid rgba(255, 171, 145, 0.6);
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1646,7 +1647,7 @@ onMounted(() => {
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
|
||||||
.info-icon {
|
.info-icon {
|
||||||
color: #909399;
|
color: rgba(226, 232, 240, 0.6);
|
||||||
cursor: help;
|
cursor: help;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted, computed } from 'vue'
|
import { ref, reactive, onMounted, computed, watch } from 'vue'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
import { getDictionaryById, createDictionary, updateDictionary } from '@/api/dictionary'
|
import { getDictionaryById, createDictionary, updateDictionary } from '@/api/dictionary'
|
||||||
@@ -81,7 +81,10 @@ const route = useRoute()
|
|||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
const submitting = ref(false)
|
const submitting = ref(false)
|
||||||
|
|
||||||
const form = reactive<DictionaryCreateRequest | DictionaryUpdateRequest>({
|
/**
|
||||||
|
* 创建/编辑表单默认值
|
||||||
|
*/
|
||||||
|
const DEFAULT_FORM: DictionaryCreateRequest = {
|
||||||
dictType: '',
|
dictType: '',
|
||||||
dictCode: '',
|
dictCode: '',
|
||||||
dictName: '',
|
dictName: '',
|
||||||
@@ -89,7 +92,14 @@ const form = reactive<DictionaryCreateRequest | DictionaryUpdateRequest>({
|
|||||||
sortOrder: 0,
|
sortOrder: 0,
|
||||||
status: 1,
|
status: 1,
|
||||||
remarks: ''
|
remarks: ''
|
||||||
})
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典表单数据
|
||||||
|
* - 创建模式:DictionaryCreateRequest
|
||||||
|
* - 编辑模式:DictionaryUpdateRequest(后端会要求 id)
|
||||||
|
*/
|
||||||
|
const form = reactive<DictionaryCreateRequest | DictionaryUpdateRequest>({ ...DEFAULT_FORM })
|
||||||
|
|
||||||
const rules = {
|
const rules = {
|
||||||
dictType: [
|
dictType: [
|
||||||
@@ -122,6 +132,14 @@ const fetchDetail = async () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置表单(用于从编辑切换到创建时清空旧数据)
|
||||||
|
*/
|
||||||
|
const resetFormToDefault = () => {
|
||||||
|
Object.assign(form, { ...DEFAULT_FORM })
|
||||||
|
formRef.value?.clearValidate?.()
|
||||||
|
}
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
if (!formRef.value) return
|
if (!formRef.value) return
|
||||||
|
|
||||||
@@ -156,6 +174,22 @@ onMounted(() => {
|
|||||||
fetchDetail()
|
fetchDetail()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听路由模式切换:
|
||||||
|
* - edit -> create:清空表单,避免复用组件实例导致“新增页带出旧数据”
|
||||||
|
* - create -> edit:拉取详情
|
||||||
|
*/
|
||||||
|
watch(
|
||||||
|
() => route.params.id,
|
||||||
|
async (id) => {
|
||||||
|
if (id) {
|
||||||
|
await fetchDetail()
|
||||||
|
} else {
|
||||||
|
resetFormToDefault()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@@ -163,7 +197,7 @@ onMounted(() => {
|
|||||||
.page-title {
|
.page-title {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
color: #333;
|
color: var(--ls-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-card {
|
.el-card {
|
||||||
|
|||||||
@@ -99,9 +99,17 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, onMounted } from 'vue'
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
import { getDictionaryPage, deleteDictionary, updateDictionary } from '@/api/dictionary'
|
import { getDictionaryPage, deleteDictionary, updateDictionary } from '@/api/dictionary'
|
||||||
import type { Dictionary, DictionaryPageRequest } from '@/types/dictionary'
|
import type { Dictionary, DictionaryPageRequest } from '@/types/dictionary'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字典列表页
|
||||||
|
* - 负责查询/展示/跳转新增与编辑
|
||||||
|
* - 注意:项目使用 history 路由模式,禁止使用 window.location.hash 跳转
|
||||||
|
*/
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const detailVisible = ref(false)
|
const detailVisible = ref(false)
|
||||||
const currentDictionary = ref<Dictionary | null>(null)
|
const currentDictionary = ref<Dictionary | null>(null)
|
||||||
@@ -156,13 +164,17 @@ const handleReset = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleCreate = () => {
|
const handleCreate = () => {
|
||||||
// 跳转到创建页面
|
/**
|
||||||
window.location.hash = '#/dictionary/create'
|
* 跳转到创建页面(history 模式)
|
||||||
|
*/
|
||||||
|
router.push('/dictionary/create')
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleEdit = (row: Dictionary) => {
|
const handleEdit = (row: Dictionary) => {
|
||||||
// 跳转到编辑页面
|
/**
|
||||||
window.location.hash = `#/dictionary/edit/${row.id}`
|
* 跳转到编辑页面(history 模式)
|
||||||
|
*/
|
||||||
|
router.push(`/dictionary/edit/${row.id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleView = (row: Dictionary) => {
|
const handleView = (row: Dictionary) => {
|
||||||
@@ -222,7 +234,7 @@ onMounted(() => {
|
|||||||
.page-title {
|
.page-title {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
color: #333;
|
color: var(--ls-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-card {
|
.search-card {
|
||||||
|
|||||||
@@ -588,7 +588,7 @@ initHistory()
|
|||||||
.page-title {
|
.page-title {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
color: #333;
|
color: var(--ls-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.request-card,
|
.request-card,
|
||||||
@@ -610,7 +610,7 @@ initHistory()
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
|
||||||
.params-tip {
|
.params-tip {
|
||||||
color: #909399;
|
color: rgba(226, 232, 240, 0.6);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,8 +642,9 @@ initHistory()
|
|||||||
.response-body {
|
.response-body {
|
||||||
max-height: 500px;
|
max-height: 500px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
background-color: #f5f7fa;
|
background: rgba(0, 0, 0, 0.2);
|
||||||
border-radius: 4px;
|
border: 1px solid rgba(255, 255, 255, 0.06);
|
||||||
|
border-radius: var(--ls-radius-md);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -654,6 +655,7 @@ initHistory()
|
|||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
|
color: rgba(226, 232, 240, 0.9);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -190,7 +190,7 @@ onMounted(() => {
|
|||||||
.page-title {
|
.page-title {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
color: #333;
|
color: var(--ls-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-card {
|
.search-card {
|
||||||
|
|||||||
Reference in New Issue
Block a user