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

7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
3 months ago
7 months ago
7 months ago
7 months ago
5 months ago
3 months ago
5 months ago
3 months ago
5 months ago
5 months ago
3 months ago
3 months ago
3 months ago
  1. import { IMenu } from '@/types/system/menus'
  2. import { FiledNames, FlattenData, MenuItem } from '@/global'
  3. import { getIcon } from '@/components/icon'
  4. import { TreeDataNode, MenuItemProps } from 'antd'
  5. import deepCopy from 'fast-copy'
  6. //vite环境变量, 判断是否是开发环境
  7. export const isDev = import.meta.env.MODE === 'development'
  8. // 格式化菜单数据, 把children转换成routes
  9. export const formatMenuData = (data: IMenu[], parentName: string[]) => {
  10. const result: MenuItem[] = []
  11. for (const item of data) {
  12. if (item.icon && typeof item.icon === 'string') {
  13. item.icon = getIcon(item.icon as string, { size: '14', theme: 'filled' })
  14. }
  15. if (!item.children || !item.children.length) {
  16. result.push({
  17. ...item,
  18. key: item.name,
  19. name: item.title,
  20. parentName,
  21. })
  22. } else {
  23. const { children, name, ...other } = item
  24. result.push({
  25. ...other,
  26. key: name,
  27. name: other.title,
  28. children: formatMenuData(children, [ ...parentName, name ]),
  29. routes: formatMenuData(children, [ ...parentName, name ]),
  30. })
  31. }
  32. }
  33. return result
  34. }
  35. //把MenuItem[]转换成antd树形结构
  36. export const formatterMenuData = (data: MenuItem[]): TreeDataNode[] => {
  37. const result: TreeDataNode[] = []
  38. for (const item of data) {
  39. if (item.children && item.children.length) {
  40. const { children, ...other } = item
  41. result.push({
  42. ...other,
  43. key: item.id!,
  44. title: item.name!,
  45. children: formatterMenuData(children),
  46. })
  47. } else {
  48. result.push({
  49. ...item,
  50. key: item.id!,
  51. title: item.name!,
  52. })
  53. }
  54. }
  55. return result
  56. }
  57. //将tree转成Menu结构
  58. export const convertToMenu = (data: any[], format?: (item: any) => any) => {
  59. const result: MenuItemProps[] = []
  60. format = format ?? ((item: any) => item)
  61. for (const item of data) {
  62. if (item.hidden) {
  63. continue
  64. }
  65. const _item = format(item)
  66. if (_item.children && _item.children.length) {
  67. result.push({
  68. ..._item,
  69. children: convertToMenu(_item.children, format),
  70. })
  71. } else {
  72. result.push(_item)
  73. }
  74. }
  75. return result
  76. }
  77. //把tree转成平铺数组
  78. const defaultTreeFieldNames: FiledNames = {
  79. key: 'id',
  80. title: 'title',
  81. children: 'children'
  82. }
  83. export function flattenTree<T>(tree: T[], fieldNames?: FiledNames) {
  84. const result: T[] = []
  85. fieldNames = {
  86. ...defaultTreeFieldNames,
  87. ...fieldNames
  88. }
  89. function flattenRecursive(item: T, level: number, fieldNames: FiledNames) {
  90. const data: FlattenData<T> = {
  91. ...item,
  92. key: item[fieldNames.key!],
  93. title: item[fieldNames.title!],
  94. level,
  95. }
  96. const children = item[fieldNames.children!]
  97. if (children) {
  98. children.forEach((child) => flattenRecursive(child, level + 1, fieldNames))
  99. data.children = children
  100. }
  101. result.push(data as T)
  102. }
  103. tree.forEach((item) => flattenRecursive(item, 0, fieldNames))
  104. return result
  105. }
  106. export const convertToBool = (value: any): boolean => {
  107. // 特殊处理字符串 '0'、'true' 和 'false'
  108. if (typeof value === 'string') {
  109. switch (value.toLowerCase()) {
  110. case '0':
  111. case '':
  112. return false
  113. case 'true':
  114. return true
  115. case 'false':
  116. return false
  117. default:
  118. // 对于其他非空字符串,转换为 true
  119. return Boolean(value)
  120. }
  121. }
  122. // 处理常见 falsy 值
  123. if (value === undefined || value === null ||
  124. value === false || value === 0 || value === '' || Number.isNaN(value)) {
  125. return false
  126. }
  127. // 对于对象或数组,我们通常认为非空即为 true
  128. if (Array.isArray(value) || typeof value === 'object') {
  129. return !!Object.keys(value).length
  130. }
  131. // 其他情况,包括数字(非零)、字符串(已经被上述逻辑处理)和其他 truthy 值
  132. return Boolean(value)
  133. }
  134. //数组去重
  135. export const unique = (arr: any[]): any[] => {
  136. return Array.from(new Set(arr))
  137. }
  138. export const getValueCount = (obj: any, filterObj: any = {}) => {
  139. // 获取对象中所有值的数量
  140. let count = 0
  141. for (const key in obj) {
  142. if ([ 'page', 'pageSize', 'pageIndex' ].includes(key)) {
  143. continue
  144. }
  145. if (Object.prototype.hasOwnProperty.call(obj, key) && obj[key]) {
  146. //如果是数组,则必须长度大于0
  147. if (!filterObj?.[key]) {
  148. if (Array.isArray(obj[key]) && obj[key].length === 0) {
  149. continue
  150. }
  151. count++
  152. }
  153. }
  154. }
  155. return count
  156. }
  157. export const unSetColumnRules = (columns: any[]) => {
  158. return deepCopy(columns)?.map(col => {
  159. col.__ignoreRules = true
  160. if (col.formItemProps?.rules?.length) {
  161. col.formItemProps.rules = []
  162. } else if (typeof col.formItemProps === 'function') {
  163. const formItemProps = col.formItemProps
  164. col.formItemProps = (form, config) => {
  165. const props = formItemProps(form, config)
  166. return {
  167. ...props,
  168. rules: [],
  169. }
  170. }
  171. }
  172. return {
  173. ...col
  174. }
  175. })
  176. }
  177. export const getColumns = (columns: any[], key: string) => {
  178. return columns.find(col => col.key === key)
  179. }
  180. //生成ProTableColumns的宽度相关属性
  181. export const genProTableColumnWidthProps = (width: string | number) => {
  182. if (!width) {
  183. return {}
  184. }
  185. return {
  186. width,
  187. fieldProps: {
  188. style: { width: '100%' }
  189. },
  190. }
  191. }