refactor ts

This commit is contained in:
LiuHao
2023-04-02 01:01:56 +08:00
parent 5c87f1cb2c
commit 251d2411f2
264 changed files with 15432 additions and 13015 deletions

View File

@ -1,3 +0,0 @@
const store = createPinia()
export default store

3
src/store/index.ts Normal file
View File

@ -0,0 +1,3 @@
const store = createPinia();
export default store;

View File

@ -1,46 +0,0 @@
import Cookies from 'js-cookie'
const useAppStore = defineStore(
'app',
{
state: () => ({
sidebar: {
opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
withoutAnimation: false,
hide: false
},
device: 'desktop',
size: Cookies.get('size') || 'default'
}),
actions: {
toggleSideBar(withoutAnimation) {
if (this.sidebar.hide) {
return false;
}
this.sidebar.opened = !this.sidebar.opened
this.sidebar.withoutAnimation = withoutAnimation
if (this.sidebar.opened) {
Cookies.set('sidebarStatus', 1)
} else {
Cookies.set('sidebarStatus', 0)
}
},
closeSideBar({ withoutAnimation }) {
Cookies.set('sidebarStatus', 0)
this.sidebar.opened = false
this.sidebar.withoutAnimation = withoutAnimation
},
toggleDevice(device) {
this.device = device
},
setSize(size) {
this.size = size;
Cookies.set('size', size)
},
toggleSideBarHide(status) {
this.sidebar.hide = status
}
}
})
export default useAppStore

73
src/store/modules/app.ts Normal file
View File

@ -0,0 +1,73 @@
import Cookies from 'js-cookie';
import zhCn from 'element-plus/es/locale/lang/zh-cn';
import en from 'element-plus/es/locale/lang/en';
export const useAppStore = defineStore('app', () => {
const sidebarStatus = Cookies.get('sidebarStatus');
const sidebar = reactive({
opened: sidebarStatus ? !!+sidebarStatus : true,
withoutAnimation: false,
hide: false
});
const device = ref<string>('desktop');
const size = ref(Cookies.get('size') || 'default');
// 语言
const language = ref(Cookies.get('language'));
const locale = computed(() => {
if (language?.value == 'en') {
return en;
} else {
return zhCn;
}
});
const toggleSideBar = (withoutAnimation?: boolean) => {
if (sidebar.hide) {
return false;
}
sidebar.opened = !sidebar.opened;
sidebar.withoutAnimation = withoutAnimation as boolean;
if (sidebar.opened) {
Cookies.set('sidebarStatus', '1');
} else {
Cookies.set('sidebarStatus', '0');
}
};
const closeSideBar = ({ withoutAnimation }: any): void => {
Cookies.set('sidebarStatus', '0');
sidebar.opened = false;
sidebar.withoutAnimation = withoutAnimation;
};
const toggleDevice = (d: string): void => {
device.value = d;
};
const setSize = (s: string): void => {
size.value = s;
Cookies.set('size', s);
};
const toggleSideBarHide = (status: boolean): void => {
sidebar.hide = status;
};
const changeLanguage = (val: string): void => {
language.value = val;
};
return {
device,
sidebar,
language,
locale,
size,
changeLanguage,
toggleSideBar,
closeSideBar,
toggleDevice,
setSize,
toggleSideBarHide
};
});
export default useAppStore;

View File

@ -1,57 +0,0 @@
const useDictStore = defineStore(
'dict',
{
state: () => ({
dict: new Array()
}),
actions: {
// 获取字典
getDict(_key) {
if (_key == null && _key == "") {
return null;
}
try {
for (let i = 0; i < this.dict.length; i++) {
if (this.dict[i].key == _key) {
return this.dict[i].value;
}
}
} catch (e) {
return null;
}
},
// 设置字典
setDict(_key, value) {
if (_key !== null && _key !== "") {
this.dict.push({
key: _key,
value: value
});
}
},
// 删除字典
removeDict(_key) {
var bln = false;
try {
for (let i = 0; i < this.dict.length; i++) {
if (this.dict[i].key == _key) {
this.dict.splice(i, 1);
return true;
}
}
} catch (e) {
bln = false;
}
return bln;
},
// 清空字典
cleanDict() {
this.dict = new Array();
},
// 初始字典
initDict() {
}
}
})
export default useDictStore

78
src/store/modules/dict.ts Normal file
View File

@ -0,0 +1,78 @@
export const useDictStore = defineStore('dict', () => {
const dict = ref<
Array<{
key: string;
value: DictDataOption[];
}>
>([]);
/**
* 获取字典
* @param _key 字典key
*/
const getDict = (_key: string): DictDataOption[] | null => {
if (_key == null && _key == '') {
return null;
}
try {
for (let i = 0; i < dict.value.length; i++) {
if (dict.value[i].key == _key) {
return dict.value[i].value;
}
}
} catch (e) {
return null;
}
return null;
};
/**
* 设置字典
* @param _key 字典key
* @param _value 字典value
*/
const setDict = (_key: string, _value: DictDataOption[]) => {
if (_key !== null && _key !== '') {
dict.value.push({
key: _key,
value: _value
});
}
};
/**
* 删除字典
* @param _key
*/
const removeDict = (_key: string): boolean => {
let bln = false;
try {
for (let i = 0; i < dict.value.length; i++) {
if (dict.value[i].key == _key) {
dict.value.splice(i, 1);
return true;
}
}
} catch (e) {
bln = false;
}
return bln;
};
/**
* 清空字典
*/
const cleanDict = (): void => {
dict.value = [];
};
return {
dict,
getDict,
setDict,
removeDict,
cleanDict
};
});
export default useDictStore;

View File

@ -1,138 +0,0 @@
import auth from '@/plugins/auth'
import router, { constantRoutes, dynamicRoutes } from '@/router'
import { getRouters } from '@/api/menu'
import Layout from '@/layout/index'
import ParentView from '@/components/ParentView'
import InnerLink from '@/layout/components/InnerLink'
// 匹配views里面所有的.vue文件
const modules = import.meta.glob('./../../views/**/*.vue')
const usePermissionStore = defineStore(
'permission',
{
state: () => ({
routes: [],
addRoutes: [],
defaultRoutes: [],
topbarRouters: [],
sidebarRouters: []
}),
actions: {
setRoutes(routes) {
this.addRoutes = routes
this.routes = constantRoutes.concat(routes)
},
setDefaultRoutes(routes) {
this.defaultRoutes = constantRoutes.concat(routes)
},
setTopbarRoutes(routes) {
this.topbarRouters = routes
},
setSidebarRouters(routes) {
this.sidebarRouters = routes
},
generateRoutes(roles) {
return new Promise(resolve => {
// 向后端请求路由数据
getRouters().then(res => {
const sdata = JSON.parse(JSON.stringify(res.data))
const rdata = JSON.parse(JSON.stringify(res.data))
const defaultData = JSON.parse(JSON.stringify(res.data))
const sidebarRoutes = filterAsyncRouter(sdata)
const rewriteRoutes = filterAsyncRouter(rdata, false, true)
const defaultRoutes = filterAsyncRouter(defaultData)
const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
asyncRoutes.forEach(route => { router.addRoute(route) })
this.setRoutes(rewriteRoutes)
this.setSidebarRouters(constantRoutes.concat(sidebarRoutes))
this.setDefaultRoutes(sidebarRoutes)
this.setTopbarRoutes(defaultRoutes)
resolve(rewriteRoutes)
})
})
}
}
})
// 遍历后台传来的路由字符串,转换为组件对象
function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
return asyncRouterMap.filter(route => {
if (type && route.children) {
route.children = filterChildren(route.children)
}
if (route.component) {
// Layout ParentView 组件特殊处理
if (route.component === 'Layout') {
route.component = Layout
} else if (route.component === 'ParentView') {
route.component = ParentView
} else if (route.component === 'InnerLink') {
route.component = InnerLink
} else {
route.component = loadView(route.component)
}
}
if (route.children != null && route.children && route.children.length) {
route.children = filterAsyncRouter(route.children, route, type)
} else {
delete route['children']
delete route['redirect']
}
return true
})
}
function filterChildren(childrenMap, lastRouter = false) {
var children = []
childrenMap.forEach((el, index) => {
if (el.children && el.children.length) {
if (el.component === 'ParentView' && !lastRouter) {
el.children.forEach(c => {
c.path = el.path + '/' + c.path
if (c.children && c.children.length) {
children = children.concat(filterChildren(c.children, c))
return
}
children.push(c)
})
return
}
}
if (lastRouter) {
el.path = lastRouter.path + '/' + el.path
}
children = children.concat(el)
})
return children
}
// 动态路由遍历,验证是否具备权限
export function filterDynamicRoutes(routes) {
const res = []
routes.forEach(route => {
if (route.permissions) {
if (auth.hasPermiOr(route.permissions)) {
res.push(route)
}
} else if (route.roles) {
if (auth.hasRoleOr(route.roles)) {
res.push(route)
}
}
})
return res
}
export const loadView = (view) => {
let res;
for (const path in modules) {
const dir = path.split('views/')[1].split('.vue')[0];
if (dir === view) {
res = () => modules[path]();
}
}
return res;
}
export default usePermissionStore

View File

@ -0,0 +1,144 @@
import { defineStore } from 'pinia';
import router, { constantRoutes, dynamicRoutes } from '@/router';
import store from '@/store';
import { getRouters } from '@/api/menu';
import Layout from '@/layout/index.vue';
import ParentView from '@/components/ParentView/index.vue';
import InnerLink from '@/layout/components/InnerLink/index.vue';
import auth from '@/plugins/auth';
import { RouteOption } from 'vue-router';
// 匹配views里面所有的.vue文件
const modules = import.meta.glob('./../../views/**/*.vue');
export const usePermissionStore = defineStore('permission', () => {
const routes = ref<RouteOption[]>([]);
const addRoutes = ref<RouteOption[]>([]);
const defaultRoutes = ref<RouteOption[]>([]);
const topbarRouters = ref<RouteOption[]>([]);
const sidebarRouters = ref<RouteOption[]>([]);
const setRoutes = (newRoutes: RouteOption[]): void => {
addRoutes.value = newRoutes;
routes.value = constantRoutes.concat(newRoutes);
};
const setDefaultRoutes = (routes: RouteOption[]): void => {
defaultRoutes.value = constantRoutes.concat(routes);
};
const setTopbarRoutes = (routes: RouteOption[]): void => {
topbarRouters.value = routes;
};
const setSidebarRouters = (routes: RouteOption[]): void => {
sidebarRouters.value = routes;
};
const generateRoutes = async (): Promise<RouteOption[]> => {
const res = await getRouters();
const { data } = res;
const sdata = JSON.parse(JSON.stringify(data));
const rdata = JSON.parse(JSON.stringify(data));
const defaultData = JSON.parse(JSON.stringify(data));
const sidebarRoutes = filterAsyncRouter(sdata);
const rewriteRoutes = filterAsyncRouter(rdata, undefined, true);
const defaultRoutes = filterAsyncRouter(defaultData);
const asyncRoutes = filterDynamicRoutes(dynamicRoutes);
asyncRoutes.forEach((route) => {
router.addRoute(route);
});
setRoutes(rewriteRoutes);
setSidebarRouters(constantRoutes.concat(sidebarRoutes));
setDefaultRoutes(sidebarRoutes);
setTopbarRoutes(defaultRoutes);
return new Promise<RouteOption[]>((resolve) => resolve(rewriteRoutes));
};
/**
* 遍历后台传来的路由字符串,转换为组件对象
* @param asyncRouterMap 后台传来的路由字符串
* @param lastRouter 上一级路由
* @param type 是否是重写路由
*/
const filterAsyncRouter = (asyncRouterMap: RouteOption[], lastRouter?: RouteOption, type = false): RouteOption[] => {
return asyncRouterMap.filter((route) => {
if (type && route.children) {
route.children = filterChildren(route.children, undefined);
}
if (route.component) {
// Layout ParentView 组件特殊处理
if (route.component === 'Layout') {
route.component = Layout;
} else if (route.component === 'ParentView') {
route.component = ParentView;
} else if (route.component === 'InnerLink') {
route.component = InnerLink;
} else {
route.component = loadView(route.component);
}
}
if (route.children != null && route.children && route.children.length) {
route.children = filterAsyncRouter(route.children, route, type);
} else {
delete route.children;
delete route.redirect;
}
return true;
});
};
const filterChildren = (childrenMap: RouteOption[], lastRouter?: RouteOption): RouteOption[] => {
let children: RouteOption[] = [];
childrenMap.forEach((el) => {
if (el.children && el.children.length) {
if (el.component === 'ParentView' && !lastRouter) {
el.children.forEach((c) => {
c.path = el.path + '/' + c.path;
if (c.children && c.children.length) {
children = children.concat(filterChildren(c.children, c));
return;
}
children.push(c);
});
return;
}
}
if (lastRouter) {
el.path = lastRouter.path + '/' + el.path;
}
children = children.concat(el);
});
return children;
};
return { routes, setRoutes, generateRoutes, setSidebarRouters, topbarRouters, sidebarRouters, defaultRoutes };
});
// 动态路由遍历,验证是否具备权限
export const filterDynamicRoutes = (routes: RouteOption[]) => {
const res: RouteOption[] = [];
routes.forEach((route) => {
if (route.permissions) {
if (auth.hasPermiOr(route.permissions)) {
res.push(route);
}
} else if (route.roles) {
if (auth.hasRoleOr(route.roles)) {
res.push(route);
}
}
});
return res;
};
export const loadView = (view: any) => {
let res;
for (const path in modules) {
const dir = path.split('views/')[1].split('.vue')[0];
if (dir === view) {
res = () => modules[path]();
}
}
return res;
};
// 非setup
export const usePermissionStoreHook = () => {
return usePermissionStore(store);
};
export default usePermissionStore;

View File

@ -1,38 +0,0 @@
import defaultSettings from '@/settings'
import { useDynamicTitle } from '@/utils/dynamicTitle'
const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
const useSettingsStore = defineStore(
'settings',
{
state: () => ({
title: '',
theme: storageSetting.theme || '#409EFF',
sideTheme: storageSetting.sideTheme || sideTheme,
showSettings: showSettings,
topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle
}),
actions: {
// 修改布局设置
changeSetting(data) {
const { key, value } = data
if (this.hasOwnProperty(key)) {
this[key] = value
}
},
// 设置网页标题
setTitle(title) {
this.title = title
useDynamicTitle();
}
}
})
export default useSettingsStore

View File

@ -0,0 +1,54 @@
import { defineStore } from 'pinia';
import defaultSettings from '@/settings';
import { SettingTypeEnum } from '@/enums/SettingTypeEnum';
import { useDynamicTitle } from '@/utils/dynamicTitle';
import { Ref } from 'vue';
export const useSettingsStore = defineStore('setting', () => {
const storageSetting = JSON.parse(localStorage.getItem('layout-setting') || '{}');
const prop: { [key: string]: Ref<any> } = {
title: ref<string>(''),
theme: ref<string>(storageSetting.theme || defaultSettings.theme),
sideTheme: ref<string>(storageSetting.sideTheme || defaultSettings.sideTheme),
showSettings: ref<boolean>(storageSetting.showSettings),
topNav: ref<boolean>(storageSetting.topNav || defaultSettings.topNav),
tagsView: ref<boolean>(storageSetting.tagsView || defaultSettings.tagsView),
fixedHeader: ref<boolean>(storageSetting.fixedHeader || defaultSettings.fixedHeader),
sidebarLogo: ref<boolean>(storageSetting.sidebarLogo || defaultSettings.sidebarLogo),
dynamicTitle: ref<boolean>(storageSetting.dynamicTitle || defaultSettings.dynamicTitle),
animationEnable: ref<boolean>(storageSetting.animationEnable || defaultSettings.animationEnable),
dark: ref<boolean>(storageSetting.dark || defaultSettings.dark)
};
const { title, theme, sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle, animationEnable, dark } = prop;
// actions
const changeSetting = (param: { key: SettingTypeEnum; value: any }) => {
const { key, value } = param;
if (key in prop) {
prop[key].value = value;
}
};
const setTitle = (value: string) => {
title.value = value;
useDynamicTitle();
};
return {
title,
theme,
sideTheme,
showSettings,
topNav,
tagsView,
fixedHeader,
sidebarLogo,
dynamicTitle,
animationEnable,
dark,
changeSetting,
setTitle
};
});
export default useSettingsStore;

View File

@ -1,182 +0,0 @@
const useTagsViewStore = defineStore(
'tags-view',
{
state: () => ({
visitedViews: [],
cachedViews: [],
iframeViews: []
}),
actions: {
addView(view) {
this.addVisitedView(view)
this.addCachedView(view)
},
addIframeView(view) {
if (this.iframeViews.some(v => v.path === view.path)) return
this.iframeViews.push(
Object.assign({}, view, {
title: view.meta.title || 'no-name'
})
)
},
addVisitedView(view) {
if (this.visitedViews.some(v => v.path === view.path)) return
this.visitedViews.push(
Object.assign({}, view, {
title: view.meta.title || 'no-name'
})
)
},
addCachedView(view) {
if (this.cachedViews.includes(view.name)) return
if (!view.meta.noCache) {
this.cachedViews.push(view.name)
}
},
delView(view) {
return new Promise(resolve => {
this.delVisitedView(view)
this.delCachedView(view)
resolve({
visitedViews: [...this.visitedViews],
cachedViews: [...this.cachedViews]
})
})
},
delVisitedView(view) {
return new Promise(resolve => {
for (const [i, v] of this.visitedViews.entries()) {
if (v.path === view.path) {
this.visitedViews.splice(i, 1)
break
}
}
this.iframeViews = this.iframeViews.filter(item => item.path !== view.path)
resolve([...this.visitedViews])
})
},
delIframeView(view) {
return new Promise(resolve => {
this.iframeViews = this.iframeViews.filter(item => item.path !== view.path)
resolve([...this.iframeViews])
})
},
delCachedView(view) {
return new Promise(resolve => {
const index = this.cachedViews.indexOf(view.name)
index > -1 && this.cachedViews.splice(index, 1)
resolve([...this.cachedViews])
})
},
delOthersViews(view) {
return new Promise(resolve => {
this.delOthersVisitedViews(view)
this.delOthersCachedViews(view)
resolve({
visitedViews: [...this.visitedViews],
cachedViews: [...this.cachedViews]
})
})
},
delOthersVisitedViews(view) {
return new Promise(resolve => {
this.visitedViews = this.visitedViews.filter(v => {
return v.meta.affix || v.path === view.path
})
this.iframeViews = this.iframeViews.filter(item => item.path === view.path)
resolve([...this.visitedViews])
})
},
delOthersCachedViews(view) {
return new Promise(resolve => {
const index = this.cachedViews.indexOf(view.name)
if (index > -1) {
this.cachedViews = this.cachedViews.slice(index, index + 1)
} else {
this.cachedViews = []
}
resolve([...this.cachedViews])
})
},
delAllViews(view) {
return new Promise(resolve => {
this.delAllVisitedViews(view)
this.delAllCachedViews(view)
resolve({
visitedViews: [...this.visitedViews],
cachedViews: [...this.cachedViews]
})
})
},
delAllVisitedViews(view) {
return new Promise(resolve => {
const affixTags = this.visitedViews.filter(tag => tag.meta.affix)
this.visitedViews = affixTags
this.iframeViews = []
resolve([...this.visitedViews])
})
},
delAllCachedViews(view) {
return new Promise(resolve => {
this.cachedViews = []
resolve([...this.cachedViews])
})
},
updateVisitedView(view) {
for (let v of this.visitedViews) {
if (v.path === view.path) {
v = Object.assign(v, view)
break
}
}
},
delRightTags(view) {
return new Promise(resolve => {
const index = this.visitedViews.findIndex(v => v.path === view.path)
if (index === -1) {
return
}
this.visitedViews = this.visitedViews.filter((item, idx) => {
if (idx <= index || (item.meta && item.meta.affix)) {
return true
}
const i = this.cachedViews.indexOf(item.name)
if (i > -1) {
this.cachedViews.splice(i, 1)
}
if(item.meta.link) {
const fi = this.iframeViews.findIndex(v => v.path === item.path)
this.iframeViews.splice(fi, 1)
}
return false
})
resolve([...this.visitedViews])
})
},
delLeftTags(view) {
return new Promise(resolve => {
const index = this.visitedViews.findIndex(v => v.path === view.path)
if (index === -1) {
return
}
this.visitedViews = this.visitedViews.filter((item, idx) => {
if (idx >= index || (item.meta && item.meta.affix)) {
return true
}
const i = this.cachedViews.indexOf(item.name)
if (i > -1) {
this.cachedViews.splice(i, 1)
}
if(item.meta.link) {
const fi = this.iframeViews.findIndex(v => v.path === item.path)
this.iframeViews.splice(fi, 1)
}
return false
})
resolve([...this.visitedViews])
})
}
}
})
export default useTagsViewStore

View File

@ -0,0 +1,198 @@
import { TagView } from 'vue-router';
export const useTagsViewStore = defineStore('tagsView', () => {
const visitedViews = ref<TagView[]>([]);
const cachedViews = ref<string[]>([]);
const iframeViews = ref<TagView[]>([]);
const addView = (view: TagView) => {
addVisitedView(view);
addCachedView(view);
};
const addIframeView = (view: TagView): void => {
if (iframeViews.value.some((v) => v.path === view.path)) return;
iframeViews.value.push(
Object.assign({}, view, {
title: view.meta?.title || 'no-name'
})
);
};
const delIframeView = (view: TagView): Promise<TagView[]> => {
return new Promise((resolve) => {
iframeViews.value = iframeViews.value.filter((item) => item.path !== view.path);
resolve([...iframeViews.value]);
});
};
const addVisitedView = (view: TagView): void => {
if (visitedViews.value.some((v) => v.path === view.path)) return;
visitedViews.value.push(
Object.assign({}, view, {
title: view.meta?.title || 'no-name'
})
);
};
const delView = (view: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> => {
return new Promise((resolve) => {
delVisitedView(view);
delCachedView(view);
resolve({
visitedViews: [...visitedViews.value],
cachedViews: [...cachedViews.value]
});
});
};
const delVisitedView = (view: TagView): Promise<TagView[]> => {
return new Promise((resolve) => {
for (const [i, v] of visitedViews.value.entries()) {
if (v.path === view.path) {
visitedViews.value.splice(i, 1);
break;
}
}
resolve([...visitedViews.value]);
});
};
const delCachedView = (view: TagView): Promise<string[]> => {
const viewName = view.name as string;
return new Promise((resolve) => {
const index = cachedViews.value.indexOf(viewName);
index > -1 && cachedViews.value.splice(index, 1);
resolve([...cachedViews.value]);
});
};
const delOthersViews = (view: TagView): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> => {
return new Promise((resolve) => {
delOthersVisitedViews(view);
delOthersCachedViews(view);
resolve({
visitedViews: [...visitedViews.value],
cachedViews: [...cachedViews.value]
});
});
};
const delOthersVisitedViews = (view: TagView): Promise<TagView[]> => {
return new Promise((resolve) => {
visitedViews.value = visitedViews.value.filter((v) => {
return v.meta?.affix || v.path === view.path;
});
resolve([...visitedViews.value]);
});
};
const delOthersCachedViews = (view: TagView): Promise<string[]> => {
const viewName = view.name as string;
return new Promise((resolve) => {
const index = cachedViews.value.indexOf(viewName);
if (index > -1) {
cachedViews.value = cachedViews.value.slice(index, index + 1);
} else {
cachedViews.value = [];
}
resolve([...cachedViews.value]);
});
};
const delAllViews = (): Promise<{ visitedViews: TagView[]; cachedViews: string[] }> => {
return new Promise((resolve) => {
delAllVisitedViews();
delAllCachedViews();
resolve({
visitedViews: [...visitedViews.value],
cachedViews: [...cachedViews.value]
});
});
};
const delAllVisitedViews = (): Promise<TagView[]> => {
return new Promise((resolve) => {
visitedViews.value = visitedViews.value.filter((tag) => tag.meta?.affix);
resolve([...visitedViews.value]);
});
};
const delAllCachedViews = (): Promise<string[]> => {
return new Promise((resolve) => {
cachedViews.value = [];
resolve([...cachedViews.value]);
});
};
const updateVisitedView = (view: TagView): void => {
for (let v of visitedViews.value) {
if (v.path === view.path) {
v = Object.assign(v, view);
break;
}
}
};
const delRightTags = (view: TagView): Promise<TagView[]> => {
return new Promise((resolve) => {
const index = visitedViews.value.findIndex((v) => v.path === view.path);
if (index === -1) {
return;
}
visitedViews.value = visitedViews.value.filter((item, idx) => {
if (idx <= index || (item.meta && item.meta.affix)) {
return true;
}
const i = cachedViews.value.indexOf(item.name as string);
if (i > -1) {
cachedViews.value.splice(i, 1);
}
return false;
});
resolve([...visitedViews.value]);
});
};
const delLeftTags = (view: TagView): Promise<TagView[]> => {
return new Promise((resolve) => {
const index = visitedViews.value.findIndex((v) => v.path === view.path);
if (index === -1) {
return;
}
visitedViews.value = visitedViews.value.filter((item, idx) => {
if (idx >= index || (item.meta && item.meta.affix)) {
return true;
}
const i = cachedViews.value.indexOf(item.name as string);
if (i > -1) {
cachedViews.value.splice(i, 1);
}
return false;
});
resolve([...visitedViews.value]);
});
};
const addCachedView = (view: TagView): void => {
const viewName = view.name as string;
if (cachedViews.value.includes(viewName)) return;
if (!view.meta?.noCache) {
cachedViews.value.push(viewName);
}
};
return {
visitedViews,
cachedViews,
iframeViews,
addVisitedView,
addCachedView,
delVisitedView,
delCachedView,
updateVisitedView,
addView,
delView,
delAllViews,
delAllVisitedViews,
delAllCachedViews,
delOthersViews,
delRightTags,
delLeftTags,
addIframeView,
delIframeView
};
});
export default useTagsViewStore;

View File

@ -1,73 +0,0 @@
import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'
import defAva from '@/assets/images/profile.jpg'
const useUserStore = defineStore(
'user',
{
state: () => ({
userId: undefined,
token: getToken(),
name: '',
avatar: '',
roles: [],
permissions: []
}),
actions: {
// 登录
login(userInfo) {
const tenantId = userInfo.tenantId.trim()
const username = userInfo.username.trim()
const password = userInfo.password
const code = userInfo.code
const uuid = userInfo.uuid
return new Promise((resolve, reject) => {
login(tenantId, username, password, code, uuid).then(res => {
setToken(res.data.token)
this.token = res.data.token
resolve()
}).catch(error => {
reject(error)
})
})
},
// 获取用户信息
getInfo() {
return new Promise((resolve, reject) => {
getInfo().then(res => {
const user = res.data.user
const avatar = (user.avatar == "" || user.avatar == null) ? defAva : user.avatar;
if (res.data.roles && res.data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
this.roles = res.data.roles
this.permissions = res.data.permissions
} else {
this.roles = ['ROLE_DEFAULT']
}
this.name = user.userName
this.avatar = avatar;
this.userId = user.userId;
resolve(res)
}).catch(error => {
reject(error)
})
})
},
// 退出系统
logOut() {
return new Promise((resolve, reject) => {
logout(this.token).then(() => {
this.token = ''
this.roles = []
this.permissions = []
removeToken()
resolve()
}).catch(error => {
reject(error)
})
})
}
}
})
export default useUserStore

83
src/store/modules/user.ts Normal file
View File

@ -0,0 +1,83 @@
import { to } from 'await-to-js';
import defAva from '@/assets/images/profile.jpg';
import store from '@/store';
import { getToken, removeToken, setToken } from '@/utils/auth';
import { login as loginApi, logout as logoutApi, getInfo as getUserInfo } from '@/api/login';
import { LoginData } from '@/api/types';
export const useUserStore = defineStore('user', () => {
const token = ref(getToken());
const name = ref('');
const nickname = ref('');
const userId = ref<string | number>('');
const avatar = ref('');
const roles = ref<Array<string>>([]); // 用户角色编码集合 → 判断路由权限
const permissions = ref<Array<string>>([]); // 用户权限编码集合 → 判断按钮权限
/**
* 登录
* @param userInfo
* @returns
*/
const login = async (userInfo: LoginData): Promise<void> => {
const [err, res] = await to(loginApi(userInfo));
if (res) {
const data = res.data;
setToken(data.token);
token.value = data.token;
return Promise.resolve();
}
return Promise.reject(err);
};
// 获取用户信息
const getInfo = async (): Promise<void> => {
const [err, res] = await to(getUserInfo());
if (res) {
const data = res.data;
const user = data.user;
const profile = user.avatar == '' || user.avatar == null ? defAva : user.avatar;
if (data.roles && data.roles.length > 0) {
// 验证返回的roles是否是一个非空数组
roles.value = data.roles;
permissions.value = data.permissions;
} else {
roles.value = ['ROLE_DEFAULT'];
}
name.value = user.userName;
nickname.value = user.nickName;
avatar.value = profile;
userId.value = user.userId;
return Promise.resolve();
}
return Promise.reject(err);
};
// 注销
const logout = async (): Promise<void> => {
await logoutApi();
token.value = '';
roles.value = [];
permissions.value = [];
removeToken();
};
return {
userId,
token,
nickname,
avatar,
roles,
permissions,
login,
getInfo,
logout
};
});
export default useUserStore;
// 非setup
export function useUserStoreHook() {
return useUserStore(store);
}