第一次
This commit is contained in:
20
src/utils/IconUtil.ts
Normal file
20
src/utils/IconUtil.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import * as AntdIcons from '@ant-design/icons';
|
||||
import React from 'react';
|
||||
|
||||
const allIcons: Record<string, any> = AntdIcons;
|
||||
|
||||
export function getIcon(name: string): React.ReactNode | string {
|
||||
const icon = allIcons[name];
|
||||
return icon || '';
|
||||
}
|
||||
|
||||
export function createIcon(icon: string | any): React.ReactNode | string {
|
||||
if (typeof icon === 'object') {
|
||||
return icon;
|
||||
}
|
||||
const ele = allIcons[icon];
|
||||
if (ele) {
|
||||
return React.createElement(allIcons[icon]);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
70
src/utils/func.js
Normal file
70
src/utils/func.js
Normal file
@@ -0,0 +1,70 @@
|
||||
|
||||
import { message } from 'antd';
|
||||
|
||||
export function copy(text) {
|
||||
let oInput = document.createElement('input')
|
||||
oInput.value = text;
|
||||
document.body.appendChild(oInput)
|
||||
oInput.select() // 选择对象
|
||||
document.execCommand("Copy") // 执行浏览器复制命令
|
||||
message.success('复制成功');
|
||||
oInput.remove()
|
||||
}
|
||||
|
||||
//下载连接
|
||||
export function exportLink(searchParams, api) {
|
||||
searchParams.token = localStorage.getItem('token');
|
||||
const params = Object.entries(searchParams).length ? `?${new URLSearchParams(searchParams)}` : '';
|
||||
return `${api}${params}`;
|
||||
};
|
||||
|
||||
export function exportData(_res,name) {
|
||||
// 获取文件的二进制数据
|
||||
const blob = new Blob([_res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
||||
// 创建下载链接
|
||||
const link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.download = name;
|
||||
// 触发点击事件以下载文件
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
// 清理
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(link.href);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* @Note:
|
||||
* @Author: 2058827620@qq.com
|
||||
* @Date: 2022-07-31 19:24:14
|
||||
*/
|
||||
export function deepCopy(data) {
|
||||
if (data.constructor.name === 'Array') {
|
||||
// 判断为数组类型
|
||||
const arrCopy = []
|
||||
for (let i = 0, len = data.length; i < len; i++) {
|
||||
//遍历数组
|
||||
if (data[i] instanceof Object) {
|
||||
arrCopy.push(deepCopy(data[i]))
|
||||
} else {
|
||||
// 基本类型
|
||||
arrCopy.push(data[i])
|
||||
}
|
||||
}
|
||||
return arrCopy;
|
||||
|
||||
} else { // 为对象
|
||||
const objCopy = {};
|
||||
for (let x in data) {
|
||||
if (data[x] instanceof Object) {
|
||||
objCopy[x] = deepCopy(data[x])
|
||||
} else { // 基本类型
|
||||
objCopy[x] = data[x];
|
||||
}
|
||||
}
|
||||
return objCopy;
|
||||
}
|
||||
}
|
||||
16
src/utils/index.ts
Normal file
16
src/utils/index.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
export const generateRoutes = (menuData: any[]): any[] => {
|
||||
const routeMapper = (item: any, isRoot: boolean = false): any => {
|
||||
const { path, name, icon, children, parentId, id } = item;
|
||||
const route: any = {
|
||||
path,
|
||||
name,
|
||||
icon,
|
||||
parentId,
|
||||
id,
|
||||
children: children ? children.map(child => routeMapper(child)) : [],
|
||||
};
|
||||
return route;
|
||||
};
|
||||
|
||||
return menuData.map(item => routeMapper(item)); // 根菜单项需要设置 isRoot 为 true
|
||||
};
|
||||
42
src/utils/menu.ts
Normal file
42
src/utils/menu.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { createIcon } from './IconUtil';
|
||||
|
||||
|
||||
interface Item {
|
||||
children?: Item[]; // children 是一个 Item 数组
|
||||
isFrame?: number;
|
||||
icon?: string | React.ReactNode | React.ComponentType<any>; // 确保 icon 类型一致
|
||||
perms?: any; // 根据实际数据结构修改类型
|
||||
menuType?: string;
|
||||
disabledTooltip?: boolean;
|
||||
access?: any;
|
||||
}
|
||||
|
||||
|
||||
export const childrenRemove = (data: Item[] | undefined): Item[] => {
|
||||
// 如果 data 是 undefined,返回空数组
|
||||
if (!data) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// 初始化一个结果数组
|
||||
let list: Item[] = [];
|
||||
|
||||
// 遍历数据
|
||||
data.forEach((i: Item) => {
|
||||
if (i.children && i.children.length === 0) {
|
||||
delete i.children; // 删除空 children 属性
|
||||
} else {
|
||||
i.children = childrenRemove(i.children); // 递归调用处理子项
|
||||
}
|
||||
i.disabledTooltip = i.isFrame === 1;
|
||||
i.icon = i.icon ? createIcon(i.icon) : '';
|
||||
i.access = i.perms;
|
||||
|
||||
// 仅将 menuType 不为 'F' 的项推入结果列表
|
||||
if (i.menuType !== 'F') {
|
||||
list.push(i);
|
||||
}
|
||||
});
|
||||
|
||||
return list; // 返回处理后的列表
|
||||
};
|
||||
64
src/utils/permission.ts
Normal file
64
src/utils/permission.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
// /**
|
||||
// * 字符权限校验
|
||||
// * @param {Array} value 校验值
|
||||
// * @returns {Boolean}
|
||||
// */
|
||||
export function matchPerms(permissions: string[], value: string[]) {
|
||||
if (value && value instanceof Array && value.length > 0) {
|
||||
const permissionDatas = value;
|
||||
const all_permission = '*:*:*';
|
||||
const hasPermission = permissions.some((permission) => {
|
||||
return all_permission === permission || permissionDatas.includes(permission);
|
||||
});
|
||||
if (!hasPermission) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`);
|
||||
return false;
|
||||
}
|
||||
|
||||
export function matchPerm(permissions: string[], value: string) {
|
||||
if (value && value.length > 0) {
|
||||
const permissionDatas = value;
|
||||
const all_permission = '*:*:*';
|
||||
const hasPermission = permissions.some((permission) => {
|
||||
return all_permission === permission || permissionDatas === permission;
|
||||
});
|
||||
if (!hasPermission) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`);
|
||||
return false;
|
||||
}
|
||||
|
||||
export function matchPermission(permissions: string[] | undefined, value: any): boolean {
|
||||
if (permissions === undefined) return false;
|
||||
const type = typeof value;
|
||||
if (type === 'string') {
|
||||
return matchPerm(permissions, value);
|
||||
}
|
||||
return matchPerms(permissions, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 角色权限校验
|
||||
* @param {Array} value 校验值
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function checkRole(roles: API.System.Role[] | undefined, value: string[]) {
|
||||
if (roles && value && value.length > 0) {
|
||||
for (let i = 0; i < roles?.length; i++) {
|
||||
for (let j = 0; j < value?.length; j++) {
|
||||
if (value[j] === roles[i].roleKey) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
console.error(`need roles! Like checkRole="['admin','editor']"`);
|
||||
return false;
|
||||
}
|
||||
93
src/utils/tree.ts
Normal file
93
src/utils/tree.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { DataNode } from 'antd/es/tree';
|
||||
import { parse } from 'querystring';
|
||||
|
||||
/**
|
||||
* 构造树型结构数据
|
||||
* @param {*} data 数据源
|
||||
* @param {*} id id字段 默认 'id'
|
||||
* @param {*} parentId 父节点字段 默认 'parentId'
|
||||
* @param {*} children 孩子节点字段 默认 'children'
|
||||
*/
|
||||
export function buildTreeData(
|
||||
data: any[],
|
||||
id: string,
|
||||
name: string,
|
||||
parentId: string,
|
||||
parentName: string,
|
||||
children: string,
|
||||
) {
|
||||
const config = {
|
||||
id: id || 'id',
|
||||
name: name || 'name',
|
||||
parentId: parentId || 'parentId',
|
||||
parentName: parentName || 'parentName',
|
||||
childrenList: children || 'children',
|
||||
};
|
||||
|
||||
const childrenListMap: any[] = [];
|
||||
const nodeIds: any[] = [];
|
||||
const tree: any[] = [];
|
||||
data.forEach((item) => {
|
||||
const d = item;
|
||||
const pId = d[config.parentId];
|
||||
if (!childrenListMap[pId]) {
|
||||
childrenListMap[pId] = [];
|
||||
}
|
||||
d.key = d[config.id];
|
||||
d.title = d[config.name];
|
||||
d.value = d[config.id];
|
||||
d[config.childrenList] = null;
|
||||
nodeIds[d[config.id]] = d;
|
||||
childrenListMap[pId].push(d);
|
||||
});
|
||||
|
||||
data.forEach((item: any) => {
|
||||
const d = item;
|
||||
const pId = d[config.parentId];
|
||||
if (!nodeIds[pId]) {
|
||||
d[config.parentName] = '';
|
||||
tree.push(d);
|
||||
}
|
||||
});
|
||||
|
||||
function adaptToChildrenList(item: any) {
|
||||
const o = item;
|
||||
if (childrenListMap[o[config.id]]) {
|
||||
if (!o[config.childrenList]) {
|
||||
o[config.childrenList] = [];
|
||||
}
|
||||
o[config.childrenList] = childrenListMap[o[config.id]];
|
||||
}
|
||||
if (o[config.childrenList]) {
|
||||
o[config.childrenList].forEach((child: any) => {
|
||||
const c = child;
|
||||
c[config.parentName] = o[config.name];
|
||||
adaptToChildrenList(c);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
tree.forEach((t: any) => {
|
||||
adaptToChildrenList(t);
|
||||
});
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
export const getPageQuery = () => parse(window.location.href.split('?')[1]);
|
||||
|
||||
export function formatTreeData(arrayList: any): DataNode[] {
|
||||
const treeSelectData: DataNode[] = arrayList.map((item: any) => {
|
||||
const node: DataNode = {
|
||||
id: item.id,
|
||||
title: item.label,
|
||||
key: `${item.id}`,
|
||||
value: item.id,
|
||||
} as DataNode;
|
||||
if (item.children) {
|
||||
node.children = formatTreeData(item.children);
|
||||
}
|
||||
return node;
|
||||
});
|
||||
return treeSelectData;
|
||||
}
|
||||
Reference in New Issue
Block a user