🎨更换web页面框架

This commit is contained in:
coward
2024-07-15 16:47:53 +08:00
parent 1f49b798eb
commit da7ffc9343
411 changed files with 7244 additions and 1 deletions

30
web/src/store/helper.js Normal file
View File

@@ -0,0 +1,30 @@
import { basePermissions } from '@/settings'
import api from '@/api'
export async function getUserInfo() {
const res = await api.getUser()
const { id, username, profile, roles, currentRole } = res.data || {}
return {
id,
username,
avatar: profile?.avatar,
nickName: profile?.nickName,
gender: profile?.gender,
address: profile?.address,
email: profile?.email,
roles,
currentRole,
}
}
export async function getPermissions() {
let asyncPermissions = []
try {
const res = await api.getRolePermissions()
asyncPermissions = res?.data || []
}
catch (error) {
console.error(error)
}
return basePermissions.concat(asyncPermissions)
}

18
web/src/store/index.js Normal file
View File

@@ -0,0 +1,18 @@
/**********************************
* @Author: Ronnie Zhang
* @LastEditor: Ronnie Zhang
* @LastEditTime: 2023/12/05 21:26:15
* @Email: zclzone@outlook.com
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
**********************************/
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
export function setupStore(app) {
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
app.use(pinia)
}
export * from './modules'

View File

@@ -0,0 +1,56 @@
/**********************************
* @Author: Ronnie Zhang
* @LastEditor: Ronnie Zhang
* @LastEditTime: 2023/12/05 21:25:31
* @Email: zclzone@outlook.com
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
**********************************/
import { defineStore } from 'pinia'
import { useDark } from '@vueuse/core'
import { generate, getRgbStr } from '@arco-design/color'
import { defaultLayout, defaultPrimaryColor, naiveThemeOverrides } from '@/settings'
export const useAppStore = defineStore('app', {
state: () => ({
collapsed: false,
isDark: useDark(),
layout: defaultLayout,
primaryColor: defaultPrimaryColor,
naiveThemeOverrides,
}),
actions: {
switchCollapsed() {
this.collapsed = !this.collapsed
},
setCollapsed(b) {
this.collapsed = b
},
toggleDark() {
this.isDark = !this.isDark
},
setLayout(v) {
this.layout = v
},
setPrimaryColor(color) {
this.primaryColor = color
},
setThemeColor(color = this.primaryColor, isDark = this.isDark) {
const colors = generate(color, {
list: true,
dark: isDark,
})
document.body.style.setProperty('--primary-color', getRgbStr(colors[5]))
this.naiveThemeOverrides.common = Object.assign(this.naiveThemeOverrides.common || {}, {
primaryColor: colors[5],
primaryColorHover: colors[4],
primaryColorSuppl: colors[4],
primaryColorPressed: colors[6],
})
},
},
persist: {
paths: ['collapsed', 'layout', 'primaryColor', 'naiveThemeOverrides'],
storage: sessionStorage,
},
})

View File

@@ -0,0 +1,59 @@
/**********************************
* @Author: Ronnie Zhang
* @LastEditor: Ronnie Zhang
* @LastEditTime: 2023/12/05 21:25:39
* @Email: zclzone@outlook.com
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
**********************************/
import { defineStore } from 'pinia'
import { usePermissionStore, useRouterStore, useTabStore, useUserStore } from '@/store'
export const useAuthStore = defineStore('auth', {
state: () => ({
accessToken: undefined,
}),
actions: {
setToken({ accessToken }) {
this.accessToken = accessToken
},
resetToken() {
this.$reset()
},
toLogin() {
const { router, route } = useRouterStore()
router.replace({
path: '/login',
query: route.query,
})
},
async switchCurrentRole(data) {
this.resetLoginState()
await nextTick()
this.setToken(data)
},
resetLoginState() {
const { resetUser } = useUserStore()
const { resetRouter } = useRouterStore()
const { resetPermission, accessRoutes } = usePermissionStore()
const { resetTabs } = useTabStore()
// 重置路由
resetRouter(accessRoutes)
// 重置用户
resetUser()
// 重置权限
resetPermission()
// 重置Tabs
resetTabs()
// 重置token
this.resetToken()
},
async logout() {
this.resetLoginState()
this.toLogin()
},
},
persist: {
key: 'vue-naivue-admin_auth',
},
})

View File

@@ -0,0 +1,6 @@
export * from './app'
export * from './auth'
export * from './permission'
export * from './tab'
export * from './user'
export * from './router'

View File

@@ -0,0 +1,82 @@
/**********************************
* @Author: Ronnie Zhang
* @LastEditor: Ronnie Zhang
* @LastEditTime: 2023/12/05 21:25:47
* @Email: zclzone@outlook.com
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
**********************************/
import { hyphenate } from '@vueuse/core'
import { defineStore } from 'pinia'
import { isExternal } from '@/utils'
export const usePermissionStore = defineStore('permission', {
state: () => ({
accessRoutes: [],
permissions: [],
menus: [],
}),
actions: {
setPermissions(permissions) {
this.permissions = permissions
this.menus = this.permissions
.filter(item => item.type === 'MENU')
.map(item => this.getMenuItem(item))
.filter(item => !!item)
.sort((a, b) => a.order - b.order)
},
getMenuItem(item, parent) {
const route = this.generateRoute(item, item.show ? null : parent?.key)
if (item.enable && route.path && !route.path.startsWith('http'))
this.accessRoutes.push(route)
if (!item.show)
return null
const menuItem = {
label: route.meta.title,
key: route.name,
path: route.path,
originPath: route.meta.originPath,
icon: () => h('i', { class: `${route.meta.icon} text-16` }),
order: item.order ?? 0,
}
const children = item.children?.filter(item => item.type === 'MENU') || []
if (children.length) {
menuItem.children = children
.map(child => this.getMenuItem(child, menuItem))
.filter(item => !!item)
.sort((a, b) => a.order - b.order)
if (!menuItem.children.length)
delete menuItem.children
}
return menuItem
},
generateRoute(item, parentKey) {
let originPath
if (isExternal(item.path)) {
originPath = item.path
item.component = '/src/views/iframe/index.vue'
item.path = `/iframe/${hyphenate(item.code)}`
}
return {
name: item.code,
path: item.path,
redirect: item.redirect,
component: item.component,
meta: {
originPath,
icon: `${item.icon}?mask`,
title: item.name,
layout: item.layout,
keepAlive: !!item.keepAlive,
parentKey,
btns: item.children
?.filter(item => item.type === 'BUTTON')
.map(item => ({ code: item.code, name: item.name })),
},
}
},
resetPermission() {
this.$reset()
},
},
})

View File

@@ -0,0 +1,26 @@
/**********************************
* @Author: Ronnie Zhang
* @LastEditor: Ronnie Zhang
* @LastEditTime: 2024/01/06 17:18:40
* @Email: zclzone@outlook.com
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
**********************************/
import { defineStore } from 'pinia'
export const useRouterStore = defineStore('router', () => {
const router = useRouter()
const route = useRoute()
function resetRouter(accessRoutes) {
accessRoutes.forEach((item) => {
router.hasRoute(item.name) && router.removeRoute(item.name)
})
}
return {
router,
route,
resetRouter,
}
})

View File

@@ -0,0 +1,94 @@
/**********************************
* @Author: Ronnie Zhang
* @LastEditor: Ronnie Zhang
* @LastEditTime: 2023/12/05 21:25:52
* @Email: zclzone@outlook.com
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
**********************************/
import { defineStore } from 'pinia'
import { useRouterStore } from './router'
export const useTabStore = defineStore('tab', {
state: () => ({
tabs: [],
activeTab: '',
reloading: false,
}),
getters: {
activeIndex() {
return this.tabs.findIndex(item => item.path === this.activeTab)
},
},
actions: {
async setActiveTab(path) {
await nextTick() // tab栏dom更新完再设置激活让tab栏定位到新增的tab上生效
this.activeTab = path
},
setTabs(tabs) {
this.tabs = tabs
},
addTab(tab = {}) {
const findIndex = this.tabs.findIndex(item => item.path === tab.path)
if (findIndex !== -1) {
this.tabs.splice(findIndex, 1, tab)
}
else {
this.setTabs([...this.tabs, tab])
}
this.setActiveTab(tab.path)
},
async reloadTab(path, keepAlive) {
const findItem = this.tabs.find(item => item.path === path)
if (!findItem)
return
// 更新key可让keepAlive失效
if (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)
},
async removeTab(path) {
this.setTabs(this.tabs.filter(tab => tab.path !== path))
if (path === this.activeTab) {
useRouterStore().router?.push(this.tabs[this.tabs.length - 1].path)
}
},
removeOther(curPath = this.activeTab) {
this.setTabs(this.tabs.filter(tab => tab.path === curPath))
if (curPath !== this.activeTab) {
useRouterStore().router?.push(this.tabs[this.tabs.length - 1].path)
}
},
removeLeft(curPath) {
const curIndex = this.tabs.findIndex(item => item.path === curPath)
const filterTabs = this.tabs.filter((item, index) => index >= curIndex)
this.setTabs(filterTabs)
if (!filterTabs.find(item => item.path === this.activeTab)) {
useRouterStore().router?.push(filterTabs[filterTabs.length - 1].path)
}
},
removeRight(curPath) {
const curIndex = this.tabs.findIndex(item => item.path === curPath)
const filterTabs = this.tabs.filter((item, index) => index <= curIndex)
this.setTabs(filterTabs)
if (!filterTabs.find(item => item.path === this.activeTab.value)) {
useRouterStore().router?.push(filterTabs[filterTabs.length - 1].path)
}
},
resetTabs() {
this.$reset()
},
},
persist: {
paths: ['tabs'],
storage: sessionStorage,
},
})

View File

@@ -0,0 +1,43 @@
/**********************************
* @Author: Ronnie Zhang
* @LastEditor: Ronnie Zhang
* @LastEditTime: 2023/12/05 21:25:59
* @Email: zclzone@outlook.com
* Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
**********************************/
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
userInfo: null,
}),
getters: {
userId() {
return this.userInfo?.id
},
username() {
return this.userInfo?.username
},
nickName() {
return this.userInfo?.nickName
},
avatar() {
return this.userInfo?.avatar
},
currentRole() {
return this.userInfo?.currentRole || {}
},
roles() {
return this.userInfo?.roles || []
},
},
actions: {
setUser(user) {
this.userInfo = user
},
resetUser() {
this.$reset()
},
},
})