refactor: remove project settings panel
This commit is contained in:
+2
-8
@@ -3,18 +3,13 @@ package com.agileboot.common.enums.common;
|
|||||||
import com.agileboot.common.enums.BasicEnum;
|
import com.agileboot.common.enums.BasicEnum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统配置
|
* 系统配置,对应 sys_config 表的 config_key 字段。
|
||||||
|
*
|
||||||
* @author valarchie
|
* @author valarchie
|
||||||
* 对应 sys_config表的config_key字段
|
|
||||||
*/
|
*/
|
||||||
public enum ConfigKeyEnum implements BasicEnum<String> {
|
public enum ConfigKeyEnum implements BasicEnum<String> {
|
||||||
|
|
||||||
/**
|
|
||||||
* 菜单类型
|
|
||||||
*/
|
|
||||||
SKIN_THEME("sys.index.skinName", "系统皮肤主题"),
|
|
||||||
INIT_PASSWORD("sys.user.initPassword", "初始密码"),
|
INIT_PASSWORD("sys.user.initPassword", "初始密码"),
|
||||||
SIDE_BAR_THEME("sys.index.sideTheme", "侧边栏开关"),
|
|
||||||
CAPTCHA("sys.account.captchaOnOff", "验证码开关"),
|
CAPTCHA("sys.account.captchaOnOff", "验证码开关"),
|
||||||
REGISTER("sys.account.registerUser", "注册开放功能");
|
REGISTER("sys.account.registerUser", "注册开放功能");
|
||||||
|
|
||||||
@@ -36,5 +31,4 @@ public enum ConfigKeyEnum implements BasicEnum<String> {
|
|||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,7 @@ Date: 2022-10-07 16:05:40
|
|||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
-- Records of sys_config
|
-- Records of sys_config
|
||||||
-- ----------------------------
|
-- ----------------------------
|
||||||
INSERT INTO `sys_config` VALUES ('1', '主框架页-默认皮肤样式名称', 'sys.index.skinName', '["skin-blue","skin-green","skin-purple","skin-red","skin-yellow"]', 'skin-blue', '1', null, null, '2022-08-28 22:12:19', '2022-05-21 08:30:55', '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow', '0');
|
|
||||||
INSERT INTO `sys_config` VALUES ('2', '用户管理-账号初始密码', 'sys.user.initPassword', '', '1234567', '1', null, null, '2022-08-28 21:54:19', '2022-05-21 08:30:55', '初始化密码 123456', '0');
|
INSERT INTO `sys_config` VALUES ('2', '用户管理-账号初始密码', 'sys.user.initPassword', '', '1234567', '1', null, null, '2022-08-28 21:54:19', '2022-05-21 08:30:55', '初始化密码 123456', '0');
|
||||||
INSERT INTO `sys_config` VALUES ('3', '主框架页-侧边栏主题', 'sys.index.sideTheme', '["theme-dark","theme-light"]', 'theme-dark', '1', null, null, '2022-08-28 22:12:15', '2022-08-20 08:30:55', '深色主题theme-dark,浅色主题theme-light', '0');
|
|
||||||
INSERT INTO `sys_config` VALUES ('4', '账号自助-验证码开关', 'sys.account.captchaOnOff', '["true","false"]', 'false', '0', null, null, '2022-08-28 22:03:37', '2022-05-21 08:30:55', '是否开启验证码功能(true开启,false关闭)', '0');
|
INSERT INTO `sys_config` VALUES ('4', '账号自助-验证码开关', 'sys.account.captchaOnOff', '["true","false"]', 'false', '0', null, null, '2022-08-28 22:03:37', '2022-05-21 08:30:55', '是否开启验证码功能(true开启,false关闭)', '0');
|
||||||
INSERT INTO `sys_config` VALUES ('5', '账号自助-是否开启用户注册功能', 'sys.account.registerUser', '["true","false"]', 'true', '0', null, '1', '2022-10-05 22:18:57', '2022-05-21 08:30:55', '是否开启注册用户功能(true开启,false关闭)', '0');
|
INSERT INTO `sys_config` VALUES ('5', '账号自助-是否开启用户注册功能', 'sys.account.registerUser', '["true","false"]', 'true', '0', null, '1', '2022-10-05 22:18:57', '2022-05-21 08:30:55', '是否开启注册用户功能(true开启,false关闭)', '0');
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
INSERT INTO app.sys_config (config_id, config_name, config_key, config_options, config_value, is_allow_change, creator_id, updater_id, update_time, create_time, remark, deleted) VALUES (1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', '["skin-blue","skin-green","skin-purple","skin-red","skin-yellow"]', 'skin-blue', true, null, null, '2022-08-28 22:12:19', '2022-05-21 08:30:55', '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow', 0);
|
|
||||||
INSERT INTO app.sys_config (config_id, config_name, config_key, config_options, config_value, is_allow_change, creator_id, updater_id, update_time, create_time, remark, deleted) VALUES (2, '用户管理-账号初始密码', 'sys.user.initPassword', '', '123456', true, null, 1, '2023-07-20 14:42:08', '2022-05-21 08:30:55', '初始化密码 123456', 0);
|
INSERT INTO app.sys_config (config_id, config_name, config_key, config_options, config_value, is_allow_change, creator_id, updater_id, update_time, create_time, remark, deleted) VALUES (2, '用户管理-账号初始密码', 'sys.user.initPassword', '', '123456', true, null, 1, '2023-07-20 14:42:08', '2022-05-21 08:30:55', '初始化密码 123456', 0);
|
||||||
INSERT INTO app.sys_config (config_id, config_name, config_key, config_options, config_value, is_allow_change, creator_id, updater_id, update_time, create_time, remark, deleted) VALUES (3, '主框架页-侧边栏主题', 'sys.index.sideTheme', '["theme-dark","theme-light"]', 'theme-dark', true, null, null, '2022-08-28 22:12:15', '2022-08-20 08:30:55', '深色主题theme-dark,浅色主题theme-light', 0);
|
|
||||||
INSERT INTO app.sys_config (config_id, config_name, config_key, config_options, config_value, is_allow_change, creator_id, updater_id, update_time, create_time, remark, deleted) VALUES (4, '账号自助-验证码开关', 'sys.account.captchaOnOff', '["true","false"]', 'false', false, null, 1, '2023-07-20 14:39:36', '2022-05-21 08:30:55', '是否开启验证码功能(true开启,false关闭)', 0);
|
INSERT INTO app.sys_config (config_id, config_name, config_key, config_options, config_value, is_allow_change, creator_id, updater_id, update_time, create_time, remark, deleted) VALUES (4, '账号自助-验证码开关', 'sys.account.captchaOnOff', '["true","false"]', 'false', false, null, 1, '2023-07-20 14:39:36', '2022-05-21 08:30:55', '是否开启验证码功能(true开启,false关闭)', 0);
|
||||||
INSERT INTO app.sys_config (config_id, config_name, config_key, config_options, config_value, is_allow_change, creator_id, updater_id, update_time, create_time, remark, deleted) VALUES (5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', '["true","false"]', 'true', false, null, 1, '2022-10-05 22:18:57', '2022-05-21 08:30:55', '是否开启注册用户功能(true开启,false关闭)', 0);
|
INSERT INTO app.sys_config (config_id, config_name, config_key, config_options, config_value, is_allow_change, creator_id, updater_id, update_time, create_time, remark, deleted) VALUES (5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', '["true","false"]', 'true', false, null, 1, '2022-10-05 22:18:57', '2022-05-21 08:30:55', '是否开启注册用户功能(true开启,false关闭)', 0);
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ create table sys_config
|
|||||||
)
|
)
|
||||||
comment '参数配置表';
|
comment '参数配置表';
|
||||||
|
|
||||||
INSERT INTO sys_config (config_id, config_name, config_key, config_options, config_value, is_allow_change, creator_id, updater_id, update_time, create_time, remark, deleted) VALUES (1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', '["skin-blue","skin-green","skin-purple","skin-red","skin-yellow"]', 'skin-blue', 1, null, null, '2022-08-28 22:12:19', '2022-05-21 08:30:55', '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow', 0);
|
|
||||||
INSERT INTO sys_config (config_id, config_name, config_key, config_options, config_value, is_allow_change, creator_id, updater_id, update_time, create_time, remark, deleted) VALUES (2, '用户管理-账号初始密码', 'sys.user.initPassword', '', '123456', 1, null, 1, '2023-07-20 14:42:08', '2022-05-21 08:30:55', '初始化密码 123456', 0);
|
INSERT INTO sys_config (config_id, config_name, config_key, config_options, config_value, is_allow_change, creator_id, updater_id, update_time, create_time, remark, deleted) VALUES (2, '用户管理-账号初始密码', 'sys.user.initPassword', '', '123456', 1, null, 1, '2023-07-20 14:42:08', '2022-05-21 08:30:55', '初始化密码 123456', 0);
|
||||||
INSERT INTO sys_config (config_id, config_name, config_key, config_options, config_value, is_allow_change, creator_id, updater_id, update_time, create_time, remark, deleted) VALUES (3, '主框架页-侧边栏主题', 'sys.index.sideTheme', '["theme-dark","theme-light"]', 'theme-dark', 1, null, null, '2022-08-28 22:12:15', '2022-08-20 08:30:55', '深色主题theme-dark,浅色主题theme-light', 0);
|
|
||||||
INSERT INTO sys_config (config_id, config_name, config_key, config_options, config_value, is_allow_change, creator_id, updater_id, update_time, create_time, remark, deleted) VALUES (4, '账号自助-验证码开关', 'sys.account.captchaOnOff', '["true","false"]', 'false', 0, null, 1, '2023-07-20 14:39:36', '2022-05-21 08:30:55', '是否开启验证码功能(true开启,false关闭)', 0);
|
INSERT INTO sys_config (config_id, config_name, config_key, config_options, config_value, is_allow_change, creator_id, updater_id, update_time, create_time, remark, deleted) VALUES (4, '账号自助-验证码开关', 'sys.account.captchaOnOff', '["true","false"]', 'false', 0, null, 1, '2023-07-20 14:39:36', '2022-05-21 08:30:55', '是否开启验证码功能(true开启,false关闭)', 0);
|
||||||
INSERT INTO sys_config (config_id, config_name, config_key, config_options, config_value, is_allow_change, creator_id, updater_id, update_time, create_time, remark, deleted) VALUES (5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', '["true","false"]', 'true', 0, null, 1, '2022-10-05 22:18:57', '2022-05-21 08:30:55', '是否开启注册用户功能(true开启,false关闭)', 0);
|
INSERT INTO sys_config (config_id, config_name, config_key, config_options, config_value, is_allow_change, creator_id, updater_id, update_time, create_time, remark, deleted) VALUES (5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', '["true","false"]', 'true', 0, null, 1, '2022-10-05 22:18:57', '2022-05-21 08:30:55', '是否开启注册用户功能(true开启,false关闭)', 0);
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "NODE_OPTIONS=--max-old-space-size=4096 vite",
|
"dev": "vite",
|
||||||
"serve": "pnpm dev",
|
"serve": "pnpm dev",
|
||||||
"build": "rimraf dist && NODE_OPTIONS=--max-old-space-size=8192 vite build",
|
"build": "rimraf dist && NODE_OPTIONS=--max-old-space-size=8192 vite build",
|
||||||
"build:staging": "rimraf dist && vite build --mode staging",
|
"build:staging": "rimraf dist && vite build --mode staging",
|
||||||
|
|||||||
@@ -8,13 +8,8 @@
|
|||||||
"Layout": "vertical",
|
"Layout": "vertical",
|
||||||
"Theme": "default",
|
"Theme": "default",
|
||||||
"DarkMode": false,
|
"DarkMode": false,
|
||||||
"Grey": false,
|
|
||||||
"Weak": false,
|
|
||||||
"HideTabs": false,
|
|
||||||
"SidebarStatus": true,
|
"SidebarStatus": true,
|
||||||
"EpThemeColor": "#409EFF",
|
"EpThemeColor": "#409EFF",
|
||||||
"ShowLogo": true,
|
|
||||||
"ShowModel": "smart",
|
|
||||||
"MenuArrowIconNoTransition": true,
|
"MenuArrowIconNoTransition": true,
|
||||||
"CachingAsyncRoutes": false,
|
"CachingAsyncRoutes": false,
|
||||||
"TooltipEffect": "light",
|
"TooltipEffect": "light",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const props = defineProps({
|
|||||||
fixedHeader: Boolean
|
fixedHeader: Boolean
|
||||||
});
|
});
|
||||||
|
|
||||||
const { $storage, $config } = useGlobal<GlobalPropertiesApi>();
|
const { $config } = useGlobal<GlobalPropertiesApi>();
|
||||||
|
|
||||||
const keepAlive = computed(() => {
|
const keepAlive = computed(() => {
|
||||||
return $config?.KeepAlive;
|
return $config?.KeepAlive;
|
||||||
@@ -20,22 +20,8 @@ const transitions = computed(() => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const hideTabs = computed(() => {
|
|
||||||
return $storage?.configure.hideTabs;
|
|
||||||
});
|
|
||||||
|
|
||||||
const layout = computed(() => {
|
|
||||||
return $storage?.layout.layout === "vertical";
|
|
||||||
});
|
|
||||||
|
|
||||||
const getSectionStyle = computed(() => {
|
const getSectionStyle = computed(() => {
|
||||||
return [
|
return ["padding-top: 85px;", props.fixedHeader ? "" : "padding-top: 0;"];
|
||||||
hideTabs.value && layout ? "padding-top: 48px;" : "",
|
|
||||||
!hideTabs.value && layout ? "padding-top: 85px;" : "",
|
|
||||||
hideTabs.value && !layout.value ? "padding-top: 48px" : "",
|
|
||||||
!hideTabs.value && !layout.value ? "padding-top: 85px;" : "",
|
|
||||||
props.fixedHeader ? "" : "padding-top: 0;"
|
|
||||||
];
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const transitionMain = defineComponent({
|
const transitionMain = defineComponent({
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
|
||||||
|
|
||||||
|
import dayIcon from "@/assets/svg/day.svg?component";
|
||||||
|
import darkIcon from "@/assets/svg/dark.svg?component";
|
||||||
|
|
||||||
|
const { dataTheme, dataThemeChange } = useDataThemeChange();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<span class="header-dark-switch navbar-bg-hover" title="切换暗黑模式">
|
||||||
|
<el-switch
|
||||||
|
v-model="dataTheme"
|
||||||
|
inline-prompt
|
||||||
|
:active-icon="dayIcon"
|
||||||
|
:inactive-icon="darkIcon"
|
||||||
|
@change="dataThemeChange"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.header-dark-switch {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 48px;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -2,18 +2,17 @@
|
|||||||
import Search from "./search/index.vue";
|
import Search from "./search/index.vue";
|
||||||
import Notice from "./notice/index.vue";
|
import Notice from "./notice/index.vue";
|
||||||
import mixNav from "./sidebar/mixNav.vue";
|
import mixNav from "./sidebar/mixNav.vue";
|
||||||
|
import HeaderDarkSwitch from "./headerDarkSwitch.vue";
|
||||||
import { useNav } from "@/layout/hooks/useNav";
|
import { useNav } from "@/layout/hooks/useNav";
|
||||||
import Breadcrumb from "./sidebar/breadCrumb.vue";
|
import Breadcrumb from "./sidebar/breadCrumb.vue";
|
||||||
import topCollapse from "./sidebar/topCollapse.vue";
|
import topCollapse from "./sidebar/topCollapse.vue";
|
||||||
import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
|
import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
|
||||||
import Setting from "@iconify-icons/ri/settings-3-line";
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
layout,
|
layout,
|
||||||
device,
|
device,
|
||||||
logout,
|
logout,
|
||||||
userProfile,
|
userProfile,
|
||||||
onPanel,
|
|
||||||
pureApp,
|
pureApp,
|
||||||
username,
|
username,
|
||||||
userAvatar,
|
userAvatar,
|
||||||
@@ -41,11 +40,9 @@ const {
|
|||||||
<mixNav v-if="layout === 'mix'" />
|
<mixNav v-if="layout === 'mix'" />
|
||||||
|
|
||||||
<div v-if="layout === 'vertical'" class="vertical-header-right">
|
<div v-if="layout === 'vertical'" class="vertical-header-right">
|
||||||
<!-- 菜单搜索 -->
|
|
||||||
<Search />
|
<Search />
|
||||||
<!-- 通知 -->
|
|
||||||
<Notice id="header-notice" />
|
<Notice id="header-notice" />
|
||||||
<!-- 退出登录 -->
|
<HeaderDarkSwitch />
|
||||||
<el-dropdown trigger="click">
|
<el-dropdown trigger="click">
|
||||||
<span class="el-dropdown-link navbar-bg-hover select-none">
|
<span class="el-dropdown-link navbar-bg-hover select-none">
|
||||||
<img :src="userAvatar" :style="avatarsStyle" />
|
<img :src="userAvatar" :style="avatarsStyle" />
|
||||||
@@ -72,13 +69,6 @@ const {
|
|||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
<span
|
|
||||||
class="set-icon navbar-bg-hover"
|
|
||||||
title="打开项目配置"
|
|
||||||
@click="onPanel"
|
|
||||||
>
|
|
||||||
<IconifyIconOffline :icon="Setting" />
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,158 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { emitter } from "@/utils/mitt";
|
|
||||||
import { onClickOutside } from "@vueuse/core";
|
|
||||||
import { ref, computed, onMounted, onBeforeUnmount } from "vue";
|
|
||||||
import Close from "@iconify-icons/ep/close";
|
|
||||||
|
|
||||||
const target = ref(null);
|
|
||||||
const show = ref<Boolean>(false);
|
|
||||||
|
|
||||||
const iconClass = computed(() => {
|
|
||||||
return [
|
|
||||||
"mr-[20px]",
|
|
||||||
"outline-none",
|
|
||||||
"width-[20px]",
|
|
||||||
"height-[20px]",
|
|
||||||
"rounded-[4px]",
|
|
||||||
"cursor-pointer",
|
|
||||||
"transition-colors",
|
|
||||||
"hover:bg-[#0000000f]",
|
|
||||||
"dark:hover:bg-[#ffffff1f]",
|
|
||||||
"dark:hover:text-[#ffffffd9]"
|
|
||||||
];
|
|
||||||
});
|
|
||||||
|
|
||||||
onClickOutside(target, (event: any) => {
|
|
||||||
if (event.clientX > target.value.offsetLeft) return;
|
|
||||||
show.value = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
emitter.on("openPanel", () => {
|
|
||||||
show.value = true;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
// 解绑`openPanel`公共事件,防止多次触发
|
|
||||||
emitter.off("openPanel");
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div :class="{ show: show }" class="right-panel-container">
|
|
||||||
<div class="right-panel-background" />
|
|
||||||
<div ref="target" class="right-panel bg-bg_color">
|
|
||||||
<div class="right-panel-items">
|
|
||||||
<div class="project-configuration">
|
|
||||||
<h4 class="dark:text-white">项目配置</h4>
|
|
||||||
<span title="关闭配置" :class="iconClass">
|
|
||||||
<IconifyIconOffline
|
|
||||||
class="dark:text-white"
|
|
||||||
width="20px"
|
|
||||||
height="20px"
|
|
||||||
:icon="Close"
|
|
||||||
@click="show = !show"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="border-b-[1px] border-solid border-[#dcdfe6] dark:border-[#303030]"
|
|
||||||
/>
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.showright-panel {
|
|
||||||
position: relative;
|
|
||||||
width: calc(100% - 15px);
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.right-panel-background {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: -1;
|
|
||||||
background: rgb(0 0 0 / 20%);
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 0.3s cubic-bezier(0.7, 0.3, 0.1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-panel {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 40000;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 315px;
|
|
||||||
height: 100vh;
|
|
||||||
box-shadow: 0 0 15px 0 rgb(0 0 0 / 5%);
|
|
||||||
transition: all 0.25s cubic-bezier(0.7, 0.3, 0.1, 1);
|
|
||||||
transform: translate(100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.show {
|
|
||||||
transition: all 0.3s cubic-bezier(0.7, 0.3, 0.1, 1);
|
|
||||||
|
|
||||||
.right-panel-background {
|
|
||||||
z-index: 20000;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-panel {
|
|
||||||
transform: translate(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.handle-button {
|
|
||||||
position: absolute;
|
|
||||||
top: 45%;
|
|
||||||
left: -48px;
|
|
||||||
z-index: 0;
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 48px;
|
|
||||||
color: #fff;
|
|
||||||
text-align: center;
|
|
||||||
pointer-events: auto;
|
|
||||||
cursor: pointer;
|
|
||||||
background: rgb(24 144 255);
|
|
||||||
border-radius: 6px 0 0 6px !important;
|
|
||||||
|
|
||||||
i {
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 48px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-panel-items {
|
|
||||||
height: calc(100vh - 60px);
|
|
||||||
margin-top: 60px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-configuration {
|
|
||||||
position: fixed;
|
|
||||||
top: 15px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
width: 100%;
|
|
||||||
height: 30px;
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-divider--horizontal) {
|
|
||||||
width: 90%;
|
|
||||||
margin: 20px auto 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,529 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import {
|
|
||||||
ref,
|
|
||||||
unref,
|
|
||||||
watch,
|
|
||||||
reactive,
|
|
||||||
computed,
|
|
||||||
nextTick,
|
|
||||||
onBeforeMount
|
|
||||||
} from "vue";
|
|
||||||
import {
|
|
||||||
useDark,
|
|
||||||
debounce,
|
|
||||||
useGlobal,
|
|
||||||
storageLocal,
|
|
||||||
storageSession
|
|
||||||
} from "@pureadmin/utils";
|
|
||||||
import { getConfig } from "@/config";
|
|
||||||
import { useRouter } from "vue-router";
|
|
||||||
import panel from "../panel/index.vue";
|
|
||||||
import { emitter } from "@/utils/mitt";
|
|
||||||
import { resetRouter } from "@/router";
|
|
||||||
import { removeToken } from "@/utils/auth";
|
|
||||||
import { routerArrays } from "@/layout/types";
|
|
||||||
import { useNav } from "@/layout/hooks/useNav";
|
|
||||||
import { useAppStoreHook } from "@/store/modules/app";
|
|
||||||
import { toggleTheme } from "@pureadmin/theme/dist/browser-utils";
|
|
||||||
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
|
|
||||||
import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
|
|
||||||
|
|
||||||
import dayIcon from "@/assets/svg/day.svg?component";
|
|
||||||
import darkIcon from "@/assets/svg/dark.svg?component";
|
|
||||||
import Check from "@iconify-icons/ep/check";
|
|
||||||
import Logout from "@iconify-icons/ri/logout-circle-r-line";
|
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const { isDark } = useDark();
|
|
||||||
const { device, tooltipEffect } = useNav();
|
|
||||||
const { $storage } = useGlobal<GlobalPropertiesApi>();
|
|
||||||
|
|
||||||
const mixRef = ref();
|
|
||||||
const verticalRef = ref();
|
|
||||||
const horizontalRef = ref();
|
|
||||||
|
|
||||||
const {
|
|
||||||
dataTheme,
|
|
||||||
layoutTheme,
|
|
||||||
themeColors,
|
|
||||||
dataThemeChange,
|
|
||||||
setEpThemeColor,
|
|
||||||
setLayoutThemeColor
|
|
||||||
} = useDataThemeChange();
|
|
||||||
|
|
||||||
/* body添加layout属性,作用于src/style/sidebar.scss */
|
|
||||||
if (unref(layoutTheme)) {
|
|
||||||
const layout = unref(layoutTheme).layout;
|
|
||||||
const theme = unref(layoutTheme).theme;
|
|
||||||
toggleTheme({
|
|
||||||
scopeName: `layout-theme-${theme}`
|
|
||||||
});
|
|
||||||
setLayoutModel(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 默认灵动模式 */
|
|
||||||
const markValue = ref($storage.configure?.showModel ?? "smart");
|
|
||||||
|
|
||||||
const logoVal = ref($storage.configure?.showLogo ?? true);
|
|
||||||
|
|
||||||
const settings = reactive({
|
|
||||||
greyVal: $storage.configure.grey,
|
|
||||||
weakVal: $storage.configure.weak,
|
|
||||||
tabsVal: $storage.configure.hideTabs,
|
|
||||||
showLogo: $storage.configure.showLogo,
|
|
||||||
showModel: $storage.configure.showModel,
|
|
||||||
multiTagsCache: $storage.configure.multiTagsCache
|
|
||||||
});
|
|
||||||
|
|
||||||
const getThemeColorStyle = computed(() => {
|
|
||||||
return color => {
|
|
||||||
return { background: color };
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
/** 当网页为暗黑模式时不显示亮白色切换选项 */
|
|
||||||
const showThemeColors = computed(() => {
|
|
||||||
return themeColor => {
|
|
||||||
return themeColor === "light" && isDark.value ? false : true;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
function storageConfigureChange<T>(key: string, val: T): void {
|
|
||||||
const storageConfigure = $storage.configure;
|
|
||||||
storageConfigure[key] = val;
|
|
||||||
$storage.configure = storageConfigure;
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleClass(flag: boolean, clsName: string, target?: HTMLElement) {
|
|
||||||
const targetEl = target || document.body;
|
|
||||||
let { className } = targetEl;
|
|
||||||
className = className.replace(clsName, "").trim();
|
|
||||||
targetEl.className = flag ? `${className} ${clsName} ` : className;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 灰色模式设置 */
|
|
||||||
const greyChange = (value): void => {
|
|
||||||
toggleClass(settings.greyVal, "html-grey", document.querySelector("html"));
|
|
||||||
storageConfigureChange("grey", value);
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 色弱模式设置 */
|
|
||||||
const weekChange = (value): void => {
|
|
||||||
toggleClass(
|
|
||||||
settings.weakVal,
|
|
||||||
"html-weakness",
|
|
||||||
document.querySelector("html")
|
|
||||||
);
|
|
||||||
storageConfigureChange("weak", value);
|
|
||||||
};
|
|
||||||
|
|
||||||
const tagsChange = () => {
|
|
||||||
const showVal = settings.tabsVal;
|
|
||||||
storageConfigureChange("hideTabs", showVal);
|
|
||||||
emitter.emit("tagViewsChange", showVal as unknown as string);
|
|
||||||
};
|
|
||||||
|
|
||||||
const multiTagsCacheChange = () => {
|
|
||||||
const multiTagsCache = settings.multiTagsCache;
|
|
||||||
storageConfigureChange("multiTagsCache", multiTagsCache);
|
|
||||||
useMultiTagsStoreHook().multiTagsCacheChange(multiTagsCache);
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 清空缓存并返回登录页 */
|
|
||||||
function onReset() {
|
|
||||||
removeToken();
|
|
||||||
storageLocal().clear();
|
|
||||||
storageSession().clear();
|
|
||||||
const { Grey, Weak, MultiTagsCache, EpThemeColor, Layout } = getConfig();
|
|
||||||
useAppStoreHook().setLayout(Layout);
|
|
||||||
setEpThemeColor(EpThemeColor);
|
|
||||||
useMultiTagsStoreHook().multiTagsCacheChange(MultiTagsCache);
|
|
||||||
toggleClass(Grey, "html-grey", document.querySelector("html"));
|
|
||||||
toggleClass(Weak, "html-weakness", document.querySelector("html"));
|
|
||||||
router.push("/login");
|
|
||||||
useMultiTagsStoreHook().handleTags("equal", [...routerArrays]);
|
|
||||||
resetRouter();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onChange(label) {
|
|
||||||
storageConfigureChange("showModel", label);
|
|
||||||
emitter.emit("tagViewsShowModel", label);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 侧边栏Logo */
|
|
||||||
function logoChange() {
|
|
||||||
unref(logoVal)
|
|
||||||
? storageConfigureChange("showLogo", true)
|
|
||||||
: storageConfigureChange("showLogo", false);
|
|
||||||
emitter.emit("logoChange", unref(logoVal));
|
|
||||||
}
|
|
||||||
|
|
||||||
function setFalse(Doms): any {
|
|
||||||
Doms.forEach(v => {
|
|
||||||
toggleClass(false, "is-select", unref(v));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 主题色 激活选择项 */
|
|
||||||
const getThemeColor = computed(() => {
|
|
||||||
return current => {
|
|
||||||
if (
|
|
||||||
current === layoutTheme.value.theme &&
|
|
||||||
layoutTheme.value.theme !== "light"
|
|
||||||
) {
|
|
||||||
return "#fff";
|
|
||||||
} else if (
|
|
||||||
current === layoutTheme.value.theme &&
|
|
||||||
layoutTheme.value.theme === "light"
|
|
||||||
) {
|
|
||||||
return "#1d2b45";
|
|
||||||
} else {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
/** 设置导航模式 */
|
|
||||||
function setLayoutModel(layout: string) {
|
|
||||||
layoutTheme.value.layout = layout;
|
|
||||||
window.document.body.setAttribute("layout", layout);
|
|
||||||
$storage.layout = {
|
|
||||||
layout,
|
|
||||||
theme: layoutTheme.value.theme,
|
|
||||||
darkMode: $storage.layout?.darkMode,
|
|
||||||
sidebarStatus: $storage.layout?.sidebarStatus,
|
|
||||||
epThemeColor: $storage.layout?.epThemeColor
|
|
||||||
};
|
|
||||||
useAppStoreHook().setLayout(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
watch($storage, ({ layout }) => {
|
|
||||||
switch (layout["layout"]) {
|
|
||||||
case "vertical":
|
|
||||||
toggleClass(true, "is-select", unref(verticalRef));
|
|
||||||
debounce(setFalse([horizontalRef]), 50);
|
|
||||||
debounce(setFalse([mixRef]), 50);
|
|
||||||
break;
|
|
||||||
case "horizontal":
|
|
||||||
toggleClass(true, "is-select", unref(horizontalRef));
|
|
||||||
debounce(setFalse([verticalRef]), 50);
|
|
||||||
debounce(setFalse([mixRef]), 50);
|
|
||||||
break;
|
|
||||||
case "mix":
|
|
||||||
toggleClass(true, "is-select", unref(mixRef));
|
|
||||||
debounce(setFalse([verticalRef]), 50);
|
|
||||||
debounce(setFalse([horizontalRef]), 50);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onBeforeMount(() => {
|
|
||||||
/* 初始化项目配置 */
|
|
||||||
nextTick(() => {
|
|
||||||
settings.greyVal &&
|
|
||||||
document.querySelector("html")?.setAttribute("class", "html-grey");
|
|
||||||
settings.weakVal &&
|
|
||||||
document.querySelector("html")?.setAttribute("class", "html-weakness");
|
|
||||||
settings.tabsVal && tagsChange();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<panel>
|
|
||||||
<el-divider>主题</el-divider>
|
|
||||||
<el-switch
|
|
||||||
v-model="dataTheme"
|
|
||||||
inline-prompt
|
|
||||||
class="pure-datatheme"
|
|
||||||
:active-icon="dayIcon"
|
|
||||||
:inactive-icon="darkIcon"
|
|
||||||
@change="dataThemeChange"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<el-divider>导航栏模式</el-divider>
|
|
||||||
<ul class="pure-theme">
|
|
||||||
<el-tooltip
|
|
||||||
:effect="tooltipEffect"
|
|
||||||
class="item"
|
|
||||||
content="左侧模式"
|
|
||||||
placement="bottom"
|
|
||||||
popper-class="pure-tooltip"
|
|
||||||
>
|
|
||||||
<li
|
|
||||||
:class="layoutTheme.layout === 'vertical' ? 'is-select' : ''"
|
|
||||||
ref="verticalRef"
|
|
||||||
@click="setLayoutModel('vertical')"
|
|
||||||
>
|
|
||||||
<div />
|
|
||||||
<div />
|
|
||||||
</li>
|
|
||||||
</el-tooltip>
|
|
||||||
|
|
||||||
<el-tooltip
|
|
||||||
v-if="device !== 'mobile'"
|
|
||||||
:effect="tooltipEffect"
|
|
||||||
class="item"
|
|
||||||
content="顶部模式"
|
|
||||||
placement="bottom"
|
|
||||||
popper-class="pure-tooltip"
|
|
||||||
>
|
|
||||||
<li
|
|
||||||
:class="layoutTheme.layout === 'horizontal' ? 'is-select' : ''"
|
|
||||||
ref="horizontalRef"
|
|
||||||
@click="setLayoutModel('horizontal')"
|
|
||||||
>
|
|
||||||
<div />
|
|
||||||
<div />
|
|
||||||
</li>
|
|
||||||
</el-tooltip>
|
|
||||||
|
|
||||||
<el-tooltip
|
|
||||||
v-if="device !== 'mobile'"
|
|
||||||
:effect="tooltipEffect"
|
|
||||||
class="item"
|
|
||||||
content="混合模式"
|
|
||||||
placement="bottom"
|
|
||||||
popper-class="pure-tooltip"
|
|
||||||
>
|
|
||||||
<li
|
|
||||||
:class="layoutTheme.layout === 'mix' ? 'is-select' : ''"
|
|
||||||
ref="mixRef"
|
|
||||||
@click="setLayoutModel('mix')"
|
|
||||||
>
|
|
||||||
<div />
|
|
||||||
<div />
|
|
||||||
</li>
|
|
||||||
</el-tooltip>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<el-divider>主题色</el-divider>
|
|
||||||
<ul class="theme-color">
|
|
||||||
<li
|
|
||||||
v-for="(item, index) in themeColors"
|
|
||||||
:key="index"
|
|
||||||
v-show="showThemeColors(item.themeColor)"
|
|
||||||
:style="getThemeColorStyle(item.color)"
|
|
||||||
@click="setLayoutThemeColor(item.themeColor)"
|
|
||||||
>
|
|
||||||
<el-icon
|
|
||||||
style="margin: 0.1em 0.1em 0 0"
|
|
||||||
:size="17"
|
|
||||||
:color="getThemeColor(item.themeColor)"
|
|
||||||
>
|
|
||||||
<IconifyIconOffline :icon="Check" />
|
|
||||||
</el-icon>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<el-divider>界面显示</el-divider>
|
|
||||||
<ul class="setting">
|
|
||||||
<li>
|
|
||||||
<span class="dark:text-white">灰色模式</span>
|
|
||||||
<el-switch
|
|
||||||
v-model="settings.greyVal"
|
|
||||||
inline-prompt
|
|
||||||
inactive-color="#a6a6a6"
|
|
||||||
active-text="开"
|
|
||||||
inactive-text="关"
|
|
||||||
@change="greyChange"
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="dark:text-white">色弱模式</span>
|
|
||||||
<el-switch
|
|
||||||
v-model="settings.weakVal"
|
|
||||||
inline-prompt
|
|
||||||
inactive-color="#a6a6a6"
|
|
||||||
active-text="开"
|
|
||||||
inactive-text="关"
|
|
||||||
@change="weekChange"
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="dark:text-white">隐藏标签页</span>
|
|
||||||
<el-switch
|
|
||||||
v-model="settings.tabsVal"
|
|
||||||
inline-prompt
|
|
||||||
inactive-color="#a6a6a6"
|
|
||||||
active-text="开"
|
|
||||||
inactive-text="关"
|
|
||||||
@change="tagsChange"
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="dark:text-white">侧边栏Logo</span>
|
|
||||||
<el-switch
|
|
||||||
v-model="logoVal"
|
|
||||||
inline-prompt
|
|
||||||
:active-value="true"
|
|
||||||
:inactive-value="false"
|
|
||||||
inactive-color="#a6a6a6"
|
|
||||||
active-text="开"
|
|
||||||
inactive-text="关"
|
|
||||||
@change="logoChange"
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span class="dark:text-white">标签页持久化</span>
|
|
||||||
<el-switch
|
|
||||||
v-model="settings.multiTagsCache"
|
|
||||||
inline-prompt
|
|
||||||
inactive-color="#a6a6a6"
|
|
||||||
active-text="开"
|
|
||||||
inactive-text="关"
|
|
||||||
@change="multiTagsCacheChange"
|
|
||||||
/>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<span class="dark:text-white">标签风格</span>
|
|
||||||
<el-radio-group v-model="markValue" size="small" @change="onChange">
|
|
||||||
<el-radio label="card">卡片</el-radio>
|
|
||||||
<el-radio label="smart">灵动</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<el-divider />
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
style="width: 90%; margin: 24px 15px"
|
|
||||||
@click="onReset"
|
|
||||||
>
|
|
||||||
<IconifyIconOffline
|
|
||||||
:icon="Logout"
|
|
||||||
width="15"
|
|
||||||
height="15"
|
|
||||||
style="margin-right: 4px"
|
|
||||||
/>
|
|
||||||
清空缓存并返回登录页
|
|
||||||
</el-button>
|
|
||||||
</panel>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
:deep(.el-divider__text) {
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.is-select {
|
|
||||||
border: 2px solid var(--el-color-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.setting {
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
li {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin: 25px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.pure-datatheme {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 50px;
|
|
||||||
padding-top: 25px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pure-theme {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: space-around;
|
|
||||||
width: 100%;
|
|
||||||
height: 50px;
|
|
||||||
margin-top: 25px;
|
|
||||||
|
|
||||||
li {
|
|
||||||
position: relative;
|
|
||||||
width: 18%;
|
|
||||||
height: 45px;
|
|
||||||
overflow: hidden;
|
|
||||||
cursor: pointer;
|
|
||||||
background: #f0f2f5;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 1px 2.5px 0 rgb(0 0 0 / 18%);
|
|
||||||
|
|
||||||
&:nth-child(1) {
|
|
||||||
div {
|
|
||||||
&:nth-child(1) {
|
|
||||||
width: 30%;
|
|
||||||
height: 100%;
|
|
||||||
background: #1b2a47;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(2) {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 70%;
|
|
||||||
height: 30%;
|
|
||||||
background: #fff;
|
|
||||||
box-shadow: 0 0 1px #888;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(2) {
|
|
||||||
div {
|
|
||||||
&:nth-child(1) {
|
|
||||||
width: 100%;
|
|
||||||
height: 30%;
|
|
||||||
background: #1b2a47;
|
|
||||||
box-shadow: 0 0 1px #888;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(3) {
|
|
||||||
div {
|
|
||||||
&:nth-child(1) {
|
|
||||||
width: 100%;
|
|
||||||
height: 30%;
|
|
||||||
background: #1b2a47;
|
|
||||||
box-shadow: 0 0 1px #888;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:nth-child(2) {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 30%;
|
|
||||||
height: 70%;
|
|
||||||
background: #fff;
|
|
||||||
box-shadow: 0 0 1px #888;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-color {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 40px;
|
|
||||||
margin-top: 20px;
|
|
||||||
|
|
||||||
li {
|
|
||||||
float: left;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
margin-top: 8px;
|
|
||||||
margin-right: 8px;
|
|
||||||
font-weight: 700;
|
|
||||||
text-align: center;
|
|
||||||
cursor: pointer;
|
|
||||||
border-radius: 2px;
|
|
||||||
|
|
||||||
&:nth-child(2) {
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -2,12 +2,12 @@
|
|||||||
import Search from "../search/index.vue";
|
import Search from "../search/index.vue";
|
||||||
import Notice from "../notice/index.vue";
|
import Notice from "../notice/index.vue";
|
||||||
import SidebarItem from "./sidebarItem.vue";
|
import SidebarItem from "./sidebarItem.vue";
|
||||||
|
import HeaderDarkSwitch from "../headerDarkSwitch.vue";
|
||||||
import { isAllEmpty } from "@pureadmin/utils";
|
import { isAllEmpty } from "@pureadmin/utils";
|
||||||
import { ref, nextTick, computed } from "vue";
|
import { ref, nextTick, computed } from "vue";
|
||||||
import { useNav } from "@/layout/hooks/useNav";
|
import { useNav } from "@/layout/hooks/useNav";
|
||||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
import { usePermissionStoreHook } from "@/store/modules/permission";
|
||||||
import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
|
import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
|
||||||
import Setting from "@iconify-icons/ri/settings-3-line";
|
|
||||||
|
|
||||||
const menuRef = ref();
|
const menuRef = ref();
|
||||||
|
|
||||||
@@ -16,7 +16,6 @@ const {
|
|||||||
title,
|
title,
|
||||||
logout,
|
logout,
|
||||||
backTopMenu,
|
backTopMenu,
|
||||||
onPanel,
|
|
||||||
username,
|
username,
|
||||||
userAvatar,
|
userAvatar,
|
||||||
avatarsStyle
|
avatarsStyle
|
||||||
@@ -55,11 +54,9 @@ nextTick(() => {
|
|||||||
/>
|
/>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
<div class="horizontal-header-right">
|
<div class="horizontal-header-right">
|
||||||
<!-- 菜单搜索 -->
|
|
||||||
<Search />
|
<Search />
|
||||||
<!-- 通知 -->
|
|
||||||
<Notice id="header-notice" />
|
<Notice id="header-notice" />
|
||||||
<!-- 退出登录 -->
|
<HeaderDarkSwitch />
|
||||||
<el-dropdown trigger="click">
|
<el-dropdown trigger="click">
|
||||||
<span class="el-dropdown-link navbar-bg-hover">
|
<span class="el-dropdown-link navbar-bg-hover">
|
||||||
<img :src="userAvatar" :style="avatarsStyle" />
|
<img :src="userAvatar" :style="avatarsStyle" />
|
||||||
@@ -77,13 +74,6 @@ nextTick(() => {
|
|||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
<span
|
|
||||||
class="set-icon navbar-bg-hover"
|
|
||||||
title="打开项目配置"
|
|
||||||
@click="onPanel"
|
|
||||||
>
|
|
||||||
<IconifyIconOffline :icon="Setting" />
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import extraIcon from "./extraIcon.vue";
|
import extraIcon from "./extraIcon.vue";
|
||||||
import Search from "../search/index.vue";
|
import Search from "../search/index.vue";
|
||||||
import Notice from "../notice/index.vue";
|
import Notice from "../notice/index.vue";
|
||||||
|
import HeaderDarkSwitch from "../headerDarkSwitch.vue";
|
||||||
import { isAllEmpty } from "@pureadmin/utils";
|
import { isAllEmpty } from "@pureadmin/utils";
|
||||||
import { useNav } from "@/layout/hooks/useNav";
|
import { useNav } from "@/layout/hooks/useNav";
|
||||||
import { ref, toRaw, watch, onMounted, nextTick } from "vue";
|
import { ref, toRaw, watch, onMounted, nextTick } from "vue";
|
||||||
@@ -9,7 +10,6 @@ import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
|||||||
import { getParentPaths, findRouteByPath } from "@/router/utils";
|
import { getParentPaths, findRouteByPath } from "@/router/utils";
|
||||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
import { usePermissionStoreHook } from "@/store/modules/permission";
|
||||||
import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
|
import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
|
||||||
import Setting from "@iconify-icons/ri/settings-3-line";
|
|
||||||
|
|
||||||
const menuRef = ref();
|
const menuRef = ref();
|
||||||
const defaultActive = ref(null);
|
const defaultActive = ref(null);
|
||||||
@@ -18,7 +18,6 @@ const {
|
|||||||
route,
|
route,
|
||||||
device,
|
device,
|
||||||
logout,
|
logout,
|
||||||
onPanel,
|
|
||||||
resolvePath,
|
resolvePath,
|
||||||
username,
|
username,
|
||||||
userAvatar,
|
userAvatar,
|
||||||
@@ -28,7 +27,6 @@ const {
|
|||||||
|
|
||||||
function getDefaultActive(routePath) {
|
function getDefaultActive(routePath) {
|
||||||
const wholeMenus = usePermissionStoreHook().wholeMenus;
|
const wholeMenus = usePermissionStoreHook().wholeMenus;
|
||||||
/** 当前路由的父级路径 */
|
|
||||||
const parentRoutes = getParentPaths(routePath, wholeMenus)[0];
|
const parentRoutes = getParentPaths(routePath, wholeMenus)[0];
|
||||||
defaultActive.value = !isAllEmpty(route.meta?.activePath)
|
defaultActive.value = !isAllEmpty(route.meta?.activePath)
|
||||||
? route.meta.activePath
|
? route.meta.activePath
|
||||||
@@ -54,8 +52,8 @@ watch(
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
v-if="device !== 'mobile'"
|
v-if="device !== 'mobile'"
|
||||||
class="horizontal-header"
|
|
||||||
v-loading="usePermissionStoreHook().wholeMenus.length === 0"
|
v-loading="usePermissionStoreHook().wholeMenus.length === 0"
|
||||||
|
class="horizontal-header"
|
||||||
>
|
>
|
||||||
<el-menu
|
<el-menu
|
||||||
router
|
router
|
||||||
@@ -88,11 +86,9 @@ watch(
|
|||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
<div class="horizontal-header-right">
|
<div class="horizontal-header-right">
|
||||||
<!-- 菜单搜索 -->
|
|
||||||
<Search />
|
<Search />
|
||||||
<!-- 通知 -->
|
|
||||||
<Notice id="header-notice" />
|
<Notice id="header-notice" />
|
||||||
<!-- 退出登录 -->
|
<HeaderDarkSwitch />
|
||||||
<el-dropdown trigger="click">
|
<el-dropdown trigger="click">
|
||||||
<span class="el-dropdown-link navbar-bg-hover select-none">
|
<span class="el-dropdown-link navbar-bg-hover select-none">
|
||||||
<img :src="userAvatar" :style="avatarsStyle" />
|
<img :src="userAvatar" :style="avatarsStyle" />
|
||||||
@@ -110,13 +106,6 @@ watch(
|
|||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
<span
|
|
||||||
class="set-icon navbar-bg-hover"
|
|
||||||
title="打开项目配置"
|
|
||||||
@click="onPanel"
|
|
||||||
>
|
|
||||||
<IconifyIconOffline :icon="Setting" />
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -1,23 +1,15 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Logo from "./logo.vue";
|
import Logo from "./logo.vue";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import { emitter } from "@/utils/mitt";
|
|
||||||
import SidebarItem from "./sidebarItem.vue";
|
import SidebarItem from "./sidebarItem.vue";
|
||||||
import leftCollapse from "./leftCollapse.vue";
|
import leftCollapse from "./leftCollapse.vue";
|
||||||
import { useNav } from "@/layout/hooks/useNav";
|
import { useNav } from "@/layout/hooks/useNav";
|
||||||
import { responsiveStorageNameSpace } from "@/config";
|
import { isAllEmpty } from "@pureadmin/utils";
|
||||||
import { storageLocal, isAllEmpty } from "@pureadmin/utils";
|
|
||||||
import { findRouteByPath, getParentPaths } from "@/router/utils";
|
import { findRouteByPath, getParentPaths } from "@/router/utils";
|
||||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
import { usePermissionStoreHook } from "@/store/modules/permission";
|
||||||
import { ref, computed, watch, onMounted, onBeforeUnmount } from "vue";
|
import { ref, computed, watch, onMounted } from "vue";
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const showLogo = ref(
|
|
||||||
storageLocal().getItem<StorageConfigs>(
|
|
||||||
`${responsiveStorageNameSpace()}configure`
|
|
||||||
)?.showLogo ?? true
|
|
||||||
);
|
|
||||||
|
|
||||||
const { device, pureApp, isCollapse, menuSelect, toggleSideBar } = useNav();
|
const { device, pureApp, isCollapse, menuSelect, toggleSideBar } = useNav();
|
||||||
|
|
||||||
const subMenuData = ref([]);
|
const subMenuData = ref([]);
|
||||||
@@ -37,21 +29,18 @@ const defaultActive = computed(() =>
|
|||||||
);
|
);
|
||||||
|
|
||||||
function getSubMenuData() {
|
function getSubMenuData() {
|
||||||
let path = "";
|
const path = defaultActive.value;
|
||||||
path = defaultActive.value;
|
|
||||||
subMenuData.value = [];
|
subMenuData.value = [];
|
||||||
// path的上级路由组成的数组
|
|
||||||
const parentPathArr = getParentPaths(
|
const parentPathArr = getParentPaths(
|
||||||
path,
|
path,
|
||||||
usePermissionStoreHook().wholeMenus
|
usePermissionStoreHook().wholeMenus
|
||||||
);
|
);
|
||||||
// 当前路由的父级路由信息
|
const parentRoute = findRouteByPath(
|
||||||
const parenetRoute = findRouteByPath(
|
|
||||||
parentPathArr[0] || path,
|
parentPathArr[0] || path,
|
||||||
usePermissionStoreHook().wholeMenus
|
usePermissionStoreHook().wholeMenus
|
||||||
);
|
);
|
||||||
if (!parenetRoute?.children) return;
|
if (!parentRoute?.children) return;
|
||||||
subMenuData.value = parenetRoute?.children;
|
subMenuData.value = parentRoute.children;
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@@ -65,24 +54,12 @@ watch(
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getSubMenuData();
|
getSubMenuData();
|
||||||
|
|
||||||
emitter.on("logoChange", key => {
|
|
||||||
showLogo.value = key;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
|
||||||
// 解绑`logoChange`公共事件,防止多次触发
|
|
||||||
emitter.off("logoChange");
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div v-loading="loading" :class="['sidebar-container', 'has-logo']">
|
||||||
v-loading="loading"
|
<Logo :collapse="isCollapse" />
|
||||||
:class="['sidebar-container', showLogo ? 'has-logo' : '']"
|
|
||||||
>
|
|
||||||
<Logo v-if="showLogo" :collapse="isCollapse" />
|
|
||||||
<el-scrollbar
|
<el-scrollbar
|
||||||
wrap-class="scrollbar-wrapper"
|
wrap-class="scrollbar-wrapper"
|
||||||
:class="[device === 'mobile' ? 'mobile' : 'pc']"
|
:class="[device === 'mobile' ? 'mobile' : 'pc']"
|
||||||
|
|||||||
@@ -243,25 +243,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 卡片模式下鼠标移入显示蓝色边框 */
|
|
||||||
.card-in {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 卡片模式下鼠标移出隐藏蓝色边框 */
|
|
||||||
.card-out {
|
|
||||||
color: #666;
|
|
||||||
border: none;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 灵动模式 */
|
/* 灵动模式 */
|
||||||
.schedule-active {
|
.schedule-active {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
@@ -21,13 +21,11 @@ const {
|
|||||||
route,
|
route,
|
||||||
router,
|
router,
|
||||||
visible,
|
visible,
|
||||||
showTags,
|
|
||||||
instance,
|
instance,
|
||||||
multiTags,
|
multiTags,
|
||||||
tagsViews,
|
tagsViews,
|
||||||
buttonTop,
|
buttonTop,
|
||||||
buttonLeft,
|
buttonLeft,
|
||||||
showModel,
|
|
||||||
translateX,
|
translateX,
|
||||||
pureSetting,
|
pureSetting,
|
||||||
activeIndex,
|
activeIndex,
|
||||||
@@ -477,17 +475,6 @@ onMounted(() => {
|
|||||||
// 根据当前路由初始化操作标签页的禁用状态
|
// 根据当前路由初始化操作标签页的禁用状态
|
||||||
showMenuModel(route.fullPath);
|
showMenuModel(route.fullPath);
|
||||||
|
|
||||||
// 触发隐藏标签页
|
|
||||||
emitter.on("tagViewsChange", (key: any) => {
|
|
||||||
if (unref(showTags as any) === key) return;
|
|
||||||
(showTags as any).value = key;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 改变标签风格
|
|
||||||
emitter.on("tagViewsShowModel", key => {
|
|
||||||
showModel.value = key;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 接收侧边栏切换传递过来的参数
|
// 接收侧边栏切换传递过来的参数
|
||||||
emitter.on("changLayoutRoute", indexPath => {
|
emitter.on("changLayoutRoute", indexPath => {
|
||||||
dynamicRouteTag(indexPath);
|
dynamicRouteTag(indexPath);
|
||||||
@@ -503,15 +490,13 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
// 解绑`tagViewsChange`、`tagViewsShowModel`、`changLayoutRoute`公共事件,防止多次触发
|
// 解绑公共事件,防止多次触发
|
||||||
emitter.off("tagViewsChange");
|
|
||||||
emitter.off("tagViewsShowModel");
|
|
||||||
emitter.off("changLayoutRoute");
|
emitter.off("changLayoutRoute");
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div ref="containerDom" class="tags-view" v-if="!showTags">
|
<div ref="containerDom" class="tags-view">
|
||||||
<span v-show="isShowArrow" class="arrow-left">
|
<span v-show="isShowArrow" class="arrow-left">
|
||||||
<IconifyIconOffline :icon="ArrowLeftSLine" @click="handleScroll(200)" />
|
<IconifyIconOffline :icon="ArrowLeftSLine" @click="handleScroll(200)" />
|
||||||
</span>
|
</span>
|
||||||
@@ -521,13 +506,7 @@ onBeforeUnmount(() => {
|
|||||||
:ref="'dynamic' + index"
|
:ref="'dynamic' + index"
|
||||||
v-for="(item, index) in multiTags"
|
v-for="(item, index) in multiTags"
|
||||||
:key="index"
|
:key="index"
|
||||||
:class="[
|
:class="['scroll-item is-closable', linkIsActive(item)]"
|
||||||
'scroll-item is-closable',
|
|
||||||
linkIsActive(item),
|
|
||||||
route.path === item.path && showModel === 'card'
|
|
||||||
? 'card-active'
|
|
||||||
: ''
|
|
||||||
]"
|
|
||||||
@contextmenu.prevent="openMenu(item, $event)"
|
@contextmenu.prevent="openMenu(item, $event)"
|
||||||
@mouseenter.prevent="onMouseenter(index)"
|
@mouseenter.prevent="onMouseenter(index)"
|
||||||
@mouseleave.prevent="onMouseleave(index)"
|
@mouseleave.prevent="onMouseleave(index)"
|
||||||
@@ -549,11 +528,7 @@ onBeforeUnmount(() => {
|
|||||||
>
|
>
|
||||||
<IconifyIconOffline :icon="CloseBold" />
|
<IconifyIconOffline :icon="CloseBold" />
|
||||||
</span>
|
</span>
|
||||||
<div
|
<div :ref="'schedule' + index" :class="[scheduleIsActive(item)]" />
|
||||||
:ref="'schedule' + index"
|
|
||||||
v-if="showModel !== 'card'"
|
|
||||||
:class="[scheduleIsActive(item)]"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -24,14 +24,9 @@ export function useLayout() {
|
|||||||
epThemeColor: $config?.EpThemeColor ?? "#409EFF"
|
epThemeColor: $config?.EpThemeColor ?? "#409EFF"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/** 灰色模式、色弱模式、隐藏标签页 */
|
/** 标签页缓存配置 */
|
||||||
if (!$storage.configure) {
|
if (!$storage.configure) {
|
||||||
$storage.configure = {
|
$storage.configure = {
|
||||||
grey: $config?.Grey ?? false,
|
|
||||||
weak: $config?.Weak ?? false,
|
|
||||||
hideTabs: $config?.HideTabs ?? false,
|
|
||||||
showLogo: $config?.ShowLogo ?? true,
|
|
||||||
showModel: $config?.ShowModel ?? "smart",
|
|
||||||
multiTagsCache: $config?.MultiTagsCache ?? false
|
multiTagsCache: $config?.MultiTagsCache ?? false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,10 +87,6 @@ export function useNav() {
|
|||||||
router.push(getTopMenu()?.path);
|
router.push(getTopMenu()?.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onPanel() {
|
|
||||||
emitter.emit("openPanel");
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleSideBar() {
|
function toggleSideBar() {
|
||||||
pureApp.toggleSideBar();
|
pureApp.toggleSideBar();
|
||||||
}
|
}
|
||||||
@@ -130,7 +126,6 @@ export function useNav() {
|
|||||||
routers,
|
routers,
|
||||||
$storage,
|
$storage,
|
||||||
backTopMenu,
|
backTopMenu,
|
||||||
onPanel,
|
|
||||||
getDivStyle,
|
getDivStyle,
|
||||||
changeTitle,
|
changeTitle,
|
||||||
toggleSideBar,
|
toggleSideBar,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
ref,
|
ref,
|
||||||
unref,
|
|
||||||
watch,
|
watch,
|
||||||
computed,
|
computed,
|
||||||
reactive,
|
reactive,
|
||||||
@@ -11,16 +10,9 @@ import {
|
|||||||
import { tagsViewsType } from "../types";
|
import { tagsViewsType } from "../types";
|
||||||
import { useEventListener } from "@vueuse/core";
|
import { useEventListener } from "@vueuse/core";
|
||||||
import { useRoute, useRouter } from "vue-router";
|
import { useRoute, useRouter } from "vue-router";
|
||||||
import { responsiveStorageNameSpace } from "@/config";
|
|
||||||
import { useSettingStoreHook } from "@/store/modules/settings";
|
import { useSettingStoreHook } from "@/store/modules/settings";
|
||||||
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
|
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
|
||||||
import {
|
import { isEqual, isBoolean, toggleClass, hasClass } from "@pureadmin/utils";
|
||||||
isEqual,
|
|
||||||
isBoolean,
|
|
||||||
storageLocal,
|
|
||||||
toggleClass,
|
|
||||||
hasClass
|
|
||||||
} from "@pureadmin/utils";
|
|
||||||
|
|
||||||
import Fullscreen from "@iconify-icons/ri/fullscreen-fill";
|
import Fullscreen from "@iconify-icons/ri/fullscreen-fill";
|
||||||
import CloseAllTags from "@iconify-icons/ri/subtract-line";
|
import CloseAllTags from "@iconify-icons/ri/subtract-line";
|
||||||
@@ -41,22 +33,7 @@ export function useTags() {
|
|||||||
const translateX = ref(0);
|
const translateX = ref(0);
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
const activeIndex = ref(-1);
|
const activeIndex = ref(-1);
|
||||||
// 当前右键选中的路由信息
|
|
||||||
const currentSelect = ref({});
|
const currentSelect = ref({});
|
||||||
|
|
||||||
/** 显示模式,默认灵动模式 */
|
|
||||||
const showModel = ref(
|
|
||||||
storageLocal().getItem<StorageConfigs>(
|
|
||||||
`${responsiveStorageNameSpace()}configure`
|
|
||||||
)?.showModel || "smart"
|
|
||||||
);
|
|
||||||
/** 是否隐藏标签页,默认显示 */
|
|
||||||
const showTags =
|
|
||||||
ref(
|
|
||||||
storageLocal().getItem<StorageConfigs>(
|
|
||||||
`${responsiveStorageNameSpace()}configure`
|
|
||||||
).hideTabs
|
|
||||||
) ?? ref("false");
|
|
||||||
const multiTags: any = computed(() => {
|
const multiTags: any = computed(() => {
|
||||||
return useMultiTagsStoreHook().multiTags;
|
return useMultiTagsStoreHook().multiTags;
|
||||||
});
|
});
|
||||||
@@ -73,35 +50,35 @@ export function useTags() {
|
|||||||
icon: Close,
|
icon: Close,
|
||||||
text: "关闭当前标签页",
|
text: "关闭当前标签页",
|
||||||
divided: false,
|
divided: false,
|
||||||
disabled: multiTags.value.length > 1 ? false : true,
|
disabled: multiTags.value.length <= 1,
|
||||||
show: true
|
show: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: CloseLeftTags,
|
icon: CloseLeftTags,
|
||||||
text: "关闭左侧标签页",
|
text: "关闭左侧标签页",
|
||||||
divided: true,
|
divided: true,
|
||||||
disabled: multiTags.value.length > 1 ? false : true,
|
disabled: multiTags.value.length <= 1,
|
||||||
show: true
|
show: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: CloseRightTags,
|
icon: CloseRightTags,
|
||||||
text: "关闭右侧标签页",
|
text: "关闭右侧标签页",
|
||||||
divided: false,
|
divided: false,
|
||||||
disabled: multiTags.value.length > 1 ? false : true,
|
disabled: multiTags.value.length <= 1,
|
||||||
show: true
|
show: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: CloseOtherTags,
|
icon: CloseOtherTags,
|
||||||
text: "关闭其他标签页",
|
text: "关闭其他标签页",
|
||||||
divided: true,
|
divided: true,
|
||||||
disabled: multiTags.value.length > 2 ? false : true,
|
disabled: multiTags.value.length <= 2,
|
||||||
show: true
|
show: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: CloseAllTags,
|
icon: CloseAllTags,
|
||||||
text: "关闭全部标签页",
|
text: "关闭全部标签页",
|
||||||
divided: false,
|
divided: false,
|
||||||
disabled: multiTags.value.length > 1 ? false : true,
|
disabled: multiTags.value.length <= 1,
|
||||||
show: true
|
show: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -124,13 +101,11 @@ export function useTags() {
|
|||||||
if (isBoolean(route?.meta?.showLink) && route?.meta?.showLink === false) {
|
if (isBoolean(route?.meta?.showLink) && route?.meta?.showLink === false) {
|
||||||
if (Object.keys(route.query).length > 0) {
|
if (Object.keys(route.query).length > 0) {
|
||||||
return isEqual(route.query, item.query) ? previous : next;
|
return isEqual(route.query, item.query) ? previous : next;
|
||||||
} else {
|
}
|
||||||
return isEqual(route.params, item.params) ? previous : next;
|
return isEqual(route.params, item.params) ? previous : next;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return route.path === item.path ? previous : next;
|
return route.path === item.path ? previous : next;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const iconIsActive = computed(() => {
|
const iconIsActive = computed(() => {
|
||||||
return (item, index) => {
|
return (item, index) => {
|
||||||
@@ -165,34 +140,25 @@ export function useTags() {
|
|||||||
visible.value = false;
|
visible.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 鼠标移入添加激活样式 */
|
function getScheduleElement(index) {
|
||||||
function onMouseenter(index) {
|
const refs = instance?.refs[`schedule${index}`];
|
||||||
if (index) activeIndex.value = index;
|
return Array.isArray(refs) ? refs[0] : refs;
|
||||||
if (unref(showModel) === "smart") {
|
}
|
||||||
if (hasClass(instance.refs["schedule" + index][0], "schedule-active"))
|
|
||||||
return;
|
function onMouseenter(index) {
|
||||||
toggleClass(true, "schedule-in", instance.refs["schedule" + index][0]);
|
if (index) activeIndex.value = index;
|
||||||
toggleClass(false, "schedule-out", instance.refs["schedule" + index][0]);
|
const scheduleEl = getScheduleElement(index);
|
||||||
} else {
|
if (!scheduleEl || hasClass(scheduleEl, "schedule-active")) return;
|
||||||
if (hasClass(instance.refs["dynamic" + index][0], "card-active")) return;
|
toggleClass(true, "schedule-in", scheduleEl);
|
||||||
toggleClass(true, "card-in", instance.refs["dynamic" + index][0]);
|
toggleClass(false, "schedule-out", scheduleEl);
|
||||||
toggleClass(false, "card-out", instance.refs["dynamic" + index][0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 鼠标移出恢复默认样式 */
|
|
||||||
function onMouseleave(index) {
|
function onMouseleave(index) {
|
||||||
activeIndex.value = -1;
|
activeIndex.value = -1;
|
||||||
if (unref(showModel) === "smart") {
|
const scheduleEl = getScheduleElement(index);
|
||||||
if (hasClass(instance.refs["schedule" + index][0], "schedule-active"))
|
if (!scheduleEl || hasClass(scheduleEl, "schedule-active")) return;
|
||||||
return;
|
toggleClass(false, "schedule-in", scheduleEl);
|
||||||
toggleClass(false, "schedule-in", instance.refs["schedule" + index][0]);
|
toggleClass(true, "schedule-out", scheduleEl);
|
||||||
toggleClass(true, "schedule-out", instance.refs["schedule" + index][0]);
|
|
||||||
} else {
|
|
||||||
if (hasClass(instance.refs["dynamic" + index][0], "card-active")) return;
|
|
||||||
toggleClass(false, "card-in", instance.refs["dynamic" + index][0]);
|
|
||||||
toggleClass(true, "card-out", instance.refs["dynamic" + index][0]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onContentFullScreen() {
|
function onContentFullScreen() {
|
||||||
@@ -201,19 +167,6 @@ export function useTags() {
|
|||||||
: pureSetting.changeSetting({ key: "hiddenSideBar", value: true });
|
: pureSetting.changeSetting({ key: "hiddenSideBar", value: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
if (!showModel.value) {
|
|
||||||
const configure = storageLocal().getItem<StorageConfigs>(
|
|
||||||
`${responsiveStorageNameSpace()}configure`
|
|
||||||
);
|
|
||||||
configure.showModel = "card";
|
|
||||||
storageLocal().setItem(
|
|
||||||
`${responsiveStorageNameSpace()}configure`,
|
|
||||||
configure
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => visible.value,
|
() => visible.value,
|
||||||
() => {
|
() => {
|
||||||
@@ -225,10 +178,8 @@ export function useTags() {
|
|||||||
route,
|
route,
|
||||||
router,
|
router,
|
||||||
visible,
|
visible,
|
||||||
showTags,
|
|
||||||
instance,
|
instance,
|
||||||
multiTags,
|
multiTags,
|
||||||
showModel,
|
|
||||||
tagsViews,
|
tagsViews,
|
||||||
buttonTop,
|
buttonTop,
|
||||||
buttonLeft,
|
buttonLeft,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { useLayout } from "./hooks/useLayout";
|
|||||||
import { useResizeObserver } from "@vueuse/core";
|
import { useResizeObserver } from "@vueuse/core";
|
||||||
import { useAppStoreHook } from "@/store/modules/app";
|
import { useAppStoreHook } from "@/store/modules/app";
|
||||||
import { useSettingStoreHook } from "@/store/modules/settings";
|
import { useSettingStoreHook } from "@/store/modules/settings";
|
||||||
import { deviceDetection, useDark, useGlobal } from "@pureadmin/utils";
|
import { deviceDetection, useGlobal } from "@pureadmin/utils";
|
||||||
import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
|
import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
|
||||||
import {
|
import {
|
||||||
h,
|
h,
|
||||||
@@ -22,13 +22,11 @@ import {
|
|||||||
import navbar from "./components/navbar.vue";
|
import navbar from "./components/navbar.vue";
|
||||||
import tag from "./components/tag/index.vue";
|
import tag from "./components/tag/index.vue";
|
||||||
import appMain from "./components/appMain.vue";
|
import appMain from "./components/appMain.vue";
|
||||||
import setting from "./components/setting/index.vue";
|
|
||||||
import Vertical from "./components/sidebar/vertical.vue";
|
import Vertical from "./components/sidebar/vertical.vue";
|
||||||
import Horizontal from "./components/sidebar/horizontal.vue";
|
import Horizontal from "./components/sidebar/horizontal.vue";
|
||||||
import backTop from "@/assets/svg/back_top.svg?component";
|
import backTop from "@/assets/svg/back_top.svg?component";
|
||||||
|
|
||||||
const appWrapperRef = ref();
|
const appWrapperRef = ref();
|
||||||
const { isDark } = useDark();
|
|
||||||
const { layout } = useLayout();
|
const { layout } = useLayout();
|
||||||
const isMobile = deviceDetection();
|
const isMobile = deviceDetection();
|
||||||
const pureSetting = useSettingStoreHook();
|
const pureSetting = useSettingStoreHook();
|
||||||
@@ -54,10 +52,6 @@ const set: setType = reactive({
|
|||||||
withoutAnimation: set.sidebar.withoutAnimation,
|
withoutAnimation: set.sidebar.withoutAnimation,
|
||||||
mobile: set.device === "mobile"
|
mobile: set.device === "mobile"
|
||||||
};
|
};
|
||||||
}),
|
|
||||||
|
|
||||||
hideTabs: computed(() => {
|
|
||||||
return $storage?.configure.hideTabs;
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -122,14 +116,7 @@ const layoutHeader = defineComponent({
|
|||||||
return h(
|
return h(
|
||||||
"div",
|
"div",
|
||||||
{
|
{
|
||||||
class: { "fixed-header": set.fixedHeader },
|
class: { "fixed-header": set.fixedHeader }
|
||||||
style: [
|
|
||||||
set.hideTabs && layout.value.includes("horizontal")
|
|
||||||
? isDark.value
|
|
||||||
? "box-shadow: 0 1px 4px #0d0d0d"
|
|
||||||
: "box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08)"
|
|
||||||
: ""
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
default: () => [
|
default: () => [
|
||||||
@@ -188,8 +175,6 @@ const layoutHeader = defineComponent({
|
|||||||
<app-main :fixed-header="set.fixedHeader" />
|
<app-main :fixed-header="set.fixedHeader" />
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
<!-- 系统设置 -->
|
|
||||||
<setting />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ export interface setType {
|
|||||||
withoutAnimation: boolean;
|
withoutAnimation: boolean;
|
||||||
mobile: boolean;
|
mobile: boolean;
|
||||||
};
|
};
|
||||||
hideTabs: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type menuType = {
|
export type menuType = {
|
||||||
|
|||||||
@@ -39,17 +39,6 @@ html.dark {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 项目配置面板 */
|
|
||||||
.right-panel-items {
|
|
||||||
.el-divider__text {
|
|
||||||
--el-bg-color: var(--el-bg-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-divider--horizontal {
|
|
||||||
border-top: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* element-plus */
|
/* element-plus */
|
||||||
.el-table__cell {
|
.el-table__cell {
|
||||||
background: var(--el-bg-color);
|
background: var(--el-bg-color);
|
||||||
|
|||||||
@@ -48,7 +48,6 @@
|
|||||||
|
|
||||||
/* 自定义 tooltip 的类名 */
|
/* 自定义 tooltip 的类名 */
|
||||||
.pure-tooltip {
|
.pure-tooltip {
|
||||||
// 右侧操作面板right-panel类名的z-index为40000,tooltip需要大于它才能显示
|
|
||||||
z-index: 41000 !important;
|
z-index: 41000 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,18 +3,6 @@
|
|||||||
@import "./sidebar";
|
@import "./sidebar";
|
||||||
@import "./dark";
|
@import "./dark";
|
||||||
|
|
||||||
/* 自定义全局 CssVar */
|
|
||||||
:root {
|
:root {
|
||||||
/* 左侧菜单展开、收起动画时长 */
|
|
||||||
--pure-transition-duration: 0.3s;
|
--pure-transition-duration: 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 灰色模式 */
|
|
||||||
.html-grey {
|
|
||||||
filter: grayscale(100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 色弱模式 */
|
|
||||||
.html-weakness {
|
|
||||||
filter: invert(80%);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,10 +3,6 @@ import mitt from "mitt";
|
|||||||
|
|
||||||
/** 全局公共事件需要在此处添加类型 */
|
/** 全局公共事件需要在此处添加类型 */
|
||||||
type Events = {
|
type Events = {
|
||||||
openPanel: string;
|
|
||||||
tagViewsChange: string;
|
|
||||||
tagViewsShowModel: string;
|
|
||||||
logoChange: boolean;
|
|
||||||
changLayoutRoute: string;
|
changLayoutRoute: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -17,11 +17,6 @@ export const injectResponsiveStorage = (app: App, config: ServerConfigs) => {
|
|||||||
epThemeColor: config.EpThemeColor ?? "#409EFF"
|
epThemeColor: config.EpThemeColor ?? "#409EFF"
|
||||||
},
|
},
|
||||||
configure: Storage.getData("configure", nameSpace) ?? {
|
configure: Storage.getData("configure", nameSpace) ?? {
|
||||||
grey: config.Grey ?? false,
|
|
||||||
weak: config.Weak ?? false,
|
|
||||||
hideTabs: config.HideTabs ?? false,
|
|
||||||
showLogo: config.ShowLogo ?? true,
|
|
||||||
showModel: config.ShowModel ?? "smart",
|
|
||||||
multiTagsCache: config.MultiTagsCache ?? false
|
multiTagsCache: config.MultiTagsCache ?? false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Vendored
-15
@@ -86,13 +86,8 @@ declare global {
|
|||||||
Layout?: string;
|
Layout?: string;
|
||||||
Theme?: string;
|
Theme?: string;
|
||||||
DarkMode?: boolean;
|
DarkMode?: boolean;
|
||||||
Grey?: boolean;
|
|
||||||
Weak?: boolean;
|
|
||||||
HideTabs?: boolean;
|
|
||||||
SidebarStatus?: boolean;
|
SidebarStatus?: boolean;
|
||||||
EpThemeColor?: string;
|
EpThemeColor?: string;
|
||||||
ShowLogo?: boolean;
|
|
||||||
ShowModel?: string;
|
|
||||||
MenuArrowIconNoTransition?: boolean;
|
MenuArrowIconNoTransition?: boolean;
|
||||||
CachingAsyncRoutes?: boolean;
|
CachingAsyncRoutes?: boolean;
|
||||||
TooltipEffect?: Effect;
|
TooltipEffect?: Effect;
|
||||||
@@ -114,13 +109,8 @@ declare global {
|
|||||||
layout?: string;
|
layout?: string;
|
||||||
theme?: string;
|
theme?: string;
|
||||||
darkMode?: boolean;
|
darkMode?: boolean;
|
||||||
grey?: boolean;
|
|
||||||
weak?: boolean;
|
|
||||||
hideTabs?: boolean;
|
|
||||||
sidebarStatus?: boolean;
|
sidebarStatus?: boolean;
|
||||||
epThemeColor?: string;
|
epThemeColor?: string;
|
||||||
showLogo?: boolean;
|
|
||||||
showModel?: string;
|
|
||||||
username?: string;
|
username?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,11 +129,6 @@ declare global {
|
|||||||
epThemeColor?: string;
|
epThemeColor?: string;
|
||||||
};
|
};
|
||||||
configure: {
|
configure: {
|
||||||
grey?: boolean;
|
|
||||||
weak?: boolean;
|
|
||||||
hideTabs?: boolean;
|
|
||||||
showLogo?: boolean;
|
|
||||||
showModel?: string;
|
|
||||||
multiTagsCache?: boolean;
|
multiTagsCache?: boolean;
|
||||||
};
|
};
|
||||||
tags?: Array<any>;
|
tags?: Array<any>;
|
||||||
|
|||||||
Reference in New Issue
Block a user