zhou zhou
1 天以前 5d31cb5f1fb32a478d5b751ebfe97d47db890778
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
export function createMenuPdaSearchState() {
  return {
    name: '',
    route: ''
  }
}
 
export function normalizeMenuPdaNumber(value, fallback = 0) {
  if (value === '' || value === null || value === undefined) {
    return fallback
  }
  const normalized = Number(value)
  return Number.isNaN(normalized) ? fallback : normalized
}
 
export function getMenuPdaDisplayTitle(row = {}) {
  return String(row.name || '').trim()
}
 
export function getMenuPdaDisplayIcon(row = {}) {
  return row.icon || ''
}
 
export function hasNestedMenuPda(row = {}) {
  return Array.isArray(row.children) && row.children.some((child) => Number(child.type) !== 1)
}
 
export function getMenuPdaTypeTag(row = {}) {
  if (Number(row.type) === 1) return 'danger'
  if (hasNestedMenuPda(row)) return 'info'
  return 'primary'
}
 
export function getMenuPdaTypeText(row = {}) {
  if (Number(row.type) === 1) return '按钮'
  if (hasNestedMenuPda(row)) return '目录'
  return '菜单'
}
 
export function getMenuPdaStatusMeta(status) {
  return normalizeMenuPdaNumber(status, 1) === 1
    ? { text: '启用', type: 'success' }
    : { text: '禁用', type: 'danger' }
}
 
export function normalizeMenuPdaTreeOptions(nodes = []) {
  if (!Array.isArray(nodes)) {
    return []
  }
 
  return nodes.map((node) => ({
    label: getMenuPdaDisplayTitle(node),
    value: normalizeMenuPdaNumber(node.id, 0),
    children: normalizeMenuPdaTreeOptions(node.children)
  }))
}
 
export function buildMenuPdaTreeOptions(tree = []) {
  return [
    {
      label: '顶级菜单',
      value: 0,
      children: normalizeMenuPdaTreeOptions(tree)
    }
  ]
}
 
export function buildMenuPdaSubmitPayload(formData = {}) {
  return {
    ...(formData.id ? { id: normalizeMenuPdaNumber(formData.id, 0) } : {}),
    parentId: normalizeMenuPdaNumber(formData.parentId, 0),
    name: String(formData.name || '').trim(),
    route: String(formData.route || '').trim(),
    component: String(formData.component || '').trim(),
    authority: String(formData.authority || '').trim(),
    icon: String(formData.icon || '').trim(),
    sort: normalizeMenuPdaNumber(formData.sort, 0),
    status: normalizeMenuPdaNumber(formData.status, 1),
    memo: String(formData.memo || '').trim(),
    type: formData.menuType === 'button' ? 1 : 0
  }
}
 
export function cloneMenuPdaTree(source) {
  if (source === null || typeof source !== 'object') return source
  if (source instanceof Date) return new Date(source)
  if (Array.isArray(source)) return source.map((item) => cloneMenuPdaTree(item))
  const cloned = {}
  for (const key in source) {
    if (Object.prototype.hasOwnProperty.call(source, key)) {
      cloned[key] = cloneMenuPdaTree(source[key])
    }
  }
  return cloned
}
 
export function filterMenuPdaTree(items = [], filters = {}) {
  const results = []
  const searchName = String(filters.name || '').toLowerCase().trim()
  const searchRoute = String(filters.route || '').toLowerCase().trim()
 
  for (const item of items) {
    const menuTitle = getMenuPdaDisplayTitle(item).toLowerCase()
    const menuRoute = String(item.route || item.path || item.authority || '').toLowerCase()
    const nameMatch = !searchName || menuTitle.includes(searchName)
    const routeMatch = !searchRoute || menuRoute.includes(searchRoute)
 
    if (item.children?.length) {
      const matchedChildren = filterMenuPdaTree(item.children, filters)
      if (matchedChildren.length > 0) {
        const clonedItem = cloneMenuPdaTree(item)
        clonedItem.children = matchedChildren
        results.push(clonedItem)
        continue
      }
    }
 
    if (nameMatch && routeMatch) {
      results.push(cloneMenuPdaTree(item))
    }
  }
 
  return results
}