feat: init
This commit is contained in:
77
src/store/modules/app/index.ts
Normal file
77
src/store/modules/app/index.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
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'
|
||||
import { AppState } from './types'
|
||||
|
||||
const useAppStore = defineStore('app', {
|
||||
state: (): AppState => ({ ...defaultSettings }),
|
||||
|
||||
getters: {
|
||||
appCurrentSetting(state: AppState): AppState {
|
||||
return { ...state }
|
||||
},
|
||||
appDevice(state: AppState) {
|
||||
return state.device
|
||||
},
|
||||
appAsyncMenus(state: AppState): RouteRecordNormalized[] {
|
||||
return state.serverMenu as unknown as RouteRecordNormalized[]
|
||||
},
|
||||
},
|
||||
|
||||
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'
|
||||
document.body.setAttribute('arco-theme', 'dark')
|
||||
} else {
|
||||
this.theme = 'light'
|
||||
document.body.removeAttribute('arco-theme')
|
||||
}
|
||||
},
|
||||
toggleDevice(device: string) {
|
||||
this.device = device
|
||||
},
|
||||
toggleMenu(value: boolean) {
|
||||
this.hideMenu = value
|
||||
},
|
||||
async fetchServerMenuConfig() {
|
||||
let notifyInstance: NotificationReturn | null = null
|
||||
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',
|
||||
closable: true,
|
||||
})
|
||||
}
|
||||
},
|
||||
clearServerMenu() {
|
||||
this.serverMenu = []
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export default useAppStore
|
||||
20
src/store/modules/app/types.ts
Normal file
20
src/store/modules/app/types.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import type { RouteRecordNormalized } from 'vue-router'
|
||||
|
||||
export interface AppState {
|
||||
theme: string
|
||||
colorWeak: boolean
|
||||
navbar: boolean
|
||||
menu: boolean
|
||||
topMenu: boolean
|
||||
hideMenu: boolean
|
||||
menuCollapse: boolean
|
||||
footer: boolean
|
||||
themeColor: string
|
||||
menuWidth: number
|
||||
globalSettings: boolean
|
||||
device: string
|
||||
tabBar: boolean
|
||||
menuFromServer: boolean
|
||||
serverMenu: RouteRecordNormalized[]
|
||||
[key: string]: unknown
|
||||
}
|
||||
70
src/store/modules/tab-bar/index.ts
Normal file
70
src/store/modules/tab-bar/index.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import type { RouteLocationNormalized } from 'vue-router'
|
||||
import { defineStore } from 'pinia'
|
||||
import { DEFAULT_ROUTE, DEFAULT_ROUTE_NAME, REDIRECT_ROUTE_NAME } from '@/router/constants'
|
||||
import { isString } from '@/utils/is'
|
||||
import { TabBarState, TagProps } from './types'
|
||||
|
||||
const formatTag = (route: RouteLocationNormalized): TagProps => {
|
||||
const { name, meta, fullPath, query } = route
|
||||
return {
|
||||
title: meta.locale || '',
|
||||
name: String(name),
|
||||
fullPath,
|
||||
query,
|
||||
ignoreCache: meta.ignoreCache,
|
||||
}
|
||||
}
|
||||
|
||||
const BAN_LIST = [REDIRECT_ROUTE_NAME]
|
||||
|
||||
const useAppStore = defineStore('tabBar', {
|
||||
state: (): TabBarState => ({
|
||||
cacheTabList: new Set([DEFAULT_ROUTE_NAME]),
|
||||
tagList: [DEFAULT_ROUTE],
|
||||
}),
|
||||
|
||||
getters: {
|
||||
getTabList(): TagProps[] {
|
||||
return this.tagList
|
||||
},
|
||||
getCacheList(): string[] {
|
||||
return Array.from(this.cacheTabList)
|
||||
},
|
||||
},
|
||||
|
||||
actions: {
|
||||
updateTabList(route: RouteLocationNormalized) {
|
||||
if (BAN_LIST.includes(route.name as string)) return
|
||||
this.tagList.push(formatTag(route))
|
||||
if (!route.meta.ignoreCache) {
|
||||
this.cacheTabList.add(route.name as string)
|
||||
}
|
||||
},
|
||||
deleteTag(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))
|
||||
},
|
||||
resetTabList() {
|
||||
this.tagList = [DEFAULT_ROUTE]
|
||||
this.cacheTabList.clear()
|
||||
this.cacheTabList.add(DEFAULT_ROUTE_NAME)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export default useAppStore
|
||||
12
src/store/modules/tab-bar/types.ts
Normal file
12
src/store/modules/tab-bar/types.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export interface TagProps {
|
||||
title: string
|
||||
name: string
|
||||
fullPath: string
|
||||
query?: any
|
||||
ignoreCache?: boolean
|
||||
}
|
||||
|
||||
export interface TabBarState {
|
||||
tagList: TagProps[]
|
||||
cacheTabList: Set<string>
|
||||
}
|
||||
86
src/store/modules/user/index.ts
Normal file
86
src/store/modules/user/index.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import { LoginData, getUserInfo, login as userLogin, logout as userLogout } from '@/api/user'
|
||||
import { clearToken, setToken } from '@/utils/auth'
|
||||
import { removeRouteListener } from '@/utils/route-listener'
|
||||
import { defineStore } from 'pinia'
|
||||
import useAppStore from '../app'
|
||||
import { UserState } from './types'
|
||||
|
||||
const useUserStore = defineStore('user', {
|
||||
state: (): UserState => ({
|
||||
name: 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: '',
|
||||
}),
|
||||
|
||||
getters: {
|
||||
userInfo(state: UserState): UserState {
|
||||
return { ...state }
|
||||
},
|
||||
},
|
||||
|
||||
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)
|
||||
},
|
||||
|
||||
// Login
|
||||
async login(loginForm: LoginData) {
|
||||
try {
|
||||
const res = await userLogin(loginForm)
|
||||
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()
|
||||
} finally {
|
||||
this.logoutCallBack()
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
export default useUserStore
|
||||
19
src/store/modules/user/types.ts
Normal file
19
src/store/modules/user/types.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
export type RoleType = '' | '*' | 'admin' | 'user'
|
||||
export interface UserState {
|
||||
name?: 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
|
||||
}
|
||||
Reference in New Issue
Block a user