feat: 更新样式并增强深色主题的图表配置 #1

Merged
zhanghao merged 1 commits from anhei into cyberpunk 2026-08-27 11:44:31 +08:00
23 changed files with 1013 additions and 89 deletions

View File

@ -7,8 +7,8 @@ VITE_APP_ENV = 'development'
# 招商车研物联网平台/开发环境 # 招商车研物联网平台/开发环境
VITE_APP_BASE_API = '/dev-api' VITE_APP_BASE_API = '/dev-api'
VITE_API_URL = http://192.168.0.222:13080 VITE_API_URL = http://192.168.0.199:13080
VITE_WS_URL = ws://192.168.0.222:13080/ws VITE_WS_URL = ws://192.168.0.199:13080/ws
VITE_PORT = 80 VITE_PORT = 80
VITE_INSPECTION_TYPE = "inspection" VITE_INSPECTION_TYPE = "inspection"
VITE_MINIO_URL = "http://192.168.28.10:9000/cmvr-iot/" VITE_MINIO_URL = "http://192.168.28.10:9000/cmvr-iot/"

View File

@ -0,0 +1,353 @@
// Immersive Dark Tech layer. Tokens live in variables.module.scss; this file
// is responsible for depth, glow, motion and component interaction states.
html.dark {
background: #0a0e17;
body,
#app,
.app-wrapper,
.main-container,
.app-main {
background-color: #0a0e17;
}
.app-wrapper,
.app-main {
background-image:
linear-gradient(rgba(6, 182, 212, 0.035) 1px, transparent 1px),
linear-gradient(90deg, rgba(6, 182, 212, 0.035) 1px, transparent 1px),
radial-gradient(circle at 78% 12%, rgba(168, 85, 247, 0.07), transparent 34%);
background-size: 48px 48px, 48px 48px, 100% 100%;
}
.app-main {
isolation: isolate;
}
.app-main::before {
position: absolute;
top: 0;
right: 0;
left: 0;
z-index: -1;
height: 1px;
content: "";
pointer-events: none;
background: linear-gradient(90deg, transparent, rgba(34, 211, 238, 0.55), rgba(168, 85, 247, 0.34), transparent);
box-shadow: 0 0 14px rgba(6, 182, 212, 0.35);
animation: cyber-scan 9s linear infinite;
}
.sidebar-container {
-webkit-backdrop-filter: blur(20px) saturate(125%);
backdrop-filter: blur(20px) saturate(125%);
background: rgba(10, 14, 23, 0.86) !important;
border-right: 1px solid rgba(6, 182, 212, 0.24);
box-shadow: 10px 0 34px rgba(0, 0, 0, 0.34), 1px 0 18px rgba(6, 182, 212, 0.08) !important;
}
.sidebar-logo-container {
background: rgba(10, 14, 23, 0.9) !important;
border-bottom: 1px solid rgba(6, 182, 212, 0.2);
}
.sidebar-logo-container .sidebar-logo {
filter: drop-shadow(0 0 7px rgba(34, 211, 238, 0.42));
}
.sidebar-logo-container .sidebar-title {
color: rgba(255, 255, 255, 0.9) !important;
text-shadow: 0 0 14px rgba(6, 182, 212, 0.22);
}
.sidebar-container .el-menu,
.sidebar-container .el-scrollbar,
.sidebar-container .scrollbar-wrapper {
background: transparent !important;
}
.sidebar-container .el-menu-item,
.sidebar-container .el-sub-menu__title {
min-height: 48px;
margin: 3px 10px;
border: 1px solid transparent;
border-radius: 5px;
transition: color 0.3s ease, background-color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
.sidebar-container .el-menu-item:hover,
.sidebar-container .el-sub-menu__title:hover {
color: rgba(255, 255, 255, 0.9) !important;
background: rgba(6, 182, 212, 0.08) !important;
border-color: rgba(6, 182, 212, 0.18);
}
.sidebar-container .el-menu-item.is-active {
color: #a5f3fc !important;
background: linear-gradient(90deg, rgba(6, 182, 212, 0.18), rgba(168, 85, 247, 0.08)) !important;
border-color: rgba(34, 211, 238, 0.38);
box-shadow: inset 3px 0 0 #22d3ee, 0 0 18px rgba(6, 182, 212, 0.1);
text-shadow: 0 0 10px rgba(34, 211, 238, 0.32);
}
.navbar {
-webkit-backdrop-filter: blur(20px) saturate(125%);
backdrop-filter: blur(20px) saturate(125%);
background: rgba(10, 14, 23, 0.72) !important;
border-bottom: 1px solid rgba(6, 182, 212, 0.22);
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3), 0 1px 14px rgba(6, 182, 212, 0.08) !important;
}
.navbar .right-menu-item:hover,
.navbar .hamburger-container:hover {
color: #67e8f9;
background: rgba(6, 182, 212, 0.1) !important;
text-shadow: 0 0 12px rgba(6, 182, 212, 0.5);
}
.tags-view-container {
-webkit-backdrop-filter: blur(20px);
backdrop-filter: blur(20px);
background: rgba(10, 14, 23, 0.68) !important;
border-bottom-color: rgba(168, 85, 247, 0.2) !important;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.22) !important;
}
.tags-view-container .tags-view-item {
background: rgba(20, 27, 45, 0.72) !important;
border-color: rgba(100, 116, 139, 0.24) !important;
transition: color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
.tags-view-container .tags-view-item:hover {
color: rgba(255, 255, 255, 0.9) !important;
border-color: rgba(6, 182, 212, 0.42) !important;
}
.tags-view-container .tags-view-item.active {
color: #e6fbff !important;
background: linear-gradient(105deg, rgba(6, 182, 212, 0.88), rgba(93, 92, 226, 0.82)) !important;
border-color: rgba(103, 232, 249, 0.72) !important;
box-shadow: 0 0 16px rgba(6, 182, 212, 0.24), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
.app-container,
.el-card,
.el-dialog,
.el-drawer,
.el-popover,
.dashboard-panel,
.metric-card,
.row-cards .card,
.main-workspace .workspace-container > .left,
.main-workspace .workspace-container > .right,
.task-log,
.page-container > .left,
.page-container > .right {
-webkit-backdrop-filter: blur(20px) saturate(125%);
backdrop-filter: blur(20px) saturate(125%);
background-color: rgba(20, 27, 45, 0.78) !important;
background-image:
linear-gradient(145deg, rgba(6, 182, 212, 0.035), rgba(168, 85, 247, 0.025)),
repeating-linear-gradient(180deg, rgba(255, 255, 255, 0.012) 0, rgba(255, 255, 255, 0.012) 1px, transparent 1px, transparent 5px) !important;
border-color: rgba(6, 182, 212, 0.22) !important;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.035), 0 16px 36px rgba(0, 0, 0, 0.2), 0 4px 15px rgba(6, 182, 212, 0.06) !important;
}
.metric-card,
.dashboard-panel,
.el-card,
.app-container {
transition: transform 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
.metric-card:hover,
.dashboard-panel:hover,
.el-card:hover {
border-color: rgba(34, 211, 238, 0.46) !important;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 18px 42px rgba(0, 0, 0, 0.26), 0 0 24px rgba(6, 182, 212, 0.1) !important;
}
.el-button--primary {
--el-button-text-color: #f5fdff;
--el-button-border-color: rgba(103, 232, 249, 0.64);
--el-button-hover-border-color: rgba(216, 180, 254, 0.76);
background: linear-gradient(110deg, #0891b2, #4f46c8) !important;
box-shadow: 0 0 16px rgba(6, 182, 212, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
.el-button--primary:hover,
.el-button--primary:focus {
background: linear-gradient(110deg, #06b6d4, #7c3aed) !important;
box-shadow: 0 0 22px rgba(6, 182, 212, 0.28), 0 0 16px rgba(168, 85, 247, 0.12);
}
.el-table::before,
.el-table__inner-wrapper::before {
background-color: rgba(6, 182, 212, 0.18) !important;
}
.el-table th.el-table__cell {
color: rgba(255, 255, 255, 0.78) !important;
background: rgba(20, 27, 45, 0.94) !important;
border-bottom-color: rgba(6, 182, 212, 0.22) !important;
}
.el-table td.el-table__cell {
border-bottom-color: rgba(100, 116, 139, 0.16) !important;
transition: background-color 0.3s ease, box-shadow 0.3s ease;
}
.el-table__body tr:hover > td.el-table__cell {
background-color: rgba(6, 182, 212, 0.075) !important;
background-image: linear-gradient(90deg, rgba(6, 182, 212, 0.02), rgba(168, 85, 247, 0.08), rgba(6, 182, 212, 0.025)) !important;
box-shadow: inset 0 1px 0 rgba(34, 211, 238, 0.09), inset 0 -1px 0 rgba(168, 85, 247, 0.07);
}
.el-tabs__active-bar {
background: linear-gradient(90deg, #06b6d4, #a855f7);
box-shadow: 0 0 12px rgba(6, 182, 212, 0.48);
}
.el-dialog,
.el-drawer,
.el-popover,
.el-dropdown-menu {
border-color: rgba(6, 182, 212, 0.28) !important;
box-shadow: 0 22px 60px rgba(0, 0, 0, 0.48), 0 0 28px rgba(6, 182, 212, 0.1), 0 0 34px rgba(168, 85, 247, 0.06) !important;
}
.el-overlay {
background-color: rgba(3, 6, 14, 0.68);
-webkit-backdrop-filter: blur(6px);
backdrop-filter: blur(6px);
}
.state-dot,
.task-status-dot,
.status-dot,
.el-badge__content.is-dot {
box-shadow: 0 0 0 4px rgba(16, 185, 129, 0.08), 0 0 14px currentColor;
animation: cyber-pulse 2.4s ease-in-out infinite;
}
.control-point {
border-color: rgba(230, 251, 255, 0.9) !important;
background: rgba(6, 182, 212, 0.88) !important;
box-shadow: 0 0 0 4px rgba(6, 182, 212, 0.1), 0 0 18px rgba(6, 182, 212, 0.62) !important;
animation: cyber-marker-pulse 2.2s ease-in-out infinite;
}
.control-point.active {
background: rgba(168, 85, 247, 0.92) !important;
box-shadow: 0 0 0 5px rgba(168, 85, 247, 0.12), 0 0 22px rgba(168, 85, 247, 0.66) !important;
}
.home-dashboard .hero-panel {
border: 1px solid rgba(6, 182, 212, 0.28);
box-shadow: 0 20px 48px rgba(0, 0, 0, 0.34), 0 0 30px rgba(6, 182, 212, 0.08);
}
.home-dashboard .hero-panel::before {
background: linear-gradient(105deg, rgba(5, 9, 20, 0.94), rgba(10, 14, 23, 0.8) 55%, rgba(35, 18, 61, 0.68)) !important;
}
.home-dashboard .section-kicker {
color: #67e8f9;
text-shadow: 0 0 12px rgba(6, 182, 212, 0.42);
}
.home-dashboard .metric-icon--blue { color: #22d3ee !important; background: rgba(6, 182, 212, 0.12) !important; }
.home-dashboard .metric-icon--green { color: #34d399 !important; background: rgba(16, 185, 129, 0.12) !important; }
.home-dashboard .metric-icon--orange { color: #fbbf24 !important; background: rgba(251, 191, 36, 0.1) !important; }
.home-dashboard .metric-icon--red { color: #fb7185 !important; background: rgba(251, 113, 133, 0.1) !important; }
[data-echarts-instance] canvas,
div[_echarts_instance_] canvas {
filter: drop-shadow(0 0 5px rgba(6, 182, 212, 0.16));
}
::-webkit-scrollbar-track { background: rgba(10, 14, 23, 0.72); }
::-webkit-scrollbar-thumb {
background: linear-gradient(180deg, rgba(6, 182, 212, 0.72), rgba(168, 85, 247, 0.58));
border: 2px solid rgba(10, 14, 23, 0.82);
border-radius: 4px;
box-shadow: 0 0 8px rgba(6, 182, 212, 0.24);
}
.login,
.register {
position: relative;
isolation: isolate;
padding: 24px;
background-color: #0a0e17 !important;
background-image:
linear-gradient(105deg, rgba(3, 6, 14, 0.88), rgba(10, 14, 23, 0.76) 54%, rgba(40, 20, 68, 0.7)),
repeating-linear-gradient(180deg, rgba(103, 232, 249, 0.018) 0, rgba(103, 232, 249, 0.018) 1px, transparent 1px, transparent 5px),
url("../images/login-background.jpg") !important;
background-position: center;
background-size: cover, auto, cover;
}
.login::before,
.register::before {
display: none !important;
}
.login .login-form,
.register .register-form {
width: min(400px, 100%);
padding: 30px 34px 16px;
-webkit-backdrop-filter: blur(24px) saturate(135%);
backdrop-filter: blur(24px) saturate(135%);
background: linear-gradient(145deg, rgba(6, 182, 212, 0.06), rgba(168, 85, 247, 0.045)), rgba(10, 14, 23, 0.84) !important;
border: 1px solid rgba(6, 182, 212, 0.38);
border-radius: 8px !important;
box-shadow: 0 26px 80px rgba(0, 0, 0, 0.52), 0 0 32px rgba(6, 182, 212, 0.12), 0 0 42px rgba(168, 85, 247, 0.08);
}
.login .title,
.register .title {
color: rgba(255, 255, 255, 0.92) !important;
text-shadow: 0 0 18px rgba(6, 182, 212, 0.22);
}
.login .el-login-footer,
.register .el-register-footer {
color: rgba(203, 213, 225, 0.62) !important;
letter-spacing: 0 !important;
}
}
@keyframes cyber-scan {
0% { transform: translateY(0); opacity: 0; }
8% { opacity: 0.44; }
82% { opacity: 0.26; }
100% { transform: translateY(calc(100vh - 104px)); opacity: 0; }
}
@keyframes cyber-pulse {
0%, 100% { opacity: 0.78; filter: brightness(0.95); }
50% { opacity: 1; filter: brightness(1.3); }
}
@keyframes cyber-marker-pulse {
0%, 100% { opacity: 0.82; filter: brightness(0.94); }
50% { opacity: 1; filter: brightness(1.28); }
}
@media (max-width: 520px) {
html.dark .login,
html.dark .register { padding: 20px; }
html.dark .login .login-form,
html.dark .register .register-form { padding: 28px 24px 12px; }
}
@media (prefers-reduced-motion: reduce) {
html.dark .app-main::before,
html.dark .state-dot,
html.dark .task-status-dot,
html.dark .status-dot,
html.dark .el-badge__content.is-dot,
html.dark .control-point { animation: none; }
}

View File

@ -0,0 +1,300 @@
// Scoped compatibility for business views that still contain light literals.
html.dark {
.tree-sidebar,
.tree-panel,
.tree-container,
.category-tree,
.corpus-list,
.task-list,
.right-panel,
.left-panel {
color: var(--el-text-color-regular);
background: var(--surface-0) !important;
border-color: var(--line-subtle) !important;
}
.tree-header,
.collapse-button-container,
.tree-sidebar.collapsed .collapse-button-container {
color: var(--el-text-color-regular) !important;
background: var(--surface-1) !important;
border-color: var(--line-subtle) !important;
}
.tree-title,
.tree-node,
.node-label { color: var(--el-text-color-primary) !important; }
.tree-action-icon:hover,
.collapse-button:hover,
.tree-wrap .el-tree-node__content:hover {
color: var(--el-color-primary) !important;
background: var(--surface-2) !important;
}
.tree-wrap .el-tree-node.is-current > .el-tree-node__content {
color: #67e8f9 !important;
background: rgba(6, 182, 212, 0.12) !important;
}
// Flow editor chrome, palette and nodes.
.page .page__container .vue-flow,
.lf-canvas-overlay { background: #090d16 !important; }
.page .page__container > .el-container > .el-header,
.page .page__container .el-header,
.page .page__container .el-aside,
.component-library,
.library-header,
.component-library .el-collapse-item__header,
.component-library .el-collapse-item__wrap,
.single-node-station-tools {
color: var(--el-text-color-regular) !important;
background: var(--surface-0) !important;
border-color: var(--line-subtle) !important;
}
.page .page__container .canvas-toolbar,
.page .page__container .vue-flow__controls {
background: rgba(10, 14, 23, 0.9) !important;
border-color: var(--line-subtle) !important;
box-shadow: 0 10px 28px rgba(0, 0, 0, 0.3), 0 0 18px rgba(6, 182, 212, 0.08) !important;
}
.page .page__container .canvas-toolbar .el-button,
.page .page__container .vue-flow__controls button {
color: var(--el-text-color-regular) !important;
background: transparent !important;
border-color: var(--line-subtle) !important;
}
.component-library .node-item,
.flow-node-card,
.group__container,
.node__container,
.node__box,
.condition-summary,
.queue-step,
.output-row,
.flow-node-card .terminal-node__icon {
color: var(--el-text-color-regular) !important;
background: var(--surface-0) !important;
border-color: var(--line-subtle) !important;
box-shadow: none !important;
}
.node-title__icon,
.node-title__type,
.node-state,
.group__container .child__container,
.condition-summary__item,
.contract-header,
.input__container {
color: var(--el-text-color-regular) !important;
background: var(--surface-1) !important;
border-color: var(--line-subtle) !important;
}
.node-title__name,
.condition-summary__title,
.flow-heading__name,
.library-title,
.node-name { color: var(--el-text-color-primary) !important; }
.node-desc,
.library-subtitle,
.flow-node-executor,
.node-title__description,
.condition-summary__text { color: var(--el-text-color-secondary) !important; }
// Corpus, speech and operational workspaces.
.row-cards .card,
.main-workspace .workspace-container > .left,
.main-workspace .workspace-container > .right,
.task-list,
.corpus-list,
.category-tree,
.page-container > .left,
.page-container > .right {
color: var(--el-text-color-regular) !important;
background: var(--surface-0) !important;
border: 1px solid var(--line-subtle) !important;
border-radius: 6px !important;
}
.page-container .taskList-container .task-item,
.page-container > .right .task {
color: var(--el-text-color-regular) !important;
background: var(--surface-1) !important;
box-shadow: inset 0 0 0 1px var(--line-subtle) !important;
border-radius: 5px !important;
}
.page-container .taskList-container .task-item.is-selected {
background: rgba(6, 182, 212, 0.1) !important;
box-shadow: inset 0 0 0 1px #06b6d4, 0 0 16px rgba(6, 182, 212, 0.1) !important;
}
.task-log {
color: var(--el-text-color-regular) !important;
background: var(--surface-0) !important;
border-color: var(--line-subtle) !important;
border-radius: 6px !important;
}
.task-log__group-header:hover,
.task-log__details,
.task-log__iteration-header,
.task-log__analysis,
.task-log__analysis-details,
.task-log__output,
.task-log__business-summary { background: var(--surface-1) !important; }
.task-log__heading,
.task-log__order,
.task-log__time,
.page-container .robot,
.page-container .progress-label { color: var(--el-text-color-secondary) !important; }
// Device list and direct control surfaces.
.robot-device-page { background: transparent !important; }
.robot-device-page .status-strip {
background: var(--surface-0) !important;
border-color: var(--line-subtle) !important;
}
.robot-device-page .page-heading h2,
.robot-device-page .status-strip strong,
.robot-device-page .device-name b { color: var(--el-text-color-primary) !important; }
.robot-device-page .page-heading p,
.robot-device-page .robot-selector,
.robot-device-page .status-strip span,
.robot-device-page .device-name small { color: var(--el-text-color-secondary) !important; }
.robot-device-page .device-icon {
color: #67e8f9 !important;
background: rgba(6, 182, 212, 0.14) !important;
}
.head-control,
.microphone-container,
.audio-player,
.container:has(> .left-panel > .hand-container) {
color: var(--el-text-color-regular) !important;
background: var(--surface-0) !important;
border: 1px solid var(--line-subtle) !important;
border-radius: 6px !important;
}
.head-control .preset-panel,
.head-control .current-display,
.microphone-container .speaker-container,
.microphone-container .audioItem,
.audio-player .audio-item,
.voice-container .voice-btn {
color: var(--el-text-color-regular) !important;
background: var(--surface-1) !important;
border-color: var(--line-subtle) !important;
}
.microphone-container .title,
.audio-player .title,
.voice-container .duration { color: var(--el-text-color-primary) !important; }
.audio-player .audio-item:hover,
.audio-player .audio-item.active,
.voice-container .voice-btn.playing {
color: #e6fbff !important;
background: linear-gradient(90deg, rgba(6, 182, 212, 0.12), rgba(168, 85, 247, 0.09)) !important;
}
// Evaluation workspaces.
.container:has(> .test-container) > .info,
.container:has(> .test-container) .btn-container,
.container:has(> .test-container) .context-container > .left > .title,
.container:has(> .test-container) .schemaList,
.evaluation-metrics > .left,
.evaluation-metrics > .right,
.evaluation-metrics .indicator-container {
color: var(--el-text-color-regular) !important;
background: var(--surface-0) !important;
border-color: var(--line-subtle) !important;
}
.container:has(> .test-container) .activeItem,
.container:has(> .test-container) .schema:hover {
color: #e6fbff !important;
background: linear-gradient(105deg, rgba(6, 182, 212, 0.12), rgba(168, 85, 247, 0.1)) !important;
border-color: rgba(6, 182, 212, 0.48) !important;
}
// Robot layout editor and context menu.
#robot-interface {
background: rgba(7, 11, 20, 0.78) !important;
border: 1px solid var(--line-subtle);
border-radius: 6px !important;
}
#robot-interface .tree-panel,
#robot-interface .robot-panel,
#robot-interface .popup,
#robot-interface .drag-handle,
#robot-interface .toggle-button,
#robot-interface .control-icon,
.context-menu {
color: var(--el-text-color-regular) !important;
background: rgba(20, 27, 45, 0.92) !important;
border-color: var(--line-subtle) !important;
}
#robot-interface .popup,
.context-menu {
border-radius: 6px !important;
box-shadow: 0 16px 42px rgba(0, 0, 0, 0.46), 0 0 20px rgba(6, 182, 212, 0.1) !important;
}
#robot-interface .toggle-button:hover,
#robot-interface .control-icon:hover,
.context-menu .menu-item:hover {
color: #67e8f9 !important;
background: rgba(6, 182, 212, 0.12) !important;
}
.context-menu .menu-item,
#robot-interface .popup-title { color: var(--el-text-color-regular) !important; }
// Utility tables, icon chooser and cron editor.
.custom-table {
color: var(--el-text-color-regular) !important;
background: rgba(10, 14, 23, 0.54) !important;
}
.custom-table th,
.custom-table td { border-color: var(--line-subtle) !important; }
.custom-table th { color: var(--el-text-color-primary) !important; background: var(--surface-1) !important; }
.custom-table tbody tr:hover,
.custom-table .dragging-row { background: linear-gradient(90deg, rgba(6, 182, 212, 0.1), rgba(168, 85, 247, 0.08)) !important; }
.icon-body .icon-item:hover,
.icon-body .icon-item.active {
color: #67e8f9 !important;
background: rgba(6, 182, 212, 0.1) !important;
border-radius: 4px !important;
}
.popup-main,
.popup-result,
.popup-result .title,
.popup-result table span {
color: var(--el-text-color-regular) !important;
background: var(--surface-0) !important;
border-color: var(--line-subtle) !important;
}
.popup-title { color: var(--el-text-color-primary) !important; background: var(--surface-1) !important; }
.pagination-container { background: transparent !important; }
.el-empty__description p,
.el-upload__tip { color: var(--el-text-color-secondary); }
}

View File

@ -6,6 +6,8 @@
@use './btn.scss'; @use './btn.scss';
@use './ruoyi.scss'; @use './ruoyi.scss';
@use './legacy-layout.scss'; @use './legacy-layout.scss';
@use './dark-overrides.scss';
@use './cyber-theme.scss';
body { body {
height: 100%; height: 100%;
@ -13,7 +15,9 @@ body {
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; font-family: "Segoe UI Variable", Inter, "SF Pro Display", "PingFang SC", "Microsoft YaHei", Arial, sans-serif;
color: var(--el-text-color-primary);
background: var(--main-fill-bg);
} }
label { label {
@ -100,24 +104,25 @@ div:focus {
} }
aside { aside {
background: #eef1f6; background: var(--surface-1);
padding: 8px 24px; padding: 10px 16px;
margin-bottom: 20px; margin-bottom: 16px;
border-radius: 2px; border: 1px solid var(--line-subtle);
border-radius: 6px;
display: block; display: block;
line-height: 32px; line-height: 32px;
font-size: 16px; font-size: 16px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
color: #2c3e50; color: var(--el-text-color-regular);
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
a { a {
color: #337ab7; color: var(--el-color-primary);
cursor: pointer; cursor: pointer;
&:hover { &:hover {
color: rgb(32, 160, 255); color: var(--el-color-primary-light-3);
} }
} }
} }
@ -125,9 +130,10 @@ aside {
//main-container全局样式 //main-container全局样式
.app-container { .app-container {
width: 100%; width: 100%;
padding: 20px; padding: 24px;
background-color: var(--el-bg-color); background-color: var(--surface-0);
border-radius: 4px; border: 1px solid var(--line-subtle);
border-radius: 6px;
} }
.components-container { .components-container {
@ -169,14 +175,78 @@ aside {
.link-type, .link-type,
.link-type:focus { .link-type:focus {
color: #337ab7; color: var(--el-color-primary);
cursor: pointer; cursor: pointer;
&:hover { &:hover {
color: rgb(32, 160, 255); color: var(--el-color-primary-light-3);
} }
} }
.el-card {
border-radius: 6px;
border-color: var(--line-subtle);
background: var(--surface-0);
box-shadow: none;
}
.el-card__header {
padding: 16px 20px !important;
border-bottom-color: var(--line-subtle);
color: var(--el-text-color-primary);
}
.el-card__body {
padding: 20px !important;
}
.el-button {
min-height: 34px;
border-radius: 5px;
font-weight: 600;
letter-spacing: 0;
transition: color 0.3s ease, background-color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease, transform 0.3s ease;
}
.el-button--small { min-height: 30px; border-radius: 4px; }
.el-button--large { min-height: 40px; border-radius: 6px; }
.el-form-item__label { color: var(--el-text-color-regular); }
.el-form-item { margin-bottom: 18px; }
.el-table {
border-radius: 6px;
overflow: hidden;
background: var(--surface-0);
}
.el-table th.el-table__cell { height: 44px; font-weight: 650; }
.el-table td.el-table__cell { height: 48px; }
.el-dialog {
border-radius: 8px;
overflow: hidden;
}
.el-dialog__header {
margin: 0;
padding: 20px 24px 16px;
border-bottom: 1px solid var(--line-subtle);
}
.el-dialog__body { padding: 22px 24px; }
.el-dialog__footer { padding: 14px 24px 20px; border-top: 1px solid var(--line-subtle); }
.el-drawer__header { margin-bottom: 0; padding: 20px 24px; border-bottom: 1px solid var(--line-subtle); }
.el-drawer__body { padding: 22px 24px; }
.el-dropdown-menu, .el-popover { border-radius: 6px; box-shadow: var(--el-box-shadow-light); }
.el-tag { border-radius: 4px; font-weight: 600; }
.el-message, .el-notification { border-radius: 6px; border-color: var(--line-subtle); background: var(--surface-0); }
html.dark ::selection {
color: #041016;
background: #67e8f9;
}
.filter-container { .filter-container {
padding-bottom: 10px; padding-bottom: 10px;

View File

@ -47,7 +47,7 @@
&.has-logo { &.has-logo {
.el-scrollbar { .el-scrollbar {
height: calc(100% - 50px); height: calc(100% - 64px);
} }
} }
@ -114,11 +114,11 @@
.hideSidebar { .hideSidebar {
.sidebar-container { .sidebar-container {
width: 54px !important; width: 68px !important;
} }
.main-container { .main-container {
margin-left: 54px; margin-left: 68px;
} }
.sub-menu-title-noDropdown { .sub-menu-title-noDropdown {
@ -129,7 +129,7 @@
padding: 0 !important; padding: 0 !important;
.svg-icon { .svg-icon {
margin-left: 20px; margin-left: 26px;
} }
} }
} }
@ -141,7 +141,7 @@
padding: 0 !important; padding: 0 !important;
.svg-icon { .svg-icon {
margin-left: 20px; margin-left: 26px;
} }
} }

View File

@ -9,10 +9,10 @@ $yellow: #fec171;
$panGreen: #30b08f; $panGreen: #30b08f;
// 默认主题变量 // 默认主题变量
$menuText: #bfcbd9; $menuText: rgba(255, 255, 255, 0.68);
$menuActiveText: #409eff; $menuActiveText: #67e8f9;
$menuBg: #304156; $menuBg: #0a0e17;
$menuHover: #263445; $menuHover: rgba(6, 182, 212, 0.1);
// 浅色主题theme-light // 浅色主题theme-light
$menuLightBg: #ffffff; $menuLightBg: #ffffff;
@ -21,18 +21,18 @@ $menuLightText: #303133;
$menuLightActiveText: #409eff; $menuLightActiveText: #409eff;
// 基础变量 // 基础变量
$base-sidebar-width: 200px; $base-sidebar-width: 232px;
$sideBarWidth: 200px; $sideBarWidth: 232px;
// 菜单暗色变量 // 菜单暗色变量
$base-menu-color: #bfcbd9; $base-menu-color: #bfcbd9;
$base-menu-color-active: #f4f4f5; $base-menu-color-active: #f4f4f5;
$base-menu-background: #304156; $base-menu-background: #0a0e17;
$base-sub-menu-background: #1f2d3d; $base-sub-menu-background: #101827;
$base-sub-menu-hover: #001528; $base-sub-menu-hover: rgba(6, 182, 212, 0.1);
// 组件变量 // 组件变量
$--color-primary: #409eff; $--color-primary: #06b6d4;
$--color-success: #67c23a; $--color-success: #67c23a;
$--color-warning: #e6a23c; $--color-warning: #e6a23c;
$--color-danger: #f56c6c; $--color-danger: #f56c6c;
@ -79,6 +79,11 @@ $--color-info: #909399;
--splitpanes-default-bg: #ffffff; --splitpanes-default-bg: #ffffff;
--main-fill-bg: rgb(242, 243, 245); --main-fill-bg: rgb(242, 243, 245);
--surface-0: #ffffff;
--surface-1: #f6f8fb;
--surface-2: #eef2f7;
--line-subtle: rgba(15, 23, 42, 0.12);
--flow-grid-color: rgba(51, 65, 85, 0.18);
} }
// 暗黑模式变量 // 暗黑模式变量
@ -284,3 +289,70 @@ html.dark {
background: #3e3e3e !important; background: #3e3e3e !important;
} }
} }
// Dark Tech design tokens. Kept after legacy compatibility rules so these
// values remain authoritative across Element Plus and custom business views.
html.dark {
color-scheme: dark;
--main-fill-bg: #0a0e17;
--surface-0: rgba(20, 27, 45, 0.82);
--surface-1: rgba(26, 34, 54, 0.9);
--surface-2: rgba(34, 45, 68, 0.9);
--line-subtle: rgba(6, 182, 212, 0.22);
--flow-grid-color: rgba(6, 182, 212, 0.14);
--el-bg-color-page: #0a0e17;
--el-bg-color: #141b2d;
--el-bg-color-overlay: #1a2236;
--el-fill-color-blank: #141b2d;
--el-fill-color: rgba(30, 41, 62, 0.94);
--el-fill-color-light: rgba(35, 47, 70, 0.9);
--el-fill-color-lighter: rgba(39, 53, 78, 0.7);
--el-fill-color-extra-light: rgba(43, 57, 82, 0.54);
--el-fill-color-dark: #101827;
--el-fill-color-darker: #0d1422;
--el-color-primary: #06b6d4;
--el-color-primary-rgb: 6, 182, 212;
--el-color-primary-light-3: #22d3ee;
--el-color-primary-light-5: #67e8f9;
--el-color-primary-light-7: rgba(34, 211, 238, 0.42);
--el-color-primary-light-8: rgba(34, 211, 238, 0.26);
--el-color-primary-light-9: rgba(6, 182, 212, 0.12);
--el-color-primary-dark-2: #0891b2;
--el-color-success: #10b981;
--el-text-color-primary: rgba(255, 255, 255, 0.85);
--el-text-color-regular: rgba(255, 255, 255, 0.68);
--el-text-color-secondary: rgba(255, 255, 255, 0.52);
--el-text-color-placeholder: rgba(203, 213, 225, 0.42);
--el-text-color-disabled: rgba(203, 213, 225, 0.3);
--el-border-color: rgba(6, 182, 212, 0.3);
--el-border-color-light: rgba(6, 182, 212, 0.2);
--el-border-color-lighter: rgba(100, 116, 139, 0.22);
--el-border-color-extra-light: rgba(100, 116, 139, 0.14);
--el-border-color-dark: rgba(34, 211, 238, 0.38);
--el-border-color-darker: rgba(34, 211, 238, 0.48);
--el-box-shadow: 0 4px 15px rgba(6, 182, 212, 0.15);
--el-box-shadow-light: 0 14px 38px rgba(0, 0, 0, 0.34), 0 0 18px rgba(6, 182, 212, 0.1);
--el-box-shadow-lighter: 0 8px 24px rgba(0, 0, 0, 0.26);
--el-box-shadow-dark: 0 24px 60px rgba(0, 0, 0, 0.48), 0 0 28px rgba(168, 85, 247, 0.1);
--sidebar-bg: rgba(10, 14, 23, 0.86);
--sidebar-text: rgba(255, 255, 255, 0.68);
--sidebar-logo-text: rgba(255, 255, 255, 0.9);
--menu-hover: rgba(6, 182, 212, 0.1);
--menu-active-text: #67e8f9;
--navbar-bg: rgba(10, 14, 23, 0.72);
--navbar-text: rgba(255, 255, 255, 0.72);
--navbar-hover: rgba(6, 182, 212, 0.1);
--tags-bg: rgba(10, 14, 23, 0.7);
--tags-item-bg: rgba(20, 27, 45, 0.76);
--tags-item-border: rgba(6, 182, 212, 0.18);
--tags-item-text: rgba(255, 255, 255, 0.6);
--tags-item-hover: rgba(6, 182, 212, 0.1);
--tags-close-hover: rgba(168, 85, 247, 0.52);
--splitpanes-default-bg: #0a0e17;
}

View File

@ -38,9 +38,8 @@ function addIframe() {
<style lang="scss" scoped> <style lang="scss" scoped>
@use "@/assets/styles/variables.module" as *; @use "@/assets/styles/variables.module" as *;
.app-main { .app-main {
/* 50= navbar 50 */ height: calc(100% - 104px);
height: calc(100% - 84px); padding: 24px;
padding: 20px;
width: 100%; width: 100%;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
@ -50,17 +49,22 @@ function addIframe() {
} }
.fixed-header + .app-main { .fixed-header + .app-main {
padding-top: 50px; padding-top: 64px;
} }
.hasTagsView { .hasTagsView {
.app-main { .app-main {
/* 84 = navbar + tags-view = 50 + 34 */ height: calc(100% - 104px);
height: calc(100% - 84px);
} }
.fixed-header + .app-main { .fixed-header + .app-main {
padding-top: 84px; padding-top: 104px;
}
}
@media (max-width: 768px) {
.app-main {
padding: 16px;
} }
} }
</style> </style>

View File

@ -155,7 +155,7 @@ defineExpose({
color: var(--notice-title-color, #1a202c); color: var(--notice-title-color, #1a202c);
line-height: 1.45; line-height: 1.45;
margin: 0 0 16px; margin: 0 0 16px;
letter-spacing: -0.2px; letter-spacing: 0;
} }
.notice-meta { .notice-meta {

View File

@ -175,14 +175,14 @@ async function toggleTheme(event) {
<style lang='scss' scoped> <style lang='scss' scoped>
.navbar { .navbar {
height: 50px; height: 64px;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
background: var(--navbar-bg); background: var(--navbar-bg);
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
.hamburger-container { .hamburger-container {
line-height: 46px; line-height: 60px;
height: 100%; height: 100%;
float: left; float: left;
cursor: pointer; cursor: pointer;
@ -200,7 +200,7 @@ async function toggleTheme(event) {
.topmenu-container { .topmenu-container {
position: absolute; position: absolute;
left: 50px; left: 64px;
} }
.errLog-container { .errLog-container {
@ -211,7 +211,7 @@ async function toggleTheme(event) {
.right-menu { .right-menu {
float: right; float: right;
height: 100%; height: 100%;
line-height: 50px; line-height: 64px;
display: flex; display: flex;
&:focus { &:focus {
@ -253,14 +253,14 @@ async function toggleTheme(event) {
margin-right: 40px; margin-right: 40px;
.avatar-wrapper { .avatar-wrapper {
margin-top: 5px; margin-top: 12px;
position: relative; position: relative;
.user-avatar { .user-avatar {
cursor: pointer; cursor: pointer;
width: 40px; width: 40px;
height: 40px; height: 40px;
border-radius: 10px; border-radius: 6px;
} }
i { i {

View File

@ -24,6 +24,18 @@
<div class="setting-drawer-title"> <div class="setting-drawer-title">
<h3 class="drawer-title">主题风格设置</h3> <h3 class="drawer-title">主题风格设置</h3>
</div> </div>
<div class="drawer-item cyber-mode-toggle">
<span>深色科技模式</span>
<span class="comp-style">
<el-switch
:model-value="settingsStore.isDark"
inline-prompt
active-text="暗"
inactive-text="亮"
@change="settingsStore.toggleTheme"
/>
</span>
</div>
<div class="setting-drawer-block-checbox"> <div class="setting-drawer-block-checbox">
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')"> <div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')">
<img src="@/assets/images/dark.svg" alt="dark" /> <img src="@/assets/images/dark.svg" alt="dark" />
@ -139,7 +151,7 @@ const theme = ref(settingsStore.theme)
const sideTheme = ref(settingsStore.sideTheme) const sideTheme = ref(settingsStore.sideTheme)
const tagsViewPersist = ref(settingsStore.tagsViewPersist) const tagsViewPersist = ref(settingsStore.tagsViewPersist)
const storeSettings = computed(() => settingsStore) const storeSettings = computed(() => settingsStore)
const predefineColors = ref(["#409EFF", "#ff4500", "#ff8c00", "#ffd700", "#90ee90", "#00ced1", "#1e90ff", "#c71585"]) const predefineColors = ref(["#06B6D4", "#22D3EE", "#A855F7", "#10B981", "#3B82F6", "#FBBF24", "#FB7185"])
/** 是否需要dynamicTitle */ /** 是否需要dynamicTitle */
function dynamicTitleChange() { function dynamicTitleChange() {
@ -278,4 +290,4 @@ defineExpose({
margin: -3px 8px 0px 0px; margin: -3px 8px 0px 0px;
} }
} }
</style> </style>

View File

@ -67,8 +67,8 @@ const getLogoTextColor = computed(() => {
.sidebar-logo-container { .sidebar-logo-container {
position: relative; position: relative;
width: 100%; width: 100%;
height: 50px; height: 64px;
line-height: 50px; line-height: 64px;
background: v-bind(getLogoBackground); background: v-bind(getLogoBackground);
text-align: center; text-align: center;
overflow: hidden; overflow: hidden;
@ -89,7 +89,7 @@ const getLogoTextColor = computed(() => {
margin: 0; margin: 0;
color: v-bind(getLogoTextColor); color: v-bind(getLogoTextColor);
font-weight: 600; font-weight: 600;
line-height: 50px; line-height: 64px;
font-size: 14px; font-size: 14px;
font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif; font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
vertical-align: middle; vertical-align: middle;

View File

@ -259,7 +259,7 @@ function handleScroll() {
<style lang="scss" scoped> <style lang="scss" scoped>
.tags-view-container { .tags-view-container {
height: 34px; height: 40px;
width: 100%; width: 100%;
background: var(--tags-bg, #fff); background: var(--tags-bg, #fff);
border-bottom: 1px solid var(--tags-item-border, #d8dce5); border-bottom: 1px solid var(--tags-item-border, #d8dce5);
@ -270,15 +270,16 @@ function handleScroll() {
display: inline-block; display: inline-block;
position: relative; position: relative;
cursor: pointer; cursor: pointer;
height: 26px; height: 28px;
line-height: 26px; line-height: 26px;
border-radius: 4px;
border: 1px solid var(--tags-item-border, #d8dce5); border: 1px solid var(--tags-item-border, #d8dce5);
color: var(--tags-item-text, #495060); color: var(--tags-item-text, #495060);
background: var(--tags-item-bg, #fff); background: var(--tags-item-bg, #fff);
padding: 0 8px; padding: 0 8px;
font-size: 12px; font-size: 12px;
margin-left: 5px; margin-left: 5px;
margin-top: 4px; margin-top: 6px;
&:first-of-type { &:first-of-type {
margin-left: 15px; margin-left: 15px;

View File

@ -65,9 +65,9 @@ onMounted(() => {
.topbar-menu.el-menu--horizontal > .el-menu-item { .topbar-menu.el-menu--horizontal > .el-menu-item {
float: left; float: left;
height: 50px !important; height: 64px !important;
line-height: 50px !important; line-height: 64px !important;
color: #303133 !important; color: var(--navbar-text) !important;
padding: 0 5px !important; padding: 0 5px !important;
margin: 0 10px !important; margin: 0 10px !important;
} }
@ -79,8 +79,8 @@ onMounted(() => {
/* sub-menu item */ /* sub-menu item */
.topbar-menu.el-menu--horizontal > .el-sub-menu .el-sub-menu__title { .topbar-menu.el-menu--horizontal > .el-sub-menu .el-sub-menu__title {
float: left; float: left;
line-height: 50px !important; line-height: 64px !important;
color: #303133 !important; color: var(--navbar-text) !important;
margin: 0 15px -3px!important; margin: 0 15px -3px!important;
} }
@ -94,6 +94,6 @@ onMounted(() => {
/* menu__title el-menu-item */ /* menu__title el-menu-item */
.topbar-menu.el-menu--horizontal .el-sub-menu__title, .topbar-menu.el-menu--horizontal .el-menu-item { .topbar-menu.el-menu--horizontal .el-sub-menu__title, .topbar-menu.el-menu--horizontal .el-menu-item {
height: 60px; height: 64px;
} }
</style> </style>

View File

@ -172,37 +172,37 @@ onMounted(() => {
<style lang="scss"> <style lang="scss">
.topmenu-container.el-menu--horizontal { .topmenu-container.el-menu--horizontal {
height: 50px !important; height: 64px !important;
border-bottom: none; border-bottom: none;
} }
.topmenu-container.el-menu--horizontal > .el-menu-item { .topmenu-container.el-menu--horizontal > .el-menu-item {
float: left; float: left;
height: 50px !important; height: 64px !important;
line-height: 50px !important; line-height: 64px !important;
color: #303133 !important; color: var(--navbar-text) !important;
padding: 0 5px !important; padding: 0 5px !important;
margin: 0 10px !important; margin: 0 10px !important;
} }
.topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-sub-menu.is-active .el-submenu__title { .topmenu-container.el-menu--horizontal > .el-menu-item.is-active, .el-menu--horizontal > .el-sub-menu.is-active .el-submenu__title {
border-bottom: 2px solid #{'var(--theme)'} !important; border-bottom: 2px solid #{'var(--theme)'} !important;
color: #303133; color: var(--navbar-text);
} }
/* sub-menu item */ /* sub-menu item */
.topmenu-container.el-menu--horizontal > .el-sub-menu .el-sub-menu__title { .topmenu-container.el-menu--horizontal > .el-sub-menu .el-sub-menu__title {
float: left; float: left;
height: 50px !important; height: 64px !important;
line-height: 50px !important; line-height: 64px !important;
color: #303133 !important; color: var(--navbar-text) !important;
padding: 0 5px !important; padding: 0 5px !important;
margin: 0 10px !important; margin: 0 10px !important;
} }
/* 背景色隐藏 */ /* 背景色隐藏 */
.topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus, .topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover, .topmenu-container.el-menu--horizontal>.el-submenu .el-submenu__title:hover { .topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):focus, .topmenu-container.el-menu--horizontal>.el-menu-item:not(.is-disabled):hover, .topmenu-container.el-menu--horizontal>.el-submenu .el-submenu__title:hover {
background-color: #ffffff; background-color: var(--navbar-hover);
} }
/* 图标右间距 */ /* 图标右间距 */

View File

@ -98,7 +98,7 @@ function setLayout() {
} }
.hideSidebar .fixed-header { .hideSidebar .fixed-header {
width: calc(100% - 54px); width: calc(100% - 68px);
} }
.sidebarHide .fixed-header { .sidebarHide .fixed-header {

View File

@ -3,19 +3,26 @@ import { useDark, useToggle } from '@vueuse/core'
import { useDynamicTitle } from '@/utils/dynamicTitle' import { useDynamicTitle } from '@/utils/dynamicTitle'
import { handleThemeStyle } from '@/utils/theme' import { handleThemeStyle } from '@/utils/theme'
const isDark = useDark() const isDark = useDark({
storageKey: 'cmvr-color-scheme',
initialValue: 'dark'
})
const toggleDark = useToggle(isDark) const toggleDark = useToggle(isDark)
const { sideTheme, showSettings, navType, tagsView, tagsViewPersist, tagsIcon, tagsViewStyle, fixedHeader, sidebarLogo, dynamicTitle, footerVisible, footerContent } = defaultSettings const { sideTheme, showSettings, navType, tagsView, tagsViewPersist, tagsIcon, tagsViewStyle, fixedHeader, sidebarLogo, dynamicTitle, footerVisible, footerContent } = defaultSettings
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || '' const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
const legacyPrimaryColors = ['#409EFF', '#43C6A4']
const initialTheme = storageSetting.theme && !legacyPrimaryColors.includes(storageSetting.theme.toUpperCase())
? storageSetting.theme
: '#06B6D4'
const useSettingsStore = defineStore( const useSettingsStore = defineStore(
'settings', 'settings',
{ {
state: () => ({ state: () => ({
title: '', title: '',
theme: storageSetting.theme || '#409EFF', theme: initialTheme,
sideTheme: storageSetting.sideTheme || sideTheme, sideTheme: storageSetting.sideTheme || sideTheme,
showSettings: showSettings, showSettings: showSettings,
navType: storageSetting.navType === undefined ? navType : storageSetting.navType, navType: storageSetting.navType === undefined ? navType : storageSetting.navType,

View File

@ -1,7 +1,6 @@
// 处理主题样式 // 处理主题样式
export function handleThemeStyle(theme) { export function handleThemeStyle(theme) {
const isDark = typeof document !== 'undefined' && document.documentElement.classList.contains('dark') const primary = theme
const primary = isDark ? softenPrimaryForDark(theme) : theme
document.documentElement.style.setProperty('--el-color-primary', primary) document.documentElement.style.setProperty('--el-color-primary', primary)
for (let i = 1; i <= 9; i++) { for (let i = 1; i <= 9; i++) {
document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, `${getLightColor(primary, i / 10)}`) document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, `${getLightColor(primary, i / 10)}`)

View File

@ -129,7 +129,7 @@ onMounted(() => {
.stat-number { .stat-number {
font-size: 24px; font-size: 24px;
font-weight: 700; font-weight: 700;
letter-spacing: -0.02em; letter-spacing: 0;
color: #0f172a; color: #0f172a;
} }
@ -158,4 +158,4 @@ onMounted(() => {
} }
} }
} }
</style> </style>

View File

@ -139,7 +139,7 @@ onMounted(() => {
.stat-number { .stat-number {
font-size: 24px; font-size: 24px;
font-weight: 700; font-weight: 700;
letter-spacing: -0.02em; letter-spacing: 0;
color: #0f172a; color: #0f172a;
} }
@ -168,4 +168,4 @@ onMounted(() => {
} }
} }
} }
</style> </style>

View File

@ -75,6 +75,9 @@ const initChart = () => {
} }
myChart = echarts.init(chart.value); myChart = echarts.init(chart.value);
const option = { const option = {
backgroundColor: 'transparent',
color: ['#06B6D4', '#10B981', '#A855F7', '#3B82F6', '#FBBF24'],
textStyle: { color: 'rgba(255, 255, 255, 0.72)' },
title: { text: '手指触觉数据' }, title: { text: '手指触觉数据' },
tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } }, tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
legend: { data: ['指端', '指尖', '指中', '指腹', '手掌触觉'] }, legend: { data: ['指端', '指尖', '指中', '指腹', '手掌触觉'] },
@ -93,6 +96,36 @@ const initChart = () => {
{ name: '手掌触觉', type: 'bar', barGap: '1%', barCategoryGap: '10%', itemStyle: { color: '#FFD700' }, label: { show: true, position: 'top' }, emphasis: { focus: 'series' }, data: [] } { name: '手掌触觉', type: 'bar', barGap: '1%', barCategoryGap: '10%', itemStyle: { color: '#FFD700' }, label: { show: true, position: 'top' }, emphasis: { focus: 'series' }, data: [] }
] ]
}; };
Object.assign(option.title, { textStyle: { color: 'rgba(255, 255, 255, 0.88)', fontWeight: 650 } });
Object.assign(option.tooltip, {
backgroundColor: 'rgba(10, 14, 23, 0.94)',
borderColor: 'rgba(6, 182, 212, 0.48)',
textStyle: { color: 'rgba(255, 255, 255, 0.88)' }
});
Object.assign(option.legend, { textStyle: { color: 'rgba(255, 255, 255, 0.62)' } });
Object.assign(option.xAxis, {
axisLine: { lineStyle: { color: 'rgba(6, 182, 212, 0.36)' } },
axisTick: { show: false },
axisLabel: { color: 'rgba(255, 255, 255, 0.64)' },
splitArea: { show: true, areaStyle: { color: ['rgba(6, 182, 212, 0.02)', 'rgba(168, 85, 247, 0.025)'] } }
});
option.yAxis.forEach((axis) => Object.assign(axis, {
axisLine: { show: true, lineStyle: { color: 'rgba(6, 182, 212, 0.3)' } },
axisLabel: { color: 'rgba(255, 255, 255, 0.62)' },
nameTextStyle: { color: 'rgba(255, 255, 255, 0.68)' },
splitLine: { lineStyle: { color: 'rgba(148, 163, 184, 0.12)', type: 'dashed' } }
}));
const seriesColors = ['#06B6D4', '#10B981', '#A855F7', '#3B82F6', '#FBBF24'];
option.series.forEach((series, index) => {
series.itemStyle = {
...series.itemStyle,
color: seriesColors[index],
borderRadius: [3, 3, 0, 0],
shadowBlur: 12,
shadowColor: `${seriesColors[index]}66`
};
series.label = { ...series.label, color: 'rgba(255, 255, 255, 0.74)' };
});
myChart.setOption(option); myChart.setOption(option);
}; };
@ -212,18 +245,20 @@ onUnmounted(() => {
margin: 0 10px; margin: 0 10px;
cursor: pointer; cursor: pointer;
font-size: 16px; font-size: 16px;
color: #333; color: var(--el-text-color-regular);
border-bottom: 3px solid transparent; border-bottom: 3px solid transparent;
transition: all 0.3s ease; transition: all 0.3s ease;
} }
.tab:hover { .tab:hover {
background-color: #f5f5f5; color: #67e8f9;
background-color: rgba(6, 182, 212, 0.1);
border-radius: 5px; border-radius: 5px;
} }
.tab.active { .tab.active {
border-bottom: 3px solid #007bff; border-bottom: 3px solid #06b6d4;
color: #007bff; color: #67e8f9;
text-shadow: 0 0 12px rgba(6, 182, 212, 0.48);
} }
</style> </style>

View File

@ -72,6 +72,43 @@ const topChartData = ref({
series: [{ data: props.topSeriesData, type: 'bar' }], series: [{ data: props.topSeriesData, type: 'bar' }],
}); });
Object.assign(topChartData.value, {
backgroundColor: 'transparent',
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow', shadowStyle: { color: 'rgba(6, 182, 212, 0.08)' } },
backgroundColor: 'rgba(10, 14, 23, 0.94)',
borderColor: 'rgba(6, 182, 212, 0.48)',
textStyle: { color: 'rgba(255, 255, 255, 0.88)' },
},
grid: { left: 54, right: 20, top: 24, bottom: 42 },
});
Object.assign(topChartData.value.xAxis, {
axisLine: { lineStyle: { color: 'rgba(6, 182, 212, 0.36)' } },
axisTick: { show: false },
axisLabel: { color: 'rgba(255, 255, 255, 0.68)', interval: 0 },
});
Object.assign(topChartData.value.yAxis, {
axisLine: { show: true, lineStyle: { color: 'rgba(6, 182, 212, 0.36)' } },
axisLabel: { formatter: '{value} g', color: 'rgba(255, 255, 255, 0.62)' },
axisTick: { show: true, lineStyle: { color: 'rgba(6, 182, 212, 0.3)' } },
splitLine: { lineStyle: { color: 'rgba(148, 163, 184, 0.12)', type: 'dashed' } },
nameTextStyle: { color: 'rgba(255, 255, 255, 0.68)' },
});
Object.assign(topChartData.value.series[0], {
barMaxWidth: 34,
itemStyle: {
borderRadius: [4, 4, 0, 0],
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#67E8F9' },
{ offset: 0.5, color: '#06B6D4' },
{ offset: 1, color: 'rgba(168, 85, 247, 0.5)' },
]),
shadowBlur: 14,
shadowColor: 'rgba(6, 182, 212, 0.42)',
},
});
const data = ref({ const data = ref({
resizeObserver: null, resizeObserver: null,
debouncedResize: null, debouncedResize: null,
@ -159,4 +196,4 @@ watch(
margin: 10px 0; margin: 10px 0;
min-height: 200px; /* 确保图表有足够的高度 */ min-height: 200px; /* 确保图表有足够的高度 */
} }
</style> </style>

View File

@ -173,7 +173,7 @@
<template #edge-flow-edge="edgeProps"> <template #edge-flow-edge="edgeProps">
<FlowEdge v-bind="edgeProps" /> <FlowEdge v-bind="edgeProps" />
</template> </template>
<Background color="#d9dee8" :gap="24" :size="1" /> <Background color="var(--flow-grid-color)" :gap="24" :size="1" />
<Controls position="bottom-right" /> <Controls position="bottom-right" />
</VueFlow> </VueFlow>
</el-main> </el-main>

View File

@ -68,6 +68,7 @@
import { getCache } from '@/api/monitor/cache' import { getCache } from '@/api/monitor/cache'
import * as echarts from 'echarts' import * as echarts from 'echarts'
const cyberPalette = ['#06B6D4', '#A855F7', '#10B981', '#3B82F6', '#FBBF24', '#FB7185']
const cache = ref([]) const cache = ref([])
const commandstats = ref(null) const commandstats = ref(null)
const usedmemory = ref(null) const usedmemory = ref(null)
@ -79,11 +80,16 @@ function getList() {
proxy.$modal.closeLoading() proxy.$modal.closeLoading()
cache.value = response.data cache.value = response.data
const commandstatsIntance = echarts.init(commandstats.value, "macarons") const commandstatsIntance = echarts.init(commandstats.value)
commandstatsIntance.setOption({ commandstatsIntance.setOption({
backgroundColor: 'transparent',
color: cyberPalette,
tooltip: { tooltip: {
trigger: "item", trigger: "item",
formatter: "{a} <br/>{b} : {c} ({d}%)" formatter: "{a} <br/>{b} : {c} ({d}%)",
backgroundColor: 'rgba(10, 14, 23, 0.94)',
borderColor: 'rgba(6, 182, 212, 0.48)',
textStyle: { color: 'rgba(255, 255, 255, 0.88)' }
}, },
series: [ series: [
{ {
@ -93,15 +99,28 @@ function getList() {
radius: [15, 95], radius: [15, 95],
center: ["50%", "38%"], center: ["50%", "38%"],
data: response.data.commandStats, data: response.data.commandStats,
label: { color: 'rgba(255, 255, 255, 0.72)' },
labelLine: { lineStyle: { color: 'rgba(6, 182, 212, 0.34)' } },
itemStyle: {
borderColor: '#0A0E17',
borderWidth: 2,
shadowBlur: 14,
shadowColor: 'rgba(6, 182, 212, 0.28)'
},
emphasis: { itemStyle: { shadowBlur: 26, shadowColor: 'rgba(168, 85, 247, 0.52)' } },
animationEasing: "cubicInOut", animationEasing: "cubicInOut",
animationDuration: 1000 animationDuration: 1000
} }
] ]
}) })
const usedmemoryInstance = echarts.init(usedmemory.value, "macarons") const usedmemoryInstance = echarts.init(usedmemory.value)
usedmemoryInstance.setOption({ usedmemoryInstance.setOption({
backgroundColor: 'transparent',
tooltip: { tooltip: {
formatter: "{b} <br/>{a} : " + cache.value.info.used_memory_human formatter: "{b} <br/>{a} : " + cache.value.info.used_memory_human,
backgroundColor: 'rgba(10, 14, 23, 0.94)',
borderColor: 'rgba(6, 182, 212, 0.48)',
textStyle: { color: 'rgba(255, 255, 255, 0.88)' }
}, },
series: [ series: [
{ {
@ -109,9 +128,24 @@ function getList() {
type: "gauge", type: "gauge",
min: 0, min: 0,
max: 1000, max: 1000,
detail: { progress: {
formatter: cache.value.info.used_memory_human show: true,
width: 14,
roundCap: true,
itemStyle: { color: '#06B6D4', shadowBlur: 18, shadowColor: 'rgba(6, 182, 212, 0.58)' }
}, },
pointer: { itemStyle: { color: '#67E8F9' } },
anchor: { show: true, size: 11, itemStyle: { color: '#A855F7', borderColor: '#E9D5FF', borderWidth: 2 } },
axisLine: { lineStyle: { width: 14, color: [[0.65, 'rgba(6, 182, 212, 0.34)'], [0.85, 'rgba(168, 85, 247, 0.42)'], [1, 'rgba(251, 113, 133, 0.48)']] } },
axisTick: { distance: -20, lineStyle: { color: 'rgba(255, 255, 255, 0.34)' } },
splitLine: { distance: -22, lineStyle: { color: 'rgba(255, 255, 255, 0.5)' } },
axisLabel: { color: 'rgba(255, 255, 255, 0.58)', distance: 24 },
detail: {
formatter: cache.value.info.used_memory_human,
color: 'rgba(255, 255, 255, 0.9)',
offsetCenter: [0, '62%']
},
title: { color: 'rgba(255, 255, 255, 0.62)', offsetCenter: [0, '82%'] },
data: [ data: [
{ {
value: parseFloat(cache.value.info.used_memory_human), value: parseFloat(cache.value.info.used_memory_human),