feat(other): init
This commit is contained in:
7
src/store/index.js
Normal file
7
src/store/index.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
export function setupStore(app) {
|
||||
app.use(createPinia())
|
||||
}
|
||||
|
||||
export * from './modules'
|
||||
28
src/store/modules/app/index.js
Normal file
28
src/store/modules/app/index.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { useDark } from '@vueuse/core'
|
||||
|
||||
const isDark = useDark()
|
||||
export const useAppStore = defineStore('app', {
|
||||
state() {
|
||||
return {
|
||||
collapsed: false,
|
||||
isDark,
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
switchCollapsed() {
|
||||
this.collapsed = !this.collapsed
|
||||
},
|
||||
setCollapsed(collapsed) {
|
||||
this.collapsed = collapsed
|
||||
},
|
||||
/** 设置暗黑模式 */
|
||||
setDark(isDark) {
|
||||
this.isDark = isDark
|
||||
},
|
||||
/** 切换/关闭 暗黑模式 */
|
||||
toggleDark() {
|
||||
this.isDark = !this.isDark
|
||||
},
|
||||
},
|
||||
})
|
||||
4
src/store/modules/index.js
Normal file
4
src/store/modules/index.js
Normal file
@@ -0,0 +1,4 @@
|
||||
export * from './app'
|
||||
export * from './permission'
|
||||
export * from './tags'
|
||||
export * from './user'
|
||||
132
src/store/modules/permission/index.js
Normal file
132
src/store/modules/permission/index.js
Normal file
@@ -0,0 +1,132 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { basicRoutes } from '@/router/routes'
|
||||
import { RouterView } from 'vue-router'
|
||||
|
||||
const Layout = () => import('@/layout/index.vue')
|
||||
|
||||
// 匹配views里面所有的.vue文件,动态引入
|
||||
const modules = import.meta.glob('/src/views/**/*.vue')
|
||||
|
||||
//
|
||||
export function getModulesKey() {
|
||||
return Object.keys(modules).map((item) => item.replace('/src/views/', '').replace('.vue', ''))
|
||||
}
|
||||
|
||||
// 动态加载组件
|
||||
export function loadRouteView(component) {
|
||||
try {
|
||||
const key = Object.keys(modules).find((key) => {
|
||||
return key.includes(`${component}.vue`)
|
||||
})
|
||||
if (key) {
|
||||
return modules[key]
|
||||
}
|
||||
throw Error(`找不到组件${component},请确保组件路径正确`)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
return RouterView
|
||||
}
|
||||
}
|
||||
|
||||
// function hasPermission(route, role) {
|
||||
// // * 不需要权限直接返回true
|
||||
// if (!route.meta?.requireAuth) return true
|
||||
|
||||
// const routeRole = route.meta?.role ? route.meta.role : []
|
||||
|
||||
// // * 登录用户没有角色或者路由没有设置角色判定为没有权限
|
||||
// if (!role.length || !routeRole.length) return false
|
||||
|
||||
// // * 路由指定的角色包含任一登录用户角色则判定有权限
|
||||
// return role.some((item) => routeRole.includes(item))
|
||||
// }
|
||||
|
||||
// 过滤异步路由
|
||||
function filterAsyncRoutes(routes = [], firstRoute = true) {
|
||||
const ret = []
|
||||
routes.forEach((route) => {
|
||||
// 过滤掉type为3的路由
|
||||
if (route.type === 3) return
|
||||
const isHidden = route.is_show === 1 ? false : true
|
||||
|
||||
const meta = {
|
||||
requireAuth: true,
|
||||
title: route.name,
|
||||
icon: route.icon,
|
||||
order: route.sort,
|
||||
}
|
||||
|
||||
const curRoute = {
|
||||
path: route.route,
|
||||
name: route.route,
|
||||
isHidden,
|
||||
meta,
|
||||
children: [],
|
||||
}
|
||||
|
||||
// if (route.route === '/' && firstRoute) {
|
||||
// curRoute['redirect'] = route.subMenu[0].route
|
||||
// } else if (route.subMenu && route.type === 1) {
|
||||
// curRoute['redirect'] = `${route.subMenu[0].route}`
|
||||
// }
|
||||
|
||||
if (route.subMenu && route.subMenu.length) {
|
||||
curRoute.children = filterAsyncRoutes(route.subMenu, false)
|
||||
} else {
|
||||
Reflect.deleteProperty(curRoute, 'children')
|
||||
}
|
||||
|
||||
switch (route.type) {
|
||||
case 1:
|
||||
curRoute.component = firstRoute ? Layout : RouterView
|
||||
break
|
||||
case 2:
|
||||
curRoute.component = loadRouteView(route.components)
|
||||
break
|
||||
}
|
||||
ret.push(curRoute)
|
||||
})
|
||||
return ret
|
||||
}
|
||||
|
||||
// 递归寻找type为3的路由
|
||||
function findType3Routes(routes = []) {
|
||||
const ret = []
|
||||
routes.forEach((route) => {
|
||||
if (route.type === 3) {
|
||||
ret.push(route.api_route)
|
||||
}
|
||||
if (route.subMenu && route.subMenu.length) {
|
||||
ret.push(...findType3Routes(route.subMenu))
|
||||
}
|
||||
})
|
||||
return ret
|
||||
}
|
||||
|
||||
export const usePermissionStore = defineStore('permission', {
|
||||
state() {
|
||||
return {
|
||||
accessRoutes: [],
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
routes() {
|
||||
return basicRoutes.concat(this.accessRoutes)
|
||||
},
|
||||
menus() {
|
||||
return this.routes.filter((route) => route.name && !route.isHidden)
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
generateRoutes() {
|
||||
const menus = JSON.parse(localStorage.getItem('menu'))
|
||||
const accessRoutes = filterAsyncRoutes(menus)
|
||||
window.localStorage.setItem('roles', JSON.stringify(findType3Routes(menus)))
|
||||
this.accessRoutes = accessRoutes
|
||||
return accessRoutes
|
||||
},
|
||||
resetPermission() {
|
||||
this.$reset()
|
||||
},
|
||||
},
|
||||
})
|
||||
6
src/store/modules/tags/helpers.js
Normal file
6
src/store/modules/tags/helpers.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import { sStorage } from '@/utils'
|
||||
|
||||
export const activeTag = sStorage.get('activeTag')
|
||||
export const tags = sStorage.get('tags')
|
||||
|
||||
export const WITHOUT_TAG_PATHS = ['/404', '/login']
|
||||
83
src/store/modules/tags/index.js
Normal file
83
src/store/modules/tags/index.js
Normal file
@@ -0,0 +1,83 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { activeTag, tags, WITHOUT_TAG_PATHS } from './helpers'
|
||||
import { router } from '@/router'
|
||||
import { sStorage } from '@/utils'
|
||||
|
||||
export const useTagsStore = defineStore('tag', {
|
||||
state() {
|
||||
return {
|
||||
tags: tags || [],
|
||||
activeTag: activeTag || '',
|
||||
reloading: false,
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
activeIndex() {
|
||||
return this.tags.findIndex((item) => item.path === this.activeTag)
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
setActiveTag(path) {
|
||||
this.activeTag = path
|
||||
sStorage.set('activeTag', path)
|
||||
},
|
||||
setTags(tags) {
|
||||
this.tags = tags
|
||||
sStorage.set('tags', tags)
|
||||
},
|
||||
addTag(tag = {}) {
|
||||
if (WITHOUT_TAG_PATHS.includes(tag.path)) return
|
||||
let findItem = this.tags.find((item) => item.path === tag.path)
|
||||
if (findItem) findItem = tag
|
||||
else this.setTags([...this.tags, tag])
|
||||
this.setActiveTag(tag.path)
|
||||
},
|
||||
async reloadTag(path, keepAlive) {
|
||||
const findItem = this.tags.find((item) => item.path === path)
|
||||
// 更新key可让keepAlive失效
|
||||
if (findItem && keepAlive) findItem.keepAlive = false
|
||||
|
||||
$loadingBar.start()
|
||||
this.reloading = true
|
||||
await nextTick()
|
||||
this.reloading = false
|
||||
findItem.keepAlive = keepAlive
|
||||
setTimeout(() => {
|
||||
document.documentElement.scrollTo({ left: 0, top: 0 })
|
||||
$loadingBar.finish()
|
||||
}, 100)
|
||||
},
|
||||
removeTag(path) {
|
||||
this.setTags(this.tags.filter((tag) => tag.path !== path))
|
||||
if (path === this.activeTag) {
|
||||
router.push(this.tags[this.tags.length - 1].path)
|
||||
}
|
||||
},
|
||||
removeOther(curPath = this.activeTag) {
|
||||
this.setTags(this.tags.filter((tag) => tag.path === curPath))
|
||||
if (curPath !== this.activeTag) {
|
||||
router.push(this.tags[this.tags.length - 1].path)
|
||||
}
|
||||
},
|
||||
removeLeft(curPath) {
|
||||
const curIndex = this.tags.findIndex((item) => item.path === curPath)
|
||||
const filterTags = this.tags.filter((item, index) => index >= curIndex)
|
||||
this.setTags(filterTags)
|
||||
if (!filterTags.find((item) => item.path === this.activeTag)) {
|
||||
router.push(filterTags[filterTags.length - 1].path)
|
||||
}
|
||||
},
|
||||
removeRight(curPath) {
|
||||
const curIndex = this.tags.findIndex((item) => item.path === curPath)
|
||||
const filterTags = this.tags.filter((item, index) => index <= curIndex)
|
||||
this.setTags(filterTags)
|
||||
if (!filterTags.find((item) => item.path === this.activeTag)) {
|
||||
router.push(filterTags[filterTags.length - 1].path)
|
||||
}
|
||||
},
|
||||
resetTags() {
|
||||
this.setTags([])
|
||||
this.setActiveTag('')
|
||||
},
|
||||
},
|
||||
})
|
||||
52
src/store/modules/user/index.js
Normal file
52
src/store/modules/user/index.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import { defineStore } from 'pinia'
|
||||
// import { resetRouter } from '@/router'
|
||||
import { useTagsStore, usePermissionStore } from '@/store'
|
||||
import { removeToken, toLogin } from '@/utils'
|
||||
// import api from '@/api'
|
||||
|
||||
export const useUserStore = defineStore('user', {
|
||||
state() {
|
||||
return {
|
||||
userInfo: {},
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
userId() {
|
||||
return this.userInfo?.id
|
||||
},
|
||||
name() {
|
||||
return this.userInfo?.name
|
||||
},
|
||||
avatar() {
|
||||
return this.userInfo?.avatar || 'https://v2.xxapi.cn/api/head?return=302'
|
||||
},
|
||||
role() {
|
||||
return this.userInfo?.role || []
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
async getUserInfo() {
|
||||
// try {
|
||||
// const res = await api.getUser()
|
||||
// const { id, name, avatar, role } = res.data
|
||||
// this.userInfo = { id, name, avatar, role }
|
||||
// return Promise.resolve(res.data)
|
||||
// } catch (error) {
|
||||
// return Promise.reject(error)
|
||||
// }
|
||||
},
|
||||
async logout() {
|
||||
const { resetTags } = useTagsStore()
|
||||
const { resetPermission } = usePermissionStore()
|
||||
removeToken()
|
||||
resetTags()
|
||||
resetPermission()
|
||||
// resetRouter()
|
||||
this.$reset()
|
||||
toLogin()
|
||||
},
|
||||
setUserInfo(userInfo = {}) {
|
||||
this.userInfo = { ...this.userInfo, ...userInfo }
|
||||
},
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user