diff --git a/.env.development b/.env.development index 10db161..a5744e5 100644 --- a/.env.development +++ b/.env.development @@ -7,8 +7,8 @@ VITE_APP_ENV = 'development' # 招商车研物联网平台/开发环境 VITE_APP_BASE_API = '/dev-api' -VITE_API_URL = http://192.168.0.222:13080 -VITE_WS_URL = ws://192.168.0.222:13080/ws +VITE_API_URL = http://192.168.0.199:13080 +VITE_WS_URL = ws://192.168.0.199:13080/ws VITE_PORT = 80 VITE_INSPECTION_TYPE = "inspection" VITE_MINIO_URL = "http://192.168.28.10:9000/cmvr-iot/" diff --git a/src/assets/styles/cyber-theme.scss b/src/assets/styles/cyber-theme.scss new file mode 100644 index 0000000..49c7044 --- /dev/null +++ b/src/assets/styles/cyber-theme.scss @@ -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; } +} diff --git a/src/assets/styles/dark-overrides.scss b/src/assets/styles/dark-overrides.scss new file mode 100644 index 0000000..ce9689a --- /dev/null +++ b/src/assets/styles/dark-overrides.scss @@ -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); } +} diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss index 129980f..bdb445f 100644 --- a/src/assets/styles/index.scss +++ b/src/assets/styles/index.scss @@ -6,6 +6,8 @@ @use './btn.scss'; @use './ruoyi.scss'; @use './legacy-layout.scss'; +@use './dark-overrides.scss'; +@use './cyber-theme.scss'; body { height: 100%; @@ -13,7 +15,9 @@ body { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; 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 { @@ -100,24 +104,25 @@ div:focus { } aside { - background: #eef1f6; - padding: 8px 24px; - margin-bottom: 20px; - border-radius: 2px; + background: var(--surface-1); + padding: 10px 16px; + margin-bottom: 16px; + border: 1px solid var(--line-subtle); + border-radius: 6px; display: block; line-height: 32px; font-size: 16px; 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; -moz-osx-font-smoothing: grayscale; a { - color: #337ab7; + color: var(--el-color-primary); cursor: pointer; &:hover { - color: rgb(32, 160, 255); + color: var(--el-color-primary-light-3); } } } @@ -125,9 +130,10 @@ aside { //main-container全局样式 .app-container { width: 100%; - padding: 20px; - background-color: var(--el-bg-color); - border-radius: 4px; + padding: 24px; + background-color: var(--surface-0); + border: 1px solid var(--line-subtle); + border-radius: 6px; } .components-container { @@ -169,14 +175,78 @@ aside { .link-type, .link-type:focus { - color: #337ab7; + color: var(--el-color-primary); cursor: pointer; &: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 { padding-bottom: 10px; diff --git a/src/assets/styles/sidebar.scss b/src/assets/styles/sidebar.scss index b3269d4..8f449f5 100644 --- a/src/assets/styles/sidebar.scss +++ b/src/assets/styles/sidebar.scss @@ -47,7 +47,7 @@ &.has-logo { .el-scrollbar { - height: calc(100% - 50px); + height: calc(100% - 64px); } } @@ -114,11 +114,11 @@ .hideSidebar { .sidebar-container { - width: 54px !important; + width: 68px !important; } .main-container { - margin-left: 54px; + margin-left: 68px; } .sub-menu-title-noDropdown { @@ -129,7 +129,7 @@ padding: 0 !important; .svg-icon { - margin-left: 20px; + margin-left: 26px; } } } @@ -141,7 +141,7 @@ padding: 0 !important; .svg-icon { - margin-left: 20px; + margin-left: 26px; } } diff --git a/src/assets/styles/variables.module.scss b/src/assets/styles/variables.module.scss index 98c265a..a0b7ebf 100644 --- a/src/assets/styles/variables.module.scss +++ b/src/assets/styles/variables.module.scss @@ -9,10 +9,10 @@ $yellow: #fec171; $panGreen: #30b08f; // 默认主题变量 -$menuText: #bfcbd9; -$menuActiveText: #409eff; -$menuBg: #304156; -$menuHover: #263445; +$menuText: rgba(255, 255, 255, 0.68); +$menuActiveText: #67e8f9; +$menuBg: #0a0e17; +$menuHover: rgba(6, 182, 212, 0.1); // 浅色主题theme-light $menuLightBg: #ffffff; @@ -21,18 +21,18 @@ $menuLightText: #303133; $menuLightActiveText: #409eff; // 基础变量 -$base-sidebar-width: 200px; -$sideBarWidth: 200px; +$base-sidebar-width: 232px; +$sideBarWidth: 232px; // 菜单暗色变量 $base-menu-color: #bfcbd9; $base-menu-color-active: #f4f4f5; -$base-menu-background: #304156; -$base-sub-menu-background: #1f2d3d; -$base-sub-menu-hover: #001528; +$base-menu-background: #0a0e17; +$base-sub-menu-background: #101827; +$base-sub-menu-hover: rgba(6, 182, 212, 0.1); // 组件变量 -$--color-primary: #409eff; +$--color-primary: #06b6d4; $--color-success: #67c23a; $--color-warning: #e6a23c; $--color-danger: #f56c6c; @@ -79,6 +79,11 @@ $--color-info: #909399; --splitpanes-default-bg: #ffffff; --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; } } + +// 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; +} diff --git a/src/layout/components/AppMain.vue b/src/layout/components/AppMain.vue index e3fef8c..4ee092f 100644 --- a/src/layout/components/AppMain.vue +++ b/src/layout/components/AppMain.vue @@ -38,9 +38,8 @@ function addIframe() { diff --git a/src/layout/components/HeaderNotice/DetailView.vue b/src/layout/components/HeaderNotice/DetailView.vue index fa08e03..50647d8 100644 --- a/src/layout/components/HeaderNotice/DetailView.vue +++ b/src/layout/components/HeaderNotice/DetailView.vue @@ -155,7 +155,7 @@ defineExpose({ color: var(--notice-title-color, #1a202c); line-height: 1.45; margin: 0 0 16px; - letter-spacing: -0.2px; + letter-spacing: 0; } .notice-meta { diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue index 00a0867..e806774 100644 --- a/src/layout/components/Navbar.vue +++ b/src/layout/components/Navbar.vue @@ -175,14 +175,14 @@ async function toggleTheme(event) { \ No newline at end of file + diff --git a/src/layout/components/Sidebar/Logo.vue b/src/layout/components/Sidebar/Logo.vue index 0373c4e..5b77280 100644 --- a/src/layout/components/Sidebar/Logo.vue +++ b/src/layout/components/Sidebar/Logo.vue @@ -67,8 +67,8 @@ const getLogoTextColor = computed(() => { .sidebar-logo-container { position: relative; width: 100%; - height: 50px; - line-height: 50px; + height: 64px; + line-height: 64px; background: v-bind(getLogoBackground); text-align: center; overflow: hidden; @@ -89,7 +89,7 @@ const getLogoTextColor = computed(() => { margin: 0; color: v-bind(getLogoTextColor); font-weight: 600; - line-height: 50px; + line-height: 64px; font-size: 14px; font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif; vertical-align: middle; diff --git a/src/layout/components/TagsView/index.vue b/src/layout/components/TagsView/index.vue index 2fa2c69..92ab475 100644 --- a/src/layout/components/TagsView/index.vue +++ b/src/layout/components/TagsView/index.vue @@ -259,7 +259,7 @@ function handleScroll() { diff --git a/src/layout/components/TopNav/index.vue b/src/layout/components/TopNav/index.vue index 3810cfe..96e32ac 100644 --- a/src/layout/components/TopNav/index.vue +++ b/src/layout/components/TopNav/index.vue @@ -172,37 +172,37 @@ onMounted(() => { \ No newline at end of file + diff --git a/src/views/corpusManger/speech_synthesis/components/StatCards.vue b/src/views/corpusManger/speech_synthesis/components/StatCards.vue index dd4656b..fa2ae8e 100644 --- a/src/views/corpusManger/speech_synthesis/components/StatCards.vue +++ b/src/views/corpusManger/speech_synthesis/components/StatCards.vue @@ -139,7 +139,7 @@ onMounted(() => { .stat-number { font-size: 24px; font-weight: 700; - letter-spacing: -0.02em; + letter-spacing: 0; color: #0f172a; } @@ -168,4 +168,4 @@ onMounted(() => { } } } - \ No newline at end of file + diff --git a/src/views/device/register/components/DexHand/RightBottomCharts.vue b/src/views/device/register/components/DexHand/RightBottomCharts.vue index bc42122..594e9ab 100644 --- a/src/views/device/register/components/DexHand/RightBottomCharts.vue +++ b/src/views/device/register/components/DexHand/RightBottomCharts.vue @@ -75,6 +75,9 @@ const initChart = () => { } myChart = echarts.init(chart.value); const option = { + backgroundColor: 'transparent', + color: ['#06B6D4', '#10B981', '#A855F7', '#3B82F6', '#FBBF24'], + textStyle: { color: 'rgba(255, 255, 255, 0.72)' }, title: { text: '手指触觉数据' }, tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } }, 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: [] } ] }; + 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); }; @@ -212,18 +245,20 @@ onUnmounted(() => { margin: 0 10px; cursor: pointer; font-size: 16px; - color: #333; + color: var(--el-text-color-regular); border-bottom: 3px solid transparent; transition: all 0.3s ease; } .tab:hover { - background-color: #f5f5f5; + color: #67e8f9; + background-color: rgba(6, 182, 212, 0.1); border-radius: 5px; } .tab.active { - border-bottom: 3px solid #007bff; - color: #007bff; + border-bottom: 3px solid #06b6d4; + color: #67e8f9; + text-shadow: 0 0 12px rgba(6, 182, 212, 0.48); } - \ No newline at end of file + diff --git a/src/views/device/register/components/DexHand/RightTopCharts.vue b/src/views/device/register/components/DexHand/RightTopCharts.vue index 09cae93..60621ee 100644 --- a/src/views/device/register/components/DexHand/RightTopCharts.vue +++ b/src/views/device/register/components/DexHand/RightTopCharts.vue @@ -72,6 +72,43 @@ const topChartData = ref({ 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({ resizeObserver: null, debouncedResize: null, @@ -159,4 +196,4 @@ watch( margin: 10px 0; min-height: 200px; /* 确保图表有足够的高度 */ } - \ No newline at end of file + diff --git a/src/views/flow/index.vue b/src/views/flow/index.vue index c6e0bf4..715a244 100644 --- a/src/views/flow/index.vue +++ b/src/views/flow/index.vue @@ -173,7 +173,7 @@ - + diff --git a/src/views/monitor/cache/index.vue b/src/views/monitor/cache/index.vue index 271cc8e..b4c82c4 100644 --- a/src/views/monitor/cache/index.vue +++ b/src/views/monitor/cache/index.vue @@ -68,6 +68,7 @@ import { getCache } from '@/api/monitor/cache' import * as echarts from 'echarts' +const cyberPalette = ['#06B6D4', '#A855F7', '#10B981', '#3B82F6', '#FBBF24', '#FB7185'] const cache = ref([]) const commandstats = ref(null) const usedmemory = ref(null) @@ -79,11 +80,16 @@ function getList() { proxy.$modal.closeLoading() cache.value = response.data - const commandstatsIntance = echarts.init(commandstats.value, "macarons") + const commandstatsIntance = echarts.init(commandstats.value) commandstatsIntance.setOption({ + backgroundColor: 'transparent', + color: cyberPalette, tooltip: { trigger: "item", - formatter: "{a}
{b} : {c} ({d}%)" + formatter: "{a}
{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: [ { @@ -93,15 +99,28 @@ function getList() { radius: [15, 95], center: ["50%", "38%"], 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", animationDuration: 1000 } ] }) - const usedmemoryInstance = echarts.init(usedmemory.value, "macarons") + const usedmemoryInstance = echarts.init(usedmemory.value) usedmemoryInstance.setOption({ + backgroundColor: 'transparent', tooltip: { - formatter: "{b}
{a} : " + cache.value.info.used_memory_human + formatter: "{b}
{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: [ { @@ -109,9 +128,24 @@ function getList() { type: "gauge", min: 0, max: 1000, - detail: { - formatter: cache.value.info.used_memory_human + progress: { + 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: [ { value: parseFloat(cache.value.info.used_memory_human),