初始化 ui.

This commit is contained in:
lijiahang
2023-07-27 18:48:15 +08:00
parent ee53ec6486
commit 5be2c7fda2
185 changed files with 1107 additions and 17815 deletions

View File

@@ -5,5 +5,10 @@ import useTabBarStore from './modules/tab-bar';
const pinia = createPinia();
export { useAppStore, useUserStore, useTabBarStore };
export {
useAppStore,
useUserStore,
useTabBarStore
};
export default pinia;

View File

@@ -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 = [];
},
},

View File

@@ -14,7 +14,6 @@ export interface AppState {
globalSettings: boolean;
device: string;
tabBar: boolean;
menuFromServer: boolean;
serverMenu: RouteRecordNormalized[];
[key: string]: unknown;
}

View File

@@ -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;

View File

@@ -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();
},
},
});

View File

@@ -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[];
}