You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
5.3 KiB
220 lines
5.3 KiB
import { IMenu } from '@/types/system/menus'
|
|
import { FiledNames, FlattenData, MenuItem } from '@/global'
|
|
import { getIcon } from '@/components/icon'
|
|
import { TreeDataNode, MenuItemProps } from 'antd'
|
|
import deepCopy from 'fast-copy'
|
|
|
|
|
|
//vite环境变量, 判断是否是开发环境
|
|
export const isDev = import.meta.env.MODE === 'development'
|
|
|
|
// 格式化菜单数据, 把children转换成routes
|
|
export const formatMenuData = (data: IMenu[], parentName: string[]) => {
|
|
const result: MenuItem[] = []
|
|
for (const item of data) {
|
|
if (item.icon && typeof item.icon === 'string') {
|
|
item.icon = getIcon(item.icon as string, { size: '14', theme: 'filled' })
|
|
}
|
|
if (!item.children || !item.children.length) {
|
|
result.push({
|
|
...item,
|
|
key: item.name,
|
|
name: item.title,
|
|
parentName,
|
|
})
|
|
} else {
|
|
const { children, name, ...other } = item
|
|
result.push({
|
|
...other,
|
|
key: name,
|
|
name: other.title,
|
|
children: formatMenuData(children, [ ...parentName, name ]),
|
|
routes: formatMenuData(children, [ ...parentName, name ]),
|
|
})
|
|
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
|
|
//把MenuItem[]转换成antd树形结构
|
|
export const formatterMenuData = (data: MenuItem[]): TreeDataNode[] => {
|
|
const result: TreeDataNode[] = []
|
|
for (const item of data) {
|
|
if (item.children && item.children.length) {
|
|
const { children, ...other } = item
|
|
result.push({
|
|
...other,
|
|
key: item.id!,
|
|
title: item.name!,
|
|
children: formatterMenuData(children),
|
|
})
|
|
} else {
|
|
result.push({
|
|
...item,
|
|
key: item.id!,
|
|
title: item.name!,
|
|
})
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
//将tree转成Menu结构
|
|
export const convertToMenu = (data: any[], format?: (item: any) => any) => {
|
|
const result: MenuItemProps[] = []
|
|
format = format ?? ((item: any) => item)
|
|
for (const item of data) {
|
|
if (item.hidden) {
|
|
continue
|
|
}
|
|
const _item = format(item)
|
|
if (_item.children && _item.children.length) {
|
|
result.push({
|
|
..._item,
|
|
children: convertToMenu(_item.children, format),
|
|
})
|
|
} else {
|
|
result.push(_item)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
//把tree转成平铺数组
|
|
const defaultTreeFieldNames: FiledNames = {
|
|
key: 'id',
|
|
title: 'title',
|
|
children: 'children'
|
|
}
|
|
|
|
export function flattenTree<T>(tree: T[], fieldNames?: FiledNames) {
|
|
const result: T[] = []
|
|
|
|
fieldNames = {
|
|
...defaultTreeFieldNames,
|
|
...fieldNames
|
|
}
|
|
|
|
function flattenRecursive(item: T, level: number, fieldNames: FiledNames) {
|
|
|
|
const data: FlattenData<T> = {
|
|
...item,
|
|
key: item[fieldNames.key!],
|
|
title: item[fieldNames.title!],
|
|
level,
|
|
}
|
|
const children = item[fieldNames.children!]
|
|
if (children) {
|
|
children.forEach((child) => flattenRecursive(child, level + 1, fieldNames))
|
|
data.children = children
|
|
}
|
|
result.push(data as T)
|
|
}
|
|
|
|
tree.forEach((item) => flattenRecursive(item, 0, fieldNames))
|
|
|
|
return result
|
|
}
|
|
|
|
|
|
export const convertToBool = (value: any): boolean => {
|
|
// 特殊处理字符串 '0'、'true' 和 'false'
|
|
if (typeof value === 'string') {
|
|
switch (value.toLowerCase()) {
|
|
case '0':
|
|
case '':
|
|
return false
|
|
case 'true':
|
|
return true
|
|
case 'false':
|
|
return false
|
|
default:
|
|
// 对于其他非空字符串,转换为 true
|
|
return Boolean(value)
|
|
}
|
|
}
|
|
|
|
// 处理常见 falsy 值
|
|
if (value === undefined || value === null ||
|
|
value === false || value === 0 || value === '' || Number.isNaN(value)) {
|
|
return false
|
|
}
|
|
|
|
// 对于对象或数组,我们通常认为非空即为 true
|
|
if (Array.isArray(value) || typeof value === 'object') {
|
|
return !!Object.keys(value).length
|
|
}
|
|
|
|
// 其他情况,包括数字(非零)、字符串(已经被上述逻辑处理)和其他 truthy 值
|
|
return Boolean(value)
|
|
}
|
|
|
|
//数组去重
|
|
export const unique = (arr: any[]): any[] => {
|
|
return Array.from(new Set(arr))
|
|
}
|
|
|
|
export const getValueCount = (obj: any, filterObj: any = {}) => {
|
|
|
|
// 获取对象中所有值的数量
|
|
let count = 0
|
|
for (const key in obj) {
|
|
if ([ 'page', 'pageSize', 'pageIndex' ].includes(key)) {
|
|
continue
|
|
}
|
|
if (Object.prototype.hasOwnProperty.call(obj, key) && obj[key]) {
|
|
//如果是数组,则必须长度大于0
|
|
if (!filterObj?.[key]) {
|
|
if (Array.isArray(obj[key]) && obj[key].length === 0) {
|
|
continue
|
|
}
|
|
count++
|
|
}
|
|
}
|
|
}
|
|
return count
|
|
}
|
|
|
|
export const unSetColumnRules = (columns: any[]) => {
|
|
|
|
return deepCopy(columns)?.map(col => {
|
|
col.__ignoreRules = true
|
|
if (col.formItemProps?.rules?.length) {
|
|
col.formItemProps.rules = []
|
|
} else if (typeof col.formItemProps === 'function') {
|
|
const formItemProps = col.formItemProps
|
|
col.formItemProps = (form, config) => {
|
|
const props = formItemProps(form, config)
|
|
return {
|
|
...props,
|
|
rules: [],
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
...col
|
|
}
|
|
})
|
|
}
|
|
|
|
export const getColumns = (columns: any[], key: string) => {
|
|
return columns.find(col => col.key === key)
|
|
}
|
|
|
|
//生成ProTableColumns的宽度相关属性
|
|
export const genProTableColumnWidthProps = (width: string | number) => {
|
|
if (!width) {
|
|
return {}
|
|
}
|
|
return {
|
|
width,
|
|
fieldProps: {
|
|
style: { width: '100%' }
|
|
},
|
|
}
|
|
}
|
|
|
|
|
|
|