434 lines
12 KiB
Plaintext
434 lines
12 KiB
Plaintext
<template>
|
|
<a-drawer v-model:visible="isDrawer" :width="width" :placement="placement" :title="title">
|
|
<div class="drawer">
|
|
<a-divider>系统风格</a-divider>
|
|
|
|
<div class="drawer-setting-item align-items-top">
|
|
<div class="drawer-setting-item-style align-items-top">
|
|
<a-tooltip placement="top">
|
|
<template #title>
|
|
<span>亮色主题</span>
|
|
</template>
|
|
<div
|
|
class="nav-mode-item nav-mode-item-light"
|
|
@click="handleToggleTheme('light')"
|
|
></div>
|
|
</a-tooltip>
|
|
<a-badge status="processing" v-if="settingStore.navTheme === 'light'" />
|
|
</div>
|
|
|
|
<div class="drawer-setting-item-style">
|
|
<a-tooltip placement="top">
|
|
<template #title>
|
|
<span>暗色侧边栏</span>
|
|
</template>
|
|
<div class="nav-mode-item nav-mode-item-dark" @click="handleToggleTheme('dark')"></div>
|
|
</a-tooltip>
|
|
<a-badge
|
|
status="processing"
|
|
v-if="!settingStore.darkTheme && settingStore.navTheme === 'dark'"
|
|
/>
|
|
</div>
|
|
|
|
<div class="drawer-setting-item-style">
|
|
<a-tooltip placement="top">
|
|
<template #title>
|
|
<span>黑暗风格</span>
|
|
</template>
|
|
<div
|
|
disabled
|
|
class="nav-mode-item nav-darkness nav-mode-item-darkness"
|
|
@click="handleToggleTheme('darkness')"
|
|
></div>
|
|
</a-tooltip>
|
|
<a-badge status="processing" v-if="settingStore.darkTheme" />
|
|
</div>
|
|
</div>
|
|
|
|
<a-divider>菜单布局模式</a-divider>
|
|
|
|
<div class="drawer-setting-item align-items-top">
|
|
<div class="drawer-setting-item-style align-items-top">
|
|
<a-tooltip placement="top">
|
|
<template #title>
|
|
<span>左侧菜单模式</span>
|
|
</template>
|
|
<div class="nav-mode-item nav-mode-item-side" @click="toggleLayout('side')"></div>
|
|
</a-tooltip>
|
|
<a-badge status="processing" v-if="settingStore.layout === 'side'" />
|
|
</div>
|
|
|
|
<div class="drawer-setting-item-style">
|
|
<a-tooltip placement="top">
|
|
<template #title>
|
|
<span>顶部菜单模式</span>
|
|
</template>
|
|
<div class="nav-mode-item nav-mode-item-top" @click="toggleLayout('top')"></div>
|
|
</a-tooltip>
|
|
<a-badge status="processing" v-if="settingStore.layout === 'top'" />
|
|
</div>
|
|
|
|
<div class="drawer-setting-item-style">
|
|
<a-tooltip placement="top">
|
|
<template #title>
|
|
<span>混合菜单</span>
|
|
</template>
|
|
<div class="nav-mode-item nav-mode-item-mix" @click="toggleLayout('mix')"></div>
|
|
</a-tooltip>
|
|
<a-badge status="processing" v-if="settingStore.layout === 'mix'" />
|
|
</div>
|
|
</div>
|
|
|
|
<a-divider>界面功能</a-divider>
|
|
|
|
<div class="drawer-setting-item">
|
|
<div class="drawer-setting-item-title"> 显示顶栏 </div>
|
|
<div class="drawer-setting-item-action">
|
|
<a-switch v-model:checked="settingStore.headerSetting.show" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="drawer-setting-item">
|
|
<div class="drawer-setting-item-title"> 固定顶栏 </div>
|
|
<div class="drawer-setting-item-action">
|
|
<a-switch v-model:checked="settingStore.headerSetting.fixed" />
|
|
</div>
|
|
</div>
|
|
|
|
<!-- <div class="drawer-setting-item">-->
|
|
<!-- <div class="drawer-setting-item-title">-->
|
|
<!-- 固定侧边栏-->
|
|
<!-- </div>-->
|
|
<!-- <div class="drawer-setting-item-action">-->
|
|
<!-- <a-switch v-model:checked="settingStore.menuSetting.fixed" />-->
|
|
<!-- </div>-->
|
|
<!-- </div>-->
|
|
|
|
<a-divider>界面显示</a-divider>
|
|
|
|
<div class="drawer-setting-item">
|
|
<div class="drawer-setting-item-title"> 显示菜单 </div>
|
|
<div class="drawer-setting-item-action">
|
|
<a-switch v-model:checked="settingStore.menuSetting.show" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="drawer-setting-item">
|
|
<div class="drawer-setting-item-title"> 折叠菜单 </div>
|
|
<div class="drawer-setting-item-action">
|
|
<a-switch v-model:checked="settingStore.menuSetting.collapsed" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="drawer-setting-item">
|
|
<div class="drawer-setting-item-title"> 重载页面按钮 </div>
|
|
<div class="drawer-setting-item-action">
|
|
<a-switch v-model:checked="settingStore.headerSetting.reload" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="drawer-setting-item">
|
|
<div class="drawer-setting-item-title"> 面包屑导航 </div>
|
|
<div class="drawer-setting-item-action">
|
|
<a-switch v-model:checked="settingStore.crumbsSetting.show" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="drawer-setting-item">
|
|
<div class="drawer-setting-item-title"> 面包屑显示图标 </div>
|
|
<div class="drawer-setting-item-action">
|
|
<a-switch v-model:checked="settingStore.crumbsSetting.showIcon" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="drawer-setting-item">
|
|
<div class="drawer-setting-item-title"> 多页签 </div>
|
|
<div class="drawer-setting-item-action">
|
|
<a-switch v-model:checked="settingStore.multiTabsSetting.show" />
|
|
</div>
|
|
</div>
|
|
<div class="drawer-setting-item">
|
|
<div class="drawer-setting-item-title"> 水印 </div>
|
|
<div class="drawer-setting-item-action">
|
|
<a-switch v-model:checked="settingStore.isWaterMark" @change="handleWaterChange" />
|
|
</div>
|
|
</div>
|
|
|
|
<a-divider>动画</a-divider>
|
|
|
|
<div class="drawer-setting-item">
|
|
<div class="drawer-setting-item-title"> 切换动画</div>
|
|
<div class="drawer-setting-item-action">
|
|
<a-switch v-model:checked="settingStore.isPageAnimate" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="drawer-setting-item">
|
|
<div class="drawer-setting-item-title"> 动画类型</div>
|
|
<div class="drawer-setting-item-select">
|
|
<a-select
|
|
style="width: 120px"
|
|
v-model:value="settingStore.pageAnimateType"
|
|
:options="animateOptions"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="drawer-setting-item">
|
|
<a-alert type="warning" :message="alertText" />
|
|
</div>
|
|
</div>
|
|
</a-drawer>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { ref } from 'vue';
|
|
import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
|
import { animates as animateOptions } from '@/settings/animateSetting';
|
|
import { toggleTheme } from '@zougt/vite-plugin-theme-preprocessor/dist/browser-utils';
|
|
import Watermark from '@/utils/wartermark';
|
|
|
|
defineProps({
|
|
title: {
|
|
type: String,
|
|
default: '项目配置',
|
|
},
|
|
width: {
|
|
type: Number,
|
|
default: 280,
|
|
},
|
|
});
|
|
|
|
const settingStore = useProjectSettingStore();
|
|
|
|
const isDrawer = ref(false);
|
|
const placement = ref('right');
|
|
|
|
const alertText = ref(
|
|
'该功能主要实时预览各种布局效果,更多完整配置在 projectSetting.ts 中设置,建议在生产环境关闭该布局预览功能。',
|
|
);
|
|
|
|
function openDrawer() {
|
|
isDrawer.value = true;
|
|
}
|
|
|
|
function handleToggleTheme(theme) {
|
|
const isDark = theme === 'darkness';
|
|
const darkMode = isDark ? 'dark' : 'light';
|
|
const inTheme = isDark ? darkMode : theme;
|
|
settingStore.darkTheme = isDark;
|
|
settingStore.navTheme = inTheme;
|
|
settingStore.headerTheme = inTheme;
|
|
// document.documentElement.className = `theme-${darkMode}`;
|
|
updateDarkTheme(darkMode);
|
|
}
|
|
|
|
async function updateDarkTheme(mode: string | null = 'light') {
|
|
const htmlRoot = document.getElementById('htmlRoot');
|
|
if (!htmlRoot) {
|
|
return;
|
|
}
|
|
// const hasDarkClass = hasClass(htmlRoot, 'dark');
|
|
if (mode === 'dark') {
|
|
// if (import.meta.env.PROD && !darkCssIsReady) {
|
|
// await loadDarkThemeCss();
|
|
// }
|
|
toggleTheme({
|
|
scopeName: 'theme-dark',
|
|
});
|
|
// htmlRoot.setAttribute('data-theme', 'dark');
|
|
// if (!hasDarkClass) {
|
|
// addClass(htmlRoot, 'dark');
|
|
// }
|
|
} else {
|
|
//htmlRoot.setAttribute('data-theme', 'light');
|
|
toggleTheme({
|
|
scopeName: 'theme-default',
|
|
});
|
|
// if (hasDarkClass) {
|
|
// removeClass(htmlRoot, 'dark');
|
|
// }
|
|
}
|
|
}
|
|
function handleWaterChange(val){
|
|
if(val) {
|
|
const waterText = import.meta.env.VITE_GLOB_APP_TITLE;
|
|
Watermark.set(waterText)
|
|
} else {
|
|
Watermark.del()
|
|
}
|
|
}
|
|
function toggleLayout(mode) {
|
|
settingStore.layout = mode;
|
|
if (mode === 'mix') {
|
|
settingStore.menuSetting.split = true;
|
|
}
|
|
}
|
|
|
|
defineExpose({
|
|
openDrawer,
|
|
});
|
|
</script>
|
|
|
|
<style lang="less" scoped>
|
|
.drawer {
|
|
.n-divider:not(.n-divider--vertical) {
|
|
margin: 10px 0;
|
|
}
|
|
|
|
&-setting-item {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 12px 0;
|
|
flex-wrap: wrap;
|
|
|
|
&-style {
|
|
display: inline-block;
|
|
position: relative;
|
|
margin-right: 16px;
|
|
cursor: pointer;
|
|
text-align: center;
|
|
}
|
|
|
|
&-title {
|
|
flex: 1 1;
|
|
font-size: 14px;
|
|
}
|
|
|
|
&-action {
|
|
flex: 0 0 auto;
|
|
}
|
|
|
|
.theme-item {
|
|
width: 20px;
|
|
min-width: 20px;
|
|
height: 20px;
|
|
cursor: pointer;
|
|
border: 1px solid #eee;
|
|
border-radius: 2px;
|
|
margin: 0 5px 5px 0;
|
|
text-align: center;
|
|
|
|
.n-icon {
|
|
color: #fff;
|
|
}
|
|
}
|
|
}
|
|
|
|
.align-items-top {
|
|
align-items: flex-start;
|
|
padding: 0;
|
|
}
|
|
|
|
.justify-center {
|
|
justify-content: center;
|
|
}
|
|
|
|
.dark-switch .a-switch--active {
|
|
:deep(.a-switch__rail) {
|
|
background-color: #000e1c;
|
|
}
|
|
}
|
|
.nav-mode-item {
|
|
position: relative;
|
|
width: 46px;
|
|
height: 38px;
|
|
overflow: hidden;
|
|
background-color: #f0f2f5;
|
|
border-radius: 4px;
|
|
margin-right: 10px;
|
|
box-shadow: 0 1px 2.5px 0 rgb(0 0 0 / 18%);
|
|
cursor: pointer;
|
|
|
|
&:before {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 33%;
|
|
height: 100%;
|
|
background-color: #fff;
|
|
content: '';
|
|
}
|
|
|
|
&:after {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 25%;
|
|
background-color: #fff;
|
|
content: '';
|
|
}
|
|
|
|
&-side {
|
|
&:before {
|
|
z-index: 1;
|
|
background-color: rgba(0, 21, 41, 0.85) !important;
|
|
content: '';
|
|
}
|
|
&:after {
|
|
background-color: #fff;
|
|
}
|
|
}
|
|
|
|
&-top {
|
|
&:before {
|
|
background-color: #f0f2f5;
|
|
content: '';
|
|
}
|
|
&:after {
|
|
z-index: 1;
|
|
background-color: rgba(0, 21, 41, 0.85) !important;
|
|
}
|
|
}
|
|
|
|
&-mix {
|
|
&:before {
|
|
background-color: #fff;
|
|
content: '';
|
|
}
|
|
&:after {
|
|
z-index: 1;
|
|
background-color: rgba(0, 21, 41, 0.85) !important;
|
|
}
|
|
}
|
|
|
|
&-light {
|
|
&:before {
|
|
background-color: #fff;
|
|
content: '';
|
|
}
|
|
&:after {
|
|
z-index: 1;
|
|
background-color: #fff;
|
|
}
|
|
}
|
|
|
|
&-dark {
|
|
&:before {
|
|
z-index: 1;
|
|
background-color: rgba(0, 21, 41, 0.85) !important;
|
|
content: '';
|
|
}
|
|
&:after {
|
|
background-color: #fff;
|
|
}
|
|
}
|
|
|
|
&-darkness {
|
|
&:before {
|
|
background-color: rgba(0, 21, 41, 0.65) !important;
|
|
content: '';
|
|
}
|
|
&:after {
|
|
z-index: 1;
|
|
background-color: rgba(0, 21, 41, 0.85) !important;
|
|
}
|
|
}
|
|
}
|
|
.nav-darkness {
|
|
background-color: rgba(0, 21, 41, 0.85) !important;
|
|
}
|
|
}
|
|
</style>
|