mirror of
https://github.com/jekip/naive-ui-admin.git
synced 2026-03-01 00:23:11 +08:00
Merge pull request #233 from WangHansen/refactor/1.8.3
refactor: remove unused files, bug fixes, name changes
This commit is contained in:
18
src/App.vue
18
src/App.vue
@@ -21,16 +21,16 @@
|
|||||||
import { zhCN, dateZhCN, darkTheme } from 'naive-ui';
|
import { zhCN, dateZhCN, darkTheme } from 'naive-ui';
|
||||||
import { LockScreen } from '@/components/Lockscreen';
|
import { LockScreen } from '@/components/Lockscreen';
|
||||||
import { AppProvider } from '@/components/Application';
|
import { AppProvider } from '@/components/Application';
|
||||||
import { useLockscreenStore } from '@/store/modules/lockscreen';
|
import { useScreenLockStore } from '@/store/modules/screenLock.js';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { useDesignSettingStore } from '@/store/modules/designSetting';
|
import { useDesignSettingStore } from '@/store/modules/designSetting';
|
||||||
import { lighten } from '@/utils/index';
|
import { lighten } from '@/utils/index';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const useLockscreen = useLockscreenStore();
|
const useScreenLock = useScreenLockStore();
|
||||||
const designStore = useDesignSettingStore();
|
const designStore = useDesignSettingStore();
|
||||||
const isLock = computed(() => useLockscreen.isLock);
|
const isLock = computed(() => useScreenLock.isLocked);
|
||||||
const lockTime = computed(() => useLockscreen.lockTime);
|
const lockTime = computed(() => useScreenLock.lockTime);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type import('naive-ui').GlobalThemeOverrides
|
* @type import('naive-ui').GlobalThemeOverrides
|
||||||
@@ -53,21 +53,21 @@
|
|||||||
|
|
||||||
const getDarkTheme = computed(() => (designStore.darkTheme ? darkTheme : undefined));
|
const getDarkTheme = computed(() => (designStore.darkTheme ? darkTheme : undefined));
|
||||||
|
|
||||||
let timer;
|
let timer: NodeJS.Timer;
|
||||||
|
|
||||||
const timekeeping = () => {
|
const timekeeping = () => {
|
||||||
clearInterval(timer);
|
clearInterval(timer);
|
||||||
if (route.name == 'login' || isLock.value) return;
|
if (route.name == 'login' || isLock.value) return;
|
||||||
// 设置不锁屏
|
// 设置不锁屏
|
||||||
useLockscreen.setLock(false);
|
useScreenLock.setLock(false);
|
||||||
// 重置锁屏时间
|
// 重置锁屏时间
|
||||||
useLockscreen.setLockTime();
|
useScreenLock.setLockTime();
|
||||||
timer = setInterval(() => {
|
timer = setInterval(() => {
|
||||||
// 锁屏倒计时递减
|
// 锁屏倒计时递减
|
||||||
useLockscreen.setLockTime(lockTime.value - 1);
|
useScreenLock.setLockTime(lockTime.value - 1);
|
||||||
if (lockTime.value <= 0) {
|
if (lockTime.value <= 0) {
|
||||||
// 设置锁屏
|
// 设置锁屏
|
||||||
useLockscreen.setLock(true);
|
useScreenLock.setLock(true);
|
||||||
return clearInterval(timer);
|
return clearInterval(timer);
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|||||||
@@ -60,11 +60,11 @@
|
|||||||
</template>
|
</template>
|
||||||
</n-input>
|
</n-input>
|
||||||
|
|
||||||
<div class="w-full flex" v-if="isLoginError">
|
<div class="flex w-full" v-if="isLoginError">
|
||||||
<span class="text-red-500">{{ errorMsg }}</span>
|
<span class="text-red-500">{{ errorMsg }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w-full mt-1 flex justify-around">
|
<div class="flex justify-around w-full mt-1">
|
||||||
<div><a @click="showLogin = false">返回</a></div>
|
<div><a @click="showLogin = false">返回</a></div>
|
||||||
<div><a @click="goLogin">重新登录</a></div>
|
<div><a @click="goLogin">重新登录</a></div>
|
||||||
<div><a @click="onLogin">进入系统</a></div>
|
<div><a @click="onLogin">进入系统</a></div>
|
||||||
@@ -91,11 +91,11 @@
|
|||||||
import { useOnline } from '@/hooks/useOnline';
|
import { useOnline } from '@/hooks/useOnline';
|
||||||
import { useTime } from '@/hooks/useTime';
|
import { useTime } from '@/hooks/useTime';
|
||||||
import { useBattery } from '@/hooks/useBattery';
|
import { useBattery } from '@/hooks/useBattery';
|
||||||
import { useLockscreenStore } from '@/store/modules/lockscreen';
|
import { useScreenLockStore } from '@/store/modules/screenLock';
|
||||||
import { useUserStore } from '@/store/modules/user';
|
import { UserInfoType, useUserStore } from '@/store/modules/user';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Lockscreen',
|
name: 'ScreenLock',
|
||||||
components: {
|
components: {
|
||||||
LockOutlined,
|
LockOutlined,
|
||||||
LoadingOutlined,
|
LoadingOutlined,
|
||||||
@@ -106,7 +106,7 @@
|
|||||||
recharge,
|
recharge,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const useLockscreen = useLockscreenStore();
|
const useScreenLock = useScreenLockStore();
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
|
|
||||||
// 获取时间
|
// 获取时间
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
const { battery, batteryStatus, calcDischargingTime, calcChargingTime } = useBattery();
|
const { battery, batteryStatus, calcDischargingTime, calcChargingTime } = useBattery();
|
||||||
const userInfo: object = userStore.getUserInfo || {};
|
const userInfo: UserInfoType = userStore.getUserInfo || {};
|
||||||
const username = userInfo['username'] || '';
|
const username = userInfo['username'] || '';
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
showLogin: false,
|
showLogin: false,
|
||||||
@@ -146,7 +146,7 @@
|
|||||||
const { code, message } = await userStore.login(params);
|
const { code, message } = await userStore.login(params);
|
||||||
if (code === ResultEnum.SUCCESS) {
|
if (code === ResultEnum.SUCCESS) {
|
||||||
onLockLogin(false);
|
onLockLogin(false);
|
||||||
useLockscreen.setLock(false);
|
useScreenLock.setLock(false);
|
||||||
} else {
|
} else {
|
||||||
state.errorMsg = message;
|
state.errorMsg = message;
|
||||||
state.isLoginError = true;
|
state.isLoginError = true;
|
||||||
@@ -157,7 +157,7 @@
|
|||||||
//重新登录
|
//重新登录
|
||||||
const goLogin = () => {
|
const goLogin = () => {
|
||||||
onLockLogin(false);
|
onLockLogin(false);
|
||||||
useLockscreen.setLock(false);
|
useScreenLock.setLock(false);
|
||||||
router.replace({
|
router.replace({
|
||||||
path: '/login',
|
path: '/login',
|
||||||
query: {
|
query: {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* 接收参数:string类型/Ref<string>类型/Reactive<string>类型
|
* 接收参数:string类型/Ref<string>类型/Reactive<string>类型
|
||||||
*/
|
*/
|
||||||
import type { Directive, DirectiveBinding } from 'vue';
|
import type { Directive, DirectiveBinding } from 'vue';
|
||||||
import { useMessage } from 'naive-ui';
|
|
||||||
interface ElType extends HTMLElement {
|
interface ElType extends HTMLElement {
|
||||||
copyData: string | number;
|
copyData: string | number;
|
||||||
__handleClick__: any;
|
__handleClick__: any;
|
||||||
|
|||||||
@@ -3,29 +3,29 @@
|
|||||||
* 按钮防抖指令,可自行扩展至input
|
* 按钮防抖指令,可自行扩展至input
|
||||||
* 接收参数:function类型
|
* 接收参数:function类型
|
||||||
*/
|
*/
|
||||||
import type { Directive, DirectiveBinding } from "vue";
|
import type { Directive, DirectiveBinding } from 'vue';
|
||||||
interface ElType extends HTMLElement {
|
interface ElType extends HTMLElement {
|
||||||
__handleClick__: () => any;
|
__handleClick__: () => any;
|
||||||
}
|
}
|
||||||
const debounce: Directive = {
|
const debounce: Directive = {
|
||||||
mounted(el: ElType, binding: DirectiveBinding) {
|
mounted(el: ElType, binding: DirectiveBinding) {
|
||||||
if (typeof binding.value !== "function") {
|
if (typeof binding.value !== 'function') {
|
||||||
throw "callback must be a function";
|
throw 'callback must be a function';
|
||||||
}
|
}
|
||||||
let timer: NodeJS.Timeout | null = null;
|
let timer: NodeJS.Timeout | null = null;
|
||||||
el.__handleClick__ = function () {
|
el.__handleClick__ = function () {
|
||||||
if (timer) {
|
if (timer) {
|
||||||
clearInterval(timer);
|
clearInterval(timer);
|
||||||
}
|
}
|
||||||
timer = setTimeout(() => {
|
timer = setTimeout(() => {
|
||||||
binding.value();
|
binding.value();
|
||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
el.addEventListener("click", el.__handleClick__);
|
el.addEventListener('click', el.__handleClick__);
|
||||||
},
|
},
|
||||||
beforeUnmount(el: ElType) {
|
beforeUnmount(el: ElType) {
|
||||||
el.removeEventListener("click", el.__handleClick__);
|
el.removeEventListener('click', el.__handleClick__);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default debounce;
|
export default debounce;
|
||||||
|
|||||||
@@ -10,40 +10,40 @@
|
|||||||
使用:在 Dom 上加上 v-draggable 即可
|
使用:在 Dom 上加上 v-draggable 即可
|
||||||
<div class="dialog-model" v-draggable></div>
|
<div class="dialog-model" v-draggable></div>
|
||||||
*/
|
*/
|
||||||
import type { Directive } from "vue";
|
import type { Directive } from 'vue';
|
||||||
interface ElType extends HTMLElement {
|
interface ElType extends HTMLElement {
|
||||||
parentNode: any;
|
parentNode: any;
|
||||||
}
|
}
|
||||||
const draggable: Directive = {
|
const draggable: Directive = {
|
||||||
mounted: function (el: ElType) {
|
mounted: function (el: ElType) {
|
||||||
el.style.cursor = "move";
|
el.style.cursor = 'move';
|
||||||
el.style.position = "absolute";
|
el.style.position = 'absolute';
|
||||||
el.onmousedown = function (e) {
|
el.onmousedown = function (e) {
|
||||||
let disX = e.pageX - el.offsetLeft;
|
const disX = e.pageX - el.offsetLeft;
|
||||||
let disY = e.pageY - el.offsetTop;
|
const disY = e.pageY - el.offsetTop;
|
||||||
document.onmousemove = function (e) {
|
document.onmousemove = function (e) {
|
||||||
let x = e.pageX - disX;
|
let x = e.pageX - disX;
|
||||||
let y = e.pageY - disY;
|
let y = e.pageY - disY;
|
||||||
let maxX = el.parentNode.offsetWidth - el.offsetWidth;
|
const maxX = el.parentNode.offsetWidth - el.offsetWidth;
|
||||||
let maxY = el.parentNode.offsetHeight - el.offsetHeight;
|
const maxY = el.parentNode.offsetHeight - el.offsetHeight;
|
||||||
if (x < 0) {
|
if (x < 0) {
|
||||||
x = 0;
|
x = 0;
|
||||||
} else if (x > maxX) {
|
} else if (x > maxX) {
|
||||||
x = maxX;
|
x = maxX;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y < 0) {
|
if (y < 0) {
|
||||||
y = 0;
|
y = 0;
|
||||||
} else if (y > maxY) {
|
} else if (y > maxY) {
|
||||||
y = maxY;
|
y = maxY;
|
||||||
}
|
}
|
||||||
el.style.left = x + "px";
|
el.style.left = x + 'px';
|
||||||
el.style.top = y + "px";
|
el.style.top = y + 'px';
|
||||||
};
|
};
|
||||||
document.onmouseup = function () {
|
document.onmouseup = function () {
|
||||||
document.onmousemove = document.onmouseup = null;
|
document.onmousemove = document.onmouseup = null;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
export default draggable;
|
export default draggable;
|
||||||
|
|||||||
@@ -2,48 +2,48 @@
|
|||||||
* v-longpress
|
* v-longpress
|
||||||
* 长按指令,长按时触发事件
|
* 长按指令,长按时触发事件
|
||||||
*/
|
*/
|
||||||
import type { Directive, DirectiveBinding } from "vue";
|
import type { Directive, DirectiveBinding } from 'vue';
|
||||||
|
|
||||||
const directive: Directive = {
|
const directive: Directive = {
|
||||||
mounted(el: HTMLElement, binding: DirectiveBinding) {
|
mounted(el: HTMLElement, binding: DirectiveBinding) {
|
||||||
if (typeof binding.value !== "function") {
|
if (typeof binding.value !== 'function') {
|
||||||
throw "callback must be a function";
|
throw 'callback must be a function';
|
||||||
}
|
}
|
||||||
// 定义变量
|
// 定义变量
|
||||||
let pressTimer: any = null;
|
let pressTimer: any = null;
|
||||||
// 创建计时器( 2秒后执行函数 )
|
// 创建计时器( 2秒后执行函数 )
|
||||||
const start = (e: any) => {
|
const start = (e: any) => {
|
||||||
if (e.button) {
|
if (e.button) {
|
||||||
if (e.type === "click" && e.button !== 0) {
|
if (e.type === 'click' && e.button !== 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pressTimer === null) {
|
if (pressTimer === null) {
|
||||||
pressTimer = setTimeout(() => {
|
pressTimer = setTimeout(() => {
|
||||||
handler(e);
|
handler(e);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 取消计时器
|
// 取消计时器
|
||||||
const cancel = () => {
|
const cancel = () => {
|
||||||
if (pressTimer !== null) {
|
if (pressTimer !== null) {
|
||||||
clearTimeout(pressTimer);
|
clearTimeout(pressTimer);
|
||||||
pressTimer = null;
|
pressTimer = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 运行函数
|
// 运行函数
|
||||||
const handler = (e: MouseEvent | TouchEvent) => {
|
const handler = (e: MouseEvent | TouchEvent) => {
|
||||||
binding.value(e);
|
binding.value(e);
|
||||||
};
|
};
|
||||||
// 添加事件监听器
|
// 添加事件监听器
|
||||||
el.addEventListener("mousedown", start);
|
el.addEventListener('mousedown', start);
|
||||||
el.addEventListener("touchstart", start);
|
el.addEventListener('touchstart', start);
|
||||||
// 取消计时器
|
// 取消计时器
|
||||||
el.addEventListener("click", cancel);
|
el.addEventListener('click', cancel);
|
||||||
el.addEventListener("mouseout", cancel);
|
el.addEventListener('mouseout', cancel);
|
||||||
el.addEventListener("touchend", cancel);
|
el.addEventListener('touchend', cancel);
|
||||||
el.addEventListener("touchcancel", cancel);
|
el.addEventListener('touchcancel', cancel);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default directive;
|
export default directive;
|
||||||
|
|||||||
@@ -8,34 +8,34 @@
|
|||||||
使用:给 Dom 加上 v-throttle 及回调函数即可
|
使用:给 Dom 加上 v-throttle 及回调函数即可
|
||||||
<button v-throttle="debounceClick">节流提交</button>
|
<button v-throttle="debounceClick">节流提交</button>
|
||||||
*/
|
*/
|
||||||
import type { Directive, DirectiveBinding } from "vue";
|
import type { Directive, DirectiveBinding } from 'vue';
|
||||||
interface ElType extends HTMLElement {
|
interface ElType extends HTMLElement {
|
||||||
__handleClick__: () => any;
|
__handleClick__: () => any;
|
||||||
disabled: boolean;
|
disabled: boolean;
|
||||||
}
|
}
|
||||||
const throttle: Directive = {
|
const throttle: Directive = {
|
||||||
mounted(el: ElType, binding: DirectiveBinding) {
|
mounted(el: ElType, binding: DirectiveBinding) {
|
||||||
if (typeof binding.value !== "function") {
|
if (typeof binding.value !== 'function') {
|
||||||
throw "callback must be a function";
|
throw 'callback must be a function';
|
||||||
}
|
}
|
||||||
let timer: NodeJS.Timeout | null = null;
|
let timer: NodeJS.Timeout | null = null;
|
||||||
el.__handleClick__ = function () {
|
el.__handleClick__ = function () {
|
||||||
if (timer) {
|
if (timer) {
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
}
|
}
|
||||||
if (!el.disabled) {
|
if (!el.disabled) {
|
||||||
el.disabled = true;
|
el.disabled = true;
|
||||||
binding.value();
|
binding.value();
|
||||||
timer = setTimeout(() => {
|
timer = setTimeout(() => {
|
||||||
el.disabled = false;
|
el.disabled = false;
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
el.addEventListener("click", el.__handleClick__);
|
el.addEventListener('click', el.__handleClick__);
|
||||||
},
|
},
|
||||||
beforeUnmount(el: ElType) {
|
beforeUnmount(el: ElType) {
|
||||||
el.removeEventListener("click", el.__handleClick__);
|
el.removeEventListener('click', el.__handleClick__);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default throttle;
|
export default throttle;
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
import { useAsync } from './use-async';
|
import { useAsync } from './useAsync';
|
||||||
|
|
||||||
export { useAsync };
|
export { useAsync };
|
||||||
|
|||||||
@@ -4,39 +4,39 @@ import { useProjectSettingStore } from '@/store/modules/projectSetting';
|
|||||||
export function useProjectSetting() {
|
export function useProjectSetting() {
|
||||||
const projectStore = useProjectSettingStore();
|
const projectStore = useProjectSettingStore();
|
||||||
|
|
||||||
const getNavMode = computed(() => projectStore.navMode);
|
const navMode = computed(() => projectStore.navMode);
|
||||||
|
|
||||||
const getNavTheme = computed(() => projectStore.navTheme);
|
const navTheme = computed(() => projectStore.navTheme);
|
||||||
|
|
||||||
const getIsMobile = computed(() => projectStore.isMobile);
|
const isMobile = computed(() => projectStore.isMobile);
|
||||||
|
|
||||||
const getHeaderSetting = computed(() => projectStore.headerSetting);
|
const headerSetting = computed(() => projectStore.headerSetting);
|
||||||
|
|
||||||
const getMultiTabsSetting = computed(() => projectStore.multiTabsSetting);
|
const multiTabsSetting = computed(() => projectStore.multiTabsSetting);
|
||||||
|
|
||||||
const getMenuSetting = computed(() => projectStore.menuSetting);
|
const menuSetting = computed(() => projectStore.menuSetting);
|
||||||
|
|
||||||
const getCrumbsSetting = computed(() => projectStore.crumbsSetting);
|
const crumbsSetting = computed(() => projectStore.crumbsSetting);
|
||||||
|
|
||||||
const getPermissionMode = computed(() => projectStore.permissionMode);
|
const permissionMode = computed(() => projectStore.permissionMode);
|
||||||
|
|
||||||
const getShowFooter = computed(() => projectStore.showFooter);
|
const showFooter = computed(() => projectStore.showFooter);
|
||||||
|
|
||||||
const getIsPageAnimate = computed(() => projectStore.isPageAnimate);
|
const isPageAnimate = computed(() => projectStore.isPageAnimate);
|
||||||
|
|
||||||
const getPageAnimateType = computed(() => projectStore.pageAnimateType);
|
const pageAnimateType = computed(() => projectStore.pageAnimateType);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getNavMode,
|
navMode,
|
||||||
getNavTheme,
|
navTheme,
|
||||||
getIsMobile,
|
isMobile,
|
||||||
getHeaderSetting,
|
headerSetting,
|
||||||
getMultiTabsSetting,
|
multiTabsSetting,
|
||||||
getMenuSetting,
|
menuSetting,
|
||||||
getCrumbsSetting,
|
crumbsSetting,
|
||||||
getPermissionMode,
|
permissionMode,
|
||||||
getShowFooter,
|
showFooter,
|
||||||
getIsPageAnimate,
|
isPageAnimate,
|
||||||
getPageAnimateType,
|
pageAnimateType,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ export function useECharts(
|
|||||||
return chartInstance;
|
return chartInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
function disposeInstance(){
|
function disposeInstance() {
|
||||||
if (!chartInstance) return;
|
if (!chartInstance) return;
|
||||||
removeResizeFn();
|
removeResizeFn();
|
||||||
chartInstance.dispose();
|
chartInstance.dispose();
|
||||||
@@ -118,6 +118,6 @@ export function useECharts(
|
|||||||
resize,
|
resize,
|
||||||
echarts,
|
echarts,
|
||||||
getInstance,
|
getInstance,
|
||||||
disposeInstance
|
disposeInstance,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@
|
|||||||
<div
|
<div
|
||||||
class="layout-header-trigger layout-header-trigger-min"
|
class="layout-header-trigger layout-header-trigger-min"
|
||||||
v-for="item in iconList"
|
v-for="item in iconList"
|
||||||
:key="item.icon.name"
|
:key="item.icon"
|
||||||
>
|
>
|
||||||
<n-tooltip placement="bottom">
|
<n-tooltip placement="bottom">
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
import { NDialogProvider, useDialog, useMessage } from 'naive-ui';
|
import { NDialogProvider, useDialog, useMessage } from 'naive-ui';
|
||||||
import { TABS_ROUTES } from '@/store/mutation-types';
|
import { TABS_ROUTES } from '@/store/mutation-types';
|
||||||
import { useUserStore } from '@/store/modules/user';
|
import { useUserStore } from '@/store/modules/user';
|
||||||
import { useLockscreenStore } from '@/store/modules/lockscreen';
|
import { useScreenLockStore } from '@/store/modules/screenLock';
|
||||||
import ProjectSetting from './ProjectSetting.vue';
|
import ProjectSetting from './ProjectSetting.vue';
|
||||||
import { AsideMenu } from '@/layout/components/Menu';
|
import { AsideMenu } from '@/layout/components/Menu';
|
||||||
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
|
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
|
||||||
@@ -153,37 +153,37 @@
|
|||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const useLockscreen = useLockscreenStore();
|
const useLockscreen = useScreenLockStore();
|
||||||
const message = useMessage();
|
const message = useMessage();
|
||||||
const dialog = useDialog();
|
const dialog = useDialog();
|
||||||
const { getNavMode, getNavTheme, getHeaderSetting, getMenuSetting, getCrumbsSetting } =
|
const { navMode, navTheme, headerSetting, menuSetting, crumbsSetting } = useProjectSetting();
|
||||||
useProjectSetting();
|
|
||||||
|
|
||||||
const { username } = userStore?.info || {};
|
const { name } = userStore?.info || {};
|
||||||
|
|
||||||
const drawerSetting = ref();
|
const drawerSetting = ref();
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
username: username || '',
|
username: name ?? '',
|
||||||
fullscreenIcon: 'FullscreenOutlined',
|
fullscreenIcon: 'FullscreenOutlined',
|
||||||
navMode: getNavMode,
|
navMode,
|
||||||
navTheme: getNavTheme,
|
navTheme,
|
||||||
headerSetting: getHeaderSetting,
|
headerSetting,
|
||||||
crumbsSetting: getCrumbsSetting,
|
crumbsSetting,
|
||||||
});
|
});
|
||||||
|
|
||||||
const getInverted = computed(() => {
|
const getInverted = computed(() => {
|
||||||
const navTheme = unref(getNavTheme);
|
return ['light', 'header-dark'].includes(unref(navTheme))
|
||||||
return ['light', 'header-dark'].includes(navTheme) ? props.inverted : !props.inverted;
|
? props.inverted
|
||||||
|
: !props.inverted;
|
||||||
});
|
});
|
||||||
|
|
||||||
const mixMenu = computed(() => {
|
const mixMenu = computed(() => {
|
||||||
return unref(getMenuSetting).mixMenu;
|
return unref(menuSetting).mixMenu;
|
||||||
});
|
});
|
||||||
|
|
||||||
const getChangeStyle = computed(() => {
|
const getChangeStyle = computed(() => {
|
||||||
const { collapsed } = props;
|
const { collapsed } = props;
|
||||||
const { minMenuWidth, menuWidth }: any = unref(getMenuSetting);
|
const { minMenuWidth, menuWidth } = unref(menuSetting);
|
||||||
return {
|
return {
|
||||||
left: collapsed ? `${minMenuWidth}px` : `${menuWidth}px`,
|
left: collapsed ? `${minMenuWidth}px` : `${menuWidth}px`,
|
||||||
width: `calc(100% - ${collapsed ? `${minMenuWidth}px` : `${menuWidth}px`})`,
|
width: `calc(100% - ${collapsed ? `${minMenuWidth}px` : `${menuWidth}px`})`,
|
||||||
@@ -352,7 +352,7 @@
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: @header-height;
|
height: 64px;
|
||||||
box-shadow: 0 1px 4px rgb(0 21 41 / 8%);
|
box-shadow: 0 1px 4px rgb(0 21 41 / 8%);
|
||||||
transition: all 0.2s ease-in-out;
|
transition: all 0.2s ease-in-out;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -30,13 +30,13 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const { getIsPageAnimate, getPageAnimateType } = useProjectSetting();
|
const { isPageAnimate, pageAnimateType } = useProjectSetting();
|
||||||
const asyncRouteStore = useAsyncRouteStore();
|
const asyncRouteStore = useAsyncRouteStore();
|
||||||
// 需要缓存的路由组件
|
// 需要缓存的路由组件
|
||||||
const keepAliveComponents = computed(() => asyncRouteStore.keepAliveComponents);
|
const keepAliveComponents = computed(() => asyncRouteStore.keepAliveComponents);
|
||||||
|
|
||||||
const getTransitionName = computed(() => {
|
const getTransitionName = computed(() => {
|
||||||
return unref(getIsPageAnimate) ? unref(getPageAnimateType) : '';
|
return unref(isPageAnimate) ? unref(pageAnimateType) : '';
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
|
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Menu',
|
name: 'AppMenu',
|
||||||
components: {},
|
components: {},
|
||||||
props: {
|
props: {
|
||||||
mode: {
|
mode: {
|
||||||
@@ -52,9 +52,7 @@
|
|||||||
const selectedKeys = ref<string>(currentRoute.name as string);
|
const selectedKeys = ref<string>(currentRoute.name as string);
|
||||||
const headerMenuSelectKey = ref<string>('');
|
const headerMenuSelectKey = ref<string>('');
|
||||||
|
|
||||||
const { getNavMode } = useProjectSetting();
|
const { navMode } = useProjectSetting();
|
||||||
|
|
||||||
const navMode = getNavMode;
|
|
||||||
|
|
||||||
// 获取当前打开的子菜单
|
// 获取当前打开的子菜单
|
||||||
const matched = currentRoute.matched;
|
const matched = currentRoute.matched;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="tabs-view box-border"
|
class="box-border tabs-view"
|
||||||
:class="{
|
:class="{
|
||||||
'tabs-view-fix': multiTabsSetting.fixed,
|
'tabs-view-fix': multiTabsSetting.fixed,
|
||||||
'tabs-view-fixed-header': isMultiHeaderFixed,
|
'tabs-view-fixed-header': isMultiHeaderFixed,
|
||||||
@@ -82,7 +82,6 @@
|
|||||||
computed,
|
computed,
|
||||||
ref,
|
ref,
|
||||||
toRefs,
|
toRefs,
|
||||||
unref,
|
|
||||||
provide,
|
provide,
|
||||||
watch,
|
watch,
|
||||||
onMounted,
|
onMounted,
|
||||||
@@ -130,7 +129,7 @@
|
|||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const { getDarkTheme, getAppTheme } = useDesignSetting();
|
const { getDarkTheme, getAppTheme } = useDesignSetting();
|
||||||
const { getNavMode, getHeaderSetting, getMenuSetting, getMultiTabsSetting, getIsMobile } =
|
const { navMode, headerSetting, menuSetting, multiTabsSetting, isMobile } =
|
||||||
useProjectSetting();
|
useProjectSetting();
|
||||||
const settingStore = useProjectSettingStore();
|
const settingStore = useProjectSettingStore();
|
||||||
|
|
||||||
@@ -161,7 +160,7 @@
|
|||||||
dropdownY: 0,
|
dropdownY: 0,
|
||||||
showDropdown: false,
|
showDropdown: false,
|
||||||
isMultiHeaderFixed: false,
|
isMultiHeaderFixed: false,
|
||||||
multiTabsSetting: getMultiTabsSetting,
|
multiTabsSetting: multiTabsSetting,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 获取简易的路由对象
|
// 获取简易的路由对象
|
||||||
@@ -173,25 +172,23 @@
|
|||||||
const isMixMenuNoneSub = computed(() => {
|
const isMixMenuNoneSub = computed(() => {
|
||||||
const mixMenu = settingStore.menuSetting.mixMenu;
|
const mixMenu = settingStore.menuSetting.mixMenu;
|
||||||
const currentRoute = useRoute();
|
const currentRoute = useRoute();
|
||||||
const navMode = unref(getNavMode);
|
if (navMode.value != 'horizontal-mix') return true;
|
||||||
if (unref(navMode) != 'horizontal-mix') return true;
|
return !(navMode.value === 'horizontal-mix' && mixMenu && currentRoute.meta.isRoot);
|
||||||
return !(unref(navMode) === 'horizontal-mix' && mixMenu && currentRoute.meta.isRoot);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//动态组装样式 菜单缩进
|
//动态组装样式 菜单缩进
|
||||||
const getChangeStyle = computed(() => {
|
const getChangeStyle = computed(() => {
|
||||||
const { collapsed } = props;
|
const { collapsed } = props;
|
||||||
const navMode = unref(getNavMode);
|
const { minMenuWidth, menuWidth }: any = menuSetting.value;
|
||||||
const { minMenuWidth, menuWidth }: any = unref(getMenuSetting);
|
const { fixed }: any = multiTabsSetting.value;
|
||||||
const { fixed }: any = unref(getMultiTabsSetting);
|
|
||||||
let lenNum =
|
let lenNum =
|
||||||
navMode === 'horizontal' || !isMixMenuNoneSub.value
|
navMode.value === 'horizontal' || !isMixMenuNoneSub.value
|
||||||
? '0px'
|
? '0px'
|
||||||
: collapsed
|
: collapsed
|
||||||
? `${minMenuWidth}px`
|
? `${minMenuWidth}px`
|
||||||
: `${menuWidth}px`;
|
: `${menuWidth}px`;
|
||||||
|
|
||||||
if (getIsMobile.value) {
|
if (isMobile.value) {
|
||||||
return {
|
return {
|
||||||
left: '0px',
|
left: '0px',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
@@ -205,7 +202,7 @@
|
|||||||
|
|
||||||
//tags 右侧下拉菜单
|
//tags 右侧下拉菜单
|
||||||
const TabsMenuOptions = computed(() => {
|
const TabsMenuOptions = computed(() => {
|
||||||
const isDisabled = unref(tabsList).length <= 1;
|
const isDisabled = tabsList.value.length <= 1;
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: '刷新当前',
|
label: '刷新当前',
|
||||||
@@ -215,7 +212,7 @@
|
|||||||
{
|
{
|
||||||
label: `关闭当前`,
|
label: `关闭当前`,
|
||||||
key: '2',
|
key: '2',
|
||||||
disabled: unref(isCurrent) || isDisabled,
|
disabled: isCurrent.value || isDisabled,
|
||||||
icon: renderIcon(CloseOutlined),
|
icon: renderIcon(CloseOutlined),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -263,8 +260,8 @@
|
|||||||
window.pageYOffset ||
|
window.pageYOffset ||
|
||||||
document.body.scrollTop; // 滚动条偏移量
|
document.body.scrollTop; // 滚动条偏移量
|
||||||
state.isMultiHeaderFixed = !!(
|
state.isMultiHeaderFixed = !!(
|
||||||
!getHeaderSetting.value.fixed &&
|
!headerSetting.value.fixed &&
|
||||||
getMultiTabsSetting.value.fixed &&
|
multiTabsSetting.value.fixed &&
|
||||||
scrollTop >= 64
|
scrollTop >= 64
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -297,7 +294,7 @@
|
|||||||
(to) => {
|
(to) => {
|
||||||
if (whiteList.includes(route.name as string)) return;
|
if (whiteList.includes(route.name as string)) return;
|
||||||
state.activeKey = to;
|
state.activeKey = to;
|
||||||
tabsViewStore.addTabs(getSimpleRoute(route));
|
tabsViewStore.addTab(getSimpleRoute(route));
|
||||||
updateNavScroll(true);
|
updateNavScroll(true);
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
@@ -328,7 +325,7 @@
|
|||||||
const reloadPage = () => {
|
const reloadPage = () => {
|
||||||
delKeepAliveCompName();
|
delKeepAliveCompName();
|
||||||
router.push({
|
router.push({
|
||||||
path: '/redirect' + unref(route).fullPath,
|
path: '/redirect' + route.fullPath,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
</n-layout-sider>
|
</n-layout-sider>
|
||||||
|
|
||||||
<n-drawer
|
<n-drawer
|
||||||
v-model:show="showSideDrawder"
|
v-model:show="showSideDrawer"
|
||||||
:width="menuWidth"
|
:width="menuWidth"
|
||||||
:placement="'left'"
|
:placement="'left'"
|
||||||
class="layout-side-drawer"
|
class="layout-side-drawer"
|
||||||
@@ -82,21 +82,19 @@
|
|||||||
|
|
||||||
const { getDarkTheme } = useDesignSetting();
|
const { getDarkTheme } = useDesignSetting();
|
||||||
const {
|
const {
|
||||||
// getShowFooter,
|
// showFooter,
|
||||||
getNavMode,
|
navMode,
|
||||||
getNavTheme,
|
navTheme,
|
||||||
getHeaderSetting,
|
headerSetting,
|
||||||
getMenuSetting,
|
menuSetting,
|
||||||
getMultiTabsSetting,
|
multiTabsSetting,
|
||||||
} = useProjectSetting();
|
} = useProjectSetting();
|
||||||
|
|
||||||
const settingStore = useProjectSettingStore();
|
const settingStore = useProjectSettingStore();
|
||||||
|
|
||||||
const navMode = getNavMode;
|
|
||||||
|
|
||||||
const collapsed = ref<boolean>(false);
|
const collapsed = ref<boolean>(false);
|
||||||
|
|
||||||
const { mobileWidth, menuWidth } = unref(getMenuSetting);
|
const { mobileWidth, menuWidth } = unref(menuSetting);
|
||||||
|
|
||||||
const isMobile = computed<boolean>({
|
const isMobile = computed<boolean>({
|
||||||
get: () => settingStore.getIsMobile,
|
get: () => settingStore.getIsMobile,
|
||||||
@@ -104,12 +102,12 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
const fixedHeader = computed(() => {
|
const fixedHeader = computed(() => {
|
||||||
const { fixed } = unref(getHeaderSetting);
|
const { fixed } = unref(headerSetting);
|
||||||
return fixed ? 'absolute' : 'static';
|
return fixed ? 'absolute' : 'static';
|
||||||
});
|
});
|
||||||
|
|
||||||
const isMixMenuNoneSub = computed(() => {
|
const isMixMenuNoneSub = computed(() => {
|
||||||
const mixMenu = settingStore.menuSetting.mixMenu;
|
const mixMenu = unref(menuSetting).mixMenu;
|
||||||
const currentRoute = useRoute();
|
const currentRoute = useRoute();
|
||||||
if (unref(navMode) != 'horizontal-mix') return true;
|
if (unref(navMode) != 'horizontal-mix') return true;
|
||||||
if (unref(navMode) === 'horizontal-mix' && mixMenu && currentRoute.meta.isRoot) {
|
if (unref(navMode) === 'horizontal-mix' && mixMenu && currentRoute.meta.isRoot) {
|
||||||
@@ -119,45 +117,37 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
const fixedMenu = computed(() => {
|
const fixedMenu = computed(() => {
|
||||||
const { fixed } = unref(getHeaderSetting);
|
const { fixed } = unref(headerSetting);
|
||||||
return fixed ? 'absolute' : 'static';
|
return fixed ? 'absolute' : 'static';
|
||||||
});
|
});
|
||||||
|
|
||||||
const isMultiTabs = computed(() => {
|
const isMultiTabs = computed(() => {
|
||||||
return unref(getMultiTabsSetting).show;
|
return unref(multiTabsSetting).show;
|
||||||
});
|
});
|
||||||
|
|
||||||
const fixedMulti = computed(() => {
|
const fixedMulti = computed(() => {
|
||||||
return unref(getMultiTabsSetting).fixed;
|
return unref(multiTabsSetting).fixed;
|
||||||
});
|
});
|
||||||
|
|
||||||
const inverted = computed(() => {
|
const inverted = computed(() => {
|
||||||
return ['dark', 'header-dark'].includes(unref(getNavTheme));
|
return ['dark', 'header-dark'].includes(unref(navTheme));
|
||||||
});
|
});
|
||||||
|
|
||||||
const getHeaderInverted = computed(() => {
|
const getHeaderInverted = computed(() => {
|
||||||
const navTheme = unref(getNavTheme);
|
return ['light', 'header-dark'].includes(unref(navTheme)) ? unref(inverted) : !unref(inverted);
|
||||||
return ['light', 'header-dark'].includes(navTheme) ? unref(inverted) : !unref(inverted);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const leftMenuWidth = computed(() => {
|
const leftMenuWidth = computed(() => {
|
||||||
const { minMenuWidth, menuWidth } = unref(getMenuSetting);
|
const { minMenuWidth, menuWidth } = unref(menuSetting);
|
||||||
return collapsed.value ? minMenuWidth : menuWidth;
|
return collapsed.value ? minMenuWidth : menuWidth;
|
||||||
});
|
});
|
||||||
|
|
||||||
// const getChangeStyle = computed(() => {
|
|
||||||
// const { minMenuWidth, menuWidth } = unref(getMenuSetting);
|
|
||||||
// return {
|
|
||||||
// 'padding-left': collapsed.value ? `${minMenuWidth}px` : `${menuWidth}px`,
|
|
||||||
// };
|
|
||||||
// });
|
|
||||||
|
|
||||||
const getMenuLocation = computed(() => {
|
const getMenuLocation = computed(() => {
|
||||||
return 'left';
|
return 'left';
|
||||||
});
|
});
|
||||||
|
|
||||||
// 控制显示或隐藏移动端侧边栏
|
// 控制显示或隐藏移动端侧边栏
|
||||||
const showSideDrawder = computed({
|
const showSideDrawer = computed({
|
||||||
get: () => isMobile.value && collapsed.value,
|
get: () => isMobile.value && collapsed.value,
|
||||||
set: (val) => (collapsed.value = val),
|
set: (val) => (collapsed.value = val),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -33,6 +33,11 @@ async function bootstrap() {
|
|||||||
// https://router.vuejs.org/api/interfaces/router.html#isready
|
// https://router.vuejs.org/api/interfaces/router.html#isready
|
||||||
await router.isReady();
|
await router.isReady();
|
||||||
|
|
||||||
|
// https://www.naiveui.com/en-US/os-theme/docs/style-conflict#About-Tailwind's-Preflight-Style-Override
|
||||||
|
const meta = document.createElement('meta');
|
||||||
|
meta.name = 'naive-ui-style';
|
||||||
|
document.head.appendChild(meta);
|
||||||
|
|
||||||
app.mount('#app', true);
|
app.mount('#app', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,73 +1,141 @@
|
|||||||
import type { App } from 'vue';
|
import type { App } from 'vue';
|
||||||
import * as NaiveUI from 'naive-ui';
|
import {
|
||||||
|
create,
|
||||||
|
NMessageProvider,
|
||||||
|
NDialogProvider,
|
||||||
|
NConfigProvider,
|
||||||
|
NInput,
|
||||||
|
NButton,
|
||||||
|
NForm,
|
||||||
|
NFormItem,
|
||||||
|
NCheckboxGroup,
|
||||||
|
NCheckbox,
|
||||||
|
NIcon,
|
||||||
|
NLayout,
|
||||||
|
NLayoutHeader,
|
||||||
|
NLayoutContent,
|
||||||
|
NLayoutFooter,
|
||||||
|
NLayoutSider,
|
||||||
|
NMenu,
|
||||||
|
NBreadcrumb,
|
||||||
|
NBreadcrumbItem,
|
||||||
|
NDropdown,
|
||||||
|
NSpace,
|
||||||
|
NTooltip,
|
||||||
|
NAvatar,
|
||||||
|
NTabs,
|
||||||
|
NTabPane,
|
||||||
|
NCard,
|
||||||
|
NRow,
|
||||||
|
NCol,
|
||||||
|
NDrawer,
|
||||||
|
NDrawerContent,
|
||||||
|
NDivider,
|
||||||
|
NSwitch,
|
||||||
|
NBadge,
|
||||||
|
NAlert,
|
||||||
|
NElement,
|
||||||
|
NTag,
|
||||||
|
NNotificationProvider,
|
||||||
|
NProgress,
|
||||||
|
NDatePicker,
|
||||||
|
NGrid,
|
||||||
|
NGridItem,
|
||||||
|
NList,
|
||||||
|
NListItem,
|
||||||
|
NThing,
|
||||||
|
NDataTable,
|
||||||
|
NPopover,
|
||||||
|
NPagination,
|
||||||
|
NSelect,
|
||||||
|
NRadioGroup,
|
||||||
|
NRadio,
|
||||||
|
NSteps,
|
||||||
|
NStep,
|
||||||
|
NInputGroup,
|
||||||
|
NResult,
|
||||||
|
NDescriptions,
|
||||||
|
NDescriptionsItem,
|
||||||
|
NTable,
|
||||||
|
NInputNumber,
|
||||||
|
NLoadingBarProvider,
|
||||||
|
NModal,
|
||||||
|
NUpload,
|
||||||
|
NTree,
|
||||||
|
NSpin,
|
||||||
|
NTimePicker,
|
||||||
|
NBackTop,
|
||||||
|
NSkeleton,
|
||||||
|
} from 'naive-ui';
|
||||||
|
|
||||||
const naive = NaiveUI.create({
|
// https://www.naiveui.com/en-US/os-theme/docs/import-on-demand
|
||||||
|
const naive = create({
|
||||||
components: [
|
components: [
|
||||||
NaiveUI.NMessageProvider,
|
NMessageProvider,
|
||||||
NaiveUI.NDialogProvider,
|
NDialogProvider,
|
||||||
NaiveUI.NConfigProvider,
|
NConfigProvider,
|
||||||
NaiveUI.NInput,
|
NInput,
|
||||||
NaiveUI.NButton,
|
NButton,
|
||||||
NaiveUI.NForm,
|
NForm,
|
||||||
NaiveUI.NFormItem,
|
NFormItem,
|
||||||
NaiveUI.NCheckboxGroup,
|
NCheckboxGroup,
|
||||||
NaiveUI.NCheckbox,
|
NCheckbox,
|
||||||
NaiveUI.NIcon,
|
NIcon,
|
||||||
NaiveUI.NLayout,
|
NLayout,
|
||||||
NaiveUI.NLayoutHeader,
|
NLayoutHeader,
|
||||||
NaiveUI.NLayoutContent,
|
NLayoutContent,
|
||||||
NaiveUI.NLayoutFooter,
|
NLayoutFooter,
|
||||||
NaiveUI.NLayoutSider,
|
NLayoutSider,
|
||||||
NaiveUI.NMenu,
|
NMenu,
|
||||||
NaiveUI.NBreadcrumb,
|
NBreadcrumb,
|
||||||
NaiveUI.NBreadcrumbItem,
|
NBreadcrumbItem,
|
||||||
NaiveUI.NDropdown,
|
NDropdown,
|
||||||
NaiveUI.NSpace,
|
NSpace,
|
||||||
NaiveUI.NTooltip,
|
NTooltip,
|
||||||
NaiveUI.NAvatar,
|
NAvatar,
|
||||||
NaiveUI.NTabs,
|
NTabs,
|
||||||
NaiveUI.NTabPane,
|
NTabPane,
|
||||||
NaiveUI.NCard,
|
NCard,
|
||||||
NaiveUI.NRow,
|
NRow,
|
||||||
NaiveUI.NCol,
|
NCol,
|
||||||
NaiveUI.NDrawer,
|
NDrawer,
|
||||||
NaiveUI.NDrawerContent,
|
NDrawerContent,
|
||||||
NaiveUI.NDivider,
|
NDivider,
|
||||||
NaiveUI.NSwitch,
|
NSwitch,
|
||||||
NaiveUI.NBadge,
|
NBadge,
|
||||||
NaiveUI.NAlert,
|
NAlert,
|
||||||
NaiveUI.NElement,
|
NElement,
|
||||||
NaiveUI.NTag,
|
NTag,
|
||||||
NaiveUI.NNotificationProvider,
|
NNotificationProvider,
|
||||||
NaiveUI.NProgress,
|
NProgress,
|
||||||
NaiveUI.NDatePicker,
|
NDatePicker,
|
||||||
NaiveUI.NGrid,
|
NGrid,
|
||||||
NaiveUI.NGridItem,
|
NGridItem,
|
||||||
NaiveUI.NList,
|
NList,
|
||||||
NaiveUI.NListItem,
|
NListItem,
|
||||||
NaiveUI.NThing,
|
NThing,
|
||||||
NaiveUI.NDataTable,
|
NDataTable,
|
||||||
NaiveUI.NPopover,
|
NPopover,
|
||||||
NaiveUI.NPagination,
|
NPagination,
|
||||||
NaiveUI.NSelect,
|
NSelect,
|
||||||
NaiveUI.NRadioGroup,
|
NRadioGroup,
|
||||||
NaiveUI.NRadio,
|
NRadio,
|
||||||
NaiveUI.NSteps,
|
NSteps,
|
||||||
NaiveUI.NStep,
|
NStep,
|
||||||
NaiveUI.NInputGroup,
|
NInputGroup,
|
||||||
NaiveUI.NResult,
|
NResult,
|
||||||
NaiveUI.NDescriptions,
|
NDescriptions,
|
||||||
NaiveUI.NDescriptionsItem,
|
NDescriptionsItem,
|
||||||
NaiveUI.NTable,
|
NTable,
|
||||||
NaiveUI.NInputNumber,
|
NInputNumber,
|
||||||
NaiveUI.NLoadingBarProvider,
|
NLoadingBarProvider,
|
||||||
NaiveUI.NModal,
|
NModal,
|
||||||
NaiveUI.NUpload,
|
NUpload,
|
||||||
NaiveUI.NTree,
|
NTree,
|
||||||
NaiveUI.NSpin,
|
NSpin,
|
||||||
NaiveUI.NTimePicker,
|
NTimePicker,
|
||||||
NaiveUI.NBackTop,
|
NBackTop,
|
||||||
NaiveUI.NSkeleton,
|
NSkeleton,
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as NaiveUI from 'naive-ui';
|
import * as NaiveUI from 'naive-ui';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { useDesignSettingWithOut } from '@/store/modules/designSetting';
|
import { useDesignSetting } from '@/store/modules/designSetting';
|
||||||
import { lighten } from '@/utils/index';
|
import { lighten } from '@/utils/index';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -10,7 +10,7 @@ import { lighten } from '@/utils/index';
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
export function setupNaiveDiscreteApi() {
|
export function setupNaiveDiscreteApi() {
|
||||||
const designStore = useDesignSettingWithOut();
|
const designStore = useDesignSetting();
|
||||||
|
|
||||||
const configProviderPropsRef = computed(() => ({
|
const configProviderPropsRef = computed(() => ({
|
||||||
theme: designStore.darkTheme ? NaiveUI.darkTheme : undefined,
|
theme: designStore.darkTheme ? NaiveUI.darkTheme : undefined,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import type { AppRouteRecordRaw } from '@/router/types';
|
|
||||||
import { ErrorPage, RedirectName, Layout } from '@/router/constant';
|
import { ErrorPage, RedirectName, Layout } from '@/router/constant';
|
||||||
|
import { RouteRecordRaw } from 'vue-router';
|
||||||
|
|
||||||
// 404 on a page
|
// 404 on a page
|
||||||
export const ErrorPageRoute: AppRouteRecordRaw = {
|
export const ErrorPageRoute: RouteRecordRaw = {
|
||||||
path: '/:path(.*)*',
|
path: '/:path(.*)*',
|
||||||
name: 'ErrorPage',
|
name: 'ErrorPage',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
@@ -23,7 +23,7 @@ export const ErrorPageRoute: AppRouteRecordRaw = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RedirectRoute: AppRouteRecordRaw = {
|
export const RedirectRoute: RouteRecordRaw = {
|
||||||
path: '/redirect',
|
path: '/redirect',
|
||||||
name: RedirectName,
|
name: RedirectName,
|
||||||
component: Layout,
|
component: Layout,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { adminMenus } from '@/api/system/menu';
|
import { adminMenus } from '@/api/system/menu';
|
||||||
import { constantRouterIcon } from './router-icons';
|
import { constantRouterIcon } from './icons';
|
||||||
import { RouteRecordRaw } from 'vue-router';
|
import { RouteRecordRaw } from 'vue-router';
|
||||||
import { Layout, ParentLayout } from '@/router/constant';
|
import { Layout, ParentLayout } from '@/router/constant';
|
||||||
import type { AppRouteRecordRaw } from '@/router/types';
|
import type { AppRouteRecordRaw } from '@/router/types';
|
||||||
@@ -16,13 +16,13 @@ LayoutMap.set('IFRAME', Iframe);
|
|||||||
* @param parent
|
* @param parent
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
export const routerGenerator = (routerMap, parent?): any[] => {
|
export const generateRoutes = (routerMap, parent?): any[] => {
|
||||||
return routerMap.map((item) => {
|
return routerMap.map((item) => {
|
||||||
const currentRouter: any = {
|
const currentRoute: any = {
|
||||||
// 路由地址 动态拼接生成如 /dashboard/workplace
|
// 路由地址 动态拼接生成如 /dashboard/workplace
|
||||||
path: `${(parent && parent.path) || ''}/${item.path}`,
|
path: `${(parent && parent.path) ?? ''}/${item.path}`,
|
||||||
// 路由名称,建议唯一
|
// 路由名称,建议唯一
|
||||||
name: item.name || '',
|
name: item.name ?? '',
|
||||||
// 该路由对应页面的 组件
|
// 该路由对应页面的 组件
|
||||||
component: item.component,
|
component: item.component,
|
||||||
// meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉)
|
// meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉)
|
||||||
@@ -35,17 +35,17 @@ export const routerGenerator = (routerMap, parent?): any[] => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 为了防止出现后端返回结果不规范,处理有可能出现拼接出两个 反斜杠
|
// 为了防止出现后端返回结果不规范,处理有可能出现拼接出两个 反斜杠
|
||||||
currentRouter.path = currentRouter.path.replace('//', '/');
|
currentRoute.path = currentRoute.path.replace('//', '/');
|
||||||
// 重定向
|
// 重定向
|
||||||
item.redirect && (currentRouter.redirect = item.redirect);
|
item.redirect && (currentRoute.redirect = item.redirect);
|
||||||
// 是否有子菜单,并递归处理
|
// 是否有子菜单,并递归处理
|
||||||
if (item.children && item.children.length > 0) {
|
if (item.children && item.children.length > 0) {
|
||||||
//如果未定义 redirect 默认第一个子路由为 redirect
|
//如果未定义 redirect 默认第一个子路由为 redirect
|
||||||
!item.redirect && (currentRouter.redirect = `${item.path}/${item.children[0].path}`);
|
!item.redirect && (currentRoute.redirect = `${item.path}/${item.children[0].path}`);
|
||||||
// Recursion
|
// Recursion
|
||||||
currentRouter.children = routerGenerator(item.children, currentRouter);
|
currentRoute.children = generateRoutes(item.children, currentRoute);
|
||||||
}
|
}
|
||||||
return currentRouter;
|
return currentRoute;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -53,19 +53,11 @@ export const routerGenerator = (routerMap, parent?): any[] => {
|
|||||||
* 动态生成菜单
|
* 动态生成菜单
|
||||||
* @returns {Promise<Router>}
|
* @returns {Promise<Router>}
|
||||||
*/
|
*/
|
||||||
export const generatorDynamicRouter = (): Promise<RouteRecordRaw[]> => {
|
export const generateDynamicRoutes = async (): Promise<RouteRecordRaw[]> => {
|
||||||
return new Promise((resolve, reject) => {
|
const result = await adminMenus();
|
||||||
adminMenus()
|
const router = generateRoutes(result);
|
||||||
.then((result) => {
|
asyncImportRoute(router);
|
||||||
const routeList = routerGenerator(result);
|
return router;
|
||||||
asyncImportRoute(routeList);
|
|
||||||
|
|
||||||
resolve(routeList);
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
reject(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router';
|
import type { RouteRecordRaw } from 'vue-router';
|
||||||
import { isNavigationFailure, Router } from 'vue-router';
|
import { isNavigationFailure, Router } from 'vue-router';
|
||||||
import { useUserStoreWidthOut } from '@/store/modules/user';
|
import { useUser } from '@/store/modules/user';
|
||||||
import { useAsyncRouteStoreWidthOut } from '@/store/modules/asyncRoute';
|
import { useAsyncRoute } from '@/store/modules/asyncRoute';
|
||||||
import { ACCESS_TOKEN } from '@/store/mutation-types';
|
import { ACCESS_TOKEN } from '@/store/mutation-types';
|
||||||
import { storage } from '@/utils/Storage';
|
import { storage } from '@/utils/Storage';
|
||||||
import { PageEnum } from '@/enums/pageEnum';
|
import { PageEnum } from '@/enums/pageEnum';
|
||||||
@@ -12,8 +12,8 @@ const LOGIN_PATH = PageEnum.BASE_LOGIN;
|
|||||||
const whitePathList = [LOGIN_PATH]; // no redirect whitelist
|
const whitePathList = [LOGIN_PATH]; // no redirect whitelist
|
||||||
|
|
||||||
export function createRouterGuards(router: Router) {
|
export function createRouterGuards(router: Router) {
|
||||||
const userStore = useUserStoreWidthOut();
|
const userStore = useUser();
|
||||||
const asyncRouteStore = useAsyncRouteStoreWidthOut();
|
const asyncRouteStore = useAsyncRoute();
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
const Loading = window['$loading'] || null;
|
const Loading = window['$loading'] || null;
|
||||||
Loading && Loading.start();
|
Loading && Loading.start();
|
||||||
@@ -51,12 +51,12 @@ export function createRouterGuards(router: Router) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (asyncRouteStore.getIsDynamicAddedRoute) {
|
if (asyncRouteStore.getIsDynamicRouteAdded) {
|
||||||
next();
|
next();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const userInfo = await userStore.GetInfo();
|
const userInfo = await userStore.getInfo();
|
||||||
|
|
||||||
const routes = await asyncRouteStore.generateRoutes(userInfo);
|
const routes = await asyncRouteStore.generateRoutes(userInfo);
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ export function createRouterGuards(router: Router) {
|
|||||||
const redirectPath = (from.query.redirect || to.path) as string;
|
const redirectPath = (from.query.redirect || to.path) as string;
|
||||||
const redirect = decodeURIComponent(redirectPath);
|
const redirect = decodeURIComponent(redirectPath);
|
||||||
const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect };
|
const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect };
|
||||||
asyncRouteStore.setDynamicAddedRoute(true);
|
asyncRouteStore.setDynamicRouteAdded(true);
|
||||||
next(nextData);
|
next(nextData);
|
||||||
Loading && Loading.finish();
|
Loading && Loading.finish();
|
||||||
});
|
});
|
||||||
@@ -84,7 +84,7 @@ export function createRouterGuards(router: Router) {
|
|||||||
if (isNavigationFailure(failure)) {
|
if (isNavigationFailure(failure)) {
|
||||||
//console.log('failed navigation', failure)
|
//console.log('failed navigation', failure)
|
||||||
}
|
}
|
||||||
const asyncRouteStore = useAsyncRouteStoreWidthOut();
|
const asyncRouteStore = useAsyncRoute();
|
||||||
// 在这里设置需要缓存的组件名称
|
// 在这里设置需要缓存的组件名称
|
||||||
const keepAliveComponents = asyncRouteStore.keepAliveComponents;
|
const keepAliveComponents = asyncRouteStore.keepAliveComponents;
|
||||||
const currentComName: any = to.matched.find((item) => item.name == to.name)?.name;
|
const currentComName: any = to.matched.find((item) => item.name == to.name)?.name;
|
||||||
@@ -1,22 +1,20 @@
|
|||||||
import { App } from 'vue';
|
import { App } from 'vue';
|
||||||
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
|
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
|
||||||
import { RedirectRoute } from '@/router/base';
|
import { RedirectRoute } from '@/router/base';
|
||||||
import { PageEnum } from '@/enums/pageEnum';
|
import { PageEnum } from '@/enums/pageEnum';
|
||||||
import { createRouterGuards } from './router-guards';
|
import { createRouterGuards } from './guards';
|
||||||
import type { IModuleType } from './types';
|
import type { IModuleType } from './types';
|
||||||
|
|
||||||
const modules = import.meta.glob<IModuleType>('./modules/**/*.ts', { eager: true });
|
const modules = import.meta.glob<IModuleType>('./modules/**/*.ts', { eager: true });
|
||||||
|
|
||||||
const routeModuleList: RouteRecordRaw[] = [];
|
const routeModuleList: RouteRecordRaw[] = Object.keys(modules).reduce((list, key) => {
|
||||||
|
const mod = modules[key].default ?? {};
|
||||||
Object.keys(modules).forEach((key) => {
|
|
||||||
const mod = modules[key].default || {};
|
|
||||||
const modList = Array.isArray(mod) ? [...mod] : [mod];
|
const modList = Array.isArray(mod) ? [...mod] : [mod];
|
||||||
routeModuleList.push(...modList);
|
return [...list, ...modList];
|
||||||
});
|
}, []);
|
||||||
|
|
||||||
function sortRoute(a, b) {
|
function sortRoute(a, b) {
|
||||||
return (a.meta?.sort || 0) - (b.meta?.sort || 0);
|
return (a.meta?.sort ?? 0) - (b.meta?.sort ?? 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
routeModuleList.sort(sortRoute);
|
routeModuleList.sort(sortRoute);
|
||||||
@@ -43,10 +41,10 @@ export const LoginRoute: RouteRecordRaw = {
|
|||||||
export const asyncRoutes = [...routeModuleList];
|
export const asyncRoutes = [...routeModuleList];
|
||||||
|
|
||||||
//普通路由 无需验证权限
|
//普通路由 无需验证权限
|
||||||
export const constantRouter: any[] = [LoginRoute, RootRoute, RedirectRoute];
|
export const constantRouter: RouteRecordRaw[] = [LoginRoute, RootRoute, RedirectRoute];
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHashHistory(''),
|
history: createWebHistory(),
|
||||||
routes: constantRouter,
|
routes: constantRouter,
|
||||||
strict: true,
|
strict: true,
|
||||||
scrollBehavior: () => ({ left: 0, top: 0 }),
|
scrollBehavior: () => ({ left: 0, top: 0 }),
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import type { RouteRecordRaw, RouteMeta } from 'vue-router';
|
import type { RouteRecordRaw, RouteMeta } from 'vue-router';
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export type Component<T extends any = any> =
|
export type Component<T = any> =
|
||||||
| ReturnType<typeof defineComponent>
|
| ReturnType<typeof defineComponent>
|
||||||
| (() => Promise<typeof import('*.vue')>)
|
| (() => Promise<typeof import('*.vue')>)
|
||||||
| (() => Promise<T>);
|
| (() => Promise<T>);
|
||||||
|
|
||||||
export interface AppRouteRecordRaw extends Omit<RouteRecordRaw, 'meta'> {
|
export interface AppRouteRecordRaw extends Omit<RouteRecordRaw, 'meta' | 'children'> {
|
||||||
name: string;
|
name: string;
|
||||||
meta: RouteMeta;
|
meta: RouteMeta;
|
||||||
component?: Component | string;
|
component?: Component | string;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { defineStore } from 'pinia';
|
|||||||
import { RouteRecordRaw } from 'vue-router';
|
import { RouteRecordRaw } from 'vue-router';
|
||||||
import { store } from '@/store';
|
import { store } from '@/store';
|
||||||
import { asyncRoutes, constantRouter } from '@/router/index';
|
import { asyncRoutes, constantRouter } from '@/router/index';
|
||||||
import { generatorDynamicRouter } from '@/router/generator-routers';
|
import { generateDynamicRoutes } from '@/router/generator';
|
||||||
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
|
import { useProjectSetting } from '@/hooks/setting/useProjectSetting';
|
||||||
|
|
||||||
interface TreeHelperConfig {
|
interface TreeHelperConfig {
|
||||||
@@ -23,9 +23,9 @@ const getConfig = (config: Partial<TreeHelperConfig>) => Object.assign({}, DEFAU
|
|||||||
export interface IAsyncRouteState {
|
export interface IAsyncRouteState {
|
||||||
menus: RouteRecordRaw[];
|
menus: RouteRecordRaw[];
|
||||||
routers: any[];
|
routers: any[];
|
||||||
addRouters: any[];
|
routersAdded: any[];
|
||||||
keepAliveComponents: string[];
|
keepAliveComponents: string[];
|
||||||
isDynamicAddedRoute: boolean;
|
isDynamicRouteAdded: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function filter<T = any>(
|
function filter<T = any>(
|
||||||
@@ -53,54 +53,53 @@ export const useAsyncRouteStore = defineStore({
|
|||||||
state: (): IAsyncRouteState => ({
|
state: (): IAsyncRouteState => ({
|
||||||
menus: [],
|
menus: [],
|
||||||
routers: constantRouter,
|
routers: constantRouter,
|
||||||
addRouters: [],
|
routersAdded: [],
|
||||||
keepAliveComponents: [],
|
keepAliveComponents: [],
|
||||||
// Whether the route has been dynamically added
|
// Whether the route has been dynamically added
|
||||||
isDynamicAddedRoute: false,
|
isDynamicRouteAdded: false,
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
getMenus(): RouteRecordRaw[] {
|
getMenus(): RouteRecordRaw[] {
|
||||||
return this.menus;
|
return this.menus;
|
||||||
},
|
},
|
||||||
getIsDynamicAddedRoute(): boolean {
|
getIsDynamicRouteAdded(): boolean {
|
||||||
return this.isDynamicAddedRoute;
|
return this.isDynamicRouteAdded;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
getRouters() {
|
getRouters() {
|
||||||
return toRaw(this.addRouters);
|
return toRaw(this.routersAdded);
|
||||||
},
|
},
|
||||||
setDynamicAddedRoute(added: boolean) {
|
setDynamicRouteAdded(added: boolean) {
|
||||||
this.isDynamicAddedRoute = added;
|
this.isDynamicRouteAdded = added;
|
||||||
},
|
},
|
||||||
// 设置动态路由
|
// 设置动态路由
|
||||||
setRouters(routers) {
|
setRouters(routers: RouteRecordRaw[]) {
|
||||||
this.addRouters = routers;
|
this.routersAdded = routers;
|
||||||
this.routers = constantRouter.concat(routers);
|
this.routers = constantRouter.concat(routers);
|
||||||
},
|
},
|
||||||
setMenus(menus) {
|
setMenus(menus: RouteRecordRaw[]) {
|
||||||
// 设置动态路由
|
// 设置动态路由
|
||||||
this.menus = menus;
|
this.menus = menus;
|
||||||
},
|
},
|
||||||
setKeepAliveComponents(compNames) {
|
setKeepAliveComponents(compNames: string[]) {
|
||||||
// 设置需要缓存的组件
|
// 设置需要缓存的组件
|
||||||
this.keepAliveComponents = compNames;
|
this.keepAliveComponents = compNames;
|
||||||
},
|
},
|
||||||
async generateRoutes(data) {
|
async generateRoutes(data) {
|
||||||
let accessedRouters;
|
let accessedRouters;
|
||||||
const permissionsList = data.permissions || [];
|
const permissionsList = data.permissions ?? [];
|
||||||
const routeFilter = (route) => {
|
const routeFilter = (route) => {
|
||||||
const { meta } = route;
|
const { meta } = route;
|
||||||
const { permissions } = meta || {};
|
const { permissions } = meta || {};
|
||||||
if (!permissions) return true;
|
if (!permissions) return true;
|
||||||
return permissionsList.some((item) => permissions.includes(item.value));
|
return permissionsList.some((item) => permissions.includes(item.value));
|
||||||
};
|
};
|
||||||
const { getPermissionMode } = useProjectSetting();
|
const { permissionMode } = useProjectSetting();
|
||||||
const permissionMode = unref(getPermissionMode);
|
if (unref(permissionMode) === 'BACK') {
|
||||||
if (permissionMode === 'BACK') {
|
|
||||||
// 动态获取菜单
|
// 动态获取菜单
|
||||||
try {
|
try {
|
||||||
accessedRouters = await generatorDynamicRouter();
|
accessedRouters = await generateDynamicRoutes();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
@@ -121,6 +120,6 @@ export const useAsyncRouteStore = defineStore({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Need to be used outside the setup
|
// Need to be used outside the setup
|
||||||
export function useAsyncRouteStoreWidthOut() {
|
export function useAsyncRoute() {
|
||||||
return useAsyncRouteStore(store);
|
return useAsyncRouteStore(store);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,6 @@ export const useDesignSettingStore = defineStore({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Need to be used outside the setup
|
// Need to be used outside the setup
|
||||||
export function useDesignSettingWithOut() {
|
export function useDesignSetting() {
|
||||||
return useDesignSettingStore(store);
|
return useDesignSettingStore(store);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
const allModules = import.meta.glob('./*/index.ts', { eager: true });
|
|
||||||
const modules = {} as any;
|
|
||||||
Object.keys(allModules).forEach((path) => {
|
|
||||||
const fileName = path.split('/')[1];
|
|
||||||
modules[fileName] = allModules[path][fileName] || allModules[path].default || allModules[path];
|
|
||||||
});
|
|
||||||
|
|
||||||
// export default modules
|
|
||||||
import asyncRoute from './async-route';
|
|
||||||
import user from './user';
|
|
||||||
import tabsView from './tabs-view';
|
|
||||||
import lockscreen from './lockscreen';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
asyncRoute,
|
|
||||||
user,
|
|
||||||
tabsView,
|
|
||||||
lockscreen,
|
|
||||||
};
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
import { defineStore } from 'pinia';
|
|
||||||
import { IS_LOCKSCREEN } from '@/store/mutation-types';
|
|
||||||
import { storage } from '@/utils/Storage';
|
|
||||||
|
|
||||||
// 长时间不操作默认锁屏时间
|
|
||||||
const initTime = 60 * 60;
|
|
||||||
|
|
||||||
const isLock = storage.get(IS_LOCKSCREEN, false);
|
|
||||||
|
|
||||||
export type ILockscreenState = {
|
|
||||||
isLock: boolean; // 是否锁屏
|
|
||||||
lockTime: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useLockscreenStore = defineStore({
|
|
||||||
id: 'app-lockscreen',
|
|
||||||
state: (): ILockscreenState => ({
|
|
||||||
isLock: isLock === true, // 是否锁屏
|
|
||||||
lockTime: isLock == 'true' ? initTime : 0,
|
|
||||||
}),
|
|
||||||
getters: {},
|
|
||||||
actions: {
|
|
||||||
setLock(payload) {
|
|
||||||
this.isLock = payload;
|
|
||||||
storage.set(IS_LOCKSCREEN, this.isLock);
|
|
||||||
},
|
|
||||||
setLockTime(payload = initTime) {
|
|
||||||
this.lockTime = payload;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { store } from '@/store';
|
|
||||||
import projectSetting from '@/settings/projectSetting';
|
import projectSetting from '@/settings/projectSetting';
|
||||||
import type { IheaderSetting, ImenuSetting, ImultiTabsSetting, IcrumbsSetting } from '/#/config';
|
import type { IHeaderSetting, IMenuSetting, IMultiTabsSetting, ICrumbsSetting } from '/#/config';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
navMode,
|
navMode,
|
||||||
@@ -20,11 +19,11 @@ const {
|
|||||||
interface ProjectSettingState {
|
interface ProjectSettingState {
|
||||||
navMode: string; //导航模式
|
navMode: string; //导航模式
|
||||||
navTheme: string; //导航风格
|
navTheme: string; //导航风格
|
||||||
headerSetting: IheaderSetting; //顶部设置
|
headerSetting: IHeaderSetting; //顶部设置
|
||||||
showFooter: boolean; //页脚
|
showFooter: boolean; //页脚
|
||||||
menuSetting: ImenuSetting; //多标签
|
menuSetting: IMenuSetting; //多标签
|
||||||
multiTabsSetting: ImultiTabsSetting; //多标签
|
multiTabsSetting: IMultiTabsSetting; //多标签
|
||||||
crumbsSetting: IcrumbsSetting; //面包屑
|
crumbsSetting: ICrumbsSetting; //面包屑
|
||||||
permissionMode: string; //权限模式
|
permissionMode: string; //权限模式
|
||||||
isPageAnimate: boolean; //是否开启路由动画
|
isPageAnimate: boolean; //是否开启路由动画
|
||||||
pageAnimateType: string; //路由动画类型
|
pageAnimateType: string; //路由动画类型
|
||||||
@@ -90,8 +89,3 @@ export const useProjectSettingStore = defineStore({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Need to be used outside the setup
|
|
||||||
export function useProjectSettingStoreWithOut() {
|
|
||||||
return useProjectSettingStore(store);
|
|
||||||
}
|
|
||||||
|
|||||||
31
src/store/modules/screenLock.ts
Normal file
31
src/store/modules/screenLock.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { IS_SCREENLOCKED } from '@/store/mutation-types';
|
||||||
|
import { storage } from '@/utils/Storage';
|
||||||
|
|
||||||
|
// 长时间不操作默认锁屏时间
|
||||||
|
const initTime = 60 * 60;
|
||||||
|
|
||||||
|
const isLocked = storage.get(IS_SCREENLOCKED, false);
|
||||||
|
|
||||||
|
export type IScreenLockState = {
|
||||||
|
isLocked: boolean; // 是否锁屏
|
||||||
|
lockTime: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useScreenLockStore = defineStore({
|
||||||
|
id: 'app-screen-lock',
|
||||||
|
state: (): IScreenLockState => ({
|
||||||
|
isLocked: isLocked === true, // 是否锁屏
|
||||||
|
lockTime: isLocked == 'true' ? initTime : 0,
|
||||||
|
}),
|
||||||
|
getters: {},
|
||||||
|
actions: {
|
||||||
|
setLock(payload: boolean) {
|
||||||
|
this.isLocked = payload;
|
||||||
|
storage.set(IS_SCREENLOCKED, this.isLocked);
|
||||||
|
},
|
||||||
|
setLockTime(payload = initTime) {
|
||||||
|
this.lockTime = payload;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -30,11 +30,11 @@ export const useTabsViewStore = defineStore({
|
|||||||
}),
|
}),
|
||||||
getters: {},
|
getters: {},
|
||||||
actions: {
|
actions: {
|
||||||
initTabs(routes) {
|
initTabs(routes: RouteItem[]) {
|
||||||
// 初始化标签页
|
// 初始化标签页
|
||||||
this.tabsList = routes;
|
this.tabsList = routes;
|
||||||
},
|
},
|
||||||
addTabs(route): boolean {
|
addTab(route: RouteItem): boolean {
|
||||||
// 添加标签页
|
// 添加标签页
|
||||||
if (whiteList.includes(route.name)) return false;
|
if (whiteList.includes(route.name)) return false;
|
||||||
const isExists = this.tabsList.some((item) => item.fullPath == route.fullPath);
|
const isExists = this.tabsList.some((item) => item.fullPath == route.fullPath);
|
||||||
@@ -43,28 +43,29 @@ export const useTabsViewStore = defineStore({
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
closeLeftTabs(route) {
|
closeLeftTabs(route: RouteItem) {
|
||||||
// 关闭左侧
|
// 关闭左侧
|
||||||
const index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
|
const index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
|
||||||
this.tabsList = this.tabsList.filter((item, i) => i >= index || (item?.meta?.affix ?? false));
|
this.tabsList = this.tabsList.filter((item, i) => i >= index || (item?.meta?.affix ?? false));
|
||||||
},
|
},
|
||||||
closeRightTabs(route) {
|
closeRightTabs(route: RouteItem) {
|
||||||
// 关闭右侧
|
// 关闭右侧
|
||||||
const index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
|
const index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
|
||||||
this.tabsList = this.tabsList.filter((item, i) => i <= index || (item?.meta?.affix ?? false));
|
this.tabsList = this.tabsList.filter((item, i) => i <= index || (item?.meta?.affix ?? false));
|
||||||
},
|
},
|
||||||
closeOtherTabs(route) {
|
closeOtherTabs(route: RouteItem) {
|
||||||
// 关闭其他
|
// 关闭其他
|
||||||
this.tabsList = this.tabsList.filter((item) => item.fullPath == route.fullPath || (item?.meta?.affix ?? false));
|
this.tabsList = this.tabsList.filter(
|
||||||
|
(item) => item.fullPath == route.fullPath || (item?.meta?.affix ?? false)
|
||||||
|
);
|
||||||
},
|
},
|
||||||
closeCurrentTab(route) {
|
closeCurrentTab(route: RouteItem) {
|
||||||
// 关闭当前页
|
// 关闭当前页
|
||||||
const index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
|
const index = this.tabsList.findIndex((item) => item.fullPath == route.fullPath);
|
||||||
this.tabsList.splice(index, 1);
|
this.tabsList.splice(index, 1);
|
||||||
},
|
},
|
||||||
closeAllTabs() {
|
closeAllTabs() {
|
||||||
// 关闭全部
|
// 关闭全部
|
||||||
console.log(retainAffixRoute(this.tabsList));
|
|
||||||
this.tabsList = retainAffixRoute(this.tabsList);
|
this.tabsList = retainAffixRoute(this.tabsList);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,18 +1,24 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { store } from '@/store';
|
import { store } from '@/store';
|
||||||
import { ACCESS_TOKEN, CURRENT_USER, IS_LOCKSCREEN } from '@/store/mutation-types';
|
import { ACCESS_TOKEN, CURRENT_USER, IS_SCREENLOCKED } from '@/store/mutation-types';
|
||||||
import { ResultEnum } from '@/enums/httpEnum';
|
import { ResultEnum } from '@/enums/httpEnum';
|
||||||
|
|
||||||
import { getUserInfo, login } from '@/api/system/user';
|
import { getUserInfo as getUserInfoApi, login } from '@/api/system/user';
|
||||||
import { storage } from '@/utils/Storage';
|
import { storage } from '@/utils/Storage';
|
||||||
|
|
||||||
|
export type UserInfoType = {
|
||||||
|
// TODO: add your own data
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
};
|
||||||
|
|
||||||
export interface IUserState {
|
export interface IUserState {
|
||||||
token: string;
|
token: string;
|
||||||
username: string;
|
username: string;
|
||||||
welcome: string;
|
welcome: string;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
permissions: any[];
|
permissions: any[];
|
||||||
info: any;
|
info: UserInfoType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useUserStore = defineStore({
|
export const useUserStore = defineStore({
|
||||||
@@ -38,7 +44,7 @@ export const useUserStore = defineStore({
|
|||||||
getPermissions(): [any][] {
|
getPermissions(): [any][] {
|
||||||
return this.permissions;
|
return this.permissions;
|
||||||
},
|
},
|
||||||
getUserInfo(): object {
|
getUserInfo(): UserInfoType {
|
||||||
return this.info;
|
return this.info;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -52,63 +58,49 @@ export const useUserStore = defineStore({
|
|||||||
setPermissions(permissions) {
|
setPermissions(permissions) {
|
||||||
this.permissions = permissions;
|
this.permissions = permissions;
|
||||||
},
|
},
|
||||||
setUserInfo(info) {
|
setUserInfo(info: UserInfoType) {
|
||||||
this.info = info;
|
this.info = info;
|
||||||
},
|
},
|
||||||
// 登录
|
// 登录
|
||||||
async login(userInfo) {
|
async login(params: any) {
|
||||||
try {
|
const response = await login(params);
|
||||||
const response = await login(userInfo);
|
const { result, code } = response;
|
||||||
const { result, code } = response;
|
if (code === ResultEnum.SUCCESS) {
|
||||||
if (code === ResultEnum.SUCCESS) {
|
const ex = 7 * 24 * 60 * 60;
|
||||||
const ex = 7 * 24 * 60 * 60;
|
storage.set(ACCESS_TOKEN, result.token, ex);
|
||||||
storage.set(ACCESS_TOKEN, result.token, ex);
|
storage.set(CURRENT_USER, result, ex);
|
||||||
storage.set(CURRENT_USER, result, ex);
|
storage.set(IS_SCREENLOCKED, false);
|
||||||
storage.set(IS_LOCKSCREEN, false);
|
this.setToken(result.token);
|
||||||
this.setToken(result.token);
|
this.setUserInfo(result);
|
||||||
this.setUserInfo(result);
|
|
||||||
}
|
|
||||||
return Promise.resolve(response);
|
|
||||||
} catch (e) {
|
|
||||||
return Promise.reject(e);
|
|
||||||
}
|
}
|
||||||
|
return response;
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
GetInfo() {
|
async getInfo() {
|
||||||
const that = this;
|
const result = await getUserInfoApi();
|
||||||
return new Promise((resolve, reject) => {
|
if (result.permissions && result.permissions.length) {
|
||||||
getUserInfo()
|
const permissionsList = result.permissions;
|
||||||
.then((res) => {
|
this.setPermissions(permissionsList);
|
||||||
const result = res;
|
this.setUserInfo(result);
|
||||||
if (result.permissions && result.permissions.length) {
|
} else {
|
||||||
const permissionsList = result.permissions;
|
throw new Error('getInfo: permissionsList must be a non-null array !');
|
||||||
that.setPermissions(permissionsList);
|
}
|
||||||
that.setUserInfo(result);
|
this.setAvatar(result.avatar);
|
||||||
} else {
|
return result;
|
||||||
reject(new Error('getInfo: permissionsList must be a non-null array !'));
|
|
||||||
}
|
|
||||||
that.setAvatar(result.avatar);
|
|
||||||
resolve(res);
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// 登出
|
// 登出
|
||||||
async logout() {
|
async logout() {
|
||||||
this.setPermissions([]);
|
this.setPermissions([]);
|
||||||
this.setUserInfo('');
|
this.setUserInfo({ name: '', email: '' });
|
||||||
storage.remove(ACCESS_TOKEN);
|
storage.remove(ACCESS_TOKEN);
|
||||||
storage.remove(CURRENT_USER);
|
storage.remove(CURRENT_USER);
|
||||||
return Promise.resolve('');
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Need to be used outside the setup
|
// Need to be used outside the setup
|
||||||
export function useUserStoreWidthOut() {
|
export function useUser() {
|
||||||
return useUserStore(store);
|
return useUserStore(store);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export const ACCESS_TOKEN = 'ACCESS-TOKEN'; // 用户token
|
export const ACCESS_TOKEN = 'ACCESS-TOKEN'; // 用户token
|
||||||
export const CURRENT_USER = 'CURRENT-USER'; // 当前用户信息
|
export const CURRENT_USER = 'CURRENT-USER'; // 当前用户信息
|
||||||
export const IS_LOCKSCREEN = 'IS-LOCKSCREEN'; // 是否锁屏
|
export const IS_SCREENLOCKED = 'IS-SCREENLOCKED'; // 是否锁屏
|
||||||
export const TABS_ROUTES = 'TABS-ROUTES'; // 标签页
|
export const TABS_ROUTES = 'TABS-ROUTES'; // 标签页
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { IAsyncRouteState } from '@/store/modules/asyncRoute';
|
import { IAsyncRouteState } from '@/store/modules/asyncRoute';
|
||||||
import { IUserState } from '@/store/modules/user';
|
import { IUserState } from '@/store/modules/user';
|
||||||
import { ILockscreenState } from '@/store/modules/lockscreen';
|
import { IScreenLockState } from '@/store/modules/screenLock';
|
||||||
import { ITabsViewState } from '@/store/modules/tabsView';
|
import { ITabsViewState } from '@/store/modules/tabsView';
|
||||||
|
|
||||||
export interface IStore {
|
export interface IStore {
|
||||||
asyncRoute: IAsyncRouteState;
|
asyncRoute: IAsyncRouteState;
|
||||||
user: IUserState;
|
user: IUserState;
|
||||||
lockscreen: ILockscreenState;
|
screenLock: IScreenLockState;
|
||||||
tabsView: ITabsViewState;
|
tabsView: ITabsViewState;
|
||||||
count: number;
|
count: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,135 +0,0 @@
|
|||||||
#app,
|
|
||||||
body,
|
|
||||||
html {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei,
|
|
||||||
'\5FAE\8F6F\96C5\9ED1', Arial, sans-serif;
|
|
||||||
line-height: 1.5;
|
|
||||||
color: #515a6e;
|
|
||||||
font-size: 14px;
|
|
||||||
background-color: #f7f7f7;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
}
|
|
||||||
|
|
||||||
//重置样式
|
|
||||||
.anticon {
|
|
||||||
svg {
|
|
||||||
vertical-align: initial;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: #2d8cf0;
|
|
||||||
background: transparent;
|
|
||||||
text-decoration: none;
|
|
||||||
outline: none;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: color 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:active,
|
|
||||||
a:hover {
|
|
||||||
outline-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
color: #57a3f3;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:active {
|
|
||||||
color: #2b85e4;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:active,
|
|
||||||
a:hover {
|
|
||||||
outline: 0;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 滚动条凹槽的颜色,还可以设置边框属性 */
|
|
||||||
*::-webkit-scrollbar-track-piece {
|
|
||||||
background-color: #f8f8f8;
|
|
||||||
-webkit-border-radius: 2em;
|
|
||||||
-moz-border-radius: 2em;
|
|
||||||
border-radius: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 滚动条的宽度 */
|
|
||||||
*::-webkit-scrollbar {
|
|
||||||
width: 9px;
|
|
||||||
height: 9px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 滚动条的设置 */
|
|
||||||
*::-webkit-scrollbar-thumb {
|
|
||||||
background-color: #ddd;
|
|
||||||
background-clip: padding-box;
|
|
||||||
-webkit-border-radius: 2em;
|
|
||||||
-moz-border-radius: 2em;
|
|
||||||
border-radius: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 滚动条鼠标移上去 */
|
|
||||||
*::-webkit-scrollbar-thumb:hover {
|
|
||||||
background-color: #bbb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* router view transition */
|
|
||||||
.zoom-fade-enter-active,
|
|
||||||
.zoom-fade-leave-active {
|
|
||||||
transition: transform 0.35s, opacity 0.28s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.zoom-fade-enter-from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(0.97);
|
|
||||||
}
|
|
||||||
|
|
||||||
.zoom-fade-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
transform: scale(1.03);
|
|
||||||
}
|
|
||||||
|
|
||||||
//antd 卡片样式定制
|
|
||||||
body .n-card {
|
|
||||||
transition: all 0.2s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .n-icon {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
body .proCard {
|
|
||||||
border-radius: 4px;
|
|
||||||
|
|
||||||
.n-card__content {
|
|
||||||
padding: 16px;
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
padding-top: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
body .n-modal {
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
//body .proCardTabs{
|
|
||||||
// .n-card__content{ padding-top: 3px}
|
|
||||||
// .n-card__content:first-child{ padding-top: 3px}
|
|
||||||
//}
|
|
||||||
|
|
||||||
.n-layout-page-header {
|
|
||||||
margin: 0 -10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
img, video{
|
|
||||||
display: block;
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
@@ -1,3 +1 @@
|
|||||||
@import 'transition/index.less';
|
@import 'transition/index.less';
|
||||||
@import './var.less';
|
|
||||||
@import './common.less';
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
@primaryColor: #2d8cf0;
|
|
||||||
@primaryColorHover: #57a3f3;
|
|
||||||
@header-height: 64px;
|
|
||||||
@footer-height: 70px;
|
|
||||||
@@ -6,122 +6,119 @@ const DEFAULT_CACHE_TIME = 60 * 60 * 24 * 7;
|
|||||||
* @param {string=} prefixKey -
|
* @param {string=} prefixKey -
|
||||||
* @param {Object} [storage=localStorage] - sessionStorage | localStorage
|
* @param {Object} [storage=localStorage] - sessionStorage | localStorage
|
||||||
*/
|
*/
|
||||||
export const createStorage = ({ prefixKey = '', storage = localStorage } = {}) => {
|
|
||||||
|
export default class Storage {
|
||||||
|
private storage: globalThis.Storage;
|
||||||
|
private prefixKey?: string;
|
||||||
|
|
||||||
|
constructor(prefixKey = '', storage = localStorage) {
|
||||||
|
this.storage = storage;
|
||||||
|
this.prefixKey = prefixKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getKey(key: string) {
|
||||||
|
return `${this.prefixKey}${key}`.toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 本地缓存类
|
* @description 设置缓存
|
||||||
* @class Storage
|
* @param {string} key 缓存键
|
||||||
|
* @param {*} value 缓存值
|
||||||
|
* @param expire
|
||||||
*/
|
*/
|
||||||
const Storage = class {
|
set(key: string, value: any, expire: number | null = DEFAULT_CACHE_TIME) {
|
||||||
private storage = storage;
|
const stringData = JSON.stringify({
|
||||||
private prefixKey?: string = prefixKey;
|
value,
|
||||||
|
expire: expire !== null ? new Date().getTime() + expire * 1000 : null,
|
||||||
|
});
|
||||||
|
this.storage.setItem(this.getKey(key), stringData);
|
||||||
|
}
|
||||||
|
|
||||||
private getKey(key: string) {
|
/**
|
||||||
return `${this.prefixKey}${key}`.toUpperCase();
|
* 读取缓存
|
||||||
}
|
* @param {string} key 缓存键
|
||||||
|
* @param {*=} def 默认值
|
||||||
/**
|
*/
|
||||||
* @description 设置缓存
|
get(key: string, def: any = null) {
|
||||||
* @param {string} key 缓存键
|
const item = this.storage.getItem(this.getKey(key));
|
||||||
* @param {*} value 缓存值
|
if (item) {
|
||||||
* @param expire
|
try {
|
||||||
*/
|
const data = JSON.parse(item);
|
||||||
set(key: string, value: any, expire: number | null = DEFAULT_CACHE_TIME) {
|
const { value, expire } = data;
|
||||||
const stringData = JSON.stringify({
|
// 在有效期内直接返回
|
||||||
value,
|
if (expire === null || expire >= Date.now()) {
|
||||||
expire: expire !== null ? new Date().getTime() + expire * 1000 : null,
|
return value;
|
||||||
});
|
|
||||||
this.storage.setItem(this.getKey(key), stringData);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取缓存
|
|
||||||
* @param {string} key 缓存键
|
|
||||||
* @param {*=} def 默认值
|
|
||||||
*/
|
|
||||||
get(key: string, def: any = null) {
|
|
||||||
const item = this.storage.getItem(this.getKey(key));
|
|
||||||
if (item) {
|
|
||||||
try {
|
|
||||||
const data = JSON.parse(item);
|
|
||||||
const { value, expire } = data;
|
|
||||||
// 在有效期内直接返回
|
|
||||||
if (expire === null || expire >= Date.now()) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
this.remove(key);
|
|
||||||
} catch (e) {
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return def;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 从缓存删除某项
|
|
||||||
* @param {string} key
|
|
||||||
*/
|
|
||||||
remove(key: string) {
|
|
||||||
this.storage.removeItem(this.getKey(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清空所有缓存
|
|
||||||
* @memberOf Cache
|
|
||||||
*/
|
|
||||||
clear(): void {
|
|
||||||
this.storage.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置cookie
|
|
||||||
* @param {string} name cookie 名称
|
|
||||||
* @param {*} value cookie 值
|
|
||||||
* @param {number=} expire 过期时间
|
|
||||||
* 如果过期时间未设置,默认关闭浏览器自动删除
|
|
||||||
* @example
|
|
||||||
*/
|
|
||||||
setCookie(name: string, value: any, expire: number | null = DEFAULT_CACHE_TIME) {
|
|
||||||
document.cookie = `${this.getKey(name)}=${value}; Max-Age=${expire}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据名字获取cookie值
|
|
||||||
* @param name
|
|
||||||
*/
|
|
||||||
getCookie(name: string): string {
|
|
||||||
const cookieArr = document.cookie.split('; ');
|
|
||||||
for (let i = 0, length = cookieArr.length; i < length; i++) {
|
|
||||||
const kv = cookieArr[i].split('=');
|
|
||||||
if (kv[0] === this.getKey(name)) {
|
|
||||||
return kv[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据名字删除指定的cookie
|
|
||||||
* @param {string} key
|
|
||||||
*/
|
|
||||||
removeCookie(key: string) {
|
|
||||||
this.setCookie(key, 1, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清空cookie,使所有cookie失效
|
|
||||||
*/
|
|
||||||
clearCookie(): void {
|
|
||||||
const keys = document.cookie.match(/[^ =;]+(?==)/g);
|
|
||||||
if (keys) {
|
|
||||||
for (let i = keys.length; i--; ) {
|
|
||||||
document.cookie = keys[i] + '=0;expire=' + new Date(0).toUTCString();
|
|
||||||
}
|
}
|
||||||
|
this.remove(key);
|
||||||
|
} catch (e) {
|
||||||
|
return def;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
return def;
|
||||||
return new Storage();
|
}
|
||||||
};
|
|
||||||
|
|
||||||
export const storage = createStorage();
|
/**
|
||||||
|
* 从缓存删除某项
|
||||||
|
* @param {string} key
|
||||||
|
*/
|
||||||
|
remove(key: string) {
|
||||||
|
this.storage.removeItem(this.getKey(key));
|
||||||
|
}
|
||||||
|
|
||||||
export default Storage;
|
/**
|
||||||
|
* 清空所有缓存
|
||||||
|
* @memberOf Cache
|
||||||
|
*/
|
||||||
|
clear(): void {
|
||||||
|
this.storage.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置cookie
|
||||||
|
* @param {string} name cookie 名称
|
||||||
|
* @param {*} value cookie 值
|
||||||
|
* @param {number=} expire 过期时间
|
||||||
|
* 如果过期时间未设置,默认关闭浏览器自动删除
|
||||||
|
* @example
|
||||||
|
*/
|
||||||
|
setCookie(name: string, value: any, expire: number | null = DEFAULT_CACHE_TIME) {
|
||||||
|
document.cookie = `${this.getKey(name)}=${value}; Max-Age=${expire}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据名字获取cookie值
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
getCookie(name: string): string {
|
||||||
|
const cookieArr = document.cookie.split('; ');
|
||||||
|
for (let i = 0, length = cookieArr.length; i < length; i++) {
|
||||||
|
const kv = cookieArr[i].split('=');
|
||||||
|
if (kv[0] === this.getKey(name)) {
|
||||||
|
return kv[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据名字删除指定的cookie
|
||||||
|
* @param {string} key
|
||||||
|
*/
|
||||||
|
removeCookie(key: string) {
|
||||||
|
this.setCookie(key, 1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空cookie,使所有cookie失效
|
||||||
|
*/
|
||||||
|
clearCookie(): void {
|
||||||
|
const keys = document.cookie.match(/[^ =;]+(?==)/g);
|
||||||
|
if (keys) {
|
||||||
|
for (let i = keys.length; i--; ) {
|
||||||
|
document.cookie = keys[i] + '=0;expire=' + new Date(0).toUTCString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const storage = new Storage('');
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { setObjToUrlParams } from '@/utils/urlUtils';
|
|||||||
|
|
||||||
import { RequestOptions, Result, CreateAxiosOptions } from './types';
|
import { RequestOptions, Result, CreateAxiosOptions } from './types';
|
||||||
|
|
||||||
import { useUserStoreWidthOut } from '@/store/modules/user';
|
import { useUser } from '@/store/modules/user';
|
||||||
|
|
||||||
const globSetting = useGlobSetting();
|
const globSetting = useGlobSetting();
|
||||||
const urlPrefix = globSetting.urlPrefix || '';
|
const urlPrefix = globSetting.urlPrefix || '';
|
||||||
@@ -176,7 +176,7 @@ const transform: AxiosTransform = {
|
|||||||
*/
|
*/
|
||||||
requestInterceptors: (config, options) => {
|
requestInterceptors: (config, options) => {
|
||||||
// 请求之前处理config
|
// 请求之前处理config
|
||||||
const userStore = useUserStoreWidthOut();
|
const userStore = useUser();
|
||||||
const token = userStore.getToken;
|
const token = userStore.getToken;
|
||||||
if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
|
if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
|
||||||
// jwt token
|
// jwt token
|
||||||
|
|||||||
@@ -1,13 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
// darkMode: 'class',
|
content: ['./index.html', './src/**/*.{vue,ts,tsx}'],
|
||||||
plugins: [createEnterPlugin()],
|
|
||||||
content: {
|
|
||||||
enable: process.env.NODE_ENV === 'production',
|
|
||||||
content: ['./index.html', './src/**/*.{vue,ts,tsx}'],
|
|
||||||
},
|
|
||||||
corePlugins: {
|
|
||||||
preflight: false,
|
|
||||||
},
|
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
zIndex: {
|
zIndex: {
|
||||||
@@ -29,52 +21,3 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
/**
|
|
||||||
* Used for animation when the element is displayed
|
|
||||||
* @param maxOutput The larger the maxOutput output, the larger the generated css volume
|
|
||||||
*/
|
|
||||||
function createEnterPlugin(maxOutput = 6) {
|
|
||||||
const createCss = (index, d = 'x') => {
|
|
||||||
const upd = d.toUpperCase();
|
|
||||||
return {
|
|
||||||
[`*> .enter-${d}:nth-child(${index})`]: {
|
|
||||||
transform: `translate${upd}(50px)`,
|
|
||||||
},
|
|
||||||
[`*> .-enter-${d}:nth-child(${index})`]: {
|
|
||||||
transform: `translate${upd}(-50px)`,
|
|
||||||
},
|
|
||||||
[`* > .enter-${d}:nth-child(${index}),* > .-enter-${d}:nth-child(${index})`]: {
|
|
||||||
'z-index': `${10 - index}`,
|
|
||||||
opacity: '0',
|
|
||||||
animation: `enter-${d}-animation 0.4s ease-in-out 0.3s`,
|
|
||||||
'animation-fill-mode': 'forwards',
|
|
||||||
'animation-delay': `${(index * 1) / 10}s`,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
const handler = ({ addBase }) => {
|
|
||||||
const addRawCss = {};
|
|
||||||
for (let index = 1; index < maxOutput; index++) {
|
|
||||||
Object.assign(addRawCss, {
|
|
||||||
...createCss(index, 'x'),
|
|
||||||
...createCss(index, 'y'),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
addBase({
|
|
||||||
...addRawCss,
|
|
||||||
[`@keyframes enter-x-animation`]: {
|
|
||||||
to: {
|
|
||||||
opacity: '1',
|
|
||||||
transform: 'translateX(0)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
[`@keyframes enter-y-animation`]: {
|
|
||||||
to: {
|
|
||||||
opacity: '1',
|
|
||||||
transform: 'translateY(0)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
return { handler };
|
|
||||||
}
|
|
||||||
|
|||||||
10
types/config.d.ts
vendored
10
types/config.d.ts
vendored
@@ -17,17 +17,17 @@ export interface ProjectSettingState {
|
|||||||
permissionMode: string;
|
permissionMode: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IbodySetting {
|
export interface IBodySetting {
|
||||||
fixed: boolean;
|
fixed: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IheaderSetting {
|
export interface IHeaderSetting {
|
||||||
bgColor: string;
|
bgColor: string;
|
||||||
fixed: boolean;
|
fixed: boolean;
|
||||||
isReload: boolean;
|
isReload: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ImenuSetting {
|
export interface IMenuSetting {
|
||||||
minMenuWidth: number;
|
minMenuWidth: number;
|
||||||
menuWidth: number;
|
menuWidth: number;
|
||||||
fixed: boolean;
|
fixed: boolean;
|
||||||
@@ -36,12 +36,12 @@ export interface ImenuSetting {
|
|||||||
mobileWidth: number;
|
mobileWidth: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IcrumbsSetting {
|
export interface ICrumbsSetting {
|
||||||
show: boolean;
|
show: boolean;
|
||||||
showIcon: boolean;
|
showIcon: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ImultiTabsSetting {
|
export interface IMultiTabsSetting {
|
||||||
bgColor: string;
|
bgColor: string;
|
||||||
fixed: boolean;
|
fixed: boolean;
|
||||||
show: boolean;
|
show: boolean;
|
||||||
|
|||||||
@@ -46,15 +46,15 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
|
|||||||
define: {
|
define: {
|
||||||
__APP_INFO__: JSON.stringify(__APP_INFO__),
|
__APP_INFO__: JSON.stringify(__APP_INFO__),
|
||||||
},
|
},
|
||||||
css: {
|
// css: {
|
||||||
preprocessorOptions: {
|
// preprocessorOptions: {
|
||||||
less: {
|
// less: {
|
||||||
modifyVars: {},
|
// modifyVars: {},
|
||||||
javascriptEnabled: true,
|
// javascriptEnabled: true,
|
||||||
additionalData: `@import "src/styles/var.less";`,
|
// additionalData: `@import "src/styles/var.less";`,
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
server: {
|
server: {
|
||||||
host: true,
|
host: true,
|
||||||
port: VITE_PORT,
|
port: VITE_PORT,
|
||||||
|
|||||||
Reference in New Issue
Block a user