mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-09-22 11:36:37 +08:00
feat(projects): 主题配置抽屉: 迁移其他功能
This commit is contained in:
parent
912bfdf439
commit
6d132c5977
@ -23,6 +23,7 @@
|
||||
"dependencies": {
|
||||
"@vueuse/core": "^7.5.3",
|
||||
"axios": "^0.24.0",
|
||||
"clipboard": "^2.0.8",
|
||||
"colord": "^2.9.2",
|
||||
"crypto-js": "^4.1.1",
|
||||
"dayjs": "^1.10.7",
|
||||
|
@ -15,6 +15,7 @@ specifiers:
|
||||
'@vue/eslint-config-typescript': ^10.0.0
|
||||
'@vueuse/core': ^7.5.3
|
||||
axios: ^0.24.0
|
||||
clipboard: ^2.0.8
|
||||
colord: ^2.9.2
|
||||
commitizen: ^4.2.4
|
||||
cross-env: ^7.0.3
|
||||
@ -57,6 +58,7 @@ specifiers:
|
||||
dependencies:
|
||||
'@vueuse/core': registry.npmmirror.com/@vueuse/core/7.5.3_vue@3.2.26
|
||||
axios: registry.npmmirror.com/axios/0.24.0
|
||||
clipboard: registry.npmmirror.com/clipboard/2.0.8
|
||||
colord: registry.npmmirror.com/colord/2.9.2
|
||||
crypto-js: registry.npmmirror.com/crypto-js/4.1.1
|
||||
dayjs: registry.npmmirror.com/dayjs/1.10.7
|
||||
@ -711,6 +713,12 @@ packages:
|
||||
engines: {node: '>=0.4.0'}
|
||||
dev: false
|
||||
|
||||
registry.nlark.com/delegate/3.2.0:
|
||||
resolution: {integrity: sha1-tmtxwxWFIuirV0T3INjKDCr1kWY=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/delegate/download/delegate-3.2.0.tgz}
|
||||
name: delegate
|
||||
version: 3.2.0
|
||||
dev: false
|
||||
|
||||
registry.nlark.com/detect-file/1.0.0:
|
||||
resolution: {integrity: sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/detect-file/download/detect-file-1.0.0.tgz}
|
||||
name: detect-file
|
||||
@ -1258,6 +1266,14 @@ packages:
|
||||
slash: registry.nlark.com/slash/3.0.0
|
||||
dev: true
|
||||
|
||||
registry.nlark.com/good-listener/1.2.2:
|
||||
resolution: {integrity: sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/good-listener/download/good-listener-1.2.2.tgz}
|
||||
name: good-listener
|
||||
version: 1.2.2
|
||||
dependencies:
|
||||
delegate: registry.nlark.com/delegate/3.2.0
|
||||
dev: false
|
||||
|
||||
registry.nlark.com/hard-rejection/2.1.0:
|
||||
resolution: {integrity: sha1-HG7aXBaFxjlCdm15u0Cudzzs2IM=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/hard-rejection/download/hard-rejection-2.1.0.tgz}
|
||||
name: hard-rejection
|
||||
@ -2471,6 +2487,12 @@ packages:
|
||||
version: 2.1.2
|
||||
dev: true
|
||||
|
||||
registry.nlark.com/select/1.1.2:
|
||||
resolution: {integrity: sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/select/download/select-1.1.2.tgz}
|
||||
name: select
|
||||
version: 1.1.2
|
||||
dev: false
|
||||
|
||||
registry.nlark.com/semver/5.7.1:
|
||||
resolution: {integrity: sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/semver/download/semver-5.7.1.tgz?cache=0&sync_timestamp=1631500167672&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz}
|
||||
name: semver
|
||||
@ -2745,6 +2767,12 @@ packages:
|
||||
readable-stream: registry.nlark.com/readable-stream/3.6.0
|
||||
dev: true
|
||||
|
||||
registry.nlark.com/tiny-emitter/2.1.0:
|
||||
resolution: {integrity: sha1-HRpW7fxRxD6GPLtTgqcjMONVVCM=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/tiny-emitter/download/tiny-emitter-2.1.0.tgz}
|
||||
name: tiny-emitter
|
||||
version: 2.1.0
|
||||
dev: false
|
||||
|
||||
registry.nlark.com/tmp/0.0.33:
|
||||
resolution: {integrity: sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=, registry: http://registry.npm.taobao.org/, tarball: https://registry.nlark.com/tmp/download/tmp-0.0.33.tgz}
|
||||
name: tmp
|
||||
@ -4227,6 +4255,16 @@ packages:
|
||||
string-width: registry.npmmirror.com/string-width/5.0.1
|
||||
dev: true
|
||||
|
||||
registry.npmmirror.com/clipboard/2.0.8:
|
||||
resolution: {integrity: sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/clipboard/download/clipboard-2.0.8.tgz}
|
||||
name: clipboard
|
||||
version: 2.0.8
|
||||
dependencies:
|
||||
good-listener: registry.nlark.com/good-listener/1.2.2
|
||||
select: registry.nlark.com/select/1.1.2
|
||||
tiny-emitter: registry.nlark.com/tiny-emitter/2.1.0
|
||||
dev: false
|
||||
|
||||
registry.npmmirror.com/color-convert/1.9.3:
|
||||
resolution: {integrity: sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=, registry: http://registry.npm.taobao.org/, tarball: https://registry.npmmirror.com/color-convert/download/color-convert-1.9.3.tgz}
|
||||
name: color-convert
|
||||
|
@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<n-divider title-placement="center">界面功能</n-divider>
|
||||
<n-space vertical size="large">
|
||||
<setting-menu label="固定头部和多页签">
|
||||
<n-switch :value="theme.fixedHeaderAndTab" @update:value="setIsFixedHeaderAndTab" />
|
||||
</setting-menu>
|
||||
<setting-menu label="顶部菜单位置">
|
||||
<n-select
|
||||
class="w-120px"
|
||||
size="small"
|
||||
:value="theme.menu.horizontalPosition"
|
||||
:options="theme.menu.horizontalPositionList"
|
||||
@update:value="setHorizontalMenuPosition"
|
||||
/>
|
||||
</setting-menu>
|
||||
<setting-menu label="头部高度">
|
||||
<n-input-number
|
||||
class="w-120px"
|
||||
size="small"
|
||||
:value="theme.header.height"
|
||||
:step="1"
|
||||
@update:value="handleSetNumber($event, setHeaderHeight)"
|
||||
/>
|
||||
</setting-menu>
|
||||
<setting-menu label="多页签高度">
|
||||
<n-input-number
|
||||
class="w-120px"
|
||||
size="small"
|
||||
:value="theme.tab.height"
|
||||
:step="1"
|
||||
@update:value="handleSetNumber($event, setTabHeight)"
|
||||
/>
|
||||
</setting-menu>
|
||||
<setting-menu label="多页签缓存">
|
||||
<n-switch :value="theme.tab.isCache" @update:value="setTabIsCache" />
|
||||
</setting-menu>
|
||||
<setting-menu label="侧边栏展开宽度">
|
||||
<n-input-number
|
||||
class="w-120px"
|
||||
size="small"
|
||||
:value="theme.sider.width"
|
||||
:step="10"
|
||||
@update:value="handleSetNumber($event, setSiderWidth)"
|
||||
/>
|
||||
</setting-menu>
|
||||
<setting-menu label="左侧混合侧边栏展开宽度">
|
||||
<n-input-number
|
||||
class="w-120px"
|
||||
size="small"
|
||||
:value="theme.sider.mixWidth"
|
||||
:step="5"
|
||||
@update:value="handleSetNumber($event, setMixSiderWidth)"
|
||||
/>
|
||||
</setting-menu>
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { NDivider, NSpace, NSwitch, NSelect, NInputNumber } from 'naive-ui';
|
||||
import { useThemeStore } from '@/store';
|
||||
import SettingMenu from '../SettingMenu/index.vue';
|
||||
|
||||
const theme = useThemeStore();
|
||||
const {
|
||||
setHorizontalMenuPosition,
|
||||
setIsFixedHeaderAndTab,
|
||||
setHeaderHeight,
|
||||
setTabHeight,
|
||||
setSiderWidth,
|
||||
setMixSiderWidth,
|
||||
setTabIsCache
|
||||
} = useThemeStore();
|
||||
|
||||
function handleSetNumber(value: number | null, callback: (value: number) => void) {
|
||||
if (value !== null) {
|
||||
callback(value);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped></style>
|
@ -0,0 +1,52 @@
|
||||
<template>
|
||||
<n-divider title-placement="center">界面显示</n-divider>
|
||||
<n-space vertical size="large">
|
||||
<setting-menu label="面包屑">
|
||||
<n-switch :value="theme.header.crumb.visible" @update:value="setHeaderCrumbVisible" />
|
||||
</setting-menu>
|
||||
<setting-menu label="面包屑图标">
|
||||
<n-switch :value="theme.header.crumb.showIcon" @update:value="setHeaderCrumbIconVisible" />
|
||||
</setting-menu>
|
||||
<setting-menu label="多页签">
|
||||
<n-switch :value="theme.tab.visible" @update:value="setTabVisible" />
|
||||
</setting-menu>
|
||||
<setting-menu label="多页签风格">
|
||||
<n-select
|
||||
class="w-120px"
|
||||
size="small"
|
||||
:value="theme.tab.mode"
|
||||
:options="theme.tab.modeList"
|
||||
@update:value="setTabMode"
|
||||
/>
|
||||
</setting-menu>
|
||||
<setting-menu label="页面切换动画">
|
||||
<n-switch :value="theme.page.animate" @update:value="setPageIsAnimate" />
|
||||
</setting-menu>
|
||||
<setting-menu label="页面切换动画类型">
|
||||
<n-select
|
||||
class="w-120px"
|
||||
size="small"
|
||||
:value="theme.page.animateMode"
|
||||
:options="theme.page.animateModeList"
|
||||
@update:value="setPageAnimateMode"
|
||||
/>
|
||||
</setting-menu>
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { NDivider, NSpace, NSwitch, NSelect } from 'naive-ui';
|
||||
import { useThemeStore } from '@/store';
|
||||
import SettingMenu from '../SettingMenu/index.vue';
|
||||
|
||||
const theme = useThemeStore();
|
||||
const {
|
||||
setHeaderCrumbVisible,
|
||||
setHeaderCrumbIconVisible,
|
||||
setTabVisible,
|
||||
setTabMode,
|
||||
setPageIsAnimate,
|
||||
setPageAnimateMode
|
||||
} = useThemeStore();
|
||||
</script>
|
||||
<style scoped></style>
|
@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<div class="flex-y-center justify-between">
|
||||
<span>{{ label }}</span>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
interface Props {
|
||||
/** 文本 */
|
||||
label: string;
|
||||
}
|
||||
|
||||
defineProps<Props>();
|
||||
</script>
|
||||
<style scoped></style>
|
@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<n-divider title-placement="center">主题配置</n-divider>
|
||||
<n-space vertical>
|
||||
<div ref="copyRef" :data-clipboard-text="dataClipboardText">
|
||||
<n-button type="primary" :block="true">拷贝当前配置</n-button>
|
||||
</div>
|
||||
<n-button type="warning" :block="true" @click="handleResetConfig">重置当前配置</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, onMounted, onUnmounted } from 'vue';
|
||||
import { NDivider, NSpace, NButton } from 'naive-ui';
|
||||
import Clipboard from 'clipboard';
|
||||
import { useThemeStore } from '@/store';
|
||||
|
||||
const theme = useThemeStore();
|
||||
|
||||
const copyRef = ref<HTMLElement | null>(null);
|
||||
const dataClipboardText = ref(getClipboardText());
|
||||
|
||||
function getClipboardText() {
|
||||
return JSON.stringify(theme.$state);
|
||||
}
|
||||
|
||||
function handleResetConfig() {
|
||||
theme.resetThemeStore();
|
||||
window.$message?.success('已重置配置,请重新拷贝!');
|
||||
}
|
||||
|
||||
function clipboardEventListener() {
|
||||
const copy = new Clipboard(copyRef.value!);
|
||||
copy.on('success', () => {
|
||||
window.$dialog?.success({
|
||||
title: '操作成功',
|
||||
content: '复制成功,请替换 src/settings/theme.json的内容!',
|
||||
positiveText: '确定'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const stopHandle = watch(
|
||||
() => theme.$state,
|
||||
() => {
|
||||
dataClipboardText.value = getClipboardText();
|
||||
},
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
clipboardEventListener();
|
||||
});
|
||||
onUnmounted(() => {
|
||||
stopHandle();
|
||||
});
|
||||
</script>
|
||||
<style scoped></style>
|
@ -2,5 +2,8 @@ import DrawerButton from './DrawerButton/index.vue';
|
||||
import DarkMode from './DarkMode/index.vue';
|
||||
import LayoutMode from './LayoutMode/index.vue';
|
||||
import ThemeColorSelect from './ThemeColorSelect/index.vue';
|
||||
import PageFunc from './PageFunc/index.vue';
|
||||
import PageView from './PageView/index.vue';
|
||||
import ThemeConfig from './ThemeConfig/index.vue';
|
||||
|
||||
export { DarkMode, DrawerButton, LayoutMode, ThemeColorSelect };
|
||||
export { DrawerButton, DarkMode, LayoutMode, ThemeColorSelect, PageFunc, PageView, ThemeConfig };
|
||||
|
@ -4,6 +4,9 @@
|
||||
<dark-mode />
|
||||
<layout-mode />
|
||||
<theme-color-select />
|
||||
<page-func />
|
||||
<page-view />
|
||||
<theme-config />
|
||||
</n-drawer-content>
|
||||
</n-drawer>
|
||||
<drawer-button />
|
||||
@ -12,7 +15,7 @@
|
||||
<script setup lang="ts">
|
||||
import { NDrawer, NDrawerContent } from 'naive-ui';
|
||||
import { useAppStore } from '@/store';
|
||||
import { DrawerButton, DarkMode, LayoutMode, ThemeColorSelect } from './components';
|
||||
import { DrawerButton, DarkMode, LayoutMode, ThemeColorSelect, PageFunc, PageView, ThemeConfig } from './components';
|
||||
|
||||
const app = useAppStore();
|
||||
</script>
|
||||
|
@ -32,7 +32,6 @@ interface AuthStore {
|
||||
|
||||
export const useAuthStore = defineStore('auth-store', () => {
|
||||
const { toLogin, toLoginRedirect } = useRouterPush(false);
|
||||
const { loading: loginLoding, startLoading: startLoginLoading, endLoading: endLoginLoading } = useLoading();
|
||||
|
||||
const userInfo: Auth.UserInfo = reactive(getUserInfo());
|
||||
function handleSetUserInfo(data: Auth.UserInfo) {
|
||||
@ -46,12 +45,18 @@ export const useAuthStore = defineStore('auth-store', () => {
|
||||
|
||||
const isLogin = computed(() => Boolean(token.value));
|
||||
|
||||
const { loading: loginLoding, startLoading: startLoginLoading, endLoading: endLoginLoading } = useLoading();
|
||||
|
||||
function resetStore() {
|
||||
handleSetUserInfo(getUserInfo());
|
||||
handleSetToken(getToken());
|
||||
}
|
||||
|
||||
function resetAuthStore(pushRoute: boolean = true) {
|
||||
const auth = useAuthStore();
|
||||
const route = unref(globalRouter.currentRoute);
|
||||
|
||||
clearAuthStorage();
|
||||
auth.$reset();
|
||||
resetStore();
|
||||
|
||||
if (pushRoute && route.meta.requiresAuth) {
|
||||
toLogin();
|
||||
|
@ -67,6 +67,8 @@ interface ThemeStore extends LayoutFunc, HeaderFunc, TabFunc, SiderFunc, FooterF
|
||||
naiveThemeOverrides: ComputedRef<GlobalThemeOverrides>;
|
||||
/** naive-ui暗黑主题 */
|
||||
naiveTheme: ComputedRef<BuiltInGlobalTheme | undefined>;
|
||||
/** 重置状态 */
|
||||
resetThemeStore(): void;
|
||||
}
|
||||
|
||||
export const useThemeStore = defineStore('theme-store', () => {
|
||||
@ -148,6 +150,11 @@ export const useThemeStore = defineStore('theme-store', () => {
|
||||
);
|
||||
const naiveTheme = computed(() => (darkMode.value ? darkTheme : undefined));
|
||||
|
||||
/** 重置theme状态 */
|
||||
function resetThemeStore() {
|
||||
setDarkMode(false);
|
||||
}
|
||||
|
||||
/** 初始化css vars, 并添加至html */
|
||||
function initThemeCssVars() {
|
||||
const updatedThemeVars = { ...naiveThemeOverrides.value.common };
|
||||
@ -214,7 +221,8 @@ export const useThemeStore = defineStore('theme-store', () => {
|
||||
setPageIsAnimate,
|
||||
setPageAnimateMode,
|
||||
naiveThemeOverrides,
|
||||
naiveTheme
|
||||
naiveTheme,
|
||||
resetThemeStore
|
||||
};
|
||||
|
||||
return themeStore;
|
||||
|
Loading…
Reference in New Issue
Block a user