diff --git a/.cursor/skills/ruoyi-industrial-dashboard-style/SKILL.md b/.cursor/skills/ruoyi-industrial-dashboard-style/SKILL.md new file mode 100644 index 0000000..dcc634f --- /dev/null +++ b/.cursor/skills/ruoyi-industrial-dashboard-style/SKILL.md @@ -0,0 +1,194 @@ +--- +name: ruoyi-industrial-dashboard-style +description: Recreate the industrial dashboard style from `ruoyi-ui/src/views/index.vue` and apply it consistently across the UI, especially buttons, inputs, tables, cards, tags, and other Element-UI components. Use when the user asks for an industrial monitoring layout, blue-themed controls, or a RuoYi UI style based on `ruoyi-ui/src/views/index.vue`. +--- + +# RuoYi Industrial Dashboard Style + +## Goal + +Produce UI that matches the look and feel of `ruoyi-ui/src/views/index.vue` and extends it into the global component system: + +- Compact, information-dense layout +- Industrial control-room aesthetic +- Dark top status bar +- White cards with subtle borders and soft shadows +- Small typography and tight spacing +- Strong blue accents across all controls, not green +- Table-first monitoring views with status badges and communication indicators + +## Core color direction + +- Primary actions, links, active states, and focused controls should use blue shades. +- Use deep navy and steel blue as the main palette. +- Avoid default Element-UI green success styling unless the semantics truly require success. +- Reserve red for alarms, orange for warnings, and gray for neutral states. +- Buttons, tags, table headers, and form focus states should visually align with the blue industrial palette. + +## Design rules + +### Overall layout + +- Use a light gray page background. +- Keep padding and gaps tight. +- Prefer multiple horizontal sections over tall stacked blocks. +- Treat each section as a bordered card with a small header. + +### Top status bar + +- Use a full-width dark header strip. +- Left side should show system name, divider, and unit tag. +- Right side should show online/offline state and a live clock. +- Keep the bar compact, stable, and highly legible. + +### KPI cards + +- Use white cards with a small colored icon block. +- Show a large numeric value and a smaller label. +- Keep card height short and consistent. +- Prefer blue for normal metrics, orange for in-progress, red for warnings. + +### Equipment or station cards + +- Use a dark card header with the equipment name and runtime badge. +- Use a grid for dense parameter display. +- Display values in monospace or tabular-style text where possible. +- Add a slim footer with current coil/order, grade, shift, or similar operational context. + +### Tables + +- Prefer compact tables with borders and stripes. +- Use small button sizes and small tags. +- Keep column widths tight and practical. +- Use status text and colors to show workflow state. + +### Communication or alarm indicators + +- Use small dots, compact labels, and timestamps. +- Use blue for healthy connections. +- Use red and subtle blinking for alarms or disconnects. + +## Visual tokens + +Use these as the default visual language unless the user asks otherwise: + +- Background: `#f0f2f5` +- Card border: `#dde1e6` +- Primary dark: `#1c2b3a` +- Primary blue: `#1d4e89` +- Secondary blue: `#2471a3` +- Warning orange: `#d68910` +- Danger red: `#c0392b` +- Muted text: `#7f8c8d` +- Soft shadow: `0 1px 4px rgba(0,0,0,.05)` + +## Typography and spacing + +- Use 11?C13px text for most labels and chrome. +- Use bold, larger numeric values for KPIs. +- Keep corner radii small, around 2?C4px. +- Use subtle dividers and minimal decoration. + +## SCSS conventions + +- Prefer scoped SCSS. +- Use BEM-style nested blocks like `card__header`, `card__body`, `card__footer`. +- Keep component styles compact and local. +- Use monospace for clocks and numeric readings when appropriate. + +## When implementing a new screen + +1. Start with the overall page shell and background. +2. Add the dark status bar. +3. Add KPI cards in a tight grid. +4. Add one or more dense equipment/status panels. +5. Add a compact table or communication panel. +6. Apply the color, spacing, border, and blue-control rules above. + +## Example prompt behavior + +If the user says they like the style from `ruoyi-ui/src/views/index.vue`, interpret that as a request to reuse this exact industrial dashboard language in new pages, components, or screens. + +## Design rules + +### Overall layout + +- Use a light gray page background. +- Keep padding and gaps tight. +- Prefer multiple horizontal sections over tall stacked blocks. +- Treat each section as a bordered card with a small header. + +### Top status bar + +- Use a full-width dark header strip. +- Left side should show system name, divider, and unit tag. +- Right side should show online/offline state and a live clock. +- Keep the bar compact, stable, and highly legible. + +### KPI cards + +- Use white cards with a small colored icon block. +- Show a large numeric value and a smaller label. +- Keep card height short and consistent. +- Prefer blue for normal metrics, orange for in-progress, red for warnings. + +### Equipment or station cards + +- Use a dark card header with the equipment name and runtime badge. +- Use a grid for dense parameter display. +- Display values in monospace or tabular-style text where possible. +- Add a slim footer with current coil/order, grade, shift, or similar operational context. + +### Tables + +- Prefer compact tables with borders and stripes. +- Use small button sizes and small tags. +- Keep column widths tight and practical. +- Use status text and colors to show workflow state. + +### Communication or alarm indicators + +- Use small dots, compact labels, and timestamps. +- Use blue for healthy connections. +- Use red and subtle blinking for alarms or disconnects. + +## Visual tokens + +Use these as the default visual language unless the user asks otherwise: + +- Background: `#f0f2f5` +- Card border: `#dde1e6` +- Primary dark: `#1c2b3a` +- Primary blue: `#1d4e89` +- Secondary blue: `#2471a3` +- Warning orange: `#d68910` +- Danger red: `#c0392b` +- Muted text: `#7f8c8d` +- Soft shadow: `0 1px 4px rgba(0,0,0,.05)` + +## Typography and spacing + +- Use 11?C13px text for most labels and chrome. +- Use bold, larger numeric values for KPIs. +- Keep corner radii small, around 2?C4px. +- Use subtle dividers and minimal decoration. + +## SCSS conventions + +- Prefer scoped SCSS. +- Use BEM-style nested blocks like `card__header`, `card__body`, `card__footer`. +- Keep component styles compact and local. +- Use monospace for clocks and numeric readings when appropriate. + +## When implementing a new screen + +1. Start with the overall page shell and background. +2. Add the dark status bar. +3. Add KPI cards in a tight grid. +4. Add one or more dense equipment/status panels. +5. Add a compact table or communication panel. +6. Apply the color, spacing, and border rules above. + +## Example prompt behavior + +If the user says they like the style from `ruoyi-ui/src/views/index.vue`, interpret that as a request to reuse this exact industrial dashboard language in new pages, components, or screens. diff --git a/gear-admin/src/main/resources/application-prod.yml b/gear-admin/src/main/resources/application-prod.yml index 76c00c7..56822a5 100644 --- a/gear-admin/src/main/resources/application-prod.yml +++ b/gear-admin/src/main/resources/application-prod.yml @@ -105,13 +105,13 @@ spring: spring: redis: # 地址 - host: localhost + host: 49.232.154.205 # 端口,默认为6379 port: 6379 # 数据库索引 database: 0 # 密码(如没有密码请注释掉) - # password: + password: WANGyu11! # 连接超时时间 timeout: 10s # 是否开启ssl diff --git a/gear-ui3/src/assets/styles/btn.scss b/gear-ui3/src/assets/styles/btn.scss index fee3ee1..3db5990 100644 --- a/gear-ui3/src/assets/styles/btn.scss +++ b/gear-ui3/src/assets/styles/btn.scss @@ -4,7 +4,7 @@ background: $color; &:hover { - color: $color; + color: #fff; &:before, &:after { @@ -82,13 +82,16 @@ } .custom-button { - display: inline-block; + display: inline-flex; + align-items: center; + justify-content: center; line-height: 1; white-space: nowrap; cursor: pointer; - background: #fff; - color: #fff; + background: var(--app-primary); + color: #fff !important; -webkit-appearance: none; + appearance: none; text-align: center; box-sizing: border-box; outline: 0; @@ -97,3 +100,26 @@ font-size: 14px; border-radius: 4px; } + +:global(.el-button) { + color: #fff !important; +} + +:global(.el-button > span), +:global(.el-button > span *) , +:global(.el-button .svg-icon), +:global(.el-button i) { + color: inherit !important; + fill: currentColor; +} + +:global(.el-button--default) { + color: var(--app-primary) !important; +} + +:global(.el-button--default > span), +:global(.el-button--default > span *), +:global(.el-button--default .svg-icon), +:global(.el-button--default i) { + color: inherit !important; +} diff --git a/gear-ui3/src/assets/styles/element-ui.scss b/gear-ui3/src/assets/styles/element-ui.scss index 20ad6bb..c04fba0 100644 --- a/gear-ui3/src/assets/styles/element-ui.scss +++ b/gear-ui3/src/assets/styles/element-ui.scss @@ -5,7 +5,13 @@ $--spacing-base: 8px; $--spacing-md: $--spacing-base; $--spacing-lg: $--spacing-base * 2; $--form-item-margin: $--spacing-base; -$--btn-height: 24px; +$--btn-height: 24px; + +$industrial-primary: #1d4e89; +$industrial-secondary: #2471a3; +$industrial-dark: #1c2b3a; +$industrial-border: #dde1e6; +$industrial-bg: #f0f2f5; // ====================== 2. CSS尺寸变量(与Sass变量同步)====================== @@ -71,16 +77,35 @@ body { // 主按钮(尺寸相关) .el-button--primary { @include button-variant(); + background: $industrial-primary; + border-color: $industrial-primary; + color: #fff !important; + + &:hover, + &:focus { + background: $industrial-secondary; + border-color: $industrial-secondary; + color: #fff !important; + } } // 功能按钮(尺寸相关) .el-button--success, -.el-button--warning, .el-button--danger, .el-button--info { @include button-variant(); } +.el-button--warning { + @include button-variant(); + color: #1c2b3a !important; + + &:hover, + &:focus { + color: #1c2b3a !important; + } +} + // 文本按钮(尺寸相关) .el-button--text { height: auto; @@ -142,9 +167,19 @@ body { // ---------------------- 5.2 表格(紧凑尺寸)---------------------- .el-table { - border-radius: 8px; + border-radius: 6px; overflow: hidden; margin-top: $--form-item-margin * 2; // 与表单间距 + border: 1px solid $industrial-border; + + .el-table__header-wrapper, + .el-table__fixed-header-wrapper { + th.el-table__cell { + background: #eef3f8; + color: $industrial-dark; + border-bottom: 1px solid $industrial-border; + } + } // 表头(紧凑padding) .el-table__header-wrapper { @@ -429,8 +464,10 @@ body { // ---------------------- 5.5 卡片/对话框(尺寸层级)---------------------- // 卡片尺寸 .el-card { - border-radius: 8px; + border-radius: 6px; overflow: hidden; + border: 1px solid $industrial-border; + box-shadow: 0 1px 4px rgba(0,0,0,.05); // 卡片头部尺寸 .el-card__header { diff --git a/gear-ui3/src/assets/styles/index.scss b/gear-ui3/src/assets/styles/index.scss index b204410..9af31f2 100644 --- a/gear-ui3/src/assets/styles/index.scss +++ b/gear-ui3/src/assets/styles/index.scss @@ -6,9 +6,25 @@ @use './btn.scss'; @use './ruoyi.scss'; +:root { + color-scheme: light; + --app-page-bg: #f0f2f5; + --app-card-bg: #ffffff; + --app-card-border: #dde1e6; + --app-primary-dark: #1c2b3a; + --app-primary: #1d4e89; + --app-secondary: #2471a3; + --app-warning: #d68910; + --app-danger: #c0392b; + --app-muted: #7f8c8d; + --app-shadow: 0 1px 4px rgba(0, 0, 0, 0.05); +} + +html, body { height: 100%; margin: 0; + background: var(--app-page-bg); -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; @@ -16,7 +32,17 @@ body { } label { - font-weight: 700; + font-weight: 600; + color: var(--app-primary-dark); +} + +:root { + --app-bg: #f0f2f5; + --app-card-border: #dde1e6; + --app-primary-dark: #1c2b3a; + --app-primary: #1d4e89; + --app-secondary: #2471a3; + --app-shadow: 0 1px 4px rgba(0, 0, 0, 0.05); } html { @@ -99,31 +125,32 @@ div:focus { } aside { - background: #eef1f6; - padding: 8px 24px; - margin-bottom: 20px; - border-radius: 2px; + background: #eef3f8; + padding: 8px 16px; + margin-bottom: 16px; + border: 1px solid var(--app-card-border); + border-radius: 4px; display: block; - line-height: 32px; - font-size: 16px; + line-height: 28px; + font-size: 14px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; - color: #2c3e50; + color: var(--app-primary-dark); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; a { - color: #337ab7; + color: var(--app-primary); cursor: pointer; &:hover { - color: rgb(32, 160, 255); + color: var(--app-secondary); } } } //main-container全局样式 .app-container { - padding: 20px; + padding: 16px; } .components-container { @@ -136,36 +163,39 @@ aside { } .sub-navbar { - height: 50px; - line-height: 50px; + height: 44px; + line-height: 44px; position: relative; width: 100%; text-align: right; - padding-right: 20px; + padding-right: 16px; transition: 600ms ease position; - background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%); + background: linear-gradient(90deg, #1c2b3a 0%, #1d4e89 100%); + color: #fff; .subtitle { - font-size: 20px; + font-size: 18px; color: #fff; } &.draft { - background: #d0d0d0; + background: #dfe5ec; + color: var(--app-primary-dark); } &.deleted { - background: #d0d0d0; + background: #dfe5ec; + color: var(--app-primary-dark); } } .link-type, .link-type:focus { - color: #337ab7; + color: var(--app-primary); cursor: pointer; &:hover { - color: rgb(32, 160, 255); + color: var(--app-secondary); } } @@ -179,3 +209,116 @@ aside { } } + +.table-card, +.dashboard-card, +.el-card { + border: 1px solid var(--app-card-border); + border-radius: 4px; + box-shadow: var(--app-shadow); +} + +.el-button { + --el-button-disabled-text-color: rgba(255, 255, 255, 0.72); + color: #ffffff; +} + +.el-button__text, +.el-button span, +.el-button .svg-icon, +.el-button i { + color: inherit; +} + +.el-button--default { + --el-button-text-color: var(--app-primary); + color: var(--app-primary); +} + +.el-button--default .el-button__text, +.el-button--default span, +.el-button--default .svg-icon, +.el-button--default i { + color: inherit; +} + +.el-card__header { + background: linear-gradient(90deg, #1c2b3a 0%, #25384a 100%); + color: #fff; + font-size: 13px; + font-weight: 600; +} + +.el-table { + --el-table-header-bg-color: #eef3f8; + --el-table-header-text-color: #1c2b3a; + --el-table-border-color: #dde1e6; + --el-table-row-hover-bg-color: #f7fbff; +} + +.el-button--primary, +.el-button--success, +.el-button--danger, +.el-button--info { + --el-button-text-color: #fff; + --el-button-disabled-text-color: rgba(255, 255, 255, 0.72); +} + +.el-button--warning { + --el-button-text-color: #ffffff; + --el-button-disabled-text-color: rgba(255, 255, 255, 0.72); + --el-button-bg-color: var(--app-warning); + --el-button-border-color: var(--app-warning); + --el-button-hover-bg-color: #e09a1b; + --el-button-hover-border-color: #e09a1b; + --el-button-active-bg-color: #c97f0f; + --el-button-active-border-color: #c97f0f; + color: #ffffff; +} + +.el-button--warning.is-plain { + --el-button-text-color: #d68910; + --el-button-border-color: #f0c674; + --el-button-bg-color: #fff6e5; + --el-button-hover-text-color: #d68910; + --el-button-hover-bg-color: #fff0d6; + --el-button-hover-border-color: #d68910; + --el-button-active-text-color: #c97f0f; + --el-button-active-border-color: #c97f0f; + color: #d68910; +} + +.el-button--primary { + --el-button-bg-color: #1d4e89; + --el-button-border-color: #1d4e89; + --el-button-hover-bg-color: #2471a3; + --el-button-hover-border-color: #2471a3; + --el-button-active-bg-color: #1c2b3a; + --el-button-active-border-color: #1c2b3a; +} + +.el-button--success { + --el-button-bg-color: #4b8b3b; + --el-button-border-color: #4b8b3b; +} + +.el-button--warning { + --el-button-bg-color: #d68910; + --el-button-border-color: #d68910; +} + +.el-button--danger { + --el-button-bg-color: #c0392b; + --el-button-border-color: #c0392b; +} + +.el-button--info { + --el-button-bg-color: #1c2b3a; + --el-button-border-color: #1c2b3a; +} + +.el-tag--success { + --el-tag-bg-color: rgba(29, 78, 137, 0.12); + --el-tag-border-color: rgba(29, 78, 137, 0.24); + --el-tag-text-color: #1d4e89; +} diff --git a/gear-ui3/src/assets/styles/sidebar.scss b/gear-ui3/src/assets/styles/sidebar.scss index 54d7441..1f4a51e 100644 --- a/gear-ui3/src/assets/styles/sidebar.scss +++ b/gear-ui3/src/assets/styles/sidebar.scss @@ -68,6 +68,7 @@ border: none; height: 100%; width: 100% !important; + background: #1c2b3a; } .el-menu-item, .menu-title { @@ -83,21 +84,25 @@ // menu hover .sub-menu-title-noDropdown, .el-sub-menu__title { + color: #d7e2ee !important; + &:hover { - background-color: rgba(0, 0, 0, 0.06) !important; + background-color: rgba(255, 255, 255, 0.05) !important; } } & .theme-dark .is-active > .el-sub-menu__title { - color: vars.$base-menu-color-active !important; + color: #ffffff !important; + background: linear-gradient(90deg, rgba(29, 78, 137, 0.95), rgba(36, 113, 163, 0.95)); } & .nest-menu .el-sub-menu>.el-sub-menu__title, & .el-sub-menu .el-menu-item { min-width: vars.$base-sidebar-width !important; + color: #d7e2ee !important; &:hover { - background-color: rgba(0, 0, 0, 0.06) !important; + background-color: rgba(255, 255, 255, 0.05) !important; } } @@ -211,9 +216,10 @@ .nest-menu .el-sub-menu>.el-sub-menu__title, .el-menu-item { + color: #d7e2ee !important; + &:hover { - // you can use $sub-menuHover - background-color: rgba(0, 0, 0, 0.06) !important; + background-color: rgba(255, 255, 255, 0.05) !important; } } diff --git a/gear-ui3/src/assets/styles/variables.module.scss b/gear-ui3/src/assets/styles/variables.module.scss index 8764e13..fde475c 100644 --- a/gear-ui3/src/assets/styles/variables.module.scss +++ b/gear-ui3/src/assets/styles/variables.module.scss @@ -1,42 +1,42 @@ -// base color -$blue: #324157; -$light-blue: #333c46; -$red: #C03639; -$pink: #E65D6E; -$green: #30B08F; -$tiffany: #4AB7BD; -$yellow: #FEC171; -$panGreen: #30B08F; +// industrial palette +$blue: #1d4e89; +$light-blue: #2471a3; +$red: #c0392b; +$pink: #e65d6e; +$green: #4b8b3b; +$tiffany: #4ab7bd; +$yellow: #d68910; +$panGreen: #2f8f5b; // 默认主题变量 -$menuText: #bfcbd9; -$menuActiveText: #409eff; -$menuBg: #304156; -$menuHover: #263445; +$menuText: #d7e2ee; +$menuActiveText: #7cc0ff; +$menuBg: #1c2b3a; +$menuHover: #25384a; // 浅色主题theme-light -$menuLightBg: #ffffff; -$menuLightHover: #f0f1f5; -$menuLightText: #303133; -$menuLightActiveText: #409EFF; +$menuLightBg: #f5f7fa; +$menuLightHover: #e9eef5; +$menuLightText: #2f3a4a; +$menuLightActiveText: #1d4e89; // 基础变量 $base-sidebar-width: 200px; $sideBarWidth: 200px; // 菜单暗色变量 -$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-color: #d7e2ee; +$base-menu-color-active: #ffffff; +$base-menu-background: #1c2b3a; +$base-sub-menu-background: #16212d; +$base-sub-menu-hover: #223243; // 组件变量 -$--color-primary: #409EFF; -$--color-success: #67C23A; -$--color-warning: #E6A23C; -$--color-danger: #F56C6C; -$--color-info: #909399; +$--color-primary: #1d4e89; +$--color-success: #4b8b3b; +$--color-warning: #d68910; +$--color-danger: #c0392b; +$--color-info: #7f8c8d; :export { menuText: $menuText; @@ -71,12 +71,20 @@ $--color-info: #909399; --sidebar-bg: #{$menuBg}; --sidebar-text: #{$menuText}; --menu-hover: #{$menuHover}; - - --navbar-bg: #ffffff; - --navbar-text: #303133; + --navbar-bg: #f5f7fa; + --navbar-text: #2f3a4a; + --navbar-hover: #e9eef5; + --page-bg: #f0f2f5; + --card-bg: #ffffff; + --card-border: #dde1e6; + --panel-header-bg: #1c2b3a; + --panel-header-text: #ffffff; + --panel-accent: #1d4e89; + --panel-accent-2: #2471a3; + --muted-text: #7f8c8d; /* splitpanes default-theme 变量 */ - --splitpanes-default-bg: #ffffff; + --splitpanes-default-bg: #f5f7fa; } diff --git a/gear-ui3/src/layout/components/AppMain.vue b/gear-ui3/src/layout/components/AppMain.vue index 0bb8b7e..796d367 100644 --- a/gear-ui3/src/layout/components/AppMain.vue +++ b/gear-ui3/src/layout/components/AppMain.vue @@ -42,6 +42,7 @@ function addIframe() { width: 100%; position: relative; overflow: hidden; + background: var(--app-bg); } .app-main:has(.copyright) { @@ -78,11 +79,11 @@ function addIframe() { } ::-webkit-scrollbar-track { - background-color: #f1f1f1; + background-color: #edf2f7; } ::-webkit-scrollbar-thumb { - background-color: #c0c0c0; + background-color: #aab7c4; border-radius: 3px; } diff --git a/gear-ui3/src/layout/components/Navbar.vue b/gear-ui3/src/layout/components/Navbar.vue index 3ff9e25..46c6544 100644 --- a/gear-ui3/src/layout/components/Navbar.vue +++ b/gear-ui3/src/layout/components/Navbar.vue @@ -102,11 +102,13 @@ function toggleTheme() {