generateMenu.uts 4.7 KB
Newer Older
1
import { pages, groups, subPackages } from '@/pages.json'
2

3 4 5 6 7
type Group = {
  id : string,
  name : string,
  children : (Group | null)[] | null
}
8 9

type PageGroup = {
10 11
  id : string,
  name : string,
12
  index : number
13 14 15
}

type Page = {
16 17
  path : string,
  style : UTSJSONObject,
18
  group ?: string | null,
19 20 21
}

export type MenuItem = {
22 23 24
  id : string,
  name : string,
  index : number,
25 26 27
  path : string,
  style : UTSJSONObject,
  group ?: string | null,
DCloud-WZF's avatar
DCloud-WZF 已提交
28
  items : MenuItem[]
29 30
}

31 32 33 34 35 36 37 38 39 40
subPackages.forEach(subPackage => {
  (subPackage.pages as UTSJSONObject[]).forEach(page => {
    pages.push({
      path: `${subPackage.root}/${page.path}`,
      style: page.style as UTSJSONObject,
      group: page.group
    })
  })
})

DCloud-WZF's avatar
DCloud-WZF 已提交
41 42
export function generateMenu(tabBarType : string) : MenuItem[] {
  let res : MenuItem[] = []
43
  const tabBarPages = JSON.parse<Page[]>(JSON.stringify(pages))!.filter((page : Page) : boolean => page.path.startsWith(tabBarType) && hasPageGroup(page.group))
44
  const groupTree = JSON.parse<(Group | null)[]>(JSON.stringify(groups))
45
  tabBarPages.forEach(page => {
DCloud-WZF's avatar
DCloud-WZF 已提交
46
    let menuItemArr : MenuItem[] = res
47
    let currentMenu : MenuItem | null = null
48 49 50 51
    const groupIndexList = page.group!.split(',').map((index : string) : number => parseInt(index))
    let currentGroups : (Group | null)[] | null = groupTree
    const pageGroups : PageGroup[] = []
    groupIndexList.forEach((groupIndex, index) => {
52
      // 跳过第一层 component API CSS
53 54 55 56 57 58
      if (index > 0) {
        pageGroups.push({ id: currentGroups![groupIndex]!.id, name: currentGroups![groupIndex]!.name, index: groupIndex } as PageGroup)
      }
      currentGroups = currentGroups![groupIndex]!.children
    })
    const lastGroup = pageGroups[pageGroups.length - 1]
59
    let hasPageGroup = false
60
    if (page.path.endsWith(camelToDash(lastGroup.name)) && pageGroups.length > 1) {
61
      hasPageGroup = true
62
      pageGroups.pop()
63
    }
64 65
    const groupLength = pageGroups.length
    pageGroups.forEach((group, groupIndex) => {
66 67
      const { index, id, name } = group

68
      const validIndex = index
DCloud-WZF's avatar
DCloud-WZF 已提交
69
      fillMenuArrayWithEmptyMenuItem(menuItemArr, validIndex)
70

DCloud-WZF's avatar
DCloud-WZF 已提交
71
      if (menuItemArr[validIndex].name == 'empty') {
72 73 74 75
        menuItemArr[validIndex] = {
          id: id.split('.').slice(-1)[0],
          name,
          index: validIndex,
76 77 78
          path: '',
          style: {},
          group: '',
DCloud-WZF's avatar
DCloud-WZF 已提交
79
          items: [] as MenuItem[],
80 81 82 83 84 85
        } as MenuItem
      }


      currentMenu = menuItemArr[validIndex]
      if (groupIndex < groupLength - 1) {
DCloud-WZF's avatar
DCloud-WZF 已提交
86
        menuItemArr = menuItemArr[validIndex].items
87 88
      }
    })
89 90 91 92 93 94 95 96

    const pageMenuItem : MenuItem = {
      id: page.path,
      name: page.style["navigationBarTitleText"] as string,
      index: lastGroup.index,
      path: page.path,
      style: page.style,
      group: page.group,
DCloud-WZF's avatar
DCloud-WZF 已提交
97
      items: [] as MenuItem[],
98
    }
99
    if (hasPageGroup) {
100
      const pageIndex = lastGroup.index
DCloud-WZF's avatar
DCloud-WZF 已提交
101 102
      fillMenuArrayWithEmptyMenuItem(currentMenu!.items, pageIndex)
      if (currentMenu!.items[pageIndex].name == 'empty') {
103
        currentMenu!.items[pageIndex] = pageMenuItem
104
      } else {
105
        currentMenu!.items.push(pageMenuItem)
106
      }
107
    } else {
108
      currentMenu!.items.push(pageMenuItem)
109
    }
110
  })
111

DCloud-WZF's avatar
DCloud-WZF 已提交
112
  return removeEmptyItem(res)
113 114
}

雪洛's avatar
雪洛 已提交
115
function hasPageGroup(value ?: string | null) : boolean {
116 117 118 119 120 121 122 123
  // #ifdef APP-ANDROID
  return value !== null
  // #endif
  // #ifndef APP-ANDROID
  return !!value
  // #endif
}

124
function camelToDash(camelStr : string) : string {
125 126 127
  return camelStr.replace(/([A-Z])/g, '-$1').toLowerCase()
}

DCloud-WZF's avatar
DCloud-WZF 已提交
128
function fillMenuArrayWithEmptyMenuItem(arr : MenuItem[], index : number) : void {
129
  const len = arr.length
130
  for (let i = 0; i <= index - (len - 1); i++) {
DCloud-WZF's avatar
DCloud-WZF 已提交
131 132 133 134 135 136 137 138
    arr.push({
      id: '',
      name: 'empty',
      index: i,
      path: '',
      style: {},
      group: '',
      items: [] as MenuItem[],
139
    } as MenuItem)
140 141 142
  }
}

DCloud-WZF's avatar
DCloud-WZF 已提交
143 144
function removeEmptyItem(arr : MenuItem[]) : MenuItem[] {
  const res = arr.filter((item : MenuItem) : boolean => item.name !== 'empty')
145
  res.forEach(menuItem => {
DCloud-WZF's avatar
DCloud-WZF 已提交
146
    addSetTabBarPage(menuItem)
147
    // #ifdef APP-ANDROID
DCloud-WZF's avatar
DCloud-WZF 已提交
148
    menuItem.items = removeEmptyItem(menuItem.items)
149 150
    // #endif
    // #ifndef APP-ANDROID
DCloud-WZF's avatar
DCloud-WZF 已提交
151
    menuItem!.items = removeEmptyItem(menuItem!.items)
152 153 154 155 156
    // #endif
  })
  return res
}

157
function addSetTabBarPage(menuItem : MenuItem) {
DCloud-WZF's avatar
DCloud-WZF 已提交
158
  const { id, name } = menuItem
159
  if (id == 'page' && name == '页面和路由') {
160 161 162 163
    menuItem.items.push({
      id: 'set-tab-bar',
      name: '设置 TabBar',
      index: 0,
164 165 166
      path: 'set-tab-bar',
      style: {
        navigationBarTitleText: '设置 TabBar'
167 168 169 170
      },
      group: null,
      items: []
    } as MenuItem)
171
  }
172
}