update README.md
This commit is contained in:
@@ -28,7 +28,7 @@ RuoYi-Vue 前端项目的三个主要演进版本,方便你直观对比其技
|
||||
| **状态管理** | Vuex | Pinia | Pinia |
|
||||
| **路由管理** | Vue Router 3 | Vue Router 4 | Vue Router 4 |
|
||||
| **核心特点** | 1. 技术栈经典稳定<br>2. 社区资料丰富<br>3. 当前维护重心已转移 | 1. 现代前端技术栈<br>2. 开发体验与性能更优<br>3. 官方主推的活跃版本 | 1. 类型加持,减少沟通成本<br>2. 开发时有提示,效率更高<br>3. 多人协作企业级开发项目 |
|
||||
| **仓库地址** | [RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue) | [RuoYi-Vue3](https://gitcode.com/yangzongzhuan/RuoYi-Vue3) | [RuoYi-Vue3-TypeScript](https://gitcode.com/yangzongzhuan/RuoYi-Vue3/tree/typescript) |
|
||||
| **仓库地址** | [RuoYi-Vue2](https://gitcode.com/yangzongzhuan/RuoYi-Vue2) | [RuoYi-Vue3](https://gitcode.com/yangzongzhuan/RuoYi-Vue3) | [RuoYi-Vue3-TypeScript](https://gitcode.com/yangzongzhuan/RuoYi-Vue3/tree/typescript) |
|
||||
|
||||
## 前端运行
|
||||
|
||||
|
||||
@@ -1,448 +1,448 @@
|
||||
// base color
|
||||
$blue: #324157;
|
||||
$light-blue: #333c46;
|
||||
$red: #C03639;
|
||||
$pink: #E65D6E;
|
||||
$green: #30B08F;
|
||||
$tiffany: #4AB7BD;
|
||||
$yellow: #FEC171;
|
||||
$panGreen: #30B08F;
|
||||
|
||||
// 默认主题变量
|
||||
$menuText: #bfcbd9;
|
||||
$menuActiveText: #409eff;
|
||||
$menuBg: #1a1f2e;
|
||||
$menuHover: #263445;
|
||||
|
||||
// 浅色主题theme-light
|
||||
$menuLightBg: #ffffff;
|
||||
$menuLightHover: #f0f1f5;
|
||||
$menuLightText: #303133;
|
||||
$menuLightActiveText: #409EFF;
|
||||
|
||||
// 基础变量
|
||||
$base-sidebar-width: 200px;
|
||||
$sideBarWidth: 200px;
|
||||
|
||||
// 菜单暗色变量
|
||||
$base-menu-color: rgba(255,255,255,.65);
|
||||
$base-menu-color-active: #ffffff;
|
||||
$base-menu-background: #1a1f2e;
|
||||
$base-sub-menu-background: #141824;
|
||||
$base-sub-menu-hover: rgba(255,255,255,.06);
|
||||
|
||||
// 组件变量
|
||||
$--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;
|
||||
--el-menu-text-color: #d0d0d0;
|
||||
--sidebar-logo-text: #d0d0d0;
|
||||
|
||||
/* primary */
|
||||
--primary-bg: #18212b;
|
||||
|
||||
/* 侧边栏 */
|
||||
--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;
|
||||
/* 卡片模式激活页签 */
|
||||
--tags-card-active-bg: var(--el-bg-color-overlay);
|
||||
--tags-card-active-bg: color-mix(in srgb, var(--el-color-primary) 22%, var(--el-bg-color-overlay) 78%);
|
||||
--tags-card-active-border: var(--tags-card-active-bg);
|
||||
|
||||
/* 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:not(.is-active), .menu-title {
|
||||
color: var(--el-text-color-regular);
|
||||
}
|
||||
& .el-menu .theme-dark .nest-menu .el-sub-menu > .el-sub-menu__title,
|
||||
& .el-menu .theme-dark .el-sub-menu .el-menu-item,
|
||||
& .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;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--menu-hover) !important;
|
||||
}
|
||||
}
|
||||
&.theme-light {
|
||||
border-right: none !important;
|
||||
.el-menu-item,
|
||||
.el-sub-menu__title {
|
||||
color: var(--sidebar-text) !important;
|
||||
}
|
||||
.el-menu-item:not(.is-active):hover,
|
||||
.submenu-title-noDropdown:hover,
|
||||
.el-sub-menu__title:hover {
|
||||
background-color: var(--menu-hover) !important;
|
||||
}
|
||||
.el-menu .nest-menu .el-sub-menu>.el-sub-menu__title,
|
||||
.el-menu .el-sub-menu .el-menu-item,
|
||||
.nest-menu .el-sub-menu>.el-sub-menu__title,
|
||||
.el-sub-menu .el-menu-item {
|
||||
background-color: var(--el-bg-color) !important;
|
||||
&:hover {
|
||||
background-color: var(--menu-hover) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.topmenu-container {
|
||||
.el-menu-item,
|
||||
.el-sub-menu .el-sub-menu__title {
|
||||
color: var(--el-text-color-regular) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.topbar-menu.el-menu--horizontal > .el-sub-menu .el-sub-menu__title{
|
||||
color: var(--el-text-color-regular) !important;
|
||||
}
|
||||
|
||||
/* 顶部栏栏菜单覆盖 */
|
||||
.el-menu--horizontal {
|
||||
.el-menu-item, .el-sub-menu {
|
||||
&:not(.is-disabled) {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: var(--navbar-hover) !important;
|
||||
.el-sub-menu__title {
|
||||
background-color: var(--navbar-hover) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 页签样式覆盖 */
|
||||
.navbar {
|
||||
box-shadow: 0 1px 4px rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
.tags-view-container {
|
||||
&.tags-view-container--chrome {
|
||||
--chrome-strip-bg: var(--el-bg-color);
|
||||
--chrome-strip-border: var(--el-border-color);
|
||||
--chrome-tab-active-bg: var(--el-bg-color-overlay);
|
||||
--chrome-tab-active-bg: color-mix(in srgb, var(--el-color-primary) 22%, var(--el-bg-color-overlay) 78%);
|
||||
--chrome-tab-text: var(--el-text-color-secondary);
|
||||
--chrome-tab-text-active: var(--el-color-primary);
|
||||
.tags-view-wrapper .tags-view-item:not(.active) + .tags-view-item:not(.active) {
|
||||
border-left-color: var(--el-border-color);
|
||||
}
|
||||
.tags-view-wrapper .tags-view-item {
|
||||
&:hover:not(.active) {
|
||||
background: var(--el-fill-color, #303030) !important;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
&.active {
|
||||
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
}
|
||||
}
|
||||
&:not(.tags-view-container--chrome) .tags-view-wrapper .tags-view-item.active {
|
||||
background-color: var(--tags-card-active-bg) !important;
|
||||
border-color: var(--tags-card-active-border) !important;
|
||||
color: var(--current-color, #409eff) !important;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
|
||||
|
||||
&::before {
|
||||
background: var(--current-color, #409eff) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 分割窗格覆盖 */
|
||||
.tree-sidebar-manage-wrap {
|
||||
.tree-sidebar-content {
|
||||
background: var(--splitpanes-bg);
|
||||
}
|
||||
.tree-sidebar {
|
||||
border-right: 1px solid var(--splitpanes-splitter-bg);
|
||||
background: var(--splitpanes-bg);
|
||||
.tree-header {
|
||||
background: var(--splitpanes-bg);
|
||||
border-color: var(--splitpanes-border);
|
||||
}
|
||||
.tree-title {
|
||||
color: var(--el-color-primary-light-2);
|
||||
}
|
||||
.collapse-button-container {
|
||||
background: var(--splitpanes-bg) !important;
|
||||
}
|
||||
.collapse-button {
|
||||
&:hover {
|
||||
color: var(--el-color-primary-light-2);
|
||||
background: var(--splitpanes-bg);
|
||||
}
|
||||
}
|
||||
.resize-handle {
|
||||
&:hover {
|
||||
background: var(--splitpanes-splitter-hover-bg);
|
||||
}
|
||||
&.active {
|
||||
background: var(--splitpanes-splitter-hover-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 按钮样式覆盖 */
|
||||
.el-button--primary.is-plain {
|
||||
background-color: var(--primary-bg);
|
||||
border: 1px solid var(--el-color-primary-light-2);
|
||||
color: var(--el-color-primary-light-2);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--el-button-hover-bg-color);
|
||||
border-color: var(--el-button-hover-border-color);
|
||||
color: var(--el-button-hover-text-color);
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
background-color: var(--link-active-bg-color);
|
||||
border-color: var(--el-color-primary-light-3);
|
||||
color: var(--el-color-primary-light-3);
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
/* primary tag 样式覆盖 */
|
||||
.el-tag--primary {
|
||||
background-color: var(--primary-bg);
|
||||
border: 1px solid var(--el-border-color-light);
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
/* 表格样式覆盖 */
|
||||
.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, #f8f8f9) !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);
|
||||
}
|
||||
|
||||
/* 底部版权样式覆盖 */
|
||||
.copyright {
|
||||
background-color: var(--el-bg-color) !important;
|
||||
color: var(--el-text-color-regular) !important;
|
||||
border-top: 1px solid var(--el-bg-color) !important;
|
||||
}
|
||||
|
||||
/* 详情抽屉暗黑模式覆盖 */
|
||||
.detail-drawer {
|
||||
.el-drawer__header {
|
||||
color: var(--el-text-color-primary);
|
||||
background: var(--el-bg-color-overlay);
|
||||
border-bottom: 1px solid var(--el-border-color);
|
||||
}
|
||||
.section-header {
|
||||
color: var(--el-color-primary-light-3);
|
||||
border-bottom-color: var(--el-border-color);
|
||||
}
|
||||
.drawer-content {
|
||||
.info-label {
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
.info-value {
|
||||
color: var(--el-text-color-primary);
|
||||
&.plaintext {
|
||||
border-bottom-color: var(--el-border-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 详情卡片暗黑模式覆盖 */
|
||||
.detail-card {
|
||||
border-color: var(--el-border-color);
|
||||
}
|
||||
.detail-card-title {
|
||||
background: var(--el-bg-color-overlay);
|
||||
color: var(--el-text-color-primary);
|
||||
border-bottom-color: var(--el-border-color);
|
||||
}
|
||||
.detail-item {
|
||||
border-bottom-color: var(--el-border-color-lighter, #2a2a2a);
|
||||
}
|
||||
.detail-label {
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
.detail-value {
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
.code-wrap {
|
||||
background: var(--el-bg-color-overlay);
|
||||
border-color: var(--el-border-color);
|
||||
}
|
||||
.code-pre {
|
||||
color: var(--el-text-color-regular);
|
||||
}
|
||||
.code-action .el-button {
|
||||
background: rgba(30, 30, 30, 0.9);
|
||||
border-color: var(--el-border-color);
|
||||
color: var(--el-text-color-regular);
|
||||
&:hover {
|
||||
background: var(--el-bg-color-overlay);
|
||||
border-color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
/* 字典详情抽屉暗黑模式变量 */
|
||||
--dict-drawer-title-color: var(--el-text-color-primary);
|
||||
--dict-drawer-subtext-color: var(--el-text-color-secondary);
|
||||
--dict-drawer-card-bg: var(--el-bg-color-overlay);
|
||||
--dict-drawer-border-color: var(--el-border-color);
|
||||
--dict-drawer-cell-divider: var(--el-border-color-lighter, #2a2a2a);
|
||||
|
||||
/* 通知公告详情抽屉暗黑模式变量 */
|
||||
--notice-title-color: var(--el-text-color-primary);
|
||||
--notice-meta-color: var(--el-text-color-secondary);
|
||||
--notice-meta-icon-color: var(--el-text-color-placeholder, #606266);
|
||||
--notice-border-color: var(--el-border-color);
|
||||
--notice-body-bg: var(--el-bg-color-overlay);
|
||||
--notice-body-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
||||
--notice-content-color: var(--el-text-color-regular);
|
||||
--notice-drawer-body-bg: var(--el-bg-color);
|
||||
--notice-divider-gradient: linear-gradient(to right, transparent, var(--el-border-color), transparent);
|
||||
--notice-divider-dot-color: var(--el-border-color-light, #434343);
|
||||
--notice-blockquote-bg: var(--el-bg-color);
|
||||
--notice-blockquote-border: var(--el-border-color);
|
||||
--notice-table-border: var(--el-border-color);
|
||||
--notice-table-header-bg: var(--el-bg-color);
|
||||
--notice-tag-notify-bg: rgba(217, 119, 6, 0.15);
|
||||
--notice-tag-notify-color: #f6ad55;
|
||||
--notice-tag-announce-bg: rgba(56, 161, 105, 0.15);
|
||||
--notice-tag-announce-color: #68d391;
|
||||
}
|
||||
|
||||
.notice-detail-drawer {
|
||||
.notice-content {
|
||||
color: var(--el-text-color-regular) !important;
|
||||
* { color: var(--el-text-color-regular) !important; }
|
||||
h1~h6, strong, b { color: var(--el-text-color-primary) !important; }
|
||||
a, a * { color: #5ba7f5 !important; }
|
||||
blockquote, blockquote * { color: var(--el-text-color-secondary) !important; }
|
||||
}
|
||||
}
|
||||
|
||||
// base color
|
||||
$blue: #324157;
|
||||
$light-blue: #333c46;
|
||||
$red: #C03639;
|
||||
$pink: #E65D6E;
|
||||
$green: #30B08F;
|
||||
$tiffany: #4AB7BD;
|
||||
$yellow: #FEC171;
|
||||
$panGreen: #30B08F;
|
||||
|
||||
// 默认主题变量
|
||||
$menuText: #bfcbd9;
|
||||
$menuActiveText: #409eff;
|
||||
$menuBg: #1a1f2e;
|
||||
$menuHover: #263445;
|
||||
|
||||
// 浅色主题theme-light
|
||||
$menuLightBg: #ffffff;
|
||||
$menuLightHover: #f0f1f5;
|
||||
$menuLightText: #303133;
|
||||
$menuLightActiveText: #409EFF;
|
||||
|
||||
// 基础变量
|
||||
$base-sidebar-width: 200px;
|
||||
$sideBarWidth: 200px;
|
||||
|
||||
// 菜单暗色变量
|
||||
$base-menu-color: rgba(255,255,255,.65);
|
||||
$base-menu-color-active: #ffffff;
|
||||
$base-menu-background: #1a1f2e;
|
||||
$base-sub-menu-background: #141824;
|
||||
$base-sub-menu-hover: rgba(255,255,255,.06);
|
||||
|
||||
// 组件变量
|
||||
$--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;
|
||||
--el-menu-text-color: #d0d0d0;
|
||||
--sidebar-logo-text: #d0d0d0;
|
||||
|
||||
/* primary */
|
||||
--primary-bg: #18212b;
|
||||
|
||||
/* 侧边栏 */
|
||||
--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;
|
||||
/* 卡片模式激活页签 */
|
||||
--tags-card-active-bg: var(--el-bg-color-overlay);
|
||||
--tags-card-active-bg: color-mix(in srgb, var(--el-color-primary) 22%, var(--el-bg-color-overlay) 78%);
|
||||
--tags-card-active-border: var(--tags-card-active-bg);
|
||||
|
||||
/* 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:not(.is-active), .menu-title {
|
||||
color: var(--el-text-color-regular);
|
||||
}
|
||||
& .el-menu .theme-dark .nest-menu .el-sub-menu > .el-sub-menu__title,
|
||||
& .el-menu .theme-dark .el-sub-menu .el-menu-item,
|
||||
& .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;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--menu-hover) !important;
|
||||
}
|
||||
}
|
||||
&.theme-light {
|
||||
border-right: none !important;
|
||||
.el-menu-item,
|
||||
.el-sub-menu__title {
|
||||
color: var(--sidebar-text) !important;
|
||||
}
|
||||
.el-menu-item:not(.is-active):hover,
|
||||
.submenu-title-noDropdown:hover,
|
||||
.el-sub-menu__title:hover {
|
||||
background-color: var(--menu-hover) !important;
|
||||
}
|
||||
.el-menu .nest-menu .el-sub-menu>.el-sub-menu__title,
|
||||
.el-menu .el-sub-menu .el-menu-item,
|
||||
.nest-menu .el-sub-menu>.el-sub-menu__title,
|
||||
.el-sub-menu .el-menu-item {
|
||||
background-color: var(--el-bg-color) !important;
|
||||
&:hover {
|
||||
background-color: var(--menu-hover) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.topmenu-container {
|
||||
.el-menu-item,
|
||||
.el-sub-menu .el-sub-menu__title {
|
||||
color: var(--el-text-color-regular) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.topbar-menu.el-menu--horizontal > .el-sub-menu .el-sub-menu__title{
|
||||
color: var(--el-text-color-regular) !important;
|
||||
}
|
||||
|
||||
/* 顶部栏栏菜单覆盖 */
|
||||
.el-menu--horizontal {
|
||||
.el-menu-item, .el-sub-menu {
|
||||
&:not(.is-disabled) {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: var(--navbar-hover) !important;
|
||||
.el-sub-menu__title {
|
||||
background-color: var(--navbar-hover) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 页签样式覆盖 */
|
||||
.navbar {
|
||||
box-shadow: 0 1px 4px rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
.tags-view-container {
|
||||
&.tags-view-container--chrome {
|
||||
--chrome-strip-bg: var(--el-bg-color);
|
||||
--chrome-strip-border: var(--el-border-color);
|
||||
--chrome-tab-active-bg: var(--el-bg-color-overlay);
|
||||
--chrome-tab-active-bg: color-mix(in srgb, var(--el-color-primary) 22%, var(--el-bg-color-overlay) 78%);
|
||||
--chrome-tab-text: var(--el-text-color-secondary);
|
||||
--chrome-tab-text-active: var(--el-color-primary);
|
||||
.tags-view-wrapper .tags-view-item:not(.active) + .tags-view-item:not(.active) {
|
||||
border-left-color: var(--el-border-color);
|
||||
}
|
||||
.tags-view-wrapper .tags-view-item {
|
||||
&:hover:not(.active) {
|
||||
background: var(--el-fill-color, #303030) !important;
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
&.active {
|
||||
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
}
|
||||
}
|
||||
&:not(.tags-view-container--chrome) .tags-view-wrapper .tags-view-item.active {
|
||||
background-color: var(--tags-card-active-bg) !important;
|
||||
border-color: var(--tags-card-active-border) !important;
|
||||
color: var(--current-color, #409eff) !important;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
|
||||
|
||||
&::before {
|
||||
background: var(--current-color, #409eff) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 分割窗格覆盖 */
|
||||
.tree-sidebar-manage-wrap {
|
||||
.tree-sidebar-content {
|
||||
background: var(--splitpanes-bg);
|
||||
}
|
||||
.tree-sidebar {
|
||||
border-right: 1px solid var(--splitpanes-splitter-bg);
|
||||
background: var(--splitpanes-bg);
|
||||
.tree-header {
|
||||
background: var(--splitpanes-bg);
|
||||
border-color: var(--splitpanes-border);
|
||||
}
|
||||
.tree-title {
|
||||
color: var(--el-color-primary-light-2);
|
||||
}
|
||||
.collapse-button-container {
|
||||
background: var(--splitpanes-bg) !important;
|
||||
}
|
||||
.collapse-button {
|
||||
&:hover {
|
||||
color: var(--el-color-primary-light-2);
|
||||
background: var(--splitpanes-bg);
|
||||
}
|
||||
}
|
||||
.resize-handle {
|
||||
&:hover {
|
||||
background: var(--splitpanes-splitter-hover-bg);
|
||||
}
|
||||
&.active {
|
||||
background: var(--splitpanes-splitter-hover-bg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 按钮样式覆盖 */
|
||||
.el-button--primary.is-plain {
|
||||
background-color: var(--primary-bg);
|
||||
border: 1px solid var(--el-color-primary-light-2);
|
||||
color: var(--el-color-primary-light-2);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--el-button-hover-bg-color);
|
||||
border-color: var(--el-button-hover-border-color);
|
||||
color: var(--el-button-hover-text-color);
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
background-color: var(--link-active-bg-color);
|
||||
border-color: var(--el-color-primary-light-3);
|
||||
color: var(--el-color-primary-light-3);
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
/* primary tag 样式覆盖 */
|
||||
.el-tag--primary {
|
||||
background-color: var(--primary-bg);
|
||||
border: 1px solid var(--el-border-color-light);
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
/* 表格样式覆盖 */
|
||||
.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, #f8f8f9) !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);
|
||||
}
|
||||
|
||||
/* 底部版权样式覆盖 */
|
||||
.copyright {
|
||||
background-color: var(--el-bg-color) !important;
|
||||
color: var(--el-text-color-regular) !important;
|
||||
border-top: 1px solid var(--el-bg-color) !important;
|
||||
}
|
||||
|
||||
/* 详情抽屉暗黑模式覆盖 */
|
||||
.detail-drawer {
|
||||
.el-drawer__header {
|
||||
color: var(--el-text-color-primary);
|
||||
background: var(--el-bg-color-overlay);
|
||||
border-bottom: 1px solid var(--el-border-color);
|
||||
}
|
||||
.section-header {
|
||||
color: var(--el-color-primary-light-3);
|
||||
border-bottom-color: var(--el-border-color);
|
||||
}
|
||||
.drawer-content {
|
||||
.info-label {
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
.info-value {
|
||||
color: var(--el-text-color-primary);
|
||||
&.plaintext {
|
||||
border-bottom-color: var(--el-border-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 详情卡片暗黑模式覆盖 */
|
||||
.detail-card {
|
||||
border-color: var(--el-border-color);
|
||||
}
|
||||
.detail-card-title {
|
||||
background: var(--el-bg-color-overlay);
|
||||
color: var(--el-text-color-primary);
|
||||
border-bottom-color: var(--el-border-color);
|
||||
}
|
||||
.detail-item {
|
||||
border-bottom-color: var(--el-border-color-lighter, #2a2a2a);
|
||||
}
|
||||
.detail-label {
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
.detail-value {
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
.code-wrap {
|
||||
background: var(--el-bg-color-overlay);
|
||||
border-color: var(--el-border-color);
|
||||
}
|
||||
.code-pre {
|
||||
color: var(--el-text-color-regular);
|
||||
}
|
||||
.code-action .el-button {
|
||||
background: rgba(30, 30, 30, 0.9);
|
||||
border-color: var(--el-border-color);
|
||||
color: var(--el-text-color-regular);
|
||||
&:hover {
|
||||
background: var(--el-bg-color-overlay);
|
||||
border-color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
/* 字典详情抽屉暗黑模式变量 */
|
||||
--dict-drawer-title-color: var(--el-text-color-primary);
|
||||
--dict-drawer-subtext-color: var(--el-text-color-secondary);
|
||||
--dict-drawer-card-bg: var(--el-bg-color-overlay);
|
||||
--dict-drawer-border-color: var(--el-border-color);
|
||||
--dict-drawer-cell-divider: var(--el-border-color-lighter, #2a2a2a);
|
||||
|
||||
/* 通知公告详情抽屉暗黑模式变量 */
|
||||
--notice-title-color: var(--el-text-color-primary);
|
||||
--notice-meta-color: var(--el-text-color-secondary);
|
||||
--notice-meta-icon-color: var(--el-text-color-placeholder, #606266);
|
||||
--notice-border-color: var(--el-border-color);
|
||||
--notice-body-bg: var(--el-bg-color-overlay);
|
||||
--notice-body-shadow: 0 1px 4px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.04);
|
||||
--notice-content-color: var(--el-text-color-regular);
|
||||
--notice-drawer-body-bg: var(--el-bg-color);
|
||||
--notice-divider-gradient: linear-gradient(to right, transparent, var(--el-border-color), transparent);
|
||||
--notice-divider-dot-color: var(--el-border-color-light, #434343);
|
||||
--notice-blockquote-bg: var(--el-bg-color);
|
||||
--notice-blockquote-border: var(--el-border-color);
|
||||
--notice-table-border: var(--el-border-color);
|
||||
--notice-table-header-bg: var(--el-bg-color);
|
||||
--notice-tag-notify-bg: rgba(217, 119, 6, 0.15);
|
||||
--notice-tag-notify-color: #f6ad55;
|
||||
--notice-tag-announce-bg: rgba(56, 161, 105, 0.15);
|
||||
--notice-tag-announce-color: #68d391;
|
||||
}
|
||||
|
||||
.notice-detail-drawer {
|
||||
.notice-content {
|
||||
color: var(--el-text-color-regular) !important;
|
||||
* { color: var(--el-text-color-regular) !important; }
|
||||
h1~h6, strong, b { color: var(--el-text-color-primary) !important; }
|
||||
a, a * { color: #5ba7f5 !important; }
|
||||
blockquote, blockquote * { color: var(--el-text-color-secondary) !important; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,344 +1,344 @@
|
||||
<template>
|
||||
<el-drawer v-model="showSettings" :withHeader="false" :lock-scroll="false" direction="rtl" size="300px">
|
||||
<div class="setting-drawer-title">
|
||||
<h3 class="drawer-title">菜单导航设置</h3>
|
||||
</div>
|
||||
<div class="nav-wrap">
|
||||
<el-tooltip content="左侧菜单" placement="bottom">
|
||||
<div class="item left" @click="handleNavType(1)" :class="{ activeItem: navType == 1 }">
|
||||
<b></b><b></b>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
|
||||
<el-tooltip content="混合菜单" placement="bottom">
|
||||
<div class="item mix" @click="handleNavType(2)" :class="{ activeItem: navType == 2 }">
|
||||
<b></b><b></b>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="顶部菜单" placement="bottom">
|
||||
<div class="item top" @click="handleNavType(3)" :class="{ activeItem: navType == 3 }">
|
||||
<b></b><b></b>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="setting-drawer-title">
|
||||
<h3 class="drawer-title">主题风格设置</h3>
|
||||
</div>
|
||||
<div class="setting-drawer-block-checbox">
|
||||
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')">
|
||||
<img src="@/assets/images/dark.svg" alt="dark" />
|
||||
<div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
|
||||
<i aria-label="图标: check" class="anticon anticon-check">
|
||||
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class>
|
||||
<path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" />
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')">
|
||||
<img src="@/assets/images/light.svg" alt="light" />
|
||||
<div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
|
||||
<i aria-label="图标: check" class="anticon anticon-check">
|
||||
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class>
|
||||
<path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" />
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="drawer-item">
|
||||
<span>主题颜色</span>
|
||||
<span class="comp-style">
|
||||
<el-color-picker v-model="theme" :predefine="predefineColors" @change="themeChange"/>
|
||||
</span>
|
||||
</div>
|
||||
<el-divider />
|
||||
|
||||
<h3 class="drawer-title">系统布局配置</h3>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>开启页签</span>
|
||||
<span class="comp-style">
|
||||
<el-switch v-model="settingsStore.tagsView" class="drawer-switch" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>持久化标签页</span>
|
||||
<span class="comp-style">
|
||||
<el-switch v-model="settingsStore.tagsViewPersist" :disabled="!settingsStore.tagsView" @change="tagsViewPersistChange" class="drawer-switch" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>显示页签图标</span>
|
||||
<span class="comp-style">
|
||||
<el-switch v-model="settingsStore.tagsIcon" :disabled="!settingsStore.tagsView" class="drawer-switch" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>标签页样式</span>
|
||||
<span class="comp-style">
|
||||
<el-radio-group v-model="settingsStore.tagsViewStyle" :disabled="!settingsStore.tagsView" size="small">
|
||||
<el-radio-button label="card">卡片</el-radio-button>
|
||||
<el-radio-button label="chrome">谷歌</el-radio-button>
|
||||
</el-radio-group>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>固定 Header</span>
|
||||
<span class="comp-style">
|
||||
<el-switch v-model="settingsStore.fixedHeader" class="drawer-switch" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>显示 Logo</span>
|
||||
<span class="comp-style">
|
||||
<el-switch v-model="settingsStore.sidebarLogo" class="drawer-switch" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>动态标题</span>
|
||||
<span class="comp-style">
|
||||
<el-switch v-model="settingsStore.dynamicTitle" @change="dynamicTitleChange" class="drawer-switch" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>底部版权</span>
|
||||
<span class="comp-style">
|
||||
<el-switch v-model="settingsStore.footerVisible" class="drawer-switch" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<el-divider />
|
||||
|
||||
<el-button type="primary" plain icon="DocumentAdd" @click="saveSetting">保存配置</el-button>
|
||||
<el-button plain icon="Refresh" @click="resetSetting">重置配置</el-button>
|
||||
</el-drawer>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import useAppStore from '@/store/modules/app'
|
||||
import useSettingsStore from '@/store/modules/settings'
|
||||
import usePermissionStore from '@/store/modules/permission'
|
||||
import { handleThemeStyle } from '@/utils/theme'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const appStore = useAppStore()
|
||||
const settingsStore = useSettingsStore()
|
||||
const permissionStore = usePermissionStore()
|
||||
const showSettings = ref(false)
|
||||
const navType = ref(settingsStore.navType)
|
||||
const theme = ref(settingsStore.theme)
|
||||
const sideTheme = ref(settingsStore.sideTheme)
|
||||
const tagsViewPersist = ref(settingsStore.tagsViewPersist)
|
||||
const storeSettings = computed(() => settingsStore)
|
||||
const predefineColors = ref(["#409EFF", "#ff4500", "#ff8c00", "#ffd700", "#90ee90", "#00ced1", "#1e90ff", "#c71585"])
|
||||
|
||||
/** 是否需要dynamicTitle */
|
||||
function dynamicTitleChange() {
|
||||
useSettingsStore().setTitle(useSettingsStore().title)
|
||||
}
|
||||
|
||||
function tagsViewPersistChange(val) {
|
||||
settingsStore.tagsViewPersist = val
|
||||
tagsViewPersist.value = val
|
||||
}
|
||||
|
||||
function themeChange(val) {
|
||||
settingsStore.theme = val
|
||||
handleThemeStyle(val)
|
||||
}
|
||||
|
||||
function handleTheme(val) {
|
||||
settingsStore.sideTheme = val
|
||||
sideTheme.value = val
|
||||
}
|
||||
|
||||
function handleNavType(val) {
|
||||
settingsStore.navType = val
|
||||
navType.value = val
|
||||
}
|
||||
|
||||
/** 菜单导航设置 */
|
||||
watch(() => navType, val => {
|
||||
if (val.value == 1) {
|
||||
appStore.sidebar.opened = true
|
||||
appStore.toggleSideBarHide(false)
|
||||
}
|
||||
if (val.value == 2) {
|
||||
appStore.sidebar.opened = true
|
||||
}
|
||||
if (val.value == 3) {
|
||||
appStore.sidebar.opened = false
|
||||
appStore.toggleSideBarHide(true)
|
||||
}
|
||||
if ([1, 3].includes(val.value)) {
|
||||
permissionStore.setSidebarRouters(permissionStore.defaultRoutes)
|
||||
}
|
||||
}, { immediate: true, deep: true }
|
||||
)
|
||||
|
||||
function saveSetting() {
|
||||
proxy.$modal.loading("正在保存到本地,请稍候...")
|
||||
if (!tagsViewPersist.value) {
|
||||
proxy.$cache.local.remove('tags-view-visited')
|
||||
}
|
||||
let layoutSetting = {
|
||||
"navType": storeSettings.value.navType,
|
||||
"tagsView": storeSettings.value.tagsView,
|
||||
"tagsIcon": storeSettings.value.tagsIcon,
|
||||
"tagsViewStyle": storeSettings.value.tagsViewStyle,
|
||||
"tagsViewPersist": storeSettings.value.tagsViewPersist,
|
||||
"fixedHeader": storeSettings.value.fixedHeader,
|
||||
"sidebarLogo": storeSettings.value.sidebarLogo,
|
||||
"dynamicTitle": storeSettings.value.dynamicTitle,
|
||||
"footerVisible": storeSettings.value.footerVisible,
|
||||
"sideTheme": storeSettings.value.sideTheme,
|
||||
"theme": storeSettings.value.theme
|
||||
}
|
||||
localStorage.setItem("layout-setting", JSON.stringify(layoutSetting))
|
||||
setTimeout(proxy.$modal.closeLoading(), 1000)
|
||||
}
|
||||
|
||||
function resetSetting() {
|
||||
proxy.$cache.local.remove('tags-view-visited')
|
||||
proxy.$modal.loading("正在清除设置缓存并刷新,请稍候...")
|
||||
localStorage.removeItem("layout-setting")
|
||||
setTimeout("window.location.reload()", 1000)
|
||||
}
|
||||
|
||||
function openSetting() {
|
||||
showSettings.value = true
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
openSetting
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
.setting-drawer-title {
|
||||
margin-bottom: 12px;
|
||||
color: var(--el-text-color-primary, rgba(0, 0, 0, 0.85));
|
||||
line-height: 22px;
|
||||
font-weight: bold;
|
||||
|
||||
.drawer-title {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.setting-drawer-block-checbox {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.setting-drawer-block-checbox-item {
|
||||
position: relative;
|
||||
margin-right: 16px;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
|
||||
img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.setting-drawer-block-checbox-selectIcon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-top: 15px;
|
||||
padding-left: 24px;
|
||||
color: #1890ff;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.drawer-item {
|
||||
color: var(--el-text-color-regular, rgba(0, 0, 0, 0.65));
|
||||
padding: 12px 0;
|
||||
font-size: 14px;
|
||||
|
||||
.comp-style {
|
||||
float: right;
|
||||
margin: -3px 8px 0px 0px;
|
||||
}
|
||||
}
|
||||
|
||||
// 导航模式
|
||||
.nav-wrap {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.activeItem {
|
||||
border: 2px solid var(--el-color-primary) !important;
|
||||
}
|
||||
|
||||
.item {
|
||||
position: relative;
|
||||
margin-right: 16px;
|
||||
cursor: pointer;
|
||||
width: 56px;
|
||||
height: 48px;
|
||||
border-radius: 4px;
|
||||
background: #f0f2f5;
|
||||
border: 2px solid transparent;
|
||||
}
|
||||
|
||||
.left {
|
||||
b:first-child {
|
||||
display: block;
|
||||
height: 30%;
|
||||
background: #fff;
|
||||
}
|
||||
b:last-child {
|
||||
width: 30%;
|
||||
background: #1b2a47;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
}
|
||||
.mix {
|
||||
b:first-child {
|
||||
border-radius: 4px 4px 0 0;
|
||||
display: block;
|
||||
height: 30%;
|
||||
background: #1b2a47;
|
||||
}
|
||||
b:last-child {
|
||||
width: 30%;
|
||||
background: #1b2a47;
|
||||
position: absolute;
|
||||
height: 70%;
|
||||
border-radius: 0 0 0 4px;
|
||||
}
|
||||
}
|
||||
.top {
|
||||
b:first-child {
|
||||
display: block;
|
||||
height: 30%;
|
||||
background: #1b2a47;
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
<template>
|
||||
<el-drawer v-model="showSettings" :withHeader="false" :lock-scroll="false" direction="rtl" size="300px">
|
||||
<div class="setting-drawer-title">
|
||||
<h3 class="drawer-title">菜单导航设置</h3>
|
||||
</div>
|
||||
<div class="nav-wrap">
|
||||
<el-tooltip content="左侧菜单" placement="bottom">
|
||||
<div class="item left" @click="handleNavType(1)" :class="{ activeItem: navType == 1 }">
|
||||
<b></b><b></b>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
|
||||
<el-tooltip content="混合菜单" placement="bottom">
|
||||
<div class="item mix" @click="handleNavType(2)" :class="{ activeItem: navType == 2 }">
|
||||
<b></b><b></b>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="顶部菜单" placement="bottom">
|
||||
<div class="item top" @click="handleNavType(3)" :class="{ activeItem: navType == 3 }">
|
||||
<b></b><b></b>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="setting-drawer-title">
|
||||
<h3 class="drawer-title">主题风格设置</h3>
|
||||
</div>
|
||||
<div class="setting-drawer-block-checbox">
|
||||
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-dark')">
|
||||
<img src="@/assets/images/dark.svg" alt="dark" />
|
||||
<div v-if="sideTheme === 'theme-dark'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
|
||||
<i aria-label="图标: check" class="anticon anticon-check">
|
||||
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class>
|
||||
<path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" />
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-drawer-block-checbox-item" @click="handleTheme('theme-light')">
|
||||
<img src="@/assets/images/light.svg" alt="light" />
|
||||
<div v-if="sideTheme === 'theme-light'" class="setting-drawer-block-checbox-selectIcon" style="display: block;">
|
||||
<i aria-label="图标: check" class="anticon anticon-check">
|
||||
<svg viewBox="64 64 896 896" data-icon="check" width="1em" height="1em" :fill="theme" aria-hidden="true" focusable="false" class>
|
||||
<path d="M912 190h-69.9c-9.8 0-19.1 4.5-25.1 12.2L404.7 724.5 207 474a32 32 0 0 0-25.1-12.2H112c-6.7 0-10.4 7.7-6.3 12.9l273.9 347c12.8 16.2 37.4 16.2 50.3 0l488.4-618.9c4.1-5.1.4-12.8-6.3-12.8z" />
|
||||
</svg>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="drawer-item">
|
||||
<span>主题颜色</span>
|
||||
<span class="comp-style">
|
||||
<el-color-picker v-model="theme" :predefine="predefineColors" @change="themeChange"/>
|
||||
</span>
|
||||
</div>
|
||||
<el-divider />
|
||||
|
||||
<h3 class="drawer-title">系统布局配置</h3>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>开启页签</span>
|
||||
<span class="comp-style">
|
||||
<el-switch v-model="settingsStore.tagsView" class="drawer-switch" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>持久化标签页</span>
|
||||
<span class="comp-style">
|
||||
<el-switch v-model="settingsStore.tagsViewPersist" :disabled="!settingsStore.tagsView" @change="tagsViewPersistChange" class="drawer-switch" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>显示页签图标</span>
|
||||
<span class="comp-style">
|
||||
<el-switch v-model="settingsStore.tagsIcon" :disabled="!settingsStore.tagsView" class="drawer-switch" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>标签页样式</span>
|
||||
<span class="comp-style">
|
||||
<el-radio-group v-model="settingsStore.tagsViewStyle" :disabled="!settingsStore.tagsView" size="small">
|
||||
<el-radio-button label="card">卡片</el-radio-button>
|
||||
<el-radio-button label="chrome">谷歌</el-radio-button>
|
||||
</el-radio-group>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>固定 Header</span>
|
||||
<span class="comp-style">
|
||||
<el-switch v-model="settingsStore.fixedHeader" class="drawer-switch" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>显示 Logo</span>
|
||||
<span class="comp-style">
|
||||
<el-switch v-model="settingsStore.sidebarLogo" class="drawer-switch" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>动态标题</span>
|
||||
<span class="comp-style">
|
||||
<el-switch v-model="settingsStore.dynamicTitle" @change="dynamicTitleChange" class="drawer-switch" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>底部版权</span>
|
||||
<span class="comp-style">
|
||||
<el-switch v-model="settingsStore.footerVisible" class="drawer-switch" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<el-divider />
|
||||
|
||||
<el-button type="primary" plain icon="DocumentAdd" @click="saveSetting">保存配置</el-button>
|
||||
<el-button plain icon="Refresh" @click="resetSetting">重置配置</el-button>
|
||||
</el-drawer>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import useAppStore from '@/store/modules/app'
|
||||
import useSettingsStore from '@/store/modules/settings'
|
||||
import usePermissionStore from '@/store/modules/permission'
|
||||
import { handleThemeStyle } from '@/utils/theme'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const appStore = useAppStore()
|
||||
const settingsStore = useSettingsStore()
|
||||
const permissionStore = usePermissionStore()
|
||||
const showSettings = ref(false)
|
||||
const navType = ref(settingsStore.navType)
|
||||
const theme = ref(settingsStore.theme)
|
||||
const sideTheme = ref(settingsStore.sideTheme)
|
||||
const tagsViewPersist = ref(settingsStore.tagsViewPersist)
|
||||
const storeSettings = computed(() => settingsStore)
|
||||
const predefineColors = ref(["#409EFF", "#ff4500", "#ff8c00", "#ffd700", "#90ee90", "#00ced1", "#1e90ff", "#c71585"])
|
||||
|
||||
/** 是否需要dynamicTitle */
|
||||
function dynamicTitleChange() {
|
||||
useSettingsStore().setTitle(useSettingsStore().title)
|
||||
}
|
||||
|
||||
function tagsViewPersistChange(val) {
|
||||
settingsStore.tagsViewPersist = val
|
||||
tagsViewPersist.value = val
|
||||
}
|
||||
|
||||
function themeChange(val) {
|
||||
settingsStore.theme = val
|
||||
handleThemeStyle(val)
|
||||
}
|
||||
|
||||
function handleTheme(val) {
|
||||
settingsStore.sideTheme = val
|
||||
sideTheme.value = val
|
||||
}
|
||||
|
||||
function handleNavType(val) {
|
||||
settingsStore.navType = val
|
||||
navType.value = val
|
||||
}
|
||||
|
||||
/** 菜单导航设置 */
|
||||
watch(() => navType, val => {
|
||||
if (val.value == 1) {
|
||||
appStore.sidebar.opened = true
|
||||
appStore.toggleSideBarHide(false)
|
||||
}
|
||||
if (val.value == 2) {
|
||||
appStore.sidebar.opened = true
|
||||
}
|
||||
if (val.value == 3) {
|
||||
appStore.sidebar.opened = false
|
||||
appStore.toggleSideBarHide(true)
|
||||
}
|
||||
if ([1, 3].includes(val.value)) {
|
||||
permissionStore.setSidebarRouters(permissionStore.defaultRoutes)
|
||||
}
|
||||
}, { immediate: true, deep: true }
|
||||
)
|
||||
|
||||
function saveSetting() {
|
||||
proxy.$modal.loading("正在保存到本地,请稍候...")
|
||||
if (!tagsViewPersist.value) {
|
||||
proxy.$cache.local.remove('tags-view-visited')
|
||||
}
|
||||
let layoutSetting = {
|
||||
"navType": storeSettings.value.navType,
|
||||
"tagsView": storeSettings.value.tagsView,
|
||||
"tagsIcon": storeSettings.value.tagsIcon,
|
||||
"tagsViewStyle": storeSettings.value.tagsViewStyle,
|
||||
"tagsViewPersist": storeSettings.value.tagsViewPersist,
|
||||
"fixedHeader": storeSettings.value.fixedHeader,
|
||||
"sidebarLogo": storeSettings.value.sidebarLogo,
|
||||
"dynamicTitle": storeSettings.value.dynamicTitle,
|
||||
"footerVisible": storeSettings.value.footerVisible,
|
||||
"sideTheme": storeSettings.value.sideTheme,
|
||||
"theme": storeSettings.value.theme
|
||||
}
|
||||
localStorage.setItem("layout-setting", JSON.stringify(layoutSetting))
|
||||
setTimeout(proxy.$modal.closeLoading(), 1000)
|
||||
}
|
||||
|
||||
function resetSetting() {
|
||||
proxy.$cache.local.remove('tags-view-visited')
|
||||
proxy.$modal.loading("正在清除设置缓存并刷新,请稍候...")
|
||||
localStorage.removeItem("layout-setting")
|
||||
setTimeout("window.location.reload()", 1000)
|
||||
}
|
||||
|
||||
function openSetting() {
|
||||
showSettings.value = true
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
openSetting
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang='scss' scoped>
|
||||
.setting-drawer-title {
|
||||
margin-bottom: 12px;
|
||||
color: var(--el-text-color-primary, rgba(0, 0, 0, 0.85));
|
||||
line-height: 22px;
|
||||
font-weight: bold;
|
||||
|
||||
.drawer-title {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.setting-drawer-block-checbox {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.setting-drawer-block-checbox-item {
|
||||
position: relative;
|
||||
margin-right: 16px;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
|
||||
img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.setting-drawer-block-checbox-selectIcon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-top: 15px;
|
||||
padding-left: 24px;
|
||||
color: #1890ff;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.drawer-item {
|
||||
color: var(--el-text-color-regular, rgba(0, 0, 0, 0.65));
|
||||
padding: 12px 0;
|
||||
font-size: 14px;
|
||||
|
||||
.comp-style {
|
||||
float: right;
|
||||
margin: -3px 8px 0px 0px;
|
||||
}
|
||||
}
|
||||
|
||||
// 导航模式
|
||||
.nav-wrap {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.activeItem {
|
||||
border: 2px solid var(--el-color-primary) !important;
|
||||
}
|
||||
|
||||
.item {
|
||||
position: relative;
|
||||
margin-right: 16px;
|
||||
cursor: pointer;
|
||||
width: 56px;
|
||||
height: 48px;
|
||||
border-radius: 4px;
|
||||
background: #f0f2f5;
|
||||
border: 2px solid transparent;
|
||||
}
|
||||
|
||||
.left {
|
||||
b:first-child {
|
||||
display: block;
|
||||
height: 30%;
|
||||
background: #fff;
|
||||
}
|
||||
b:last-child {
|
||||
width: 30%;
|
||||
background: #1b2a47;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
}
|
||||
.mix {
|
||||
b:first-child {
|
||||
border-radius: 4px 4px 0 0;
|
||||
display: block;
|
||||
height: 30%;
|
||||
background: #1b2a47;
|
||||
}
|
||||
b:last-child {
|
||||
width: 30%;
|
||||
background: #1b2a47;
|
||||
position: absolute;
|
||||
height: 70%;
|
||||
border-radius: 0 0 0 4px;
|
||||
}
|
||||
}
|
||||
.top {
|
||||
b:first-child {
|
||||
display: block;
|
||||
height: 30%;
|
||||
background: #1b2a47;
|
||||
border-radius: 4px 4px 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
+67
-67
@@ -1,67 +1,67 @@
|
||||
export default {
|
||||
/**
|
||||
* 网页标题
|
||||
*/
|
||||
title: import.meta.env.VITE_APP_TITLE,
|
||||
|
||||
/**
|
||||
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
||||
*/
|
||||
sideTheme: 'theme-dark',
|
||||
|
||||
/**
|
||||
* 是否系统布局配置
|
||||
*/
|
||||
showSettings: true,
|
||||
|
||||
/**
|
||||
* 菜单导航模式 1、纯左侧 2、混合(左侧+顶部) 3、纯顶部
|
||||
*/
|
||||
navType: 1,
|
||||
|
||||
/**
|
||||
* 是否显示 tagsView
|
||||
*/
|
||||
tagsView: true,
|
||||
|
||||
/**
|
||||
* 持久化标签页
|
||||
*/
|
||||
tagsViewPersist: false,
|
||||
|
||||
/**
|
||||
* 显示页签图标
|
||||
*/
|
||||
tagsIcon: false,
|
||||
|
||||
/**
|
||||
* 标签页样式:card 卡片(默认)、chrome 谷歌浏览器风格
|
||||
*/
|
||||
tagsViewStyle: 'card',
|
||||
|
||||
/**
|
||||
* 是否固定头部
|
||||
*/
|
||||
fixedHeader: true,
|
||||
|
||||
/**
|
||||
* 是否显示logo
|
||||
*/
|
||||
sidebarLogo: true,
|
||||
|
||||
/**
|
||||
* 是否显示动态标题
|
||||
*/
|
||||
dynamicTitle: false,
|
||||
|
||||
/**
|
||||
* 是否显示底部版权
|
||||
*/
|
||||
footerVisible: false,
|
||||
|
||||
/**
|
||||
* 底部版权文本内容
|
||||
*/
|
||||
footerContent: 'Copyright © 2018-2026 RuoYi. All Rights Reserved.'
|
||||
}
|
||||
|
||||
export default {
|
||||
/**
|
||||
* 网页标题
|
||||
*/
|
||||
title: import.meta.env.VITE_APP_TITLE,
|
||||
|
||||
/**
|
||||
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
||||
*/
|
||||
sideTheme: 'theme-dark',
|
||||
|
||||
/**
|
||||
* 是否系统布局配置
|
||||
*/
|
||||
showSettings: true,
|
||||
|
||||
/**
|
||||
* 菜单导航模式 1、纯左侧 2、混合(左侧+顶部) 3、纯顶部
|
||||
*/
|
||||
navType: 1,
|
||||
|
||||
/**
|
||||
* 是否显示 tagsView
|
||||
*/
|
||||
tagsView: true,
|
||||
|
||||
/**
|
||||
* 持久化标签页
|
||||
*/
|
||||
tagsViewPersist: false,
|
||||
|
||||
/**
|
||||
* 显示页签图标
|
||||
*/
|
||||
tagsIcon: false,
|
||||
|
||||
/**
|
||||
* 标签页样式:card 卡片(默认)、chrome 谷歌浏览器风格
|
||||
*/
|
||||
tagsViewStyle: 'card',
|
||||
|
||||
/**
|
||||
* 是否固定头部
|
||||
*/
|
||||
fixedHeader: true,
|
||||
|
||||
/**
|
||||
* 是否显示logo
|
||||
*/
|
||||
sidebarLogo: true,
|
||||
|
||||
/**
|
||||
* 是否显示动态标题
|
||||
*/
|
||||
dynamicTitle: false,
|
||||
|
||||
/**
|
||||
* 是否显示底部版权
|
||||
*/
|
||||
footerVisible: false,
|
||||
|
||||
/**
|
||||
* 底部版权文本内容
|
||||
*/
|
||||
footerContent: 'Copyright © 2018-2026 RuoYi. All Rights Reserved.'
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user