From bb79544e81d32aeea1f7e666de29b6e22d93f1a2 Mon Sep 17 00:00:00 2001 From: xxm Date: Thu, 13 Oct 2022 17:35:05 +0800 Subject: [PATCH] =?UTF-8?q?feat=20=E5=AF=B9=E6=8E=A5=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 11 +-- .env.production | 36 +++++---- src/api/sys/menu.ts | 10 +-- src/api/sys/model/menuModel.ts | 15 ++++ src/hooks/web/usePermission.ts | 1 + src/layouts/default/footer/index.vue | 14 ++-- src/router/guard/index.ts | 2 +- src/router/guard/paramMenuGuard.ts | 5 +- src/router/guard/permissionGuard.ts | 8 +- src/router/helper/menuHelper.ts | 4 +- src/router/helper/routeHelper.ts | 5 +- src/router/index.ts | 2 +- src/settings/componentSetting.ts | 2 +- src/settings/projectSetting.ts | 75 +++++++++---------- src/store/modules/app.ts | 1 + src/store/modules/permission.ts | 46 ++++++------ src/store/modules/user.ts | 3 +- .../modules/system/client/ClientEdit.vue | 6 +- .../system/loginType/LoginTypeEdit.vue | 10 +-- 19 files changed, 139 insertions(+), 117 deletions(-) diff --git a/.env.development b/.env.development index 784d6e292..e536770e1 100644 --- a/.env.development +++ b/.env.development @@ -1,20 +1,17 @@ # 是否打开mock -VITE_USE_MOCK = true +VITE_USE_MOCK=true # 发布路径 -VITE_PUBLIC_PATH = / +VITE_PUBLIC_PATH=/ # 跨域代理,您可以配置多个 ,请注意,没有换行符 -VITE_PROXY = [["/api","http://localhost:9999"],["/upload","http://localhost:3300/upload"]] -#VITE_PROXY = [["/api","http://localhost:9999"],["/upload","http://localhost:3300/upload"]] -# VITE_PROXY=[["/api","http://localhost:9999"]] +VITE_PROXY=[["/api","http://localhost:9999"],["/upload","http://localhost:3300/upload"]] # 控制台不输出console -VITE_DROP_CONSOLE = false +VITE_DROP_CONSOLE=false # 接口地址 VITE_GLOB_API_URL=/api -#VITE_GLOB_API_URL=/basic-api # 文件上传地址 VITE_GLOB_UPLOAD_URL=/upload diff --git a/.env.production b/.env.production index a0bdfb7f4..b3378da39 100644 --- a/.env.production +++ b/.env.production @@ -1,35 +1,33 @@ -# Whether to open mock -VITE_USE_MOCK = true +# 是否打开mock +VITE_USE_MOCK=true -# public path -VITE_PUBLIC_PATH = / +# 发布路径 +VITE_PUBLIC_PATH=/ -# Delete console -VITE_DROP_CONSOLE = true +# 控制台不输出console +VITE_DROP_CONSOLE=true -# Whether to enable gzip or brotli compression -# Optional: gzip | brotli | none -# If you need multiple forms, you can use `,` to separate -VITE_BUILD_COMPRESS = 'none' +# 是否启用gzip或brotli压缩可选: gzip | brotli | +# 无如果您需要多个表单,可以使用 ',' 分隔 +VITE_BUILD_COMPRESS='none' -# Whether to delete origin files when using compress, default false -VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE = false +# 使用compress时是否删除origin文件,默认为false +VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE=false -# Basic interface address SPA -VITE_GLOB_API_URL=/basic-api +# 接口地址 +VITE_GLOB_API_URL=/api -# File upload address, optional -# It can be forwarded by nginx or write the actual address directly +# 文件上传地址 VITE_GLOB_UPLOAD_URL=/upload -# Interface prefix +# 接口前缀 VITE_GLOB_API_URL_PREFIX= # Whether to enable image compression -VITE_USE_IMAGEMIN= true +VITE_USE_IMAGEMIN=true # use pwa -VITE_USE_PWA = false +VITE_USE_PWA=false # Is it compatible with older browsers VITE_LEGACY = false diff --git a/src/api/sys/menu.ts b/src/api/sys/menu.ts index e12271396..2fc0fbb90 100644 --- a/src/api/sys/menu.ts +++ b/src/api/sys/menu.ts @@ -1,14 +1,14 @@ import { defHttp } from '/@/utils/http/axios' -import { getMenuListResultModel } from './model/menuModel' +import { getMenuListResultModel, MenuAndResource } from './model/menuModel' +import { Result } from '/#/axios' enum Api { GetMenuList = '/getMenuList', } /** - * @description: Get user menu based on id + * 获取菜单和权限码 */ - -export const getMenuList = () => { - return defHttp.get({ url: Api.GetMenuList }) +export const getPermissions = (clientCode: string) => { + return defHttp.get>({ url: '/role/menu/getPermissions', params: { clientCode } }) } diff --git a/src/api/sys/model/menuModel.ts b/src/api/sys/model/menuModel.ts index 2d7789fe4..dbe79c3c5 100644 --- a/src/api/sys/model/menuModel.ts +++ b/src/api/sys/model/menuModel.ts @@ -14,3 +14,18 @@ export interface RouteItem { * @description: Get menu return value */ export type getMenuListResultModel = RouteItem[] + +/** + * 用户菜单及资源权限返回类 + */ +export interface MenuAndResource { + // 权限码 + resourcePerms: Array + // 菜单 + menus: Array +} + +/** + * 权限菜单 + */ +export interface PermMenu {} diff --git a/src/hooks/web/usePermission.ts b/src/hooks/web/usePermission.ts index 7ba69853a..06895a030 100644 --- a/src/hooks/web/usePermission.ts +++ b/src/hooks/web/usePermission.ts @@ -41,6 +41,7 @@ export function usePermission() { * @param id */ async function resume() { + console.log('重置和重新获得权限资源信息') const tabStore = useMultipleTabStore() tabStore.clearCacheTabs() resetRouter() diff --git a/src/layouts/default/footer/index.vue b/src/layouts/default/footer/index.vue index c95a18c39..d09580393 100644 --- a/src/layouts/default/footer/index.vue +++ b/src/layouts/default/footer/index.vue @@ -1,13 +1,11 @@ diff --git a/src/router/guard/index.ts b/src/router/guard/index.ts index 67a920caa..468238572 100644 --- a/src/router/guard/index.ts +++ b/src/router/guard/index.ts @@ -46,7 +46,7 @@ function createPageGuard(router: Router) { }) } -// Used to handle page loading status +// 用于处理页面加载状态 function createPageLoadingGuard(router: Router) { const userStore = useUserStoreWithOut() const appStore = useAppStoreWithOut() diff --git a/src/router/guard/paramMenuGuard.ts b/src/router/guard/paramMenuGuard.ts index 0618ce3d8..428746a56 100644 --- a/src/router/guard/paramMenuGuard.ts +++ b/src/router/guard/paramMenuGuard.ts @@ -32,16 +32,15 @@ export function createParamMenuGuard(router: Router) { next() }) } - const getPermissionMode = () => { const appStore = useAppStoreWithOut() return appStore.getProjectConfig.permissionMode } - +// 后端模式 const isBackMode = () => { return getPermissionMode() === PermissionModeEnum.BACK } - +// 路由映射 const isRouteMappingMode = () => { return getPermissionMode() === PermissionModeEnum.ROUTE_MAPPING } diff --git a/src/router/guard/permissionGuard.ts b/src/router/guard/permissionGuard.ts index a6dcdd938..cd3c8e2e6 100644 --- a/src/router/guard/permissionGuard.ts +++ b/src/router/guard/permissionGuard.ts @@ -15,6 +15,10 @@ const ROOT_PATH = RootRoute.path const whitePathList: PageEnum[] = [LOGIN_PATH] +/** + * 路由守卫 + * @param router + */ export function createPermissionGuard(router: Router) { const userStore = useUserStoreWithOut() const permissionStore = usePermissionStoreWithOut() @@ -22,6 +26,7 @@ export function createPermissionGuard(router: Router) { if ( from.path === ROOT_PATH && to.path === PageEnum.BASE_HOME && + // TODO 没有用户首页配置这个字段 userStore.getUserInfo.homePath && userStore.getUserInfo.homePath !== PageEnum.BASE_HOME ) { @@ -94,7 +99,8 @@ export function createPermissionGuard(router: Router) { next() return } - + console.log(`路由守卫`) + // 重载菜单 const routes = await permissionStore.buildRoutesAction() routes.forEach((route) => { diff --git a/src/router/helper/menuHelper.ts b/src/router/helper/menuHelper.ts index 3670929c9..31948f686 100644 --- a/src/router/helper/menuHelper.ts +++ b/src/router/helper/menuHelper.ts @@ -41,7 +41,9 @@ export function transformMenuModule(menuModule: MenuModule): Menu { return menuList[0] } -// 将路由转换成菜单 +/** + * 将路由转换成菜单 + */ export function transformRouteToMenu(routeModList: AppRouteModule[], routerMapping = false) { // 借助 lodash 深拷贝 const cloneRouteModList = cloneDeep(routeModList) diff --git a/src/router/helper/routeHelper.ts b/src/router/helper/routeHelper.ts index 0420629bc..d41b3fa66 100644 --- a/src/router/helper/routeHelper.ts +++ b/src/router/helper/routeHelper.ts @@ -64,8 +64,9 @@ function dynamicImport(dynamicViewsModules: Record Promise(routeList: AppRouteModule[]): T[] { routeList.forEach((route) => { const component = route.component as string diff --git a/src/router/index.ts b/src/router/index.ts index 0c0203acd..510ed9f72 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -25,7 +25,7 @@ export const router = createRouter({ scrollBehavior: () => ({ left: 0, top: 0 }), }) -// reset router +// 重置路由 export function resetRouter() { router.getRoutes().forEach((route) => { const { name } = route diff --git a/src/settings/componentSetting.ts b/src/settings/componentSetting.ts index 2cf29e5c9..6f8a656ed 100644 --- a/src/settings/componentSetting.ts +++ b/src/settings/componentSetting.ts @@ -1,4 +1,4 @@ -// Used to configure the general configuration of some components without modifying the components +// 用于配置某些组件的通用配置,而无需修改组件 import type { SorterResult } from '../components/Table' diff --git a/src/settings/projectSetting.ts b/src/settings/projectSetting.ts index d0366e353..548eaefaf 100644 --- a/src/settings/projectSetting.ts +++ b/src/settings/projectSetting.ts @@ -12,95 +12,94 @@ import { import { SIDE_BAR_BG_COLOR_LIST, HEADER_PRESET_BG_COLOR_LIST } from './designSetting' import { primaryColor } from '../../build/config/themeConfig' -// ! You need to clear the browser cache after the change +// ! 更改后需要清除浏览器缓存 const setting: ProjectConfig = { - // Whether to show the configuration button + // 是否显示配置按钮 showSettingButton: true, - // Whether to show the theme switch button + // 是否显示主题切换按钮 showDarkModeToggle: true, - // `Settings` button position + // `Settings` 按钮位置 settingButtonPosition: SettingButtonPositionEnum.AUTO, - // Permission mode - permissionMode: PermissionModeEnum.ROUTE_MAPPING, + // 权限模式 + permissionMode: PermissionModeEnum.BACK, - // Permission-related cache is stored in sessionStorage or localStorage + // 权限相关缓存存储在sessionStorage或localStorage中 permissionCacheType: CacheTypeEnum.LOCAL, - // Session timeout processing + // 会话超时处理 sessionTimeoutProcessing: SessionTimeoutProcessingEnum.ROUTE_JUMP, - // color + // 颜色 themeColor: primaryColor, - // Website gray mode, open for possible mourning dates + // 灰度迷失 grayMode: false, - // Color Weakness Mode + // 色日模式 colorWeak: false, - // Whether to cancel the menu, the top, the multi-tab page display, for possible embedded in other systems + // 是否取消菜单,顶部,多选项卡页面显示,对于可能嵌入其他系统 fullContent: false, - // content mode + // 内容模式 contentMode: ContentEnum.FULL, - // Whether to display the logo + // 是否显示Logo showLogo: true, - // Whether to show footer + // 是否显示页脚 showFooter: false, - // Header configuration + // 页头设置 headerSetting: { - // header bg color + // 背景颜色 bgColor: HEADER_PRESET_BG_COLOR_LIST[0], - // Fixed at the top + // 固定在顶部 fixed: true, - // Whether to show top + // 是否显示 show: true, - // theme + // 主题 theme: ThemeEnum.LIGHT, - // Whether to enable the lock screen function + // 是否启用锁屏功能 useLockPage: true, - // Whether to show the full screen button + // 是否显示全屏按钮 showFullScreen: true, - // Whether to show the document button + // 是否显示文档按钮 showDoc: true, - // Whether to show the notification button + // 是否显示通知按钮 showNotice: true, - // Whether to display the menu search + // 是否显示搜索按钮 showSearch: true, }, - // Menu configuration + // 菜单配置 menuSetting: { - // sidebar menu bg color + // 背景颜色 bgColor: SIDE_BAR_BG_COLOR_LIST[0], - // Whether to fix the left menu + // 是否固定 fixed: true, // Menu collapse collapsed: false, - // When sider hide because of the responsive layout + // 当sider因为响应式布局而隐藏时 siderHidden: false, - // Whether to display the menu name when folding the menu + // 折叠菜单时是否显示菜单名称 collapsedShowTitle: false, - // Whether it can be dragged - // Only limited to the opening of the left menu, the mouse has a drag bar on the right side of the menu + // 是否可以拖动仅限于左侧菜单的打开,鼠标在菜单的右侧有一个拖动条 canDrag: false, - // Whether to show no dom + // Whether to show no dom 是否不显示dom show: true, - // Whether to show dom + // Whether to show dom 是否隐藏 hidden: false, - // Menu width + // Menu width 宽度 menuWidth: 210, - // Menu mode + // Menu mode 模式 mode: MenuModeEnum.INLINE, - // Menu type + // Menu 类型 type: MenuTypeEnum.SIDEBAR, - // Menu theme + // Menu 主题 theme: ThemeEnum.DARK, // Split menu split: false, diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts index 324daab92..83bee5942 100644 --- a/src/store/modules/app.ts +++ b/src/store/modules/app.ts @@ -78,6 +78,7 @@ export const useAppStore = defineStore({ }, async resetAllState() { + console.log('重置所有状态') resetRouter() Persistent.clearAll() }, diff --git a/src/store/modules/permission.ts b/src/store/modules/permission.ts index 1158c63f3..cb69b45fd 100644 --- a/src/store/modules/permission.ts +++ b/src/store/modules/permission.ts @@ -18,7 +18,7 @@ import { ERROR_LOG_ROUTE, PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic' import { filter } from '/@/utils/helper/treeHelper' -import { getMenuList } from '/@/api/sys/menu' +import { getMenuList, getPermissions } from "/@/api/sys/menu"; import { getPermCode } from '/@/api/sys/user' import { useMessage } from '/@/hooks/web/useMessage' @@ -103,14 +103,22 @@ export const usePermissionStore = defineStore({ this.backMenuList = [] this.lastBuildMenuTime = 0 }, - async changePermissionCode() { - const codeList = await getPermCode() - this.setPermCodeList(codeList) + /** + * 权限码和菜单更新 + */ + async changeMenuAndPermCode() { + const { + data: { menus, resourcePerms }, + } = await getPermissions('admin') + console.log(menus) + // this.setBackMenuList(menus) + this.setPermCodeList(resourcePerms) }, - // 构建路由 + /** + * 构建路由 + */ async buildRoutesAction(): Promise { - const { t } = useI18n() const userStore = useUserStore() const appStore = useAppStoreWithOut() @@ -141,7 +149,8 @@ export const usePermissionStore = defineStore({ * */ const patchHomeAffix = (routes: AppRouteRecordRaw[]) => { if (!routes || routes.length === 0) return - let homePath: string = userStore.getUserInfo.homePath || PageEnum.BASE_HOME + // let homePath: string = userStore.getUserInfo.homePath || PageEnum.BASE_HOME + let homePath: string = PageEnum.BASE_HOME function patcher(routes: AppRouteRecordRaw[], parentPath = '') { if (parentPath) parentPath = parentPath + '/' @@ -180,7 +189,7 @@ export const usePermissionStore = defineStore({ routes = flatMultiLevelRoutes(routes) break - // 路由映射, 默认进入该case + // 路由映射, 默认进入该case(不用了) case PermissionModeEnum.ROUTE_MAPPING: // 对非一级路由进行过滤 routes = filter(asyncRoutes, routeFilter) @@ -196,7 +205,6 @@ export const usePermissionStore = defineStore({ menuList.sort((a, b) => { return (a.meta?.orderNo || 0) - (b.meta?.orderNo || 0) }) - // 设置菜单列表 this.setFrontMenuList(menuList) @@ -205,38 +213,34 @@ export const usePermissionStore = defineStore({ routes = flatMultiLevelRoutes(routes) break - // If you are sure that you do not need to do background dynamic permissions, please comment the entire judgment below - // 如果确定不需要做后台动态权限,请在下方评论整个判断 + // 后端控制 现在在用的方案 case PermissionModeEnum.BACK: const { createMessage } = useMessage() createMessage.loading({ - content: t('sys.app.menuLoading'), + content: '菜单加载中...', duration: 1, }) - // !Simulate to obtain permission codes from the background, - // 模拟从后台获取权限码, - // this function may only need to be executed once, and the actual project can be put at the right time by itself - // 这个功能可能只需要执行一次,实际项目可以自己放在合适的时间 let routeList: AppRouteRecordRaw[] = [] + + // 获取菜单和权限码 try { - await this.changePermissionCode() - routeList = (await getMenuList()) as AppRouteRecordRaw[] + await this.changeMenuAndPermCode() + // 获取菜单列表 + routeList = this.backMenuList as any } catch (error) { console.error(error) } - // Dynamically introduce components // 动态引入组件 + console.log(routeList) routeList = transformObjToRoute(routeList) - // Background routing to menu structure // 后台路由到菜单结构 const backMenuList = transformRouteToMenu(routeList) this.setBackMenuList(backMenuList) - // remove meta.ignoreRoute item // 删除 meta.ignoreRoute 项 routeList = filter(routeList, routeRemoveIgnoreFilter) routeList = routeList.filter(routeRemoveIgnoreFilter) diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 69daf2276..c50041616 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -107,12 +107,13 @@ export const useUserStore = defineStore({ this.setSessionTimeout(false) } else { const permissionStore = usePermissionStore() - console.log(permissionStore) if (!permissionStore.isDynamicAddedRoute) { + // 构建路由 const routes = await permissionStore.buildRoutesAction() routes.forEach((route) => { router.addRoute(route as unknown as RouteRecordRaw) }) + // 404路由 router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw) permissionStore.setDynamicAddedRoute(true) } diff --git a/src/views/modules/system/client/ClientEdit.vue b/src/views/modules/system/client/ClientEdit.vue index 634b45ef7..2b3d9affe 100644 --- a/src/views/modules/system/client/ClientEdit.vue +++ b/src/views/modules/system/client/ClientEdit.vue @@ -10,13 +10,13 @@ - + - + - + diff --git a/src/views/modules/system/loginType/LoginTypeEdit.vue b/src/views/modules/system/loginType/LoginTypeEdit.vue index f33a0f752..a2537842c 100644 --- a/src/views/modules/system/loginType/LoginTypeEdit.vue +++ b/src/views/modules/system/loginType/LoginTypeEdit.vue @@ -10,13 +10,13 @@ - + - + - + @@ -35,7 +35,7 @@ - -