Browse Source

⚗ 重写登录逻辑

master
wangxiang 3 years ago
parent
commit
61adba1a82
  1. 6
      kicc-system/kicc-system-biz/src/main/java/com/cloud/kicc/admin/controller/MenuController.java
  2. 7
      kicc-ui/src/api/sys/menu.ts
  3. 2
      kicc-ui/src/router/guard/paramMenuGuard.ts
  4. 3
      kicc-ui/src/router/guard/permissionGuard.ts
  5. 4
      kicc-ui/src/router/helper/menuHelper.ts
  6. 90
      kicc-ui/src/router/helper/routeHelper.ts
  7. 3
      kicc-ui/src/router/index.ts
  8. 51
      kicc-ui/src/store/modules/permission.ts
  9. 7
      kicc-ui/src/store/modules/user.ts
  10. 8
      kicc-ui/src/utils/helper/treeHelper.ts

6
kicc-system/kicc-system-biz/src/main/java/com/cloud/kicc/admin/controller/MenuController.java

@ -65,7 +65,7 @@ public class MenuController { @@ -65,7 +65,7 @@ public class MenuController {
@SysLog("菜单新增")
@PostMapping("/save")
//@PreAuthorize("@pms.hasPermission('menu_add')")
@PreAuthorize("@pms.hasPermission('menu_add')")
public R save(@RequestBody Menu menu) {
menuService.save(menu);
return R.ok();
@ -73,7 +73,7 @@ public class MenuController { @@ -73,7 +73,7 @@ public class MenuController {
@SysLog("菜单修改")
@PutMapping("/update")
//@PreAuthorize("@pms.hasPermission('menu_edit')")
@PreAuthorize("@pms.hasPermission('menu_edit')")
public R update(@RequestBody Menu menu) {
menuService.updateById(menu);
return R.ok();
@ -81,7 +81,7 @@ public class MenuController { @@ -81,7 +81,7 @@ public class MenuController {
@SysLog("菜单删除")
@DeleteMapping("/remove/{id:\\w+}")
//@PreAuthorize("@pms.hasPermission('menu_del')")
@PreAuthorize("@pms.hasPermission('menu_del')")
public R remove(@PathVariable String id) {
if (menuService.count(new QueryWrapper<Menu>().eq("parent_id", id)) > 0) {
return R.error("存在子菜单,不允许删除");

7
kicc-ui/src/api/sys/menu.ts

@ -2,13 +2,10 @@ import { defHttp } from '/@/utils/http/axios'; @@ -2,13 +2,10 @@ import { defHttp } from '/@/utils/http/axios';
import { getMenuListResultModel } from './model/menuModel';
enum Api {
GetMenuList = '/system/menu/tree',
GetMenuList = '/admin/system/menu/menus',
}
/**
* @description: Get user menu based on id
*/
/** 获取用户菜单 */
export const getMenuList = () => {
return defHttp.get<getMenuListResultModel>({ url: Api.GetMenuList });
};

2
kicc-ui/src/router/guard/paramMenuGuard.ts

@ -19,7 +19,7 @@ export function createParamMenuGuard(router: Router) { @@ -19,7 +19,7 @@ export function createParamMenuGuard(router: Router) {
next();
return;
}
// 菜单已建立
// 检测是否菜单已建立
if (!permissionStore.getIsDynamicAddedRoute) {
next();
return;

3
kicc-ui/src/router/guard/permissionGuard.ts

@ -79,13 +79,10 @@ export function createPermissionGuard(router: Router) { @@ -79,13 +79,10 @@ export function createPermissionGuard(router: Router) {
}
const routes = await permissionStore.buildRoutesAction();
routes.forEach((route) => {
router.addRoute(route as unknown as RouteRecordRaw);
});
router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw);
permissionStore.setDynamicAddedRoute(true);
if (to.name === PAGE_NOT_FOUND_ROUTE.name) {

4
kicc-ui/src/router/helper/menuHelper.ts

@ -69,9 +69,7 @@ export function transformRouteToMenu(routeModList: AppRouteModule[], routerMappi @@ -69,9 +69,7 @@ export function transformRouteToMenu(routeModList: AppRouteModule[], routerMappi
return cloneDeep(list);
}
/**
*
*/
/** 带有给定参数的配置菜单 */
const menuParamRegex = /(?::)([\s\S]+?)((?=\/)|$)/g;
export function configureDynamicParamsMenu(menu: Menu, params: RouteParams) {
const { path, paramPath } = toRaw(menu);

90
kicc-ui/src/router/helper/routeHelper.ts

@ -7,20 +7,14 @@ @@ -7,20 +7,14 @@
*/
import type { AppRouteModule, AppRouteRecordRaw } from '/@/router/types';
import type { Router, RouteRecordNormalized } from 'vue-router';
import { getParentLayout, LAYOUT } from '/@/router/constant';
import { cloneDeep, omit } from 'lodash-es';
import { cloneDeep } from 'lodash-es';
import { warn } from '/@/utils/log';
import { createRouter, createWebHashHistory } from 'vue-router';
const IFRAME = () => import('/@/views/sys/iframe/FrameBlank.vue');
const LayoutMap = new Map<string, () => Promise<typeof import('*.vue')>>();
LayoutMap.set('LAYOUT', LAYOUT);
LayoutMap.set('IFRAME', IFRAME);
let dynamicViewsModules: Record<string, () => Promise<Recordable>>;
function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) {
@ -46,10 +40,7 @@ function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) { @@ -46,10 +40,7 @@ function asyncImportRoute(routes: AppRouteRecordRaw[] | undefined) {
});
}
function dynamicImport(
dynamicViewsModules: Record<string, () => Promise<Recordable>>,
component: string
) {
function dynamicImport(dynamicViewsModules: Record<string, () => Promise<Recordable>>, component: string) {
const keys = Object.keys(dynamicViewsModules);
const matchKeys = keys.filter((key) => {
let k = key.replace('../../views', '');
@ -62,14 +53,12 @@ function dynamicImport( @@ -62,14 +53,12 @@ function dynamicImport(
return dynamicViewsModules[matchKey];
}
if (matchKeys?.length > 1) {
warn(
'Please do not create `.vue` and `.TSX` files with the same file name in the same hierarchical directory under the views folder. This will cause dynamic introduction failure'
);
warn('Please do not create `.vue` and `.TSX` files with the same file name in the same hierarchical directory under the views folder. This will cause dynamic introduction failure');
return;
}
}
// 将菜单对象变成路由对象
/** 将菜单对象变成路由对象 */
export function transformObjToRoute<T = AppRouteModule>(routeList: AppRouteModule[]): T[] {
routeList.forEach((route) => {
const component = route.component as string;
@ -91,74 +80,3 @@ export function transformObjToRoute<T = AppRouteModule>(routeList: AppRouteModul @@ -91,74 +80,3 @@ export function transformObjToRoute<T = AppRouteModule>(routeList: AppRouteModul
});
return routeList as unknown as T[];
}
/**
* 2
*/
export function flatMultiLevelRoutes(routeModules: AppRouteModule[]) {
const modules: AppRouteModule[] = cloneDeep(routeModules);
for (let index = 0; index < modules.length; index++) {
const routeModule = modules[index];
if (!isMultipleRoute(routeModule)) {
continue;
}
promoteRouteLevel(routeModule);
}
return modules;
}
// 路由等级升级
function promoteRouteLevel(routeModule: AppRouteModule) {
// 使用vue-router拼接菜单
let router: Router | null = createRouter({
routes: [routeModule as unknown as RouteRecordNormalized],
history: createWebHashHistory(),
});
const routes = router.getRoutes();
addToChildren(routes, routeModule.children || [], routeModule);
router = null;
routeModule.children = routeModule.children?.map((item) => omit(item, 'children'));
}
// 将所有子路由添加到二级路由
function addToChildren(
routes: RouteRecordNormalized[],
children: AppRouteRecordRaw[],
routeModule: AppRouteModule
) {
for (let index = 0; index < children.length; index++) {
const child = children[index];
const route = routes.find((item) => item.name === child.name);
if (!route) {
continue;
}
routeModule.children = routeModule.children || [];
if (!routeModule.children.find((item) => item.name === route.name)) {
routeModule.children?.push(route as unknown as AppRouteModule);
}
if (child.children?.length) {
addToChildren(routes, child.children, routeModule);
}
}
}
// 判断级别是否超过2级
function isMultipleRoute(routeModule: AppRouteModule) {
if (!routeModule || !Reflect.has(routeModule, 'children') || !routeModule.children?.length) {
return false;
}
const children = routeModule.children;
let flag = false;
for (let index = 0; index < children.length; index++) {
const child = children[index];
if (child.children?.length) {
flag = true;
break;
}
}
return flag;
}

3
kicc-ui/src/router/index.ts

@ -22,8 +22,7 @@ getRouteNames(basicRoutes); @@ -22,8 +22,7 @@ getRouteNames(basicRoutes);
// 应用路由器
export const router = createRouter({
// @ts-ignore
history: createWebHashHistory(import.meta.env.VITE_PUBLIC_PATH),
history: createWebHashHistory(import.meta.env.VITE_PUBLIC_PATH as string),
routes: basicRoutes as unknown as RouteRecordRaw[],
strict: true,
scrollBehavior: () => ({ left: 0, top: 0 }),

51
kicc-ui/src/store/modules/permission.ts

@ -11,7 +11,7 @@ import { defineStore } from 'pinia'; @@ -11,7 +11,7 @@ import { defineStore } from 'pinia';
import { store } from '/@/store';
import { useI18n } from '/@/hooks/web/useI18n';
import { useUserStore } from './user';
import { transformObjToRoute, flatMultiLevelRoutes } from '/@/router/helper/routeHelper';
import { transformObjToRoute } from '/@/router/helper/routeHelper';
import { transformRouteToMenu } from '/@/router/helper/menuHelper';
import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic';
import { filter } from '/@/utils/helper/treeHelper';
@ -75,9 +75,7 @@ export const usePermissionStore = defineStore({ @@ -75,9 +75,7 @@ export const usePermissionStore = defineStore({
return !ignoreRoute;
};
/**
* pathroutes中的affix标记
*/
/** 根据设置的首页path,修正routes中的affix标记(固定首页) */
const patchHomeAffix = (routes: AppRouteRecordRaw[]) => {
if (!routes || routes.length === 0) return;
let homePath: string = userStore.getUserInfo.homePath || PageEnum.BASE_HOME;
@ -88,7 +86,7 @@ export const usePermissionStore = defineStore({ @@ -88,7 +86,7 @@ export const usePermissionStore = defineStore({
const currentPath = path.startsWith('/') ? path : parentPath + path;
if (currentPath === homePath) {
if (redirect) {
homePath = route.redirect! as string;
homePath = route.redirect as string;
} else {
route.meta = Object.assign({}, route.meta, { affix: true });
throw new Error('end');
@ -100,42 +98,33 @@ export const usePermissionStore = defineStore({ @@ -100,42 +98,33 @@ export const usePermissionStore = defineStore({
try {
patcher(routes);
} catch (e) {
// 已处理完毕跳出循环
// 固定首页已处理完毕跳出循环
return;
}
return;
};
// 如果确定不需要做后台动态权限,请在下方评论整个判断
/** 提示菜单正在加载中 */
const { createMessage } = useMessage();
createMessage.loading({
content: t('sys.app.menuLoading'),
duration: 1,
});
// !模拟从后台获取权限码,
// 这个功能可能只需要执行一次,实际项目可以自己放在合适的时间
let routeList: AppRouteRecordRaw[] = [];
try {
routeList = (await getMenuList()) as AppRouteRecordRaw[];
} catch (error) {
/** 构建菜单与路由 */
return (await getMenuList().then(data=> {
let routeList = <AppRouteRecordRaw[]>data;
// 将菜单对象变成路由对象
routeList = transformObjToRoute(routeList);
const menuList = transformRouteToMenu(routeList);
this.setMenuList(menuList);
// 过滤忽略路由配置项,只构建菜单不构建路由
routeList = filter(routeList, routeRemoveIgnoreFilter);
routes = [PAGE_NOT_FOUND_ROUTE, ...routeList];
patchHomeAffix(routes);
return routes;
}).catch(error => {
console.error(error);
}
// 动态引入组件
routeList = transformObjToRoute(routeList);
// 后台路由到菜单结构
const menuList = transformRouteToMenu(routeList);
this.setMenuList(menuList);
// 删除 meta.ignoreRoute 项目
routeList = filter(routeList, routeRemoveIgnoreFilter);
routeList = routeList.filter(routeRemoveIgnoreFilter);
routeList = flatMultiLevelRoutes(routeList);
routes = [PAGE_NOT_FOUND_ROUTE, ...routeList];
patchHomeAffix(routes);
return routes;
})) as AppRouteRecordRaw[];
},
},
});

7
kicc-ui/src/store/modules/user.ts

@ -103,16 +103,16 @@ export const useUserStore = defineStore({ @@ -103,16 +103,16 @@ export const useUserStore = defineStore({
const { access_token, refresh_token } = data;
this.setAccessToken(access_token);
this.setRefreshToken(refresh_token);
// 获取用户信息
const userInfo = await this.getUserInfoAction();
const sessionTimeout = this.sessionTimeout;
if (sessionTimeout) {
this.setSessionTimeout(false);
} else if (goHome) {
// 处理路由与菜单的构建,并且进行缓存
const permissionStore = usePermissionStore();
// 使用isDynamicAddedRoute字段做菜单路由缓存功能
if (!permissionStore.isDynamicAddedRoute) {
const routes = await permissionStore.buildRoutesAction();
routes.forEach((route) => {
@ -122,7 +122,6 @@ export const useUserStore = defineStore({ @@ -122,7 +122,6 @@ export const useUserStore = defineStore({
permissionStore.setDynamicAddedRoute(true);
}
await router.replace(userInfo.homePath || PageEnum.BASE_HOME);
}
return userInfo;
} catch (error) {

8
kicc-ui/src/utils/helper/treeHelper.ts

@ -8,12 +8,12 @@ @@ -8,12 +8,12 @@
interface TreeHelperConfig {
id: string;
children: string;
pid: string;
parentId: string;
}
const DEFAULT_CONFIG: TreeHelperConfig = {
id: 'id',
children: 'children',
pid: 'pid',
parentId: 'parentId',
};
const getConfig = (config: Partial<TreeHelperConfig>) => Object.assign({}, DEFAULT_CONFIG, config);
@ -23,14 +23,14 @@ export function listToTree<T = any>(list: any[], config: Partial<TreeHelperConfi @@ -23,14 +23,14 @@ export function listToTree<T = any>(list: any[], config: Partial<TreeHelperConfi
const conf = getConfig(config) as TreeHelperConfig;
const nodeMap = new Map();
const result: T[] = [];
const { id, children, pid } = conf;
const { id, children, parentId } = conf;
for (const node of list) {
node[children] = node[children] || [];
nodeMap.set(node[id], node);
}
for (const node of list) {
const parent = nodeMap.get(node[pid]);
const parent = nodeMap.get(node[parentId]);
(parent ? parent.children : result).push(node);
}
return result;

Loading…
Cancel
Save