diff --git a/frontend/components.d.ts b/frontend/components.d.ts
index 9fc6636..7821290 100644
--- a/frontend/components.d.ts
+++ b/frontend/components.d.ts
@@ -12,14 +12,12 @@ declare module 'vue' {
AppSidebar: typeof import('./src/components/Layout/AppSidebar.vue')['default']
AuditLogTable: typeof import('./src/components/AuditLogTable.vue')['default']
ElButton: typeof import('element-plus/es')['ElButton']
- ElDivider: typeof import('element-plus/es')['ElDivider']
ElForm: typeof import('element-plus/es')['ElForm']
ElFormItem: typeof import('element-plus/es')['ElFormItem']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElInput: typeof import('element-plus/es')['ElInput']
ElOption: typeof import('element-plus/es')['ElOption']
ElSelect: typeof import('element-plus/es')['ElSelect']
- ElSpace: typeof import('element-plus/es')['ElSpace']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
SubsystemCard: typeof import('./src/components/SubsystemCard.vue')['default']
diff --git a/frontend/src/components/AuditLogTable.vue b/frontend/src/components/AuditLogTable.vue
index e568768..0813817 100644
--- a/frontend/src/components/AuditLogTable.vue
+++ b/frontend/src/components/AuditLogTable.vue
@@ -187,11 +187,11 @@ tr.tr-hover:hover td {
.pg-btn.active {
background: var(--accent-dim);
border-color: var(--accent-dim);
- color: #CFFCE9;
+ color: var(--active-text);
}
.pg-btn:hover {
- border-color: #3A4356;
+ border-color: var(--hover-border);
color: var(--text-hi);
}
diff --git a/frontend/src/components/Layout/AppHeader.vue b/frontend/src/components/Layout/AppHeader.vue
index 0b9b8df..324d6ed 100644
--- a/frontend/src/components/Layout/AppHeader.vue
+++ b/frontend/src/components/Layout/AppHeader.vue
@@ -11,6 +11,14 @@
搜索集群 / 节点 / 服务实例
⌘K
+
{{ userInitial }}
@@ -24,12 +32,16 @@
diff --git a/frontend/src/components/Layout/AppSidebar.vue b/frontend/src/components/Layout/AppSidebar.vue
index 298e2fd..09f4fea 100644
--- a/frontend/src/components/Layout/AppSidebar.vue
+++ b/frontend/src/components/Layout/AppSidebar.vue
@@ -118,24 +118,26 @@
}
.nav-item.active {
- background: #13261F;
+ background: var(--accent-dim);
color: var(--accent);
- border-color: var(--accent-dim);
+ border-color: var(--accent);
}
.nav-item .badge {
margin-left: auto;
font-family: var(--mono);
font-size: 10px;
- background: #262C38;
+ background: var(--bg-panel-2);
color: var(--text-dim);
padding: 1px 6px;
border-radius: 10px;
+ border: 1px solid var(--line);
}
.nav-item.active .badge {
- background: var(--accent-dim);
- color: #CFFCE9;
+ background: var(--accent);
+ color: #FFFFFF;
+ border-color: var(--accent);
}
.sidebar-foot {
diff --git a/frontend/src/components/SubsystemCard.vue b/frontend/src/components/SubsystemCard.vue
index bd31574..1815db0 100644
--- a/frontend/src/components/SubsystemCard.vue
+++ b/frontend/src/components/SubsystemCard.vue
@@ -27,26 +27,26 @@ const props = defineProps<{
const bgColor = computed(() => {
const colors: Record = {
- W: '#1C2A3A',
- DM: '#1C3A2E',
- CC: '#3A1C28',
- AP: '#1C2A3A',
- QP: '#241B0A',
- GF: '#1B202B',
+ W: 'var(--logo-w-bg)',
+ DM: 'var(--logo-dm-bg)',
+ CC: 'var(--logo-cc-bg)',
+ AP: 'var(--logo-ap-bg)',
+ QP: 'var(--logo-qp-bg)',
+ GF: 'var(--logo-gf-bg)',
}
- return colors[props.system.icon] || '#262C38'
+ return colors[props.system.icon] || 'var(--bg-panel-2)'
})
const iconColor = computed(() => {
const colors: Record = {
- W: '#7FB8FF',
- DM: '#7FFFC2',
- CC: '#FF8E9C',
- AP: '#8EC8FF',
- QP: '#FFC97A',
- GF: '#F2B544',
+ W: 'var(--tag-blue-text)',
+ DM: 'var(--tag-green-text)',
+ CC: 'var(--err)',
+ AP: 'var(--tag-blue-text)',
+ QP: 'var(--tag-amber-text)',
+ GF: 'var(--warn)',
}
- return colors[props.system.icon] || '#9AA3B5'
+ return colors[props.system.icon] || 'var(--text-mid)'
})
const description = computed(() => {
@@ -85,7 +85,7 @@ const handleClick = async () => {
}
.ext-card:hover {
- border-color: #3A4356;
+ border-color: var(--hover-border);
}
.ext-top {
diff --git a/frontend/src/composables/useTheme.ts b/frontend/src/composables/useTheme.ts
new file mode 100644
index 0000000..b74e5a9
--- /dev/null
+++ b/frontend/src/composables/useTheme.ts
@@ -0,0 +1,68 @@
+import { ref, watch, onMounted } from 'vue'
+
+export type Theme = 'light' | 'dark'
+
+const THEME_KEY = 'xinfra-theme'
+
+// 默认浅色模式
+const theme = ref('light')
+
+export function useTheme() {
+ // 初始化主题
+ const initTheme = () => {
+ const savedTheme = localStorage.getItem(THEME_KEY) as Theme | null
+ if (savedTheme && ['light', 'dark'].includes(savedTheme)) {
+ theme.value = savedTheme
+ } else {
+ // 默认浅色模式
+ theme.value = 'light'
+ }
+ applyTheme(theme.value)
+ }
+
+ // 应用主题
+ const applyTheme = (newTheme: Theme) => {
+ document.documentElement.setAttribute('data-theme', newTheme)
+ document.documentElement.classList.toggle('dark', newTheme === 'dark')
+ }
+
+ // 切换主题
+ const toggleTheme = () => {
+ theme.value = theme.value === 'light' ? 'dark' : 'light'
+ localStorage.setItem(THEME_KEY, theme.value)
+ applyTheme(theme.value)
+ }
+
+ // 设置主题
+ const setTheme = (newTheme: Theme) => {
+ theme.value = newTheme
+ localStorage.setItem(THEME_KEY, theme.value)
+ applyTheme(theme.value)
+ }
+
+ // 监听系统主题变化(可选)
+ const watchSystemTheme = () => {
+ if (window.matchMedia) {
+ const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
+ mediaQuery.addEventListener('change', (e) => {
+ // 只有在用户没有手动设置过主题时才跟随系统
+ if (!localStorage.getItem(THEME_KEY)) {
+ theme.value = e.matches ? 'dark' : 'light'
+ applyTheme(theme.value)
+ }
+ })
+ }
+ }
+
+ onMounted(() => {
+ initTheme()
+ watchSystemTheme()
+ })
+
+ return {
+ theme,
+ toggleTheme,
+ setTheme,
+ initTheme
+ }
+}
\ No newline at end of file
diff --git a/frontend/src/styles/global.css b/frontend/src/styles/global.css
index 324f9d7..e8586df 100644
--- a/frontend/src/styles/global.css
+++ b/frontend/src/styles/global.css
@@ -11,6 +11,22 @@ html, body {
color: var(--text-hi);
font-family: var(--sans);
font-size: 14px;
+ transition: background-color 0.3s ease, color 0.3s ease;
+}
+
+/* 主题切换过渡效果 */
+*, *::before, *::after {
+ transition: background-color 0.2s ease,
+ border-color 0.2s ease,
+ box-shadow 0.2s ease;
+}
+
+/* 排除不需要过渡的元素 */
+.no-transition,
+.no-transition *,
+.no-transition *::before,
+.no-transition *::after {
+ transition: none !important;
}
/* 滚动条样式 */
@@ -20,10 +36,14 @@ html, body {
}
::-webkit-scrollbar-thumb {
- background: #2A3140;
+ background: var(--bar-bg);
border-radius: 4px;
}
+::-webkit-scrollbar-thumb:hover {
+ background: var(--text-dim);
+}
+
::-webkit-scrollbar-track {
background: transparent;
}
@@ -54,7 +74,7 @@ button {
.dot.ok {
background: var(--accent);
- box-shadow: 0 0 6px #3FE0A599;
+ box-shadow: 0 0 6px var(--accent-glow);
}
.dot.warn {
@@ -109,7 +129,7 @@ button {
.bar-wrap {
width: 90px;
height: 5px;
- background: #262C38;
+ background: var(--bar-bg);
border-radius: 3px;
overflow: hidden;
display: inline-block;
@@ -130,3 +150,15 @@ button {
.bar-fill.err {
background: var(--err);
}
+
+/* 卡片样式 */
+.card {
+ background: var(--bg-panel);
+ border: 1px solid var(--line);
+ border-radius: var(--radius);
+ box-shadow: var(--shadow-sm);
+}
+
+.card:hover {
+ box-shadow: var(--shadow-md);
+}
diff --git a/frontend/src/styles/variables.css b/frontend/src/styles/variables.css
index 30748e4..fe4e32e 100644
--- a/frontend/src/styles/variables.css
+++ b/frontend/src/styles/variables.css
@@ -1,4 +1,96 @@
+/* 浅色模式(默认) */
:root {
+ /* 背景色 */
+ --bg-deep: #F5F7FA;
+ --bg-panel: #FFFFFF;
+ --bg-panel-2: #F0F2F5;
+
+ /* 边框色 */
+ --line: #E4E7ED;
+ --line-soft: #EBEEF5;
+
+ /* 文字色 */
+ --text-hi: #1D2129;
+ --text-mid: #4E5969;
+ --text-dim: #86909C;
+
+ /* 强调色 */
+ --accent: #00B42A;
+ --accent-dim: #E8FFEA;
+
+ /* 状态色 */
+ --warn: #FF7D00;
+ --err: #F53F3F;
+ --info: #165DFF;
+
+ /* 圆角 */
+ --radius: 6px;
+
+ /* 字体 */
+ --mono: 'IBM Plex Mono', monospace;
+ --sans: 'IBM Plex Sans', sans-serif;
+
+ /* 阴影 */
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
+
+ /* 标签/徽章颜色 - 蓝色系 */
+ --tag-blue-text: #165DFF;
+ --tag-blue-bg: #E8F3FF;
+ --tag-blue-border: #BEDAFF;
+
+ /* 标签/徽章颜色 - 紫色系 */
+ --tag-purple-text: #722ED1;
+ --tag-purple-bg: #F5E8FF;
+ --tag-purple-border: #D3ADF7;
+
+ /* 标签/徽章颜色 - 琥珀色系 */
+ --tag-amber-text: #D46B08;
+ --tag-amber-bg: #FFF7E6;
+ --tag-amber-border: #FFD591;
+
+ /* 标签/徽章颜色 - 绿色系 */
+ --tag-green-text: #00B42A;
+ --tag-green-bg: #E8FFEA;
+ --tag-green-border: #9FD9A8;
+
+ /* 节点单元格颜色 */
+ --node-empty-bg: #F0F2F5;
+ --node-a-bg: #E8FFEA;
+ --node-a-border: #9FD9A8;
+ --node-b-bg: #F5E8FF;
+ --node-b-border: #D3ADF7;
+ --node-c-bg: #FFF7E6;
+ --node-c-border: #FFD591;
+
+ /* 进度条背景 */
+ --bar-bg: #E4E7ED;
+
+ /* 悬停边框 */
+ --hover-border: #C9CDD4;
+
+ /* 激活状态文字 */
+ --active-text: #00873E;
+
+ /* 主题切换按钮 */
+ --theme-btn-bg: #F0F2F5;
+ --theme-btn-hover: #E4E7ED;
+
+ /* 子系统卡片logo背景 */
+ --logo-w-bg: #E8F3FF;
+ --logo-dm-bg: #E8FFEA;
+ --logo-cc-bg: #FFF0F0;
+ --logo-ap-bg: #E8F3FF;
+ --logo-qp-bg: #FFF7E6;
+ --logo-gf-bg: #F5F7FA;
+
+ /* 发光/阴影效果 */
+ --accent-glow: rgba(0, 180, 42, 0.3);
+}
+
+/* 深色模式 */
+:root.dark {
/* 背景色 */
--bg-deep: #0E1117;
--bg-panel: #151922;
@@ -28,4 +120,62 @@
/* 字体 */
--mono: 'IBM Plex Mono', monospace;
--sans: 'IBM Plex Sans', sans-serif;
+
+ /* 阴影 */
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.3);
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -2px rgba(0, 0, 0, 0.3);
+
+ /* 标签/徽章颜色 - 蓝色系 */
+ --tag-blue-text: #8EC8FF;
+ --tag-blue-bg: #0E1C2C;
+ --tag-blue-border: #1C3A5C;
+
+ /* 标签/徽章颜色 - 紫色系 */
+ --tag-purple-text: #C9A6FF;
+ --tag-purple-bg: #1A1430;
+ --tag-purple-border: #3A2C5C;
+
+ /* 标签/徽章颜色 - 琥珀色系 */
+ --tag-amber-text: #FFC97A;
+ --tag-amber-bg: #241B0A;
+ --tag-amber-border: #5C4A1C;
+
+ /* 标签/徽章颜色 - 绿色系 */
+ --tag-green-text: #7FFFC2;
+ --tag-green-bg: #0F261D;
+ --tag-green-border: var(--accent-dim);
+
+ /* 节点单元格颜色 */
+ --node-empty-bg: #1E2532;
+ --node-a-bg: #13261F;
+ --node-a-border: var(--accent-dim);
+ --node-b-bg: #1A1430;
+ --node-b-border: #3A2C5C;
+ --node-c-bg: #241B0A;
+ --node-c-border: #5C4A1C;
+
+ /* 进度条背景 */
+ --bar-bg: #262C38;
+
+ /* 悬停边框 */
+ --hover-border: #3A4356;
+
+ /* 激活状态文字 */
+ --active-text: #CFFCE9;
+
+ /* 主题切换按钮 */
+ --theme-btn-bg: #1B202B;
+ --theme-btn-hover: #262C38;
+
+ /* 子系统卡片logo背景 */
+ --logo-w-bg: #1C2A3A;
+ --logo-dm-bg: #1C3A2E;
+ --logo-cc-bg: #3A1C28;
+ --logo-ap-bg: #1C2A3A;
+ --logo-qp-bg: #241B0A;
+ --logo-gf-bg: #1B202B;
+
+ /* 发光/阴影效果 */
+ --accent-glow: rgba(63, 224, 165, 0.3);
}
diff --git a/frontend/src/views/auth/Login.vue b/frontend/src/views/auth/Login.vue
index db9f04a..610aaa0 100644
--- a/frontend/src/views/auth/Login.vue
+++ b/frontend/src/views/auth/Login.vue
@@ -135,7 +135,7 @@ const handleLogin = async () => {
font-family: var(--mono);
font-size: 16px;
font-weight: 600;
- color: #08140F;
+ color: var(--bg-deep);
}
.login-header h2 {
@@ -174,7 +174,7 @@ const handleLogin = async () => {
}
:deep(.el-input__wrapper:hover) {
- border-color: #3A4356;
+ border-color: var(--hover-border);
}
:deep(.el-input__wrapper.is-focus) {
@@ -188,11 +188,11 @@ const handleLogin = async () => {
:deep(.el-button--primary) {
background: var(--accent);
border-color: var(--accent);
- color: #06150F;
+ color: var(--bg-deep);
font-weight: 600;
}
:deep(.el-button--primary:hover) {
- background: #55E8B3;
+ opacity: 0.9;
}
diff --git a/frontend/src/views/cluster/ClusterList.vue b/frontend/src/views/cluster/ClusterList.vue
index 8234378..c317218 100644
--- a/frontend/src/views/cluster/ClusterList.vue
+++ b/frontend/src/views/cluster/ClusterList.vue
@@ -86,9 +86,9 @@ const clusters = ref([
])
const nodes = ref([
- { name: 'bj-node-014', ip: '10.21.4.14', label: 'business-line=kodo', labelColor: '#8EC8FF', labelBorder: '#1C3A5C', taint: 'kodo:NoSchedule', spec: '64C/256G', cpu: 58, cpuClass: '', status: 'Ready', statusClass: 'ok' },
- { name: 'bj-node-015', ip: '10.21.4.15', label: 'business-line=kodo', labelColor: '#8EC8FF', labelBorder: '#1C3A5C', taint: 'kodo:NoSchedule', spec: '64C/256G', cpu: 62, cpuClass: '', status: 'Ready', statusClass: 'ok' },
- { name: 'bj-node-031', ip: '10.21.4.31', label: 'business-line=las', labelColor: '#C9A6FF', labelBorder: '#3A2C5C', taint: 'las:NoSchedule', spec: '32C/128G', cpu: 88, cpuClass: 'warn', status: '资源告警', statusClass: 'warn' },
+ { name: 'bj-node-014', ip: '10.21.4.14', label: 'business-line=kodo', labelColor: 'var(--tag-blue-text)', labelBorder: 'var(--tag-blue-border)', taint: 'kodo:NoSchedule', spec: '64C/256G', cpu: 58, cpuClass: '', status: 'Ready', statusClass: 'ok' },
+ { name: 'bj-node-015', ip: '10.21.4.15', label: 'business-line=kodo', labelColor: 'var(--tag-blue-text)', labelBorder: 'var(--tag-blue-border)', taint: 'kodo:NoSchedule', spec: '64C/256G', cpu: 62, cpuClass: '', status: 'Ready', statusClass: 'ok' },
+ { name: 'bj-node-031', ip: '10.21.4.31', label: 'business-line=las', labelColor: 'var(--tag-purple-text)', labelBorder: 'var(--tag-purple-border)', taint: 'las:NoSchedule', spec: '32C/128G', cpu: 88, cpuClass: 'warn', status: '资源告警', statusClass: 'warn' },
{ name: 'bj-node-048', ip: '10.21.4.48', label: '未分配', labelColor: 'var(--text-dim)', labelBorder: 'var(--line)', taint: '—', spec: '32C/128G', cpu: 4, cpuClass: '', status: 'Ready · 空闲', statusClass: 'ok' },
])
@@ -197,21 +197,21 @@ tr.tr-hover:hover td {
}
.tag.zone-a {
- color: #8EC8FF;
- border-color: #1C3A5C;
- background: #0E1C2C;
+ color: var(--tag-blue-text);
+ border-color: var(--tag-blue-border);
+ background: var(--tag-blue-bg);
}
.tag.zone-b {
- color: #C9A6FF;
- border-color: #3A2C5C;
- background: #1A1430;
+ color: var(--tag-purple-text);
+ border-color: var(--tag-purple-border);
+ background: var(--tag-purple-bg);
}
.tag.zone-c {
- color: #FFC97A;
- border-color: #5C4A1C;
- background: #241B0A;
+ color: var(--tag-amber-text);
+ border-color: var(--tag-amber-border);
+ background: var(--tag-amber-bg);
}
.tag.biz {
@@ -221,7 +221,7 @@ tr.tr-hover:hover td {
.bar-wrap {
width: 90px;
height: 5px;
- background: #262C38;
+ background: var(--bar-bg);
border-radius: 3px;
overflow: hidden;
display: inline-block;
diff --git a/frontend/src/views/config/ConfigCenter.vue b/frontend/src/views/config/ConfigCenter.vue
index c28aa19..582bde4 100644
--- a/frontend/src/views/config/ConfigCenter.vue
+++ b/frontend/src/views/config/ConfigCenter.vue
@@ -133,7 +133,7 @@ const clusters = ref([
font-size: 11px;
color: var(--accent);
border: 1px solid var(--accent-dim);
- background: #0F261D;
+ background: var(--accent-dim);
padding: 3px 9px;
border-radius: 20px;
letter-spacing: 0.4px;
@@ -312,21 +312,21 @@ tr.tr-hover:hover td {
}
.tag.zone-a {
- color: #8EC8FF;
- border-color: #1C3A5C;
- background: #0E1C2C;
+ color: var(--tag-blue-text);
+ border-color: var(--tag-blue-border);
+ background: var(--tag-blue-bg);
}
.tag.zone-b {
- color: #C9A6FF;
- border-color: #3A2C5C;
- background: #1A1430;
+ color: var(--tag-purple-text);
+ border-color: var(--tag-purple-border);
+ background: var(--tag-purple-bg);
}
.tag.zone-c {
- color: #FFC97A;
- border-color: #5C4A1C;
- background: #241B0A;
+ color: var(--tag-amber-text);
+ border-color: var(--tag-amber-border);
+ background: var(--tag-amber-bg);
}
.status-text {
diff --git a/frontend/src/views/dashboard/Index.vue b/frontend/src/views/dashboard/Index.vue
index efa84f2..8e9c3b8 100644
--- a/frontend/src/views/dashboard/Index.vue
+++ b/frontend/src/views/dashboard/Index.vue
@@ -260,23 +260,23 @@ const refresh = () => {
.node-cell {
aspect-ratio: 1;
border-radius: 3px;
- background: #1E2532;
+ background: var(--node-empty-bg);
border: 1px solid var(--line-soft);
}
.node-cell.a {
- background: #13261F;
- border-color: var(--accent-dim);
+ background: var(--node-a-bg);
+ border-color: var(--node-a-border);
}
.node-cell.b {
- background: #1A1430;
- border-color: #3A2C5C;
+ background: var(--node-b-bg);
+ border-color: var(--node-b-border);
}
.node-cell.c {
- background: #241B0A;
- border-color: #5C4A1C;
+ background: var(--node-c-bg);
+ border-color: var(--node-c-border);
}
.node-cell.empty {
@@ -352,21 +352,21 @@ td.strong {
}
.tag.zone-a {
- color: #8EC8FF;
- border-color: #1C3A5C;
- background: #0E1C2C;
+ color: var(--tag-blue-text);
+ border-color: var(--tag-blue-border);
+ background: var(--tag-blue-bg);
}
.tag.zone-b {
- color: #C9A6FF;
- border-color: #3A2C5C;
- background: #1A1430;
+ color: var(--tag-purple-text);
+ border-color: var(--tag-purple-border);
+ background: var(--tag-purple-bg);
}
.tag.zone-c {
- color: #FFC97A;
- border-color: #5C4A1C;
- background: #241B0A;
+ color: var(--tag-amber-text);
+ border-color: var(--tag-amber-border);
+ background: var(--tag-amber-bg);
}
.status-text {
diff --git a/frontend/src/views/resource/Management.vue b/frontend/src/views/resource/Management.vue
index 91af0bb..275d5fb 100644
--- a/frontend/src/views/resource/Management.vue
+++ b/frontend/src/views/resource/Management.vue
@@ -278,21 +278,21 @@ tr.tr-hover:hover td {
}
.tag.vm {
- color: #8EC8FF;
- border-color: #1C3A5C;
- background: #0E1C2C;
+ color: var(--tag-blue-text);
+ border-color: var(--tag-blue-border);
+ background: var(--tag-blue-bg);
}
.tag.zone-a {
- color: #8EC8FF;
- border-color: #1C3A5C;
- background: #0E1C2C;
+ color: var(--tag-blue-text);
+ border-color: var(--tag-blue-border);
+ background: var(--tag-blue-bg);
}
.tag.src-cmdb {
- color: #7FFFC2;
- border-color: var(--accent-dim);
- background: #0F261D;
+ color: var(--tag-green-text);
+ border-color: var(--tag-green-border);
+ background: var(--tag-green-bg);
}
.status-text {
@@ -340,11 +340,11 @@ tr.tr-hover:hover td {
.pg-btn.active {
background: var(--accent-dim);
border-color: var(--accent-dim);
- color: #CFFCE9;
+ color: var(--active-text);
}
.pg-btn:hover {
- border-color: #3A4356;
+ border-color: var(--hover-border);
color: var(--text-hi);
}
diff --git a/frontend/src/views/resource/StatusBoard.vue b/frontend/src/views/resource/StatusBoard.vue
index 324b683..04c1be2 100644
--- a/frontend/src/views/resource/StatusBoard.vue
+++ b/frontend/src/views/resource/StatusBoard.vue
@@ -272,7 +272,7 @@ tr.tr-hover:hover td {
.bar-wrap {
width: 90px;
height: 5px;
- background: #262C38;
+ background: var(--bar-bg);
border-radius: 3px;
overflow: hidden;
display: inline-block;
diff --git a/frontend/src/views/service/Catalog.vue b/frontend/src/views/service/Catalog.vue
index de32d0f..53d0b7b 100644
--- a/frontend/src/views/service/Catalog.vue
+++ b/frontend/src/views/service/Catalog.vue
@@ -30,11 +30,11 @@ import { ref } from 'vue'
import { ElMessage } from 'element-plus'
const services = ref([
- { name: 'MySQL', icon: 'My', bgColor: '#1C2E4A', iconColor: '#7FB8FF', description: '一主多从,自动注册进 open-cdm 数据源,支持 LDAP 账号统一审核 SQL 上线。', playbook: 'roles/mysql-deploy', version: 'v8.0.36' },
- { name: 'Redis', icon: 'Rd', bgColor: '#3A1C28', iconColor: '#FF8E9C', description: '支持 Standalone / Sentinel / Cluster,部署完成后自动注册进 CacheCloud。', playbook: 'roles/redis-deploy', version: 'v7.2' },
- { name: 'openresty', icon: 'Or', bgColor: '#1C3A2E', iconColor: '#7FFFC2', description: '容器化部署在 K8s 内,作为业务边缘网关,支持灰度路由配置。', playbook: 'roles/openresty-deploy', version: 'v1.25' },
- { name: 'dpvs', icon: 'Dp', bgColor: '#3A2E1C', iconColor: '#FFC97A', description: '四层负载均衡,直接管理宿主机网络命名空间,不纳入容器编排。', playbook: 'roles/dpvs-deploy', version: 'v1.9' },
- { name: 'PgSQL', icon: 'Pg', bgColor: '#2E1C3A', iconColor: '#C9A6FF', description: '流复制主从架构,规划中 · 第二期接入 open-cdm 统一审核体系。', playbook: 'roles/pgsql-deploy', version: '规划中' },
+ { name: 'MySQL', icon: 'My', bgColor: 'var(--tag-blue-bg)', iconColor: 'var(--tag-blue-text)', description: '一主多从,自动注册进 open-cdm 数据源,支持 LDAP 账号统一审核 SQL 上线。', playbook: 'roles/mysql-deploy', version: 'v8.0.36' },
+ { name: 'Redis', icon: 'Rd', bgColor: 'var(--logo-cc-bg)', iconColor: 'var(--err)', description: '支持 Standalone / Sentinel / Cluster,部署完成后自动注册进 CacheCloud。', playbook: 'roles/redis-deploy', version: 'v7.2' },
+ { name: 'openresty', icon: 'Or', bgColor: 'var(--logo-dm-bg)', iconColor: 'var(--tag-green-text)', description: '容器化部署在 K8s 内,作为业务边缘网关,支持灰度路由配置。', playbook: 'roles/openresty-deploy', version: 'v1.25' },
+ { name: 'dpvs', icon: 'Dp', bgColor: 'var(--logo-qp-bg)', iconColor: 'var(--tag-amber-text)', description: '四层负载均衡,直接管理宿主机网络命名空间,不纳入容器编排。', playbook: 'roles/dpvs-deploy', version: 'v1.9' },
+ { name: 'PgSQL', icon: 'Pg', bgColor: 'var(--tag-purple-bg)', iconColor: 'var(--tag-purple-text)', description: '流复制主从架构,规划中 · 第二期接入 open-cdm 统一审核体系。', playbook: 'roles/pgsql-deploy', version: '规划中' },
])
const handleDeploy = (service: any) => {
@@ -78,7 +78,7 @@ const handleDeploy = (service: any) => {
}
.svc-card:hover {
- border-color: #3A4356;
+ border-color: var(--hover-border);
}
.svc-top {
diff --git a/frontend/src/views/service/Management.vue b/frontend/src/views/service/Management.vue
index 32354e8..271e247 100644
--- a/frontend/src/views/service/Management.vue
+++ b/frontend/src/views/service/Management.vue
@@ -273,21 +273,21 @@ tr.tr-hover:hover td {
}
.tag.zone-a {
- color: #8EC8FF;
- border-color: #1C3A5C;
- background: #0E1C2C;
+ color: var(--tag-blue-text);
+ border-color: var(--tag-blue-border);
+ background: var(--tag-blue-bg);
}
.tag.zone-b {
- color: #C9A6FF;
- border-color: #3A2C5C;
- background: #1A1430;
+ color: var(--tag-purple-text);
+ border-color: var(--tag-purple-border);
+ background: var(--tag-purple-bg);
}
.tag.zone-c {
- color: #FFC97A;
- border-color: #5C4A1C;
- background: #241B0A;
+ color: var(--tag-amber-text);
+ border-color: var(--tag-amber-border);
+ background: var(--tag-amber-bg);
}
.status-text {
@@ -339,11 +339,11 @@ tr.tr-hover:hover td {
.pg-btn.active {
background: var(--accent-dim);
border-color: var(--accent-dim);
- color: #CFFCE9;
+ color: var(--active-text);
}
.pg-btn:hover {
- border-color: #3A4356;
+ border-color: var(--hover-border);
color: var(--text-hi);
}
diff --git a/frontend/src/views/task/TaskCenter.vue b/frontend/src/views/task/TaskCenter.vue
index 53bf7e6..44b20d1 100644
--- a/frontend/src/views/task/TaskCenter.vue
+++ b/frontend/src/views/task/TaskCenter.vue
@@ -212,7 +212,7 @@ tr.tr-hover.active td {
}
.task-log-line.tag-ok {
- color: #7FB8FF;
+ color: var(--tag-blue-text);
}
.blink {
@@ -259,11 +259,11 @@ tr.tr-hover.active td {
.pg-btn.active {
background: var(--accent-dim);
border-color: var(--accent-dim);
- color: #CFFCE9;
+ color: var(--active-text);
}
.pg-btn:hover {
- border-color: #3A4356;
+ border-color: var(--hover-border);
color: var(--text-hi);
}