UPDATE: 1、优化动态加载路由;2、修改模式切换,菜单没刷新等问题

This commit is contained in:
贾同学
2025-10-27 16:27:12 +08:00
parent 9376d702f3
commit 425b54bc44
17 changed files with 507 additions and 466 deletions

View File

@@ -1,65 +1,69 @@
export type LayoutType = 'vertical' | 'classic' | 'transverse' | 'columns';
import { type Activate } from '@/api/activate/interface'
export type AssemblySizeType = 'large' | 'default' | 'small';
export type LayoutType = 'vertical' | 'classic' | 'transverse' | 'columns'
export type LanguageType = 'zh' | 'en' | null;
export type AssemblySizeType = 'large' | 'default' | 'small'
export type LanguageType = 'zh' | 'en' | null
/* GlobalState */
export interface GlobalState {
layout: LayoutType;
assemblySize: AssemblySizeType;
language: LanguageType;
maximize: boolean;
primary: string;
isDark: boolean;
isGrey: boolean;
isWeak: boolean;
asideInverted: boolean;
headerInverted: boolean;
isCollapse: boolean;
accordion: boolean;
breadcrumb: boolean;
breadcrumbIcon: boolean;
tabs: boolean;
tabsIcon: boolean;
footer: boolean;
layout: LayoutType
assemblySize: AssemblySizeType
language: LanguageType
maximize: boolean
primary: string
isDark: boolean
isGrey: boolean
isWeak: boolean
asideInverted: boolean
headerInverted: boolean
isCollapse: boolean
accordion: boolean
breadcrumb: boolean
breadcrumbIcon: boolean
tabs: boolean
tabsIcon: boolean
footer: boolean
}
/* UserState */
export interface UserState {
accessToken: string;
refreshToken: string;
isRefreshToken: boolean;
userInfo: { id: string, name: string,loginName:string };
accessToken: string
refreshToken: string
isRefreshToken: boolean
exp: number
userInfo: { id: string; name: string; loginName: string }
}
/* tabsMenuProps */
export interface TabsMenuProps {
icon: string;
title: string;
path: string;
name: string;
close: boolean;
isKeepAlive: boolean;
unshift?: boolean;
icon: string
title: string
path: string
name: string
close: boolean
isKeepAlive: boolean
unshift?: boolean
}
/* TabsState */
export interface TabsState {
tabsMenuList: TabsMenuProps[];
tabsMenuList: TabsMenuProps[]
}
/* AuthState */
export interface AuthState {
routeName: string;
routeName: string
authButtonList: {
[key: string]: string[];
};
authMenuList: Menu.MenuOptions[];
showMenuFlag: boolean;
[key: string]: string[]
}
authMenuList: Menu.MenuOptions[]
showMenuFlag: boolean
activateInfo: Activate.ActivationCodePlaintext
}
/* KeepAliveState */
export interface KeepAliveState {
keepAliveName: string[];
keepAliveName: string[]
}

View File

@@ -1,15 +1,13 @@
import { defineStore } from 'pinia'
import { AuthState } from '@/stores/interface'
import { type AuthState } from '@/stores/interface'
import { getAuthButtonListApi, getAuthMenuListApi } from '@/api/user/login'
import { getAllBreadcrumbList, getFlatMenuList, getShowMenuList } from '@/utils'
import { useRouter } from 'vue-router'
import { AUTH_STORE_KEY } from '@/stores/constant'
import { useModeStore } from '@/stores/modules/mode'
import { getLicense } from '@/api/activate'
import type { Activate } from '@/api/activate/interface'
export const useAuthStore = defineStore({
id: AUTH_STORE_KEY,
export const useAuthStore = defineStore(AUTH_STORE_KEY, {
state: (): AuthState => ({
// 按钮权限列表
authButtonList: {},
@@ -19,8 +17,7 @@ export const useAuthStore = defineStore({
routeName: '',
//登录不显示菜单栏和导航栏,点击进入测试的时候显示
showMenuFlag: JSON.parse(localStorage.getItem('showMenuFlag') as string),
router: useRouter(),
activateInfo: {}
activateInfo: {} as Activate.ActivationCodePlaintext
}),
getters: {
// 按钮权限列表
@@ -72,10 +69,9 @@ export const useAuthStore = defineStore({
localStorage.setItem('showMenuFlag', 'true')
},
//更改模式
async changeModel() {
changeModel() {
this.showMenuFlag = false
localStorage.removeItem('showMenuFlag')
this.router.push({ path: '/home/index' })
},
async setActivateInfo() {
const license_result = await getLicense()

View File

@@ -1,32 +1,37 @@
import {defineStore} from "pinia";
import {CHECK_STORE_KEY} from "@/stores/constant";
import type {CheckData} from "@/api/check/interface";
import type {Plan} from '@/api/plan/interface'
import {useAppSceneStore} from "@/stores/modules/mode";
import { defineStore } from 'pinia'
import { CHECK_STORE_KEY } from '@/stores/constant'
import type { CheckData } from '@/api/check/interface'
import type { Plan } from '@/api/plan/interface'
import { useAppSceneStore } from '@/stores/modules/mode'
export const useCheckStore = defineStore(CHECK_STORE_KEY, {
state: () => ({
devices: [] as CheckData.Device[],
plan: {} as Plan.ResPlan,
selectTestItems: {preTest: true, timeTest: false, channelsTest: false, test: true} as CheckData.SelectTestItem,
selectTestItems: {
preTest: true,
timeTest: false,
channelsTest: false,
test: true
} as CheckData.SelectTestItem,
checkType: 1, // 0:手动检测 1:自动检测
reCheckType: 1, // 0:不合格项复检 1:全部复检
showDetailType: 0, // 0:数据查询 1:误差体系跟换 2正式检测
temperature: 0,
humidity: 0,
chnNumList: [],//连线数据
nodesConnectable: true,//设置是能可以连线
chnNumList: [] as string[], //连线数据
nodesConnectable: true //设置是能可以连线
}),
getters: {},
actions: {
addDevices(device: CheckData.Device[]) {
this.devices.push(...device);
this.devices.push(...device)
},
setPlan(plan: Plan.ResPlan) {
this.plan = plan
},
clearDevices() {
this.devices = [];
this.devices = []
},
initSelectTestItems() {
const appSceneStore = useAppSceneStore()
@@ -56,12 +61,11 @@ export const useCheckStore = defineStore(CHECK_STORE_KEY, {
setHumidity(humidity: number) {
this.humidity = humidity
},
setChnNum(chnNumList: string[]) {
setChnNum(chnNumList: string[]) {
this.chnNumList = chnNumList
},
setNodesConnectable(nodesConnectable: boolean) {
setNodesConnectable(nodesConnectable: boolean) {
this.nodesConnectable = nodesConnectable
},
}
}
});
})

View File

@@ -5,11 +5,9 @@ import { DICT_STORE_KEY } from '@/stores/constant'
// 模拟数据
//import dictData from '@/api/system/dictData'
export const useDictStore = defineStore({
id: DICT_STORE_KEY,
export const useDictStore = defineStore(DICT_STORE_KEY, {
state: () => ({
dictData: [] as Dict[],
dictData: [] as Dict[]
}),
getters: {},
actions: {
@@ -27,7 +25,7 @@ export const useDictStore = defineStore({
// 初始化获取全部字典数据并缓存
async initDictData(initData: Dict[]) {
this.dictData = initData
},
}
},
persist: piniaPersistConfig(DICT_STORE_KEY),
persist: piniaPersistConfig(DICT_STORE_KEY)
})

View File

@@ -1,55 +1,53 @@
import { defineStore } from "pinia";
import { type GlobalState } from "@/stores/interface";
import { DEFAULT_PRIMARY} from "@/config";
import piniaPersistConfig from "@/stores/helper/persist";
import {GLOBAL_STORE_KEY} from "@/stores/constant";
import { defineStore } from 'pinia'
import { type GlobalState } from '@/stores/interface'
import { DEFAULT_PRIMARY } from '@/config'
import piniaPersistConfig from '@/stores/helper/persist'
import { GLOBAL_STORE_KEY } from '@/stores/constant'
export const useGlobalStore = defineStore({
id: GLOBAL_STORE_KEY,
// 修改默认值之后,需清除 localStorage 数据
state: (): GlobalState => ({
// 布局模式 (纵向vertical | 经典classic | 横向transverse | 分栏columns)
layout: "transverse",
// element 组件大小
assemblySize: "default",
// 当前系统语言
language: null,
// 当前页面是否全屏
maximize: false,
// 主题颜色
primary: DEFAULT_PRIMARY,
// 深色模式
isDark: false,
// 灰色模式
isGrey: false,
// 色弱模式
isWeak: false,
// 侧边栏反转
asideInverted: false,
// 头部反转
headerInverted: false,
// 折叠菜单
isCollapse: false,
// 菜单手风琴
accordion: false,
// 面包屑导航
breadcrumb: true,
// 面包屑导航图标
breadcrumbIcon: true,
// 标签页
tabs: true,
// 标签页图标
tabsIcon: true,
// 页脚
footer: false
}),
getters: {},
actions: {
// Set GlobalState
setGlobalState(...args: ObjToKeyValArray<GlobalState>) {
this.$patch({ [args[0]]: args[1] });
}
},
persist: piniaPersistConfig(GLOBAL_STORE_KEY)
});
export const useGlobalStore = defineStore(GLOBAL_STORE_KEY, {
// 修改默认值之后,需清除 localStorage 数据
state: (): GlobalState => ({
// 布局模式 (纵向vertical | 经典classic | 横向transverse | 分栏columns)
layout: 'transverse',
// element 组件大小
assemblySize: 'default',
// 当前系统语言
language: null,
// 当前页面是否全屏
maximize: false,
// 主题颜色
primary: DEFAULT_PRIMARY,
// 深色模式
isDark: false,
// 灰色模式
isGrey: false,
// 色弱模式
isWeak: false,
// 侧边栏反转
asideInverted: false,
// 头部反转
headerInverted: false,
// 折叠菜单
isCollapse: false,
// 菜单手风琴
accordion: false,
// 面包屑导航
breadcrumb: true,
// 面包屑导航图标
breadcrumbIcon: true,
// 标签页
tabs: true,
// 标签页图标
tabsIcon: true,
// 页脚
footer: false
}),
getters: {},
actions: {
// Set GlobalState
setGlobalState(...args: ObjToKeyValArray<GlobalState>) {
this.$patch({ [args[0]]: args[1] })
}
},
persist: piniaPersistConfig(GLOBAL_STORE_KEY)
})

View File

@@ -1,24 +1,23 @@
import {defineStore} from "pinia";
import {KeepAliveState} from "@/stores/interface";
import {KEEP_ALIVE_STORE_KEY} from '@/stores/constant'
import { defineStore } from 'pinia'
import { type KeepAliveState } from '@/stores/interface'
import { KEEP_ALIVE_STORE_KEY } from '@/stores/constant'
export const useKeepAliveStore = defineStore({
id: KEEP_ALIVE_STORE_KEY,
state: (): KeepAliveState => ({
keepAliveName: []
}),
actions: {
// Add KeepAliveName
async addKeepAliveName(name: string) {
!this.keepAliveName.includes(name) && this.keepAliveName.push(name);
},
// Remove KeepAliveName
async removeKeepAliveName(name: string) {
this.keepAliveName = this.keepAliveName.filter(item => item !== name);
},
// Set KeepAliveName
async setKeepAliveName(keepAliveName: string[] = []) {
this.keepAliveName = keepAliveName;
export const useKeepAliveStore = defineStore(KEEP_ALIVE_STORE_KEY, {
state: (): KeepAliveState => ({
keepAliveName: []
}),
actions: {
// Add KeepAliveName
async addKeepAliveName(name: string) {
!this.keepAliveName.includes(name) && this.keepAliveName.push(name)
},
// Remove KeepAliveName
async removeKeepAliveName(name: string) {
this.keepAliveName = this.keepAliveName.filter(item => item !== name)
},
// Set KeepAliveName
async setKeepAliveName(keepAliveName: string[] = []) {
this.keepAliveName = keepAliveName
}
}
}
});
})

View File

@@ -1,29 +1,17 @@
// src/stores/modules/mode.ts
import { defineStore } from 'pinia';
// export const useModeStore = defineStore('mode', {
// state: () => ({
// currentMode: '' as string,
// }),
// actions: {
// setCurrentMode(modeName: string) {
// this.currentMode = modeName;
// },
// },
// });
import { defineStore } from 'pinia'
export const useModeStore = defineStore('mode', {
state: () => ({
currentMode: localStorage.getItem('currentMode') || '' as string,
currentMode: localStorage.getItem('currentMode') || ('' as string)
}),
actions: {
setCurrentMode(modeName: string) {
this.currentMode = modeName;
localStorage.setItem('currentMode', modeName); // 保存到 localStorage
},
},
});
setCurrentMode(modeName: string) {
this.currentMode = modeName
localStorage.setItem('currentMode', modeName) // 保存到 localStorage
}
}
})
export const useAppSceneStore = defineStore('scene', {
state: () => ({

View File

@@ -1,81 +1,77 @@
import router from "@/routers";
import { defineStore } from "pinia";
import { getUrlWithParams } from "@/utils";
import { useKeepAliveStore } from "./keepAlive";
import { TabsState, TabsMenuProps } from "@/stores/interface";
import piniaPersistConfig from "@/stores/helper/persist";
import {TABS_STORE_KEY} from "@/stores/constant";
import router from '@/routers'
import { defineStore } from 'pinia'
import { getUrlWithParams } from '@/utils'
import { useKeepAliveStore } from './keepAlive'
import type { TabsMenuProps, TabsState } from '@/stores/interface'
import { TABS_STORE_KEY } from '@/stores/constant'
const keepAliveStore = useKeepAliveStore();
export const useTabsStore = defineStore({
id: TABS_STORE_KEY,
state: (): TabsState => ({
tabsMenuList: []
}),
actions: {
// Add Tabs
async addTabs(tabItem: TabsMenuProps) {
if (this.tabsMenuList.every(item => item.path !== tabItem.path)) {
if (tabItem?.unshift) {
this.tabsMenuList.unshift(tabItem);
}else{
this.tabsMenuList.push(tabItem);
const keepAliveStore = useKeepAliveStore()
export const useTabsStore = defineStore(TABS_STORE_KEY, {
state: (): TabsState => ({
tabsMenuList: []
}),
actions: {
// Add Tabs
async addTabs(tabItem: TabsMenuProps) {
if (this.tabsMenuList.every(item => item.path !== tabItem.path)) {
if (tabItem?.unshift) {
this.tabsMenuList.unshift(tabItem)
} else {
this.tabsMenuList.push(tabItem)
}
}
if (!keepAliveStore.keepAliveName.includes(tabItem.name) && tabItem.isKeepAlive) {
await keepAliveStore.addKeepAliveName(tabItem.name)
}
},
// Remove Tabs
async removeTabs(tabPath: string, isCurrent: boolean = true) {
if (isCurrent) {
this.tabsMenuList.forEach((item, index) => {
if (item.path !== tabPath) return
const nextTab = this.tabsMenuList[index + 1] || this.tabsMenuList[index - 1]
if (!nextTab) return
router.push(nextTab.path)
})
}
this.tabsMenuList = this.tabsMenuList.filter(item => item.path !== tabPath)
// remove keepalive
const tabItem = this.tabsMenuList.find(item => item.path === tabPath)
tabItem?.isKeepAlive && (await keepAliveStore.removeKeepAliveName(tabItem.name))
},
// Close Tabs On Side
async closeTabsOnSide(path: string, type: 'left' | 'right') {
const currentIndex = this.tabsMenuList.findIndex(item => item.path === path)
if (currentIndex !== -1) {
const range = type === 'left' ? [0, currentIndex] : [currentIndex + 1, this.tabsMenuList.length]
this.tabsMenuList = this.tabsMenuList.filter((item, index) => {
return index < range[0] || index >= range[1] || !item.close
})
}
// set keepalive
const KeepAliveList = this.tabsMenuList.filter(item => item.isKeepAlive)
await keepAliveStore.setKeepAliveName(KeepAliveList.map(item => item.name))
},
// Close MultipleTab
async closeMultipleTab(tabsMenuValue?: string) {
this.tabsMenuList = this.tabsMenuList.filter(item => {
return item.path === tabsMenuValue || !item.close
})
// set keepalive
const KeepAliveList = this.tabsMenuList.filter(item => item.isKeepAlive)
await keepAliveStore.setKeepAliveName(KeepAliveList.map(item => item.name))
},
// Set Tabs
async setTabs(tabsMenuList: TabsMenuProps[]) {
this.tabsMenuList = tabsMenuList
},
// Set Tabs Title
async setTabsTitle(title: string) {
this.tabsMenuList.forEach(item => {
if (item.path == getUrlWithParams()) item.title = title
})
}
}
if (!keepAliveStore.keepAliveName.includes(tabItem.name) && tabItem.isKeepAlive) {
keepAliveStore.addKeepAliveName(tabItem.name);
}
},
// Remove Tabs
async removeTabs(tabPath: string, isCurrent: boolean = true) {
if (isCurrent) {
this.tabsMenuList.forEach((item, index) => {
if (item.path !== tabPath) return;
const nextTab = this.tabsMenuList[index + 1] || this.tabsMenuList[index - 1];
if (!nextTab) return;
router.push(nextTab.path);
});
}
this.tabsMenuList = this.tabsMenuList.filter(item => item.path !== tabPath);
// remove keepalive
const tabItem = this.tabsMenuList.find(item => item.path === tabPath);
tabItem?.isKeepAlive && keepAliveStore.removeKeepAliveName(tabItem.name);
},
// Close Tabs On Side
async closeTabsOnSide(path: string, type: "left" | "right") {
const currentIndex = this.tabsMenuList.findIndex(item => item.path === path);
if (currentIndex !== -1) {
const range = type === "left" ? [0, currentIndex] : [currentIndex + 1, this.tabsMenuList.length];
this.tabsMenuList = this.tabsMenuList.filter((item, index) => {
return index < range[0] || index >= range[1] || !item.close;
});
}
// set keepalive
const KeepAliveList = this.tabsMenuList.filter(item => item.isKeepAlive);
keepAliveStore.setKeepAliveName(KeepAliveList.map(item => item.name));
},
// Close MultipleTab
async closeMultipleTab(tabsMenuValue?: string) {
this.tabsMenuList = this.tabsMenuList.filter(item => {
return item.path === tabsMenuValue || !item.close;
});
// set keepalive
const KeepAliveList = this.tabsMenuList.filter(item => item.isKeepAlive);
keepAliveStore.setKeepAliveName(KeepAliveList.map(item => item.name));
},
// Set Tabs
async setTabs(tabsMenuList: TabsMenuProps[]) {
this.tabsMenuList = tabsMenuList;
},
// Set Tabs Title
async setTabsTitle(title: string) {
this.tabsMenuList.forEach(item => {
if (item.path == getUrlWithParams()) item.title = title;
});
}
}
// persist: piniaPersistConfig(TABS_STORE_KEY)
});
// persist: piniaPersistConfig(TABS_STORE_KEY)
})

View File

@@ -1,36 +1,57 @@
import {defineStore} from "pinia";
import {UserState} from "@/stores/interface";
import piniaPersistConfig from "@/stores/helper/persist";
import {USER_STORE_KEY} from "@/stores/constant";
import { defineStore } from 'pinia'
import { type UserState } from '@/stores/interface'
import piniaPersistConfig from '@/stores/helper/persist'
import { USER_STORE_KEY } from '@/stores/constant'
import { logoutApi } from '@/api/user/login'
import { useAuthStore } from '@/stores/modules/auth'
import { useAppSceneStore, useModeStore } from '@/stores/modules/mode'
import { useDictStore } from '@/stores/modules/dict'
export const useUserStore = defineStore({
id: USER_STORE_KEY,
state: (): UserState => ({
accessToken: "",
refreshToken: "",
isRefreshToken:false,
exp: Number(0),
userInfo: {id:"", name: "" ,loginName:""},
}),
getters: {},
actions: {
// Set Token
setAccessToken(accessToken: string) {
this.accessToken = accessToken;
export const useUserStore = defineStore(USER_STORE_KEY, {
state: (): UserState => ({
accessToken: '',
refreshToken: '',
isRefreshToken: false,
exp: Number(0),
userInfo: { id: '', name: '', loginName: '' }
}),
getters: {},
actions: {
// Set Token
setAccessToken(accessToken: string) {
this.accessToken = accessToken
},
setRefreshToken(refreshToken: string) {
this.refreshToken = refreshToken
},
setIsRefreshToken(isRefreshToken: boolean) {
this.isRefreshToken = isRefreshToken
},
// Set setUserInfo
setUserInfo(userInfo: UserState['userInfo']) {
this.userInfo = userInfo
},
setExp(exp: number) {
this.exp = exp
},
async logout() {
const authStore = useAuthStore()
const modeStore = useModeStore()
const appSceneStore = useAppSceneStore()
const dictStore = useDictStore()
// 1.执行退出登录接口
await logoutApi()
// 2.清除 Token
this.setAccessToken('')
this.setRefreshToken('')
this.setExp(0)
this.setUserInfo({ id: '', name: '', loginName: '' })
this.setIsRefreshToken(false)
dictStore.setDictData([])
modeStore.setCurrentMode('')
appSceneStore.setCurrentMode('')
await authStore.resetAuthStore()
}
},
setRefreshToken(refreshToken: string) {
this.refreshToken = refreshToken;
},
setIsRefreshToken(isRefreshToken: boolean) {
this.isRefreshToken = isRefreshToken;
},
// Set setUserInfo
setUserInfo(userInfo: UserState["userInfo"]) {
this.userInfo = userInfo;
},
setExp(exp: number) {
this.exp = exp;
}
},
persist: piniaPersistConfig(USER_STORE_KEY),
});
persist: piniaPersistConfig(USER_STORE_KEY)
})