init: 初始系统模板
This commit is contained in:
31
src/store/modules/app.ts
Normal file
31
src/store/modules/app.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
/**应用参数类型 */
|
||||
type AppStore = {
|
||||
/**应用名称 */
|
||||
appName: string;
|
||||
/**应用标识 */
|
||||
appCode: string;
|
||||
/**应用版本 */
|
||||
appVersion: string;
|
||||
};
|
||||
|
||||
const useAppStore = defineStore('app', {
|
||||
state: (): AppStore => ({
|
||||
appName: import.meta.env.VITE_APP_NAME,
|
||||
appCode: import.meta.env.VITE_APP_CODE,
|
||||
appVersion: import.meta.env.VITE_APP_VERSION,
|
||||
}),
|
||||
actions: {
|
||||
/**设置网页标题 */
|
||||
setTitle(title?: string) {
|
||||
if (title) {
|
||||
document.title = `${title} - ${this.appName}`;
|
||||
} else {
|
||||
document.title = this.appName;
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default useAppStore;
|
||||
63
src/store/modules/dict.ts
Normal file
63
src/store/modules/dict.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { getDictDataType } from '@/api/system/dict/data';
|
||||
|
||||
/**字典参数类型 */
|
||||
type DictStore = {
|
||||
/**字典数据 */
|
||||
dicts: Map<string, DictType[]>;
|
||||
};
|
||||
|
||||
const useDictStore = defineStore('dict', {
|
||||
state: (): DictStore => ({
|
||||
dicts: new Map(),
|
||||
}),
|
||||
actions: {
|
||||
/**清空字典 */
|
||||
clearDict() {
|
||||
this.dicts.clear();
|
||||
},
|
||||
/**删除字典 */
|
||||
removeDict(key: string) {
|
||||
if (!key) return;
|
||||
return this.dicts.delete(key);
|
||||
},
|
||||
/**
|
||||
* 处理字典数据对象用于回显标签
|
||||
* @param data 字典数据项
|
||||
* @returns
|
||||
*/
|
||||
parseDataDict(data: Record<string, any>) {
|
||||
return [
|
||||
{
|
||||
label: data.dictLabel,
|
||||
value: data.dictValue,
|
||||
elTagType: data.tagType,
|
||||
elTagClass: data.tagClass,
|
||||
},
|
||||
];
|
||||
},
|
||||
/**获取字典 */
|
||||
async getDict(key: string) {
|
||||
if (!key) return [];
|
||||
let disct = this.dicts.get(key);
|
||||
if (disct === undefined || disct.length === 0) {
|
||||
const res = await getDictDataType(key);
|
||||
if (res.code === 200 && Array.isArray(res.data)) {
|
||||
const dictData: DictType[] = res.data.map(d => ({
|
||||
label: d.dictLabel,
|
||||
value: d.dictValue,
|
||||
elTagType: d.tagType,
|
||||
elTagClass: d.tagClass,
|
||||
}));
|
||||
this.dicts.set(key, dictData);
|
||||
disct = dictData;
|
||||
} else {
|
||||
disct = [];
|
||||
}
|
||||
}
|
||||
return disct;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default useDictStore;
|
||||
91
src/store/modules/layout.ts
Normal file
91
src/store/modules/layout.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { CACHE_LOCAL_PROCONFIG } from '@/constants/cache-keys-constants';
|
||||
import { localGetJSON, localSetJSON } from '@/utils/cache-local-utils';
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
/**布局参数类型 */
|
||||
type LayoutStore = {
|
||||
/**布局设置抽屉显示 */
|
||||
visible: boolean;
|
||||
/**布局配置 */
|
||||
proConfig: {
|
||||
/**导航布局 */
|
||||
layout: 'side' | 'top' | 'mix';
|
||||
/**导航菜单主题色 */
|
||||
navTheme: 'dark' | 'light';
|
||||
/**顶部导航主题,仅导航布局为mix时生效 */
|
||||
headerTheme: 'dark' | 'light';
|
||||
/**固定顶部栏 */
|
||||
fixedHeader: boolean;
|
||||
/**固定菜单栏 */
|
||||
fixSiderbar: boolean;
|
||||
/**自动分割菜单 */
|
||||
splitMenus: boolean;
|
||||
/**内容区域-顶栏 */
|
||||
headerRender: any | boolean | undefined;
|
||||
/**内容区域-页脚 */
|
||||
footerRender: any | boolean | undefined;
|
||||
/**内容区域-菜单头 */
|
||||
menuHeaderRender: any | boolean | undefined;
|
||||
/**内容区域-导航标签项 */
|
||||
tabRender: any | boolean | undefined;
|
||||
};
|
||||
/**水印内容 */
|
||||
waterMarkContent: string;
|
||||
};
|
||||
|
||||
/**判断是否关闭内容区域 */
|
||||
const proRender = (render: any) => (render === false ? false : undefined);
|
||||
|
||||
/**本地缓存-布局配置设置 */
|
||||
const proConfigLocal: LayoutStore['proConfig'] = localGetJSON(
|
||||
CACHE_LOCAL_PROCONFIG
|
||||
) || {
|
||||
layout: 'side',
|
||||
headerTheme: 'light',
|
||||
navTheme: 'light',
|
||||
fixSiderbar: true,
|
||||
fixedHeader: true,
|
||||
splitMenus: true,
|
||||
};
|
||||
|
||||
const useLayoutStore = defineStore('layout', {
|
||||
state: (): LayoutStore => ({
|
||||
visible: false,
|
||||
proConfig: {
|
||||
layout: proConfigLocal.layout,
|
||||
navTheme: proConfigLocal.navTheme,
|
||||
headerTheme: proConfigLocal.headerTheme,
|
||||
fixedHeader: Boolean(proConfigLocal.fixedHeader),
|
||||
fixSiderbar: Boolean(proConfigLocal.fixSiderbar),
|
||||
splitMenus: Boolean(proConfigLocal.splitMenus),
|
||||
headerRender: proRender(proConfigLocal.headerRender),
|
||||
footerRender: proRender(proConfigLocal.footerRender),
|
||||
menuHeaderRender: proRender(proConfigLocal.menuHeaderRender),
|
||||
tabRender: proRender(proConfigLocal.tabRender),
|
||||
},
|
||||
waterMarkContent: import.meta.env.VITE_APP_NAME,
|
||||
}),
|
||||
actions: {
|
||||
/**改变显示状态 */
|
||||
changeVisibleLayoutSetting() {
|
||||
this.visible = !this.visible;
|
||||
},
|
||||
/**修改水印文字 */
|
||||
changeWaterMark(text: string) {
|
||||
this.waterMarkContent = text;
|
||||
},
|
||||
/**修改布局设置 */
|
||||
changeConf(key: string, value: boolean | string | number | undefined) {
|
||||
if (Reflect.has(this.proConfig, key)) {
|
||||
// 同时修改mix混合菜单的导航主题
|
||||
if (key === 'navTheme') {
|
||||
Reflect.set(this.proConfig, 'headerTheme', value);
|
||||
}
|
||||
Reflect.set(this.proConfig, key, value);
|
||||
localSetJSON(CACHE_LOCAL_PROCONFIG, this.proConfig);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default useLayoutStore;
|
||||
152
src/store/modules/router.ts
Normal file
152
src/store/modules/router.ts
Normal file
@@ -0,0 +1,152 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import {
|
||||
RouteComponent,
|
||||
RouteLocationRaw,
|
||||
RouteMeta,
|
||||
RouteRecordRaw,
|
||||
} from 'vue-router';
|
||||
import { getRouters } from '@/api/router';
|
||||
import BasicLayout from '@/layouts/BasicLayout.vue';
|
||||
import BlankLayout from '@/layouts/BlankLayout.vue';
|
||||
import LinkLayout from '@/layouts/LinkLayout.vue';
|
||||
import {
|
||||
MENU_COMPONENT_LAYOUT_BASIC,
|
||||
MENU_COMPONENT_LAYOUT_BLANK,
|
||||
MENU_COMPONENT_LAYOUT_LINK,
|
||||
} from '@/constants/menu-constants';
|
||||
|
||||
/**路由构建参数类型 */
|
||||
type RouterStore = {
|
||||
/**初始的根路由数据 */
|
||||
rootRouterData: RouteRecordRaw[];
|
||||
/**动态路由数据 */
|
||||
buildRouterData: RouteRecordRaw[];
|
||||
};
|
||||
|
||||
const useRouterStore = defineStore('router', {
|
||||
state: (): RouterStore => ({
|
||||
rootRouterData: [],
|
||||
buildRouterData: [],
|
||||
}),
|
||||
actions: {
|
||||
/**
|
||||
* 记录初始根节点菜单数据
|
||||
* @param data 初始数据
|
||||
* @returns 初始数据
|
||||
*/
|
||||
setRootRouterData(data: RouteRecordRaw[]) {
|
||||
if (this.rootRouterData.length <= 0) {
|
||||
this.rootRouterData = data;
|
||||
}
|
||||
return this.rootRouterData;
|
||||
},
|
||||
/**
|
||||
* 动态路由列表数据生成
|
||||
* @returns 生成的路由菜单
|
||||
*/
|
||||
async generateRoutes() {
|
||||
const res = await getRouters();
|
||||
if (res.code === 200 && Array.isArray(res.data)) {
|
||||
const buildRoutes = buildRouters(res.data.concat());
|
||||
this.buildRouterData = buildRoutes;
|
||||
return buildRoutes;
|
||||
}
|
||||
return [];
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
/**异步路由类型 */
|
||||
type RecordRaws = {
|
||||
path: string;
|
||||
name: string;
|
||||
meta: RouteMeta;
|
||||
redirect: RouteLocationRaw;
|
||||
component: string;
|
||||
children: RecordRaws[];
|
||||
};
|
||||
|
||||
/**
|
||||
* 构建动态路由
|
||||
*
|
||||
* 遍历后台配置的路由菜单,转换为组件路由菜单
|
||||
*
|
||||
* @param recordRaws 异步路由列表
|
||||
* @returns 可添加的路由列表
|
||||
*/
|
||||
function buildRouters(recordRaws: RecordRaws[]): RouteRecordRaw[] {
|
||||
const routers: RouteRecordRaw[] = [];
|
||||
for (const item of recordRaws) {
|
||||
// 路由页面组件
|
||||
let component: RouteComponent = {};
|
||||
if (item.component) {
|
||||
const comp = item.component;
|
||||
if (comp === MENU_COMPONENT_LAYOUT_BASIC) {
|
||||
component = BasicLayout;
|
||||
} else if (comp === MENU_COMPONENT_LAYOUT_BLANK) {
|
||||
component = BlankLayout;
|
||||
} else if (comp === MENU_COMPONENT_LAYOUT_LINK) {
|
||||
component = LinkLayout;
|
||||
} else {
|
||||
// 指定页面视图,一般用于显示子菜单
|
||||
component = findView(comp);
|
||||
}
|
||||
}
|
||||
|
||||
// 有子菜单进行递归
|
||||
let children: RouteRecordRaw[] = [];
|
||||
if (item.children && item.children.length > 0) {
|
||||
children = buildRouters(item.children);
|
||||
}
|
||||
|
||||
// 对元数据特殊参数进行处理
|
||||
let metaIcon = (item.meta?.icon as string) || '';
|
||||
if (!metaIcon.startsWith('icon-')) {
|
||||
metaIcon = '';
|
||||
}
|
||||
item.meta = Object.assign(item.meta, {
|
||||
icon: metaIcon,
|
||||
});
|
||||
|
||||
// 构建路由
|
||||
const router: RouteRecordRaw = {
|
||||
path: item.path,
|
||||
name: item.name,
|
||||
meta: item.meta,
|
||||
redirect: item.redirect,
|
||||
component: component,
|
||||
children: children,
|
||||
};
|
||||
routers.push(router);
|
||||
}
|
||||
return routers;
|
||||
}
|
||||
|
||||
/**匹配views里面所有的.vue或.tsx文件 */
|
||||
const views = import.meta.glob('./../../views/**/*.{vue,tsx}');
|
||||
|
||||
/**
|
||||
* 查找页面模块
|
||||
*
|
||||
* 查找 `/views/system/menu/index.vue` 或 `/views/system/menu/index.tsx`
|
||||
*
|
||||
* 参数值为 `system/menu/index`
|
||||
*
|
||||
* @param dirName 组件路径
|
||||
* @returns 路由懒加载函数
|
||||
*/
|
||||
function findView(dirName: string) {
|
||||
for (const dir in views) {
|
||||
let viewDirName = '';
|
||||
const component = dir.match(/views\/(.+)\.(vue|tsx)/);
|
||||
if (component && component.length === 3) {
|
||||
viewDirName = component[1];
|
||||
}
|
||||
if (viewDirName === dirName) {
|
||||
return () => views[dir]();
|
||||
}
|
||||
}
|
||||
return () => import('@/views/error/404.vue');
|
||||
}
|
||||
|
||||
export default useRouterStore;
|
||||
189
src/store/modules/tabs.ts
Normal file
189
src/store/modules/tabs.ts
Normal file
@@ -0,0 +1,189 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import type { LocationQuery, RouteLocationNormalizedLoaded } from 'vue-router';
|
||||
|
||||
/**导航标签栏类型 */
|
||||
type TabsStore = {
|
||||
/**标签列表 */
|
||||
tabs: TabType[];
|
||||
/**激活标签项 */
|
||||
activePath: string;
|
||||
/**缓存页面路由名称 */
|
||||
caches: Set<string>;
|
||||
};
|
||||
|
||||
/**标签信息类型 */
|
||||
type TabType = {
|
||||
path: string;
|
||||
query: LocationQuery;
|
||||
name: string;
|
||||
title: string;
|
||||
icon?: any;
|
||||
cache?: boolean;
|
||||
};
|
||||
|
||||
const useTabsStore = defineStore('tabs', {
|
||||
state: (): TabsStore => ({
|
||||
tabs: [],
|
||||
activePath: '',
|
||||
caches: new Set(),
|
||||
}),
|
||||
getters: {
|
||||
/**获取导航标签栏列表 */
|
||||
getTabs(state) {
|
||||
return state.tabs;
|
||||
},
|
||||
/**获取缓存页面名 */
|
||||
getCaches(state) {
|
||||
return [...state.caches];
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
/**清空标签项和缓存项列表 */
|
||||
clear() {
|
||||
this.tabs = [];
|
||||
this.caches.clear();
|
||||
},
|
||||
/**
|
||||
* 删除标签项
|
||||
* @param path 当期标签路由地址
|
||||
* @returns 布尔 true/false
|
||||
*/
|
||||
remove(path: string) {
|
||||
if (!path) return false;
|
||||
const tabIndex = this.tabs.findIndex(tab => tab.path === path);
|
||||
if (tabIndex === -1) return false;
|
||||
// 同名称标签只剩一个时,才移除缓存
|
||||
const name = this.tabs[tabIndex].name;
|
||||
const tabs = this.tabs.filter(tab => tab.name === name);
|
||||
if (tabs.length <= 1) {
|
||||
this.cacheDelete(name);
|
||||
}
|
||||
this.tabs.splice(tabIndex, 1);
|
||||
return true;
|
||||
},
|
||||
/**
|
||||
* 添加标签项
|
||||
* @param tab 标签信息对象
|
||||
* @param index 插入指定位置,默认加到最后
|
||||
* @returns 布尔 true/false
|
||||
*/
|
||||
add(tab: TabType, index?: number) {
|
||||
const { path, query, name, title, icon, cache } = tab;
|
||||
// 是否缓存
|
||||
if (cache) {
|
||||
this.cacheAdd(name);
|
||||
}
|
||||
// 获取没有才添加
|
||||
let tabIndex = this.tabs.findIndex(tab => tab.path === path);
|
||||
if (tabIndex >= 0) return false;
|
||||
const idx = index ? index : this.tabs.length;
|
||||
this.tabs.splice(idx, 0, { path, query, name, title, icon });
|
||||
return true;
|
||||
},
|
||||
/**添加缓存项
|
||||
* @param name 路由名称
|
||||
* @returns 布尔 true/false
|
||||
*/
|
||||
cacheAdd(name: string) {
|
||||
if (!name) return;
|
||||
const has = this.caches.has(name);
|
||||
if (has) return;
|
||||
this.caches.add(name);
|
||||
},
|
||||
/**
|
||||
* 删除缓存项
|
||||
* @param name 路由名称
|
||||
* @returns 布尔 true/false
|
||||
*/
|
||||
cacheDelete(name: string) {
|
||||
if (!name) return false;
|
||||
const has = this.caches.has(name);
|
||||
if (!has) return false;
|
||||
return this.caches.delete(name);
|
||||
},
|
||||
|
||||
/**
|
||||
* 打开标签
|
||||
*
|
||||
* 动态参数会开新标签,这是考虑多信息查看才没用同一个标签打开。
|
||||
* @param raw 跳转的路由信息
|
||||
* @returns 无
|
||||
*/
|
||||
tabOpen(raw: RouteLocationNormalizedLoaded) {
|
||||
// 刷新是重定向不记录
|
||||
if (raw.path.startsWith('/redirect')) return;
|
||||
// 标签缓存使用路由名称
|
||||
const name = (raw.name && raw.name.toString()) || '-';
|
||||
// 新增到当期标签后面打开,获取当期标签下标
|
||||
const tabIndex = this.tabs.findIndex(tab => tab.path === this.activePath);
|
||||
this.add(
|
||||
{
|
||||
path: raw.path,
|
||||
query: raw.query,
|
||||
name: name,
|
||||
title: raw.meta.title || '-',
|
||||
icon: raw.meta.icon || '#',
|
||||
cache: Boolean(raw.meta.cache),
|
||||
},
|
||||
tabIndex + 1
|
||||
);
|
||||
// 设置激活项
|
||||
this.activePath = raw.path;
|
||||
},
|
||||
/**
|
||||
* 关闭标签
|
||||
* @param path 当期标签路由地址
|
||||
* @returns 新跳转push路由参数
|
||||
*/
|
||||
tabClose(path: string) {
|
||||
if (!path) return null;
|
||||
// 获取当前项和最后项下标
|
||||
const tabIndex = this.tabs.findIndex(tab => tab.path === path);
|
||||
if (tabIndex === -1) return null;
|
||||
const lastIndex = this.tabs.length - 1;
|
||||
let to = null;
|
||||
// 只有一项默认跳首页
|
||||
if (lastIndex === 0) {
|
||||
to = {
|
||||
path: '/index',
|
||||
query: {},
|
||||
};
|
||||
}
|
||||
// 关闭当期标签,操作第一项跳后一项
|
||||
else if (path === this.activePath && tabIndex === 0) {
|
||||
const tab = this.tabs[tabIndex + 1];
|
||||
to = {
|
||||
path: tab.path,
|
||||
query: tab.query,
|
||||
};
|
||||
}
|
||||
// 关闭当期标签,默认跳前一项
|
||||
else if (path === this.activePath && tabIndex <= lastIndex) {
|
||||
const tab = this.tabs[tabIndex - 1];
|
||||
to = {
|
||||
path: tab.path,
|
||||
query: tab.query,
|
||||
};
|
||||
}
|
||||
// 移除标签
|
||||
this.remove(path);
|
||||
return to;
|
||||
},
|
||||
/**
|
||||
* 跳转标签
|
||||
* @param path 当期标签路由地址
|
||||
* @returns 新跳转push路由参数
|
||||
*/
|
||||
tabGoto(path: string) {
|
||||
if (!path) return null;
|
||||
const tab = this.tabs.find(tab => tab.path === path);
|
||||
if (!tab) return null;
|
||||
return {
|
||||
path: tab.path,
|
||||
query: tab.query,
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default useTabsStore;
|
||||
171
src/store/modules/user.ts
Normal file
171
src/store/modules/user.ts
Normal file
@@ -0,0 +1,171 @@
|
||||
import defaultAvatar from '@/assets/images/default_avatar.png';
|
||||
import useLayoutStore from './layout';
|
||||
import { login, logout, getInfo } from '@/api/login';
|
||||
import { getToken, setToken, removeToken } from '@/plugins/auth-token';
|
||||
import { defineStore } from 'pinia';
|
||||
import { TOKEN_RESPONSE_FIELD } from '@/constants/token-constants';
|
||||
import { validHttp } from '@/utils/regular-utils';
|
||||
|
||||
/**用户信息类型 */
|
||||
type UserInfo = {
|
||||
/**授权凭证 */
|
||||
token: string;
|
||||
/**登录账号 */
|
||||
userName: string;
|
||||
/**用户角色 字符串数组 */
|
||||
roles: string[];
|
||||
/**用户权限 字符串数组 */
|
||||
permissions: string[];
|
||||
/**用户头像 */
|
||||
avatar: string;
|
||||
/**用户昵称 */
|
||||
nickName: string;
|
||||
/**用户手机号 */
|
||||
phonenumber: string;
|
||||
/**用户邮箱 */
|
||||
email: string;
|
||||
/**用户性别 */
|
||||
sex: string | undefined;
|
||||
};
|
||||
|
||||
/**
|
||||
* 格式解析头像地址
|
||||
* @param avatar 头像路径
|
||||
* @returns url地址
|
||||
*/
|
||||
function parseAvatar(avatar: string): string {
|
||||
if (!avatar) {
|
||||
return defaultAvatar;
|
||||
}
|
||||
if (validHttp(avatar)) {
|
||||
return avatar;
|
||||
}
|
||||
const baseApi = import.meta.env.VITE_API_BASE_URL;
|
||||
return `${baseApi}${avatar}`;
|
||||
}
|
||||
|
||||
const useUserStore = defineStore('user', {
|
||||
state: (): UserInfo => ({
|
||||
token: getToken(),
|
||||
userName: '',
|
||||
roles: [],
|
||||
permissions: [],
|
||||
avatar: '',
|
||||
nickName: '',
|
||||
phonenumber: '',
|
||||
email: '',
|
||||
sex: undefined,
|
||||
}),
|
||||
getters: {
|
||||
/**
|
||||
* 获取正确头像地址
|
||||
* @param state 内部属性不用传入
|
||||
* @returns 头像地址url
|
||||
*/
|
||||
getAvatar(state) {
|
||||
return parseAvatar(state.avatar);
|
||||
},
|
||||
/**
|
||||
* 获取基础信息属性
|
||||
* @param state 内部属性不用传入
|
||||
* @returns 基础信息
|
||||
*/
|
||||
getBaseInfo(state) {
|
||||
return {
|
||||
nickName: state.nickName,
|
||||
phonenumber: state.phonenumber,
|
||||
email: state.email,
|
||||
sex: state.sex,
|
||||
};
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
/**
|
||||
* 更新基础信息属性
|
||||
* @param data 变更信息
|
||||
*/
|
||||
setBaseInfo(data: Record<string, any>) {
|
||||
this.nickName = data.nickName;
|
||||
this.phonenumber = data.phonenumber;
|
||||
this.email = data.email;
|
||||
this.sex = data.sex;
|
||||
},
|
||||
/**
|
||||
* 更新头像
|
||||
* @param avatar 上传后的地址
|
||||
*/
|
||||
setAvatar(avatar: string) {
|
||||
this.avatar = avatar;
|
||||
},
|
||||
/**
|
||||
* 获取正确头像地址
|
||||
* @param avatar
|
||||
*/
|
||||
fnAvatar(avatar: string) {
|
||||
return parseAvatar(avatar);
|
||||
},
|
||||
// 登录
|
||||
async fnLogin(loginBody: Record<string, string>) {
|
||||
const res = await login(loginBody);
|
||||
if (res.code === 200 && res.data) {
|
||||
const token = res.data[TOKEN_RESPONSE_FIELD];
|
||||
setToken(token);
|
||||
this.token = token;
|
||||
}
|
||||
return res;
|
||||
},
|
||||
// 获取用户信息
|
||||
async fnGetInfo() {
|
||||
const res = await getInfo();
|
||||
if (res.code === 200 && res.data) {
|
||||
const { user, roles, permissions } = res.data;
|
||||
// 登录账号
|
||||
this.userName = user.userName;
|
||||
// 用户头像
|
||||
this.avatar = user.avatar;
|
||||
// 基础信息
|
||||
this.nickName = user.nickName;
|
||||
this.phonenumber = user.phonenumber;
|
||||
this.email = user.email;
|
||||
this.sex = user.sex;
|
||||
|
||||
// 验证返回的roles是否是一个非空数组
|
||||
if (Array.isArray(roles) && roles.length > 0) {
|
||||
this.roles = roles;
|
||||
this.permissions = permissions;
|
||||
} else {
|
||||
this.roles = ['ROLE_DEFAULT'];
|
||||
this.permissions = [];
|
||||
}
|
||||
|
||||
// 水印文字信息=用户昵称 手机号
|
||||
let waterMarkContent = this.nickName;
|
||||
if (this.phonenumber) {
|
||||
waterMarkContent = `${this.nickName} ${this.phonenumber}`;
|
||||
}
|
||||
useLayoutStore().changeWaterMark(waterMarkContent);
|
||||
}
|
||||
// 网络错误时退出登录状态
|
||||
if (res.code === 500) {
|
||||
removeToken();
|
||||
window.location.reload();
|
||||
}
|
||||
return res;
|
||||
},
|
||||
// 退出系统
|
||||
async fnLogOut() {
|
||||
try {
|
||||
await logout();
|
||||
} catch (error) {
|
||||
throw error;
|
||||
} finally {
|
||||
this.token = '';
|
||||
this.roles = [];
|
||||
this.permissions = [];
|
||||
removeToken();
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default useUserStore;
|
||||
Reference in New Issue
Block a user