初始化 ui.
This commit is contained in:
@@ -5,5 +5,10 @@ import useTabBarStore from './modules/tab-bar';
|
||||
|
||||
const pinia = createPinia();
|
||||
|
||||
export { useAppStore, useUserStore, useTabBarStore };
|
||||
export {
|
||||
useAppStore,
|
||||
useUserStore,
|
||||
useTabBarStore
|
||||
};
|
||||
|
||||
export default pinia;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import { Notification } from '@arco-design/web-vue';
|
||||
import type { NotificationReturn } from '@arco-design/web-vue/es/notification/interface';
|
||||
import type { RouteRecordNormalized } from 'vue-router';
|
||||
import defaultSettings from '@/config/settings.json';
|
||||
import { getMenuList } from '@/api/user';
|
||||
@@ -22,13 +21,17 @@ const useAppStore = defineStore('app', {
|
||||
},
|
||||
|
||||
actions: {
|
||||
// Update app settings
|
||||
/**
|
||||
* 更新配置
|
||||
*/
|
||||
updateSettings(partial: Partial<AppState>) {
|
||||
// @ts-ignore-next-line
|
||||
this.$patch(partial);
|
||||
},
|
||||
|
||||
// Change theme color
|
||||
/**
|
||||
* 修改颜色主题
|
||||
*/
|
||||
toggleTheme(dark: boolean) {
|
||||
if (dark) {
|
||||
this.theme = 'dark';
|
||||
@@ -38,37 +41,40 @@ const useAppStore = defineStore('app', {
|
||||
document.body.removeAttribute('arco-theme');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 切换设备
|
||||
*/
|
||||
toggleDevice(device: string) {
|
||||
this.device = device;
|
||||
},
|
||||
|
||||
/**
|
||||
* 切换菜单状态
|
||||
*/
|
||||
toggleMenu(value: boolean) {
|
||||
this.hideMenu = value;
|
||||
},
|
||||
async fetchServerMenuConfig() {
|
||||
let notifyInstance: NotificationReturn | null = null;
|
||||
|
||||
/**
|
||||
* 加载菜单
|
||||
*/
|
||||
async fetchMenuConfig() {
|
||||
try {
|
||||
notifyInstance = Notification.info({
|
||||
id: 'menuNotice', // Keep the instance id the same
|
||||
content: 'loading',
|
||||
closable: true,
|
||||
});
|
||||
const { data } = await getMenuList();
|
||||
this.serverMenu = data;
|
||||
notifyInstance = Notification.success({
|
||||
id: 'menuNotice',
|
||||
content: 'success',
|
||||
closable: true,
|
||||
});
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
notifyInstance = Notification.error({
|
||||
id: 'menuNotice',
|
||||
content: 'error',
|
||||
Notification.error({
|
||||
content: '加载菜单失败',
|
||||
closable: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
clearServerMenu() {
|
||||
|
||||
/**
|
||||
* 清空菜单
|
||||
*/
|
||||
clearMenu() {
|
||||
this.serverMenu = [];
|
||||
},
|
||||
},
|
||||
|
||||
@@ -14,7 +14,6 @@ export interface AppState {
|
||||
globalSettings: boolean;
|
||||
device: string;
|
||||
tabBar: boolean;
|
||||
menuFromServer: boolean;
|
||||
serverMenu: RouteRecordNormalized[];
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import type { RouteLocationNormalized } from 'vue-router';
|
||||
import { defineStore } from 'pinia';
|
||||
import {
|
||||
DEFAULT_ROUTE,
|
||||
DEFAULT_ROUTE_NAME,
|
||||
REDIRECT_ROUTE_NAME,
|
||||
} from '@/router/constants';
|
||||
import { DEFAULT_TAB, DEFAULT_ROUTE_NAME, REDIRECT_ROUTE_NAME, } from '@/router/constants';
|
||||
import { isString } from '@/utils/is';
|
||||
import { TabBarState, TagProps } from './types';
|
||||
|
||||
/**
|
||||
* router 转 tag
|
||||
*/
|
||||
const formatTag = (route: RouteLocationNormalized): TagProps => {
|
||||
const { name, meta, fullPath, query } = route;
|
||||
return {
|
||||
@@ -19,12 +18,13 @@ const formatTag = (route: RouteLocationNormalized): TagProps => {
|
||||
};
|
||||
};
|
||||
|
||||
// 不添加的 tab 集合
|
||||
const BAN_LIST = [REDIRECT_ROUTE_NAME];
|
||||
|
||||
const useAppStore = defineStore('tabBar', {
|
||||
const useTabBarStore = defineStore('tabBar', {
|
||||
state: (): TabBarState => ({
|
||||
cacheTabList: new Set([DEFAULT_ROUTE_NAME]),
|
||||
tagList: [DEFAULT_ROUTE],
|
||||
tagList: [DEFAULT_TAB],
|
||||
}),
|
||||
|
||||
getters: {
|
||||
@@ -37,6 +37,9 @@ const useAppStore = defineStore('tabBar', {
|
||||
},
|
||||
|
||||
actions: {
|
||||
/**
|
||||
* 添加 tab
|
||||
*/
|
||||
updateTabList(route: RouteLocationNormalized) {
|
||||
if (BAN_LIST.includes(route.name as string)) return;
|
||||
this.tagList.push(formatTag(route));
|
||||
@@ -44,31 +47,50 @@ const useAppStore = defineStore('tabBar', {
|
||||
this.cacheTabList.add(route.name as string);
|
||||
}
|
||||
},
|
||||
deleteTag(idx: number, tag: TagProps) {
|
||||
|
||||
/**
|
||||
* 移除 tab
|
||||
*/
|
||||
deleteTab(idx: number, tag: TagProps) {
|
||||
this.tagList.splice(idx, 1);
|
||||
this.cacheTabList.delete(tag.name);
|
||||
},
|
||||
|
||||
/**
|
||||
* 添加缓存
|
||||
*/
|
||||
addCache(name: string) {
|
||||
if (isString(name) && name !== '') this.cacheTabList.add(name);
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除缓存
|
||||
*/
|
||||
deleteCache(tag: TagProps) {
|
||||
this.cacheTabList.delete(tag.name);
|
||||
},
|
||||
|
||||
/**
|
||||
* 重设缓存
|
||||
*/
|
||||
freshTabList(tags: TagProps[]) {
|
||||
this.tagList = tags;
|
||||
this.cacheTabList.clear();
|
||||
// 要先判断ignoreCache
|
||||
this.tagList
|
||||
.filter((el) => !el.ignoreCache)
|
||||
.map((el) => el.name)
|
||||
.forEach((x) => this.cacheTabList.add(x));
|
||||
// 要先判断 ignoreCache
|
||||
this.tagList.filter((el) => !el.ignoreCache)
|
||||
.map((el) => el.name)
|
||||
.forEach((x) => this.cacheTabList.add(x));
|
||||
},
|
||||
|
||||
/**
|
||||
* 重设 tab
|
||||
*/
|
||||
resetTabList() {
|
||||
this.tagList = [DEFAULT_ROUTE];
|
||||
this.tagList = [DEFAULT_TAB];
|
||||
this.cacheTabList.clear();
|
||||
this.cacheTabList.add(DEFAULT_ROUTE_NAME);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default useAppStore;
|
||||
export default useTabBarStore;
|
||||
|
||||
@@ -1,33 +1,20 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import {
|
||||
login as userLogin,
|
||||
logout as userLogout,
|
||||
getUserInfo,
|
||||
LoginData,
|
||||
} from '@/api/user';
|
||||
import { setToken, clearToken } from '@/utils/auth';
|
||||
import { getUserInfo } from '@/api/user';
|
||||
import { login as userLogin, LoginRequest, logout as userLogout, } from '@/api/user/auth';
|
||||
import { clearToken, setToken } from '@/utils/auth';
|
||||
import { md5 } from '@/utils';
|
||||
import { removeRouteListener } from '@/utils/route-listener';
|
||||
import { UserState } from './types';
|
||||
import useAppStore from '../app';
|
||||
|
||||
const useUserStore = defineStore('user', {
|
||||
state: (): UserState => ({
|
||||
name: undefined,
|
||||
id: undefined,
|
||||
username: undefined,
|
||||
nickname: undefined,
|
||||
avatar: undefined,
|
||||
job: undefined,
|
||||
organization: undefined,
|
||||
location: undefined,
|
||||
email: undefined,
|
||||
introduction: undefined,
|
||||
personalWebsite: undefined,
|
||||
jobName: undefined,
|
||||
organizationName: undefined,
|
||||
locationName: undefined,
|
||||
phone: undefined,
|
||||
registrationDate: undefined,
|
||||
accountId: undefined,
|
||||
certification: undefined,
|
||||
role: '',
|
||||
permission: undefined,
|
||||
roles: undefined,
|
||||
}),
|
||||
|
||||
getters: {
|
||||
@@ -37,47 +24,47 @@ const useUserStore = defineStore('user', {
|
||||
},
|
||||
|
||||
actions: {
|
||||
switchRoles() {
|
||||
return new Promise((resolve) => {
|
||||
this.role = this.role === 'user' ? 'admin' : 'user';
|
||||
resolve(this.role);
|
||||
});
|
||||
},
|
||||
// Set user's information
|
||||
/**
|
||||
* 设置用户信息
|
||||
*/
|
||||
setInfo(partial: Partial<UserState>) {
|
||||
this.$patch(partial);
|
||||
},
|
||||
|
||||
// Reset user's information
|
||||
resetInfo() {
|
||||
this.$reset();
|
||||
},
|
||||
|
||||
// Get user's information
|
||||
/**
|
||||
* 获取用户信息
|
||||
*/
|
||||
async info() {
|
||||
const res = await getUserInfo();
|
||||
|
||||
this.setInfo(res.data);
|
||||
this.setInfo({
|
||||
id: 1,
|
||||
username: 'admin',
|
||||
nickname: '管理员',
|
||||
permission: ['*'],
|
||||
roles: ['admin'],
|
||||
});
|
||||
},
|
||||
|
||||
// Login
|
||||
async login(loginForm: LoginData) {
|
||||
/**
|
||||
* 登录
|
||||
*/
|
||||
async login(loginForm: LoginRequest) {
|
||||
try {
|
||||
const res = await userLogin(loginForm);
|
||||
const loginRequest: LoginRequest = {
|
||||
username: loginForm.username,
|
||||
password: md5(loginForm.password),
|
||||
};
|
||||
const res = await userLogin(loginRequest);
|
||||
setToken(res.data.token);
|
||||
} catch (err) {
|
||||
clearToken();
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
logoutCallBack() {
|
||||
const appStore = useAppStore();
|
||||
this.resetInfo();
|
||||
clearToken();
|
||||
removeRouteListener();
|
||||
appStore.clearServerMenu();
|
||||
},
|
||||
// Logout
|
||||
|
||||
/**
|
||||
* 登出
|
||||
*/
|
||||
async logout() {
|
||||
try {
|
||||
await userLogout();
|
||||
@@ -85,6 +72,19 @@ const useUserStore = defineStore('user', {
|
||||
this.logoutCallBack();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 登出回调
|
||||
*/
|
||||
logoutCallBack() {
|
||||
this.$reset();
|
||||
clearToken();
|
||||
// 移除路由监听器
|
||||
removeRouteListener();
|
||||
// 清空菜单
|
||||
const appStore = useAppStore();
|
||||
appStore.clearMenu();
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -1,19 +1,8 @@
|
||||
export type RoleType = '' | '*' | 'admin' | 'user';
|
||||
export interface UserState {
|
||||
name?: string;
|
||||
id?: number;
|
||||
username?: string;
|
||||
nickname?: string;
|
||||
avatar?: string;
|
||||
job?: string;
|
||||
organization?: string;
|
||||
location?: string;
|
||||
email?: string;
|
||||
introduction?: string;
|
||||
personalWebsite?: string;
|
||||
jobName?: string;
|
||||
organizationName?: string;
|
||||
locationName?: string;
|
||||
phone?: string;
|
||||
registrationDate?: string;
|
||||
accountId?: string;
|
||||
certification?: number;
|
||||
role: RoleType;
|
||||
permission?: string[];
|
||||
roles?: string[];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user