From 31bc616ad716daf2ba0ec7fa38352644b6293dfc Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 07 四月 2026 11:36:16 +0800
Subject: [PATCH] 1.整体样式修改
---
src/assets/styles/index.scss | 121 ++-
src/assets/styles/sidebar.scss | 37
src/layout/components/Navbar.vue | 116 ++-
src/assets/styles/element-ui.scss | 169 +++-
src/layout/index.vue | 48
src/components/PIMTable/PIMTable.vue | 28
src/layout/components/TagsView/index.vue | 178 +++--
src/components/PageHeader/index.vue | 10
src/assets/styles/variables.module.scss | 446 ++++++------
src/components/Breadcrumb/index.vue | 43
src/views/login.vue | 633 +++++++++++------
src/layout/components/Sidebar/Logo.vue | 94 +-
src/layout/components/TagsView/ScrollPane.vue | 2
src/layout/components/AppMain.vue | 49
src/layout/components/Sidebar/index.vue | 57 +
15 files changed, 1,227 insertions(+), 804 deletions(-)
diff --git a/src/assets/styles/element-ui.scss b/src/assets/styles/element-ui.scss
index 8c741af..61055c3 100644
--- a/src/assets/styles/element-ui.scss
+++ b/src/assets/styles/element-ui.scss
@@ -47,50 +47,57 @@
}
// to fixed https://github.com/ElemeFE/element/issues/2461
-.el-dialog {
- transform: none;
- left: 0;
- position: relative;
- margin: 0 auto;
- border-radius: 8px;
- padding: 0 !important;
-}
-.el-dialog__header {
- background: #f5f6f7;
- padding: 12px 16px;
- border-radius: 8px 8px 0 0;
-}
-.el-dialog__title {
- font-weight: 400;
- font-size: 16px;
- color: #2e3033;
-}
-.el-dialog__body {
- padding: 16px 40px 0 40px;
- max-height: 74vh;
- overflow-y: auto;
-}
-.el-dialog__footer {
- text-align: center;
- padding: 16px;
-}
-.el-message-box {
- padding: 0 !important;
- border-radius: 8px;
-}
-.el-message-box__header {
- background: #f5f6f7;
- padding: 12px 16px;
- border-radius: 8px 8px 0 0;
-}
-.el-message-box__title {
- font-weight: 400;
- font-size: 16px;
- color: #2e3033;
-}
-.el-message-box__content {
- padding: 16px 40px 0 40px;
-}
+.el-dialog {
+ transform: none;
+ left: 0;
+ position: relative;
+ margin: 0 auto;
+ border-radius: 24px;
+ padding: 0 !important;
+ border: 1px solid var(--surface-border);
+ box-shadow: var(--shadow-md);
+ background: rgba(255, 255, 255, 0.96);
+}
+.el-dialog__header {
+ background: linear-gradient(180deg, rgba(247, 250, 248, 0.98), rgba(242, 247, 244, 0.88));
+ padding: 18px 24px 14px;
+ border-bottom: 1px solid var(--surface-border);
+ border-radius: 24px 24px 0 0;
+}
+.el-dialog__title {
+ font-weight: 600;
+ font-size: 17px;
+ color: var(--text-primary);
+}
+.el-dialog__body {
+ padding: 24px 24px 0;
+ max-height: 74vh;
+ overflow-y: auto;
+}
+.el-dialog__footer {
+ text-align: center;
+ padding: 18px 24px 24px;
+}
+.el-message-box {
+ padding: 0 !important;
+ border-radius: 22px;
+ border: 1px solid var(--surface-border);
+ box-shadow: var(--shadow-md);
+}
+.el-message-box__header {
+ background: linear-gradient(180deg, rgba(247, 250, 248, 0.98), rgba(242, 247, 244, 0.88));
+ padding: 18px 24px 14px;
+ border-bottom: 1px solid var(--surface-border);
+ border-radius: 22px 22px 0 0;
+}
+.el-message-box__title {
+ font-weight: 600;
+ font-size: 17px;
+ color: var(--text-primary);
+}
+.el-message-box__content {
+ padding: 24px 24px 0;
+}
.el-message-box__container {
justify-content: center;
}
@@ -105,12 +112,12 @@
margin-right: 12px;
}
}
-.el-table__expanded-cell {
- padding: 0 !important;
- .el-table__header-wrapper {
- background-color: #f5f8ff !important;
- }
-}
+.el-table__expanded-cell {
+ padding: 0 !important;
+ .el-table__header-wrapper {
+ background-color: var(--surface-soft) !important;
+ }
+}
// refine element ui upload
.upload-container {
@@ -149,6 +156,62 @@
display: none;
}
-.el-dropdown .el-dropdown-link {
- color: var(--el-color-primary) !important;
-}
+.el-dropdown .el-dropdown-link {
+ color: var(--el-color-primary) !important;
+}
+
+.el-button {
+ border-radius: 12px;
+ font-weight: 600;
+}
+
+.el-button--primary {
+ --el-button-bg-color: var(--el-color-primary);
+ --el-button-border-color: var(--el-color-primary);
+ --el-button-hover-bg-color: var(--el-color-primary-light-3);
+ --el-button-hover-border-color: var(--el-color-primary-light-3);
+ --el-button-active-bg-color: var(--el-color-primary-dark-2);
+ --el-button-active-border-color: var(--el-color-primary-dark-2);
+ box-shadow: 0 10px 24px color-mix(in srgb, var(--el-color-primary) 18%, transparent);
+}
+
+.el-input__wrapper,
+.el-textarea__inner,
+.el-select__wrapper,
+.el-date-editor.el-input__wrapper,
+.el-date-editor .el-input__wrapper {
+ border-radius: 12px;
+ box-shadow: 0 0 0 1px rgba(216, 225, 219, 0.92) inset !important;
+ background: rgba(255, 255, 255, 0.9);
+}
+
+.el-input__wrapper.is-focus,
+.el-select__wrapper.is-focused,
+.el-textarea__inner:focus {
+ box-shadow: 0 0 0 1px rgba(0, 47, 167, 0.28) inset !important;
+}
+
+.el-card {
+ border: 1px solid var(--surface-border);
+ box-shadow: var(--shadow-sm);
+ background: rgba(255, 255, 255, 0.88);
+}
+
+.el-table {
+ --el-table-border-color: var(--surface-border);
+ --el-table-header-bg-color: var(--surface-soft);
+ --el-table-row-hover-bg-color: rgba(0, 47, 167, 0.04);
+ --el-table-current-row-bg-color: rgba(0, 47, 167, 0.08);
+ border-radius: 18px;
+ overflow: hidden;
+}
+
+.el-table th.el-table__cell {
+ background: var(--surface-soft) !important;
+ color: var(--text-secondary);
+ font-weight: 600;
+}
+
+.el-pagination {
+ margin-top: 18px;
+}
diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss
index 13d26ee..de72ee0 100644
--- a/src/assets/styles/index.scss
+++ b/src/assets/styles/index.scss
@@ -6,27 +6,38 @@
@import './btn.scss';
@import './ruoyi.scss';
-body {
- height: 100%;
- margin: 0;
- -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;
-}
+body {
+ height: 100%;
+ margin: 0;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-font-smoothing: antialiased;
+ text-rendering: optimizeLegibility;
+ font-family: "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
+ background:
+ radial-gradient(circle at top left, rgba(214, 226, 219, 0.8), transparent 28%),
+ linear-gradient(180deg, #f7faf8 0%, var(--app-bg) 100%);
+ color: var(--text-primary);
+}
-label {
- font-weight: 700;
-}
+label {
+ font-weight: 600;
+ color: var(--text-secondary);
+}
html {
height: 100%;
box-sizing: border-box;
}
-#app {
- height: 100%;
-}
+#app {
+ height: 100%;
+}
+
+html,
+body,
+#app {
+ background-color: var(--app-bg);
+}
*,
*:before,
@@ -122,25 +133,29 @@
}
//main-container鍏ㄥ眬鏍峰紡
-.app-container {
- padding: 20px;
-}
-.search_form {
- display: flex;
- align-items: center;
- justify-content: space-between;
- .search_title {
- font-size: 14px;
- font-weight: 700;
- color: #333333;
- }
-}
-.table_list {
- height: calc(100vh - 11em);
- margin-top: 20px;
- background: #fff;
- padding: 18px
-}
+.app-container {
+ padding: 20px 24px 24px;
+}
+.search_form {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ .search_title {
+ font-size: 14px;
+ font-weight: 600;
+ letter-spacing: 0.04em;
+ color: var(--text-secondary);
+ }
+}
+.table_list {
+ height: calc(100vh - 11em);
+ margin-top: 20px;
+ background: rgba(255, 255, 255, 0.88);
+ border: 1px solid var(--surface-border);
+ border-radius: var(--radius-md);
+ box-shadow: var(--shadow-sm);
+ padding: 18px;
+}
.components-container {
margin: 30px 50px;
position: relative;
@@ -174,22 +189,36 @@
}
}
-.link-type,
-.link-type:focus {
- color: #337ab7;
- cursor: pointer;
+.link-type,
+.link-type:focus {
+ color: var(--el-color-primary);
+ cursor: pointer;
+
+ &:hover {
+ color: #165e57;
+ }
+}
- &:hover {
- color: rgb(32, 160, 255);
- }
-}
-
-.filter-container {
- padding-bottom: 10px;
+.filter-container {
+ padding-bottom: 10px;
.filter-item {
display: inline-block;
vertical-align: middle;
margin-bottom: 10px;
- }
-}
+ }
+}
+
+.app-container,
+.table_list,
+.components-container {
+ .el-card,
+ .el-dialog,
+ .el-drawer,
+ .el-table,
+ .el-descriptions,
+ .el-collapse-item__wrap,
+ .el-tabs__content {
+ border-radius: var(--radius-md);
+ }
+}
diff --git a/src/assets/styles/sidebar.scss b/src/assets/styles/sidebar.scss
index 8534448..5cdd71c 100644
--- a/src/assets/styles/sidebar.scss
+++ b/src/assets/styles/sidebar.scss
@@ -4,7 +4,7 @@
transition: margin-left 0.28s;
margin-left: $base-sidebar-width;
position: relative;
- background: #f5f7fb;
+ background: transparent;
}
.sidebarHide {
@@ -22,8 +22,9 @@
left: 0;
z-index: 1001;
overflow: hidden;
- -webkit-box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
- box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
+ padding: 12px 0 16px 16px;
+ background: transparent;
+ box-shadow: none;
// reset element-ui css
.horizontal-collapse-transition {
@@ -45,7 +46,8 @@
&.has-logo {
.el-scrollbar {
- height: calc(100% - 50px);
+ height: calc(100% - 72px);
+ margin-top: 10px;
}
}
@@ -67,6 +69,11 @@
border: none;
height: 100%;
width: 100% !important;
+ padding: 10px 8px 18px;
+ border-radius: 0 28px 28px 0;
+ background: var(--menu-surface);
+ backdrop-filter: blur(18px);
+ box-shadow: var(--shadow-sm);
}
.el-menu-item,
@@ -84,11 +91,11 @@
.sub-menu-title-noDropdown,
.el-sub-menu__title {
&:hover {
- background-color: rgba(212, 221, 255, 0.8) !important;
+ background-color: var(--menu-hover) !important;
}
}
& .theme-light .is-active > .el-sub-menu__title {
- color: #fff !important;
+ color: var(--current-color) !important;
}
& .nest-menu .el-sub-menu > .el-sub-menu__title,
@@ -96,10 +103,10 @@
min-width: $base-sidebar-width !important;
&:hover {
- background-color: rgba(212, 221, 255, 0.8) !important;
+ background-color: var(--menu-hover) !important;
}
&.is-active {
- background-color: #fff !important;
+ background-color: var(--menu-active-bg) !important;
}
}
@@ -108,7 +115,7 @@
//background-color: transparent;
&:hover {
- background-color: rgba(212, 221, 255, 0.8) !important;
+ background-color: var(--menu-hover) !important;
}
}
}
@@ -212,10 +219,10 @@
.el-menu-item {
&:hover {
// you can use $sub-menuHover
- background-color: rgba(212, 221, 255, 0.56) !important;
+ background-color: var(--menu-hover) !important;
}
&.is-active {
- background-color: rgba(212, 221, 255, 0.56) !important;
+ background-color: var(--menu-active-bg) !important;
}
}
@@ -223,9 +230,13 @@
> .el-menu--popup {
max-height: 100vh;
overflow-y: auto;
+ padding: 8px;
+ border-radius: 18px;
+ border: 1px solid var(--surface-border);
+ box-shadow: var(--shadow-md);
&::-webkit-scrollbar-track-piece {
- background: #d3dce6;
+ background: #dfe7e1;
}
&::-webkit-scrollbar {
@@ -233,7 +244,7 @@
}
&::-webkit-scrollbar-thumb {
- background: #99a9bf;
+ background: #9aa79e;
border-radius: 20px;
}
}
diff --git a/src/assets/styles/variables.module.scss b/src/assets/styles/variables.module.scss
index 3194051..9537be3 100644
--- a/src/assets/styles/variables.module.scss
+++ b/src/assets/styles/variables.module.scss
@@ -1,221 +1,225 @@
-// base color
-$blue: #324157;
-$light-blue: #333c46;
-$red: #c03639;
-$pink: #e65d6e;
-$green: #30b08f;
-$tiffany: #4ab7bd;
-$yellow: #fec171;
-$panGreen: #30b08f;
-
-// 榛樿涓婚鍙橀噺
-$menuText: #bfcbd9;
-$menuActiveText: #409eff;
-$menuBg: #304156;
-$menuHover: #263445;
-
-// 娴呰壊涓婚theme-light
-$menuLightBg: #002fa7;
-$menuLightHover: #f0f1f5;
-$menuLightText: #fff;
-$menuLightActiveText: #002fa7;
-
-// 鍩虹鍙橀噺
-$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: #fff;
-
-// 缁勪欢鍙橀噺
-$--color-primary: #409eff;
-$--color-success: #67c23a;
-$--color-warning: #e6a23c;
-$--color-danger: #f56c6c;
-$--color-info: #909399;
-
-:export {
- menuText: $menuText;
- menuActiveText: $menuActiveText;
- menuBg: $menuBg;
- menuHover: $menuHover;
- menuLightBg: $menuLightBg;
- menuLightHover: $menuLightHover;
- menuLightText: $menuLightText;
- menuLightActiveText: $menuLightActiveText;
- sideBarWidth: $sideBarWidth;
- // 瀵煎嚭鍩虹棰滆壊
- blue: $blue;
- lightBlue: $light-blue;
- red: $red;
- pink: $pink;
- green: $green;
- tiffany: $tiffany;
- yellow: $yellow;
- panGreen: $panGreen;
- // 瀵煎嚭缁勪欢棰滆壊
- colorPrimary: $--color-primary;
- colorSuccess: $--color-success;
- colorWarning: $--color-warning;
- colorDanger: $--color-danger;
- colorInfo: $--color-info;
-}
-
-// CSS鍙橀噺瀹氫箟
-:root {
- /* 浜壊妯″紡鍙橀噺 */
- --sidebar-bg: #{$menuBg};
- --sidebar-text: #{$menuText};
- --menu-hover: #{$menuHover};
-
- --navbar-bg: #ffffff;
- --navbar-text: #303133;
-
- /* splitpanes default-theme 鍙橀噺 */
- --splitpanes-default-bg: #ffffff;
-}
-
-// 鏆楅粦妯″紡鍙橀噺
-html.dark {
- /* 榛樿閫氱敤 */
- --el-bg-color: #141414;
- --el-bg-color-overlay: #1d1e1f;
- --el-text-color-primary: #ffffff;
- --el-text-color-regular: #d0d0d0;
- --el-border-color: #434343;
- --el-border-color-light: #434343;
-
- /* 渚ц竟鏍� */
- --sidebar-bg: #141414;
- --sidebar-text: #ffffff;
- --menu-hover: #2d2d2d;
- --menu-active-text: #{$menuActiveText};
-
- /* 椤堕儴瀵艰埅鏍� */
- --navbar-bg: #141414;
- --navbar-text: #ffffff;
- --navbar-hover: #141414;
-
- /* 鏍囩鏍� */
- --tags-bg: #141414;
- --tags-item-bg: #1d1e1f;
- --tags-item-border: #303030;
- --tags-item-text: #d0d0d0;
- --tags-item-hover: #2d2d2d;
- --tags-close-hover: #64666a;
-
- /* splitpanes 缁勪欢鏆楅粦妯″紡鍙橀噺 */
- --splitpanes-bg: #141414;
- --splitpanes-border: #303030;
- --splitpanes-splitter-bg: #1d1e1f;
- --splitpanes-splitter-hover-bg: #2d2d2d;
-
- /* blockquote 鏆楅粦妯″紡鍙橀噺 */
- --blockquote-bg: #1d1e1f;
- --blockquote-border: #303030;
- --blockquote-text: #d0d0d0;
-
- /* Cron 鏃堕棿琛ㄨ揪寮� 妯″紡鍙橀噺 */
- --cron-border: #303030;
-
- /* splitpanes default-theme 鏆楅粦妯″紡鍙橀噺 */
- --splitpanes-default-bg: #141414;
-
- /* 渚ц竟鏍忚彍鍗曡鐩� */
- .sidebar-container {
- .el-menu-item,
- .menu-title {
- color: var(--el-text-color-regular);
- }
- & .theme-dark .nest-menu .el-sub-menu > .el-sub-menu__title,
- & .theme-dark .el-sub-menu .el-menu-item {
- background-color: var(--el-bg-color) !important;
- }
- }
-
- /* 椤堕儴鏍忔爮鑿滃崟瑕嗙洊 */
- .el-menu--horizontal {
- .el-menu-item {
- &:not(.is-disabled) {
- &:hover,
- &:focus {
- background-color: var(--navbar-hover) !important;
- }
- }
- }
- }
-
- /* 鍒嗗壊绐楁牸瑕嗙洊 */
- .splitpanes {
- background-color: var(--splitpanes-bg);
-
- .splitpanes__pane {
- background-color: var(--splitpanes-bg);
- border-color: var(--splitpanes-border);
- }
-
- .splitpanes__splitter {
- background-color: var(--splitpanes-splitter-bg);
- border-color: var(--splitpanes-border);
-
- &:hover {
- background-color: var(--splitpanes-splitter-hover-bg);
- }
-
- &:before,
- &:after {
- background-color: var(--splitpanes-border);
- }
- }
- }
-
- /* 琛ㄦ牸鏍峰紡瑕嗙洊 */
- .el-table {
- --el-table-header-bg-color: var(--el-bg-color-overlay) !important;
- --el-table-header-text-color: var(--el-text-color-regular) !important;
- --el-table-border-color: var(--el-border-color-light) !important;
- --el-table-row-hover-bg-color: var(--el-bg-color-overlay) !important;
-
- .el-table__header-wrapper,
- .el-table__fixed-header-wrapper {
- th {
- background-color: var(--el-bg-color-overlay, #f0f1f5) !important;
- color: var(--el-text-color-regular, #515a6e);
- }
- }
- }
-
- /* 鏍戠粍浠堕珮浜牱寮忚鐩� */
- .el-tree {
- .el-tree-node.is-current > .el-tree-node__content {
- background-color: var(--el-bg-color-overlay) !important;
- color: var(--el-color-primary);
- }
-
- .el-tree-node__content:hover {
- background-color: var(--el-bg-color-overlay);
- }
- }
-
- /* 涓嬫媺鑿滃崟鏍峰紡瑕嗙洊 */
- .el-dropdown-menu__item:not(.is-disabled):focus,
- .el-dropdown-menu__item:not(.is-disabled):hover {
- background-color: var(--navbar-hover) !important;
- }
-
- /* blockquote鏍峰紡瑕嗙洊 */
- blockquote {
- background-color: var(--blockquote-bg) !important;
- border-left-color: var(--blockquote-border) !important;
- color: var(--blockquote-text) !important;
- }
-
- /* 鏃堕棿琛ㄨ揪寮忔爣棰樻牱寮忚鐩� */
- .popup-result .title {
- background: var(--cron-border);
- }
-}
+// base color
+$blue: #324157;
+$light-blue: #333c46;
+$red: #c03639;
+$pink: #e65d6e;
+$green: #30b08f;
+$tiffany: #4ab7bd;
+$yellow: #fec171;
+$panGreen: #30b08f;
+
+// menu palette
+$menuText: #677287;
+$menuActiveText: #1f7a72;
+$menuBg: #f4f7f4;
+$menuHover: #e7eeea;
+
+// light theme
+$menuLightBg: #f4f7f4;
+$menuLightHover: #e7eeea;
+$menuLightText: #3b4658;
+$menuLightActiveText: #1f7a72;
+
+// layout
+$base-sidebar-width: 200px;
+$sideBarWidth: 200px;
+
+// sidebar
+$base-menu-color: #677287;
+$base-menu-color-active: #1f7a72;
+$base-menu-background: #f4f7f4;
+$base-sub-menu-background: #eef3ef;
+$base-sub-menu-hover: #ffffff;
+
+// component
+$--color-primary: #1f7a72;
+$--color-success: #67c23a;
+$--color-warning: #d89b41;
+$--color-danger: #d25b52;
+$--color-info: #7d8797;
+
+:export {
+ menuText: $menuText;
+ menuActiveText: $menuActiveText;
+ menuBg: $menuBg;
+ menuHover: $menuHover;
+ menuLightBg: $menuLightBg;
+ menuLightHover: $menuLightHover;
+ menuLightText: $menuLightText;
+ menuLightActiveText: $menuLightActiveText;
+ sideBarWidth: $sideBarWidth;
+ blue: $blue;
+ lightBlue: $light-blue;
+ red: $red;
+ pink: $pink;
+ green: $green;
+ tiffany: $tiffany;
+ yellow: $yellow;
+ panGreen: $panGreen;
+ colorPrimary: $--color-primary;
+ colorSuccess: $--color-success;
+ colorWarning: $--color-warning;
+ colorDanger: $--color-danger;
+ colorInfo: $--color-info;
+}
+
+:root {
+ --sidebar-bg: #{$menuBg};
+ --sidebar-text: #{$menuText};
+ --sidebar-muted: #93a0b1;
+ --menu-hover: #{$menuHover};
+ --menu-active-bg: #dfe9e4;
+ --menu-surface: rgba(255, 255, 255, 0.72);
+
+ --app-bg: #eef2ee;
+ --app-bg-accent: #dfe8e2;
+ --surface-base: #ffffff;
+ --surface-soft: #f7faf8;
+ --surface-muted: #eff4f1;
+ --surface-border: #d8e1db;
+ --surface-border-strong: #c9d5ce;
+ --text-primary: #21313f;
+ --text-secondary: #5f6d7e;
+ --text-tertiary: #8a98a8;
+ --shadow-sm: 0 10px 30px rgba(31, 49, 38, 0.06);
+ --shadow-md: 0 18px 50px rgba(31, 49, 38, 0.1);
+ --radius-lg: 24px;
+ --radius-md: 18px;
+ --radius-sm: 12px;
+
+ --navbar-bg: rgba(255, 255, 255, 0.78);
+ --navbar-text: #21313f;
+ --navbar-hover: rgba(31, 122, 114, 0.08);
+
+ --tags-bg: transparent;
+ --tags-item-bg: rgba(255, 255, 255, 0.74);
+ --tags-item-border: rgba(201, 213, 206, 0.88);
+ --tags-item-text: #5f6d7e;
+ --tags-item-hover: rgba(31, 122, 114, 0.08);
+ --tags-close-hover: rgba(31, 122, 114, 0.18);
+
+ --splitpanes-default-bg: #ffffff;
+}
+
+html.dark {
+ --el-bg-color: #141414;
+ --el-bg-color-overlay: #1d1e1f;
+ --el-text-color-primary: #ffffff;
+ --el-text-color-regular: #d0d0d0;
+ --el-border-color: #434343;
+ --el-border-color-light: #434343;
+
+ --sidebar-bg: #141414;
+ --sidebar-text: #ffffff;
+ --menu-hover: #2d2d2d;
+ --menu-active-text: #{$menuActiveText};
+
+ --navbar-bg: #141414;
+ --navbar-text: #ffffff;
+ --navbar-hover: #141414;
+
+ --tags-bg: #141414;
+ --tags-item-bg: #1d1e1f;
+ --tags-item-border: #303030;
+ --tags-item-text: #d0d0d0;
+ --tags-item-hover: #2d2d2d;
+ --tags-close-hover: #64666a;
+
+ --splitpanes-bg: #141414;
+ --splitpanes-border: #303030;
+ --splitpanes-splitter-bg: #1d1e1f;
+ --splitpanes-splitter-hover-bg: #2d2d2d;
+
+ --blockquote-bg: #1d1e1f;
+ --blockquote-border: #303030;
+ --blockquote-text: #d0d0d0;
+ --cron-border: #303030;
+ --splitpanes-default-bg: #141414;
+
+ .sidebar-container {
+ .el-menu-item,
+ .menu-title {
+ color: var(--el-text-color-regular);
+ }
+
+ & .theme-dark .nest-menu .el-sub-menu > .el-sub-menu__title,
+ & .theme-dark .el-sub-menu .el-menu-item {
+ background-color: var(--el-bg-color) !important;
+ }
+ }
+
+ .el-menu--horizontal {
+ .el-menu-item {
+ &:not(.is-disabled) {
+ &:hover,
+ &:focus {
+ background-color: var(--navbar-hover) !important;
+ }
+ }
+ }
+ }
+
+ .splitpanes {
+ background-color: var(--splitpanes-bg);
+
+ .splitpanes__pane {
+ background-color: var(--splitpanes-bg);
+ border-color: var(--splitpanes-border);
+ }
+
+ .splitpanes__splitter {
+ background-color: var(--splitpanes-splitter-bg);
+ border-color: var(--splitpanes-border);
+
+ &:hover {
+ background-color: var(--splitpanes-splitter-hover-bg);
+ }
+
+ &:before,
+ &:after {
+ background-color: var(--splitpanes-border);
+ }
+ }
+ }
+
+ .el-table {
+ --el-table-header-bg-color: var(--el-bg-color-overlay) !important;
+ --el-table-header-text-color: var(--el-text-color-regular) !important;
+ --el-table-border-color: var(--el-border-color-light) !important;
+ --el-table-row-hover-bg-color: var(--el-bg-color-overlay) !important;
+
+ .el-table__header-wrapper,
+ .el-table__fixed-header-wrapper {
+ th {
+ background-color: var(--el-bg-color-overlay, #f0f1f5) !important;
+ color: var(--el-text-color-regular, #515a6e);
+ }
+ }
+ }
+
+ .el-tree {
+ .el-tree-node.is-current > .el-tree-node__content {
+ background-color: var(--el-bg-color-overlay) !important;
+ color: var(--el-color-primary);
+ }
+
+ .el-tree-node__content:hover {
+ background-color: var(--el-bg-color-overlay);
+ }
+ }
+
+ .el-dropdown-menu__item:not(.is-disabled):focus,
+ .el-dropdown-menu__item:not(.is-disabled):hover {
+ background-color: var(--navbar-hover) !important;
+ }
+
+ blockquote {
+ background-color: var(--blockquote-bg) !important;
+ border-left-color: var(--blockquote-border) !important;
+ color: var(--blockquote-text) !important;
+ }
+
+ .popup-result .title {
+ background: var(--cron-border);
+ }
+}
diff --git a/src/components/Breadcrumb/index.vue b/src/components/Breadcrumb/index.vue
index 5385ec4..0ff79ef 100644
--- a/src/components/Breadcrumb/index.vue
+++ b/src/components/Breadcrumb/index.vue
@@ -85,15 +85,34 @@
</script>
<style lang='scss' scoped>
-.app-breadcrumb.el-breadcrumb {
- display: inline-block;
- font-size: 14px;
- line-height: 50px;
- margin-left: 8px;
-
- .no-redirect {
- color: #002FA7;
- cursor: text;
- }
-}
-</style>
\ No newline at end of file
+.app-breadcrumb.el-breadcrumb {
+ display: inline-block;
+ font-size: 14px;
+ line-height: 56px;
+ margin-left: 8px;
+
+ :deep(.el-breadcrumb__inner) {
+ color: var(--text-secondary);
+ font-weight: 500;
+ transition: color 0.2s ease;
+ }
+
+ :deep(.el-breadcrumb__separator) {
+ color: var(--text-tertiary);
+ }
+
+ a {
+ color: var(--text-secondary);
+
+ &:hover {
+ color: var(--current-color);
+ }
+ }
+
+ .no-redirect {
+ color: var(--current-color);
+ font-weight: 600;
+ cursor: text;
+ }
+}
+</style>
diff --git a/src/components/PIMTable/PIMTable.vue b/src/components/PIMTable/PIMTable.vue
index 8e22459..dffd515 100644
--- a/src/components/PIMTable/PIMTable.vue
+++ b/src/components/PIMTable/PIMTable.vue
@@ -4,7 +4,7 @@
v-loading="tableLoading"
:border="border"
:data="tableData"
- :header-cell-style="{ background: '#F0F1F5', color: '#333333' }"
+ :header-cell-style="mergedHeaderCellStyle"
:height="height"
:highlight-current-row="highlightCurrentRow"
:row-class-name="rowClassName"
@@ -226,7 +226,7 @@
<script setup>
import pagination from "./Pagination.vue";
-import { ref, inject, getCurrentInstance } from "vue";
+import { computed, ref, inject, getCurrentInstance } from "vue";
import { ElMessage } from "element-plus";
// 鑾峰彇鍏ㄥ眬鐨� uploadHeader
@@ -333,6 +333,13 @@
default: () => ({ width: "100%" }),
},
});
+
+const mergedHeaderCellStyle = computed(() => ({
+ background: "var(--surface-soft)",
+ color: "var(--text-secondary)",
+ fontWeight: 600,
+ ...props.headerCellStyle,
+}));
// Data
const uploadRefs = ref([]);
@@ -507,6 +514,12 @@
</script>
<style scoped lang="scss">
+.lims-table {
+ border: 1px solid var(--surface-border);
+ border-radius: 18px;
+ background: rgba(255, 255, 255, 0.9);
+}
+
.cell {
white-space: nowrap;
overflow: hidden;
@@ -519,4 +532,15 @@
.pim-table-header-extra :deep(.el-select) {
width: 100%;
}
+
+.pim-table-header-cell {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 10px;
+}
+
+.pim-table-header-title {
+ font-weight: 600;
+}
</style>
diff --git a/src/components/PageHeader/index.vue b/src/components/PageHeader/index.vue
index d8fc6fa..60d3961 100644
--- a/src/components/PageHeader/index.vue
+++ b/src/components/PageHeader/index.vue
@@ -43,6 +43,11 @@
<style scoped>
.page-header-wrapper {
margin-bottom: 16px;
+ padding: 16px 18px;
+ border: 1px solid var(--surface-border);
+ border-radius: var(--radius-md);
+ background: rgba(255, 255, 255, 0.82);
+ box-shadow: var(--shadow-sm);
}
.page-header-wrapper :deep(.el-page-header__extra) {
@@ -50,4 +55,9 @@
align-items: center;
gap: 8px;
}
+
+.page-header-wrapper :deep(.el-page-header__content) {
+ font-weight: 600;
+ color: var(--text-primary);
+}
</style>
diff --git a/src/layout/components/AppMain.vue b/src/layout/components/AppMain.vue
index 1e7a78b..c3d9416 100644
--- a/src/layout/components/AppMain.vue
+++ b/src/layout/components/AppMain.vue
@@ -37,23 +37,24 @@
</script>
<style lang="scss" scoped>
-.app-main {
+.app-main {
/* 50= navbar 50 */
min-height: calc(100vh - 50px);
width: 100%;
position: relative;
overflow: hidden;
- background: #F5F7FB;
-}
-
-.route-view-wrapper {
- width: 100%;
- height: 100%;
-}
-
-.fixed-header + .app-main {
- padding-top: 50px;
-}
+ background: transparent;
+}
+
+.route-view-wrapper {
+ width: 100%;
+ height: 100%;
+ padding: 108px 16px 24px 0;
+}
+
+.fixed-header + .app-main {
+ padding-top: 0;
+}
.hasTagsView {
.app-main {
@@ -61,10 +62,10 @@
min-height: calc(100vh - 84px);
}
- .fixed-header + .app-main {
- padding-top: 84px;
- }
-}
+ .fixed-header + .app-main {
+ padding-top: 0;
+ }
+}
</style>
<style lang="scss">
@@ -80,13 +81,13 @@
height: 6px;
}
-::-webkit-scrollbar-track {
- background-color: #f1f1f1;
-}
-
-::-webkit-scrollbar-thumb {
- background-color: #c0c0c0;
- border-radius: 3px;
-}
+::-webkit-scrollbar-track {
+ background-color: rgba(218, 225, 220, 0.8);
+}
+
+::-webkit-scrollbar-thumb {
+ background-color: #b2bdb5;
+ border-radius: 3px;
+}
</style>
diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue
index d4e938d..cb08221 100644
--- a/src/layout/components/Navbar.vue
+++ b/src/layout/components/Navbar.vue
@@ -158,15 +158,19 @@
</script>
<style lang='scss' scoped>
-.navbar {
- height: 50px;
- overflow: hidden;
- position: relative;
- background: var(--navbar-bg);
- box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
+.navbar {
+ height: 56px;
+ overflow: hidden;
+ position: relative;
+ background: var(--navbar-bg);
+ border: 1px solid rgba(216, 225, 219, 0.9);
+ border-radius: 22px;
+ backdrop-filter: blur(18px);
+ box-shadow: var(--shadow-sm);
+ padding: 0 18px;
.hamburger-container {
- line-height: 46px;
+ line-height: 52px;
height: 100%;
float: left;
cursor: pointer;
@@ -174,7 +178,7 @@
-webkit-tap-highlight-color: transparent;
&:hover {
- background: rgba(0, 0, 0, 0.025);
+ background: var(--navbar-hover);
}
}
@@ -192,30 +196,32 @@
vertical-align: top;
}
- .right-menu {
- float: right;
- height: 100%;
- line-height: 50px;
- display: flex;
+ .right-menu {
+ float: right;
+ height: 100%;
+ align-items: center;
+ display: flex;
&:focus {
outline: none;
}
- .right-menu-item {
- display: inline-block;
- padding: 0 8px;
- height: 100%;
- font-size: 18px;
- color: var(--navbar-text);
- vertical-align: text-bottom;
+ .right-menu-item {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0 8px;
+ height: 100%;
+ font-size: 18px;
+ color: var(--navbar-text);
+ border-radius: 14px;
&.hover-effect {
cursor: pointer;
transition: background 0.3s;
&:hover {
- background: rgba(0, 0, 0, 0.025);
+ background: var(--navbar-hover);
}
}
@@ -234,7 +240,7 @@
}
.notification-container {
- margin-right: 20px;
+ margin-right: 12px;
display: flex;
align-items: center;
cursor: pointer;
@@ -246,28 +252,43 @@
}
}
- .avatar-container {
- margin-right: 40px;
-
- .avatar-wrapper {
- margin-top: 5px;
- position: relative;
-
- .user-avatar {
- cursor: pointer;
- width: 40px;
- height: 40px;
- border-radius: 50px;
- }
-
- i {
- cursor: pointer;
- position: absolute;
- right: -20px;
- top: 14px;
- font-size: 12px;
- }
- }
+ .avatar-container {
+ margin-right: 4px;
+ height: 100%;
+ display: flex;
+ align-items: center;
+
+ :deep(.el-dropdown) {
+ height: 100%;
+ display: flex;
+ align-items: center;
+ }
+
+ .avatar-wrapper {
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 10px;
+ padding: 6px 10px 6px 6px;
+ height: 44px;
+ border-radius: 999px;
+ background: rgba(247, 250, 248, 0.92);
+ border: 1px solid var(--surface-border);
+
+ .user-avatar {
+ cursor: pointer;
+ width: 34px;
+ height: 34px;
+ border-radius: 50px;
+ }
+
+ i {
+ cursor: pointer;
+ position: static;
+ font-size: 12px;
+ }
+ }
}
}
}
@@ -275,8 +296,11 @@
</style>
<style lang="scss">
-.notification-popover {
- padding: 0 !important;
+.notification-popover {
+ padding: 0 !important;
+ border-radius: 20px !important;
+ border: 1px solid var(--surface-border) !important;
+ box-shadow: var(--shadow-md) !important;
.el-popover__title {
display: none;
diff --git a/src/layout/components/Sidebar/Logo.vue b/src/layout/components/Sidebar/Logo.vue
index f8f1da3..7f9c969 100644
--- a/src/layout/components/Sidebar/Logo.vue
+++ b/src/layout/components/Sidebar/Logo.vue
@@ -3,11 +3,11 @@
<transition name="sidebarLogoFade">
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
<img v-if="logoUrl" :src="logoUrl" class="sidebar-logo" @error="handleImageError" alt="鍏徃Logo" />
- <h1 class="sidebar-title">{{ title }}</h1>
+ <h1 v-if="!logoUrl" class="sidebar-title">{{ title }}</h1>
</router-link>
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
<img v-if="logoUrl" :src="logoUrl" class="sidebar-logo" @error="handleImageError" alt="鍏徃Logo" />
- <h1 class="sidebar-title">{{ title }}</h1>
+ <h1 v-if="!logoUrl" class="sidebar-title">{{ title }}</h1>
</router-link>
</transition>
</div>
@@ -87,43 +87,57 @@
opacity: 0;
}
-.sidebar-logo-container {
- position: relative;
- width: 100% !important;
- height: 50px !important;
- line-height: 50px;
- background: #fff;
- text-align: center;
- overflow: hidden;
-
- & .sidebar-logo-link {
- height: 100%;
- width: 100%;
-
- & .sidebar-logo {
- width: 100%;
- height: 100%;
- // height: 32px;
- vertical-align: middle;
- margin-right: 12px;
- }
-
- & .sidebar-title {
- display: inline-block;
- margin: 0;
- color: v-bind(getLogoTextColor);
- font-weight: 600;
- line-height: 50px;
- font-size: 14px;
- font-family: Avenir, Helvetica Neue, Arial, Helvetica, sans-serif;
- vertical-align: middle;
- }
- }
+.sidebar-logo-container {
+ position: relative;
+ width: 100% !important;
+ height: 56px !important;
+ line-height: 56px;
+ background: rgba(255, 255, 255, 0.78);
+ border: 1px solid var(--surface-border);
+ border-radius: 0 22px 22px 0;
+ text-align: center;
+ overflow: hidden;
+ box-shadow: var(--shadow-sm);
+
+ & .sidebar-logo-link {
+ height: 100%;
+ width: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0 18px 0 14px;
+
+ & .sidebar-logo {
+ width: auto;
+ max-width: 132px;
+ max-height: 34px;
+ height: auto;
+ vertical-align: middle;
+ object-fit: contain;
+ object-position: center;
+ }
+
+ & .sidebar-title {
+ display: inline-block;
+ margin: 0;
+ color: var(--text-primary);
+ font-weight: 600;
+ line-height: 1.2;
+ font-size: 14px;
+ font-family: "Segoe UI", "PingFang SC", sans-serif;
+ vertical-align: middle;
+ }
+ }
&.collapse {
- .sidebar-logo {
- margin-right: 0px;
- }
- }
-}
-</style>
+ .sidebar-logo-link {
+ padding: 0;
+ }
+
+ .sidebar-logo {
+ max-width: 30px;
+ max-height: 30px;
+ }
+ }
+}
+</style>
diff --git a/src/layout/components/Sidebar/index.vue b/src/layout/components/Sidebar/index.vue
index 9044945..92f49c4 100644
--- a/src/layout/components/Sidebar/index.vue
+++ b/src/layout/components/Sidebar/index.vue
@@ -70,25 +70,40 @@
height: 100%;
width: 100% !important;
- .el-menu-item,
- .el-sub-menu__title {
- &:hover {
- background-color: var(--menu-hover, rgba(0, 0, 0, 0.06)) !important;
- }
- }
+ .el-menu-item,
+ .el-sub-menu__title {
+ margin-bottom: 6px;
+ border-radius: 14px;
+ color: v-bind(getMenuTextColor);
+
+ &:hover {
+ background-color: var(--menu-hover, rgba(0, 0, 0, 0.06)) !important;
+ }
+ }
+
+ .el-menu-item {
+ &.is-active {
+ color: v-bind(theme);
+ background-color: var(--menu-active-bg, rgba(0, 0, 0, 0.06)) !important;
+ font-weight: 600;
+ }
+ }
- .el-menu-item {
- color: v-bind(getMenuTextColor);
-
- &.is-active {
- color: var(--menu-active-text, #409eff);
- background-color: var(--menu-hover, rgba(0, 0, 0, 0.06)) !important;
- }
- }
-
- .el-sub-menu__title {
- color: v-bind(getMenuTextColor);
- }
- }
-}
-</style>
+ .el-sub-menu__title {
+ color: v-bind(getMenuTextColor);
+ }
+
+ :deep(.el-sub-menu.is-active > .el-sub-menu__title) {
+ color: v-bind(theme) !important;
+ font-weight: 600;
+ }
+
+ :deep(.el-sub-menu.is-active > .el-sub-menu__title .menu-title),
+ :deep(.el-sub-menu.is-active > .el-sub-menu__title .svg-icon),
+ :deep(.el-menu-item.is-active .menu-title),
+ :deep(.el-menu-item.is-active .svg-icon) {
+ color: v-bind(theme) !important;
+ }
+ }
+}
+</style>
diff --git a/src/layout/components/TagsView/ScrollPane.vue b/src/layout/components/TagsView/ScrollPane.vue
index 0189a17..9067108 100644
--- a/src/layout/components/TagsView/ScrollPane.vue
+++ b/src/layout/components/TagsView/ScrollPane.vue
@@ -101,7 +101,7 @@
bottom: 0px;
}
:deep(.el-scrollbar__wrap) {
- height: 39px;
+ height: 42px;
}
}
</style>
\ No newline at end of file
diff --git a/src/layout/components/TagsView/index.vue b/src/layout/components/TagsView/index.vue
index d3aa736..8fe064a 100644
--- a/src/layout/components/TagsView/index.vue
+++ b/src/layout/components/TagsView/index.vue
@@ -13,9 +13,9 @@
@contextmenu.prevent="openMenu(tag, $event)"
>
{{ tag.title }}
- <span v-if="!isAffix(tag)" @click.prevent.stop="closeSelectedTag(tag)">
- <close class="el-icon-close" style="width: 1em; height: 1em;vertical-align: middle;" />
- </span>
+ <span v-if="!isAffix(tag)" class="tags-view-close" @click.prevent.stop="closeSelectedTag(tag)">
+ <close class="el-icon-close" />
+ </span>
</router-link>
</scroll-pane>
<ul v-show="visible" :style="{ left: left + 'px', top: top + 'px' }" class="contextmenu">
@@ -258,44 +258,54 @@
</script>
<style lang="scss" scoped>
-.tags-view-container {
- height: 34px;
- width: 100%;
- background: transparent;
-
- .tags-view-wrapper {
- .tags-view-item {
- display: inline-block;
- position: relative;
- cursor: pointer;
- height: 32px;
- line-height: 32px;
- //border: 1px solid var(--tags-item-border, #d8dce5);
- color: #4E5463;
- background: #E5E7EA;
- padding: 0 16px;
- font-size: 12px;
- //margin-left: 5px;
- //margin-top: 4px;
-
- //&:first-of-type {
- // margin-left: 8px;
- //}
- //
- //&:last-of-type {
- // margin-right: 15px;
- //}
-
- &.active {
- background-color: #FFFFFF !important;
- color: #2C51D9;
- }
- }
- //.tags-view-item div {
- // transform: skew(12deg);
- // display: inline-block;
- //}
- }
+.tags-view-container {
+ height: 42px;
+ width: 100%;
+ margin-top: 10px;
+ padding: 4px 10px;
+ background: rgba(255, 255, 255, 0.9);
+ border: 1px solid rgba(216, 225, 219, 0.92);
+ border-radius: 20px;
+ backdrop-filter: blur(18px);
+ box-shadow: var(--shadow-sm);
+
+ .tags-view-wrapper {
+ display: flex;
+ align-items: center;
+ min-height: 42px;
+
+ .tags-view-item {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ position: relative;
+ cursor: pointer;
+ height: 34px;
+ line-height: 1;
+ color: var(--tags-item-text, #4E5463);
+ background: var(--tags-item-bg, #E5E7EA);
+ border: 1px solid var(--tags-item-border, #d8dce5);
+ border-radius: 999px;
+ padding: 0 16px;
+ font-size: 12px;
+ margin-right: 8px;
+ flex-shrink: 0;
+ gap: 6px;
+ transition: all 0.24s ease;
+
+ &:hover {
+ background: var(--tags-item-hover, #eee);
+ border-color: rgba(31, 122, 114, 0.18);
+ }
+
+ &.active {
+ background-color: #FFFFFF !important;
+ color: var(--el-color-primary);
+ box-shadow: 0 10px 24px rgba(31, 122, 114, 0.12);
+ border-color: rgba(31, 122, 114, 0.2) !important;
+ }
+ }
+ }
.contextmenu {
margin: 0;
@@ -304,12 +314,12 @@
position: absolute;
list-style-type: none;
padding: 5px 0;
- border-radius: 4px;
+ border-radius: 16px;
font-size: 12px;
font-weight: 400;
color: var(--tags-item-text, #333);
- box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, .3);
- border: 1px solid var(--el-border-color-light, #e4e7ed);
+ box-shadow: var(--shadow-md);
+ border: 1px solid var(--surface-border, #e4e7ed);
li {
margin: 0;
@@ -326,30 +336,56 @@
<style lang="scss">
//reset element css of el-icon-close
-.tags-view-wrapper {
- .tags-view-item {
- .el-icon-close {
- width: 16px;
- height: 16px;
- vertical-align: 2px;
- border-radius: 50%;
- text-align: center;
- transition: all .3s cubic-bezier(.645, .045, .355, 1);
- transform-origin: 100% 50%;
-
- &:before {
- transform: scale(.6);
- display: inline-block;
- vertical-align: -3px;
- }
-
- &:hover {
- background-color: var(--tags-close-hover, #b4bccc);
- color: #fff;
- width: 12px !important;
- height: 12px !important;
- }
- }
- }
-}
-</style>
\ No newline at end of file
+.tags-view-wrapper {
+ .el-scrollbar__view {
+ display: flex;
+ align-items: center;
+ }
+
+ .tags-view-item {
+ .tags-view-close {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 12px;
+ height: 12px;
+ line-height: 1;
+ align-self: center;
+ transform: translateY(1px);
+ }
+
+ .el-icon-close {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 12px;
+ height: 12px;
+ line-height: 1;
+ vertical-align: initial !important;
+ border-radius: 50%;
+ text-align: center;
+ transition: all .3s cubic-bezier(.645, .045, .355, 1);
+ transform-origin: 100% 50%;
+ align-self: center;
+
+ &:before {
+ transform: scale(.6);
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ svg {
+ display: block;
+ width: 10px;
+ height: 10px;
+ }
+
+ &:hover {
+ background-color: var(--tags-close-hover, #b4bccc);
+ color: #fff;
+ }
+ }
+ }
+}
+</style>
diff --git a/src/layout/index.vue b/src/layout/index.vue
index 67ac803..90d72b9 100644
--- a/src/layout/index.vue
+++ b/src/layout/index.vue
@@ -69,11 +69,14 @@
@import "@/assets/styles/mixin.scss";
@import "@/assets/styles/variables.module.scss";
-.app-wrapper {
- @include clearfix;
- position: relative;
- height: 100%;
- width: 100%;
+.app-wrapper {
+ @include clearfix;
+ position: relative;
+ height: 100%;
+ width: 100%;
+ background:
+ radial-gradient(circle at top, rgba(223, 232, 226, 0.95), transparent 32%),
+ linear-gradient(180deg, #f7faf8 0%, var(--app-bg) 100%);
&.mobile.openSidebar {
position: fixed;
@@ -91,24 +94,25 @@
z-index: 999;
}
-.fixed-header {
- position: fixed;
- top: 0;
- right: 0;
- z-index: 9;
- width: calc(100% - #{$base-sidebar-width});
- transition: width 0.28s;
-}
-
-.hideSidebar .fixed-header {
- width: calc(100% - 54px);
-}
-
-.sidebarHide .fixed-header {
- width: 100%;
-}
+.fixed-header {
+ position: fixed;
+ top: 12px;
+ right: 16px;
+ z-index: 9;
+ width: calc(100% - #{$base-sidebar-width} - 32px);
+ transition: width 0.28s, right 0.28s;
+ padding-bottom: 8px;
+}
+
+.hideSidebar .fixed-header {
+ width: calc(100% - 70px);
+}
+
+.sidebarHide .fixed-header {
+ width: calc(100% - 32px);
+}
.mobile .fixed-header {
width: 100%;
}
-</style>
\ No newline at end of file
+</style>
diff --git a/src/views/login.vue b/src/views/login.vue
index 6217877..872537b 100644
--- a/src/views/login.vue
+++ b/src/views/login.vue
@@ -1,232 +1,401 @@
-<template>
- <div class="login">
- <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
- <h3 class="title">{{ title }}</h3>
- <el-divider />
- <el-form-item prop="username">
- <el-input
- v-model="loginForm.username"
- type="text"
- size="large"
- auto-complete="off"
- placeholder="璐﹀彿"
- >
- <template #prefix><el-icon><User /></el-icon></template>
- </el-input>
- </el-form-item>
- <el-form-item prop="password">
- <el-input
- v-model="loginForm.password"
- type="password"
- size="large"
- auto-complete="off"
- placeholder="瀵嗙爜"
- show-password
- @keyup.enter="handleLogin"
- >
- <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
- </el-input>
- </el-form-item>
-<!-- <el-form-item prop="code" v-if="captchaEnabled">-->
-<!-- <el-input-->
-<!-- v-model="loginForm.code"-->
-<!-- size="large"-->
-<!-- auto-complete="off"-->
-<!-- placeholder="楠岃瘉鐮�"-->
-<!-- style="width: 63%"-->
-<!-- @keyup.enter="handleLogin"-->
-<!-- >-->
-<!-- <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>-->
-<!-- </el-input>-->
-<!-- <div class="login-code">-->
-<!-- <img :src="codeUrl" @click="getCode" class="login-code-img"/>-->
-<!-- </div>-->
-<!-- </el-form-item>-->
- <el-form-item style="width:100%;">
- <el-button
- :loading="loading"
- size="large"
- type="primary"
- style="width:100%;"
- @click.prevent="handleLogin"
- >
- <span v-if="!loading">鐧� 褰�</span>
- <span v-else>鐧� 褰� 涓�...</span>
- </el-button>
- <div style="float: right;" v-if="register">
- <router-link class="link-type" :to="'/register'">绔嬪嵆娉ㄥ唽</router-link>
- </div>
- </el-form-item>
- <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">璁颁綇瀵嗙爜</el-checkbox>
- </el-form>
- <!-- 搴曢儴 -->
-<!-- <div class="el-login-footer">-->
-<!-- <span>Copyright 漏 2018-2025 ruoyi.vip All Rights Reserved.</span>-->
-<!-- </div>-->
- </div>
-</template>
-
-<script setup>
-import {getCodeImg} from "@/api/login"
-import Cookies from "js-cookie"
-import { encrypt, decrypt } from "@/utils/jsencrypt"
-import useUserStore from '@/store/modules/user'
-
-const title = import.meta.env.VITE_APP_TITLE
-const userStore = useUserStore()
-const route = useRoute()
-const router = useRouter()
-const { proxy } = getCurrentInstance()
-
-const loginForm = ref({
- username: "",
- password: "",
- rememberMe: false,
-})
-
-const loginRules = {
- username: [{ required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勮处鍙�" }],
- password: [{ required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勫瘑鐮�" }],
- // code: [{ required: true, trigger: "change", message: "璇疯緭鍏ラ獙璇佺爜" }]
-}
-
-const codeUrl = ref("")
-const loading = ref(false)
-// 楠岃瘉鐮佸紑鍏�
-const captchaEnabled = ref(true)
-// 娉ㄥ唽寮�鍏�
-const register = ref(false)
-const redirect = ref(undefined)
-
-watch(route, (newRoute) => {
- redirect.value = newRoute.query && newRoute.query.redirect
-}, { immediate: true })
-
-function handleLogin() {
- proxy.$refs.loginRef.validate(valid => {
- if (valid) {
- loading.value = true
- // 鍕鹃�変簡闇�瑕佽浣忓瘑鐮佽缃湪 cookie 涓缃浣忕敤鎴峰悕鍜屽瘑鐮�
- Cookies.set("username", loginForm.value.username, { expires: 30 })
- Cookies.set("password", encrypt(loginForm.value.password), { expires: 30 })
- Cookies.set("rememberMe", loginForm.value.rememberMe, { expires: 30 })
- userStore.loginCheckFactory(loginForm.value).then(res => {
- const query = route.query
- const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
- if (cur !== "redirect") {
- acc[cur] = query[cur]
- }
- return acc
- }, {})
- router.push({ path: redirect.value || "/", query: otherQueryParams })
- }).catch(() => {
- loading.value = false
- // 閲嶆柊鑾峰彇楠岃瘉鐮�
- if (captchaEnabled.value) {
- getCode()
- }
- })
- }
- })
-}
-
-function getCode() {
- getCodeImg().then(res => {
- captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled
- if (captchaEnabled.value) {
- codeUrl.value = "data:image/gif;base64," + res.img
- loginForm.value.uuid = res.uuid
- }
- })
-}
-
-function getCookie() {
- const username = Cookies.get("username")
- const password = Cookies.get("password")
- const rememberMe = Cookies.get("rememberMe")
- loginForm.value = {
- username: username === undefined ? loginForm.value.username : username,
- password: password === undefined ? loginForm.value.password : decrypt(password),
- rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
- }
-}
-
-getCode()
-getCookie()
-</script>
-
-<style lang='scss' scoped>
-.login {
- height: 100%;
- background-image: url("../assets/images/login-background.png");
- background-size: cover;
- position: relative;
-}
-.title {
- margin: 20px auto 14px auto;
- text-align: center;
- color: #2C51D9;
- font-size: 28px;
- font-weight: 700;
-}
-
-.login-form {
- position: absolute;
- top: 50%;
- right: 15%;
- transform: translate(0, -50%);
- border-radius: 6px;
- background: #ffffff;
- width: 420px;
- height: 500px;
- padding: 40px;
- z-index: 1;
- box-shadow: 0 0 5px 1px #ccc;
- .el-input {
- height: 40px;
- input {
- height: 40px;
- }
- }
- .input-icon {
- height: 39px;
- width: 14px;
- margin-left: 0px;
- }
-}
-.login-tip {
- font-size: 13px;
- text-align: center;
- color: #bfbfbf;
-}
-.login-code {
- width: 33%;
- height: 40px;
- float: right;
- img {
- cursor: pointer;
- vertical-align: middle;
- }
-}
-.el-login-footer {
- height: 40px;
- line-height: 40px;
- position: fixed;
- bottom: 0;
- width: 100%;
- text-align: center;
- color: #fff;
- font-family: Arial;
- font-size: 12px;
- letter-spacing: 1px;
-}
-.login-code-img {
- height: 40px;
- padding-left: 12px;
-}
-:deep() {
- .el-form-item--default {
- margin-bottom: 36px;
- }
-}
-</style>
+<template>
+ <div class="login-page">
+ <div class="login-shell">
+ <section class="login-brand">
+ <div class="brand-badge">PRODUCT INVENTORY</div>
+ <img :src="brandLogo" alt="brand logo" class="brand-logo" />
+ <h1 class="brand-title">{{ title }}</h1>
+ <p class="brand-copy">
+ 缁熶竴绠$悊搴撳瓨銆佹祦绋嬩笌涓氬姟鏁版嵁锛岃绯荤粺鍏ュ彛鍜屽悗鍙颁富鐣岄潰淇濇寔鍚屼竴濂楃畝绾﹁瑙夎瑷�銆�
+ </p>
+ <div class="brand-points">
+ <div class="brand-point">
+ <span class="point-dot"></span>
+ <span>娓呮櫚鐨勬暟鎹叆鍙�</span>
+ </div>
+ <div class="brand-point">
+ <span class="point-dot"></span>
+ <span>鏇磋交鐨勭晫闈㈠眰娆�</span>
+ </div>
+ <div class="brand-point">
+ <span class="point-dot"></span>
+ <span>绋冲畾鐨勪笟鍔″崗鍚屼綋楠�</span>
+ </div>
+ </div>
+ </section>
+
+ <section class="login-panel">
+ <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
+ <div class="panel-head">
+ <p class="panel-kicker">WELCOME BACK</p>
+ <h2 class="panel-title">鐧诲綍绯荤粺</h2>
+ <p class="panel-subtitle">杈撳叆璐﹀彿鍜屽瘑鐮佽繘鍏ュ伐浣滃彴銆�</p>
+ </div>
+
+ <el-form-item prop="username">
+ <el-input
+ v-model="loginForm.username"
+ type="text"
+ size="large"
+ auto-complete="off"
+ placeholder="璐﹀彿"
+ >
+ <template #prefix><el-icon><User /></el-icon></template>
+ </el-input>
+ </el-form-item>
+
+ <el-form-item prop="password">
+ <el-input
+ v-model="loginForm.password"
+ type="password"
+ size="large"
+ auto-complete="off"
+ placeholder="瀵嗙爜"
+ show-password
+ @keyup.enter="handleLogin"
+ >
+ <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
+ </el-input>
+ </el-form-item>
+
+ <div class="login-options">
+ <el-checkbox v-model="loginForm.rememberMe">璁颁綇瀵嗙爜</el-checkbox>
+ <router-link v-if="register" class="register-link" :to="'/register'">绔嬪嵆娉ㄥ唽</router-link>
+ </div>
+
+ <el-button
+ :loading="loading"
+ size="large"
+ type="primary"
+ class="login-submit"
+ @click.prevent="handleLogin"
+ >
+ <span v-if="!loading">鐧诲綍</span>
+ <span v-else>鐧诲綍涓�...</span>
+ </el-button>
+ </el-form>
+ </section>
+ </div>
+ </div>
+</template>
+
+<script setup>
+import { getCodeImg } from "@/api/login"
+import Cookies from "js-cookie"
+import { encrypt, decrypt } from "@/utils/jsencrypt"
+import useUserStore from "@/store/modules/user"
+import brandLogo from "@/assets/logo/logo.png"
+
+const title = import.meta.env.VITE_APP_TITLE
+const userStore = useUserStore()
+const route = useRoute()
+const router = useRouter()
+const { proxy } = getCurrentInstance()
+
+const loginForm = ref({
+ username: "",
+ password: "",
+ rememberMe: false,
+})
+
+const loginRules = {
+ username: [{ required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勮处鍙�" }],
+ password: [{ required: true, trigger: "blur", message: "璇疯緭鍏ユ偍鐨勫瘑鐮�" }],
+}
+
+const codeUrl = ref("")
+const loading = ref(false)
+const captchaEnabled = ref(true)
+const register = ref(false)
+const redirect = ref(undefined)
+
+watch(
+ route,
+ (newRoute) => {
+ redirect.value = newRoute.query && newRoute.query.redirect
+ },
+ { immediate: true }
+)
+
+function handleLogin() {
+ proxy.$refs.loginRef.validate((valid) => {
+ if (valid) {
+ loading.value = true
+ Cookies.set("username", loginForm.value.username, { expires: 30 })
+ Cookies.set("password", encrypt(loginForm.value.password), { expires: 30 })
+ Cookies.set("rememberMe", loginForm.value.rememberMe, { expires: 30 })
+ userStore
+ .loginCheckFactory(loginForm.value)
+ .then(() => {
+ const query = route.query
+ const otherQueryParams = Object.keys(query).reduce((acc, cur) => {
+ if (cur !== "redirect") {
+ acc[cur] = query[cur]
+ }
+ return acc
+ }, {})
+ router.push({ path: redirect.value || "/", query: otherQueryParams })
+ })
+ .catch(() => {
+ loading.value = false
+ if (captchaEnabled.value) {
+ getCode()
+ }
+ })
+ }
+ })
+}
+
+function getCode() {
+ getCodeImg().then((res) => {
+ captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled
+ if (captchaEnabled.value) {
+ codeUrl.value = "data:image/gif;base64," + res.img
+ loginForm.value.uuid = res.uuid
+ }
+ })
+}
+
+function getCookie() {
+ const username = Cookies.get("username")
+ const password = Cookies.get("password")
+ const rememberMe = Cookies.get("rememberMe")
+ loginForm.value = {
+ username: username === undefined ? loginForm.value.username : username,
+ password: password === undefined ? loginForm.value.password : decrypt(password),
+ rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
+ }
+}
+
+getCode()
+getCookie()
+</script>
+
+<style lang="scss" scoped>
+.login-page {
+ min-height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 32px;
+ background:
+ radial-gradient(circle at top left, rgba(207, 223, 214, 0.95), transparent 30%),
+ radial-gradient(circle at bottom right, rgba(222, 232, 227, 0.9), transparent 28%),
+ linear-gradient(180deg, #f7faf8 0%, #eef2ee 100%);
+}
+
+.login-shell {
+ width: min(1120px, 100%);
+ min-height: 680px;
+ display: grid;
+ grid-template-columns: 1.1fr 0.9fr;
+ border: 1px solid rgba(216, 225, 219, 0.9);
+ border-radius: 32px;
+ overflow: hidden;
+ background: rgba(255, 255, 255, 0.76);
+ box-shadow: 0 26px 80px rgba(31, 49, 38, 0.12);
+ backdrop-filter: blur(24px);
+}
+
+.login-brand {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ padding: 56px 64px;
+ background:
+ linear-gradient(180deg, rgba(244, 248, 245, 0.9), rgba(233, 240, 236, 0.9)),
+ linear-gradient(135deg, rgba(31, 122, 114, 0.05), rgba(255, 255, 255, 0));
+
+ &::after {
+ content: "";
+ position: absolute;
+ inset: 28px;
+ border: 1px solid rgba(31, 122, 114, 0.08);
+ border-radius: 28px;
+ pointer-events: none;
+ }
+}
+
+.brand-badge {
+ width: fit-content;
+ padding: 8px 14px;
+ border-radius: 999px;
+ background: rgba(31, 122, 114, 0.1);
+ color: #1f7a72;
+ font-size: 12px;
+ font-weight: 700;
+ letter-spacing: 0.14em;
+}
+
+.brand-logo {
+ width: 160px;
+ height: auto;
+ margin: 30px 0 24px;
+ object-fit: contain;
+}
+
+.brand-title {
+ margin: 0;
+ font-size: 42px;
+ line-height: 1.12;
+ color: #21313f;
+ letter-spacing: -0.03em;
+}
+
+.brand-copy {
+ max-width: 460px;
+ margin: 18px 0 0;
+ font-size: 16px;
+ line-height: 1.75;
+ color: #5f6d7e;
+}
+
+.brand-points {
+ margin-top: 34px;
+ display: flex;
+ flex-direction: column;
+ gap: 14px;
+}
+
+.brand-point {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ color: #3d4b59;
+ font-size: 15px;
+ font-weight: 500;
+}
+
+.point-dot {
+ width: 10px;
+ height: 10px;
+ border-radius: 50%;
+ background: linear-gradient(135deg, #1f7a72, #5ca39c);
+ box-shadow: 0 0 0 6px rgba(31, 122, 114, 0.08);
+}
+
+.login-panel {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 40px;
+ background: rgba(255, 255, 255, 0.7);
+}
+
+.login-form {
+ width: min(420px, 100%);
+ padding: 38px 34px 34px;
+ border: 1px solid rgba(216, 225, 219, 0.92);
+ border-radius: 28px;
+ background: rgba(255, 255, 255, 0.88);
+ box-shadow: 0 18px 52px rgba(31, 49, 38, 0.1);
+}
+
+.panel-head {
+ margin-bottom: 28px;
+}
+
+.panel-kicker {
+ margin: 0 0 10px;
+ color: #8a98a8;
+ font-size: 12px;
+ font-weight: 700;
+ letter-spacing: 0.16em;
+}
+
+.panel-title {
+ margin: 0;
+ color: #21313f;
+ font-size: 30px;
+ font-weight: 700;
+}
+
+.panel-subtitle {
+ margin: 10px 0 0;
+ color: #6b7888;
+ font-size: 14px;
+}
+
+.login-options {
+ margin: -4px 0 22px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ color: #5f6d7e;
+}
+
+.register-link {
+ color: var(--el-color-primary);
+ font-weight: 600;
+}
+
+.login-submit {
+ width: 100%;
+ height: 48px;
+}
+
+.input-icon {
+ width: 14px;
+}
+
+:deep(.el-form-item) {
+ margin-bottom: 22px;
+}
+
+:deep(.el-input__wrapper) {
+ min-height: 42px;
+ height: 42px;
+ padding-top: 0;
+ padding-bottom: 0;
+}
+
+:deep(.el-input__inner) {
+ height: 42px;
+ line-height: 42px;
+}
+
+:deep(.el-checkbox) {
+ color: #5f6d7e;
+}
+
+@media (max-width: 960px) {
+ .login-page {
+ padding: 18px;
+ }
+
+ .login-shell {
+ min-height: auto;
+ grid-template-columns: 1fr;
+ }
+
+ .login-brand {
+ padding: 40px 28px 22px;
+ }
+
+ .login-brand::after {
+ inset: 16px;
+ }
+
+ .brand-title {
+ font-size: 32px;
+ }
+
+ .brand-copy {
+ font-size: 14px;
+ }
+
+ .brand-points {
+ margin-top: 24px;
+ }
+
+ .login-panel {
+ padding: 12px 18px 24px;
+ }
+
+ .login-form {
+ width: 100%;
+ padding: 28px 22px 24px;
+ }
+}
+</style>
--
Gitblit v1.9.3