Align iOS home common apps and all-functions page with Android.

Add unified HomeCommonMenu/HomeAllFunctions diagnostics, rebuild all-functions from top-level menuList permissions, and document Home and AllFunctions module logic.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-30 09:40:02 +08:00
parent 63fb0462d6
commit 5692134efc
11 changed files with 693 additions and 138 deletions

View File

@ -14,26 +14,20 @@ struct HomeMoreFunctionsView: View {
@EnvironmentObject private var appRouter: AppRouter
@EnvironmentObject private var router: RouterPath
@StateObject private var viewModel = HomeViewModel()
@State private var snapshot = HomeAllFunctionsSnapshot(
allFunctions: [],
commonFunctions: [],
moreFunctions: []
)
@State private var commonUris: [String] = []
private let commonMenuStore = HomeCommonMenuStore()
private var commonItems: [HomeMenuItem] {
commonUris.compactMap(menuItem(for:))
}
private var moreItems: [HomeMenuItem] {
viewModel.menuItems.filter { item in
!isCommonURI(item.uri)
}
}
var body: some View {
ScrollView {
VStack(alignment: .leading, spacing: 26) {
section(title: "常用应用", items: commonItems, isCommon: true)
section(title: "更多功能", items: moreItems, isCommon: false)
section(title: "常用应用", items: snapshot.commonFunctions, isCommon: true)
section(title: "更多功能", items: snapshot.moreFunctions, isCommon: false)
}
.padding(.horizontal, AppMetrics.Spacing.mediumLarge)
.padding(.top, AppMetrics.Spacing.medium)
@ -87,23 +81,7 @@ struct HomeMoreFunctionsView: View {
.buttonStyle(.plain)
Button {
let roleCode = permissionContext.currentAppRole?.rawValue
if isCommon {
commonUris = commonMenuStore.remove(
item.uri,
current: commonUris,
roleCode: roleCode,
accountScope: accountContext.accountCachePrefix
)
} else {
commonUris = commonMenuStore.add(
item.uri,
current: commonUris,
menuItems: viewModel.menuItems,
roleCode: roleCode,
accountScope: accountContext.accountCachePrefix
)
}
updateCommonUris(isCommon: isCommon, uri: item.uri)
} label: {
Image(systemName: isCommon ? "minus.circle.fill" : "plus.circle.fill")
.font(.system(size: 24, weight: .bold))
@ -134,24 +112,6 @@ struct HomeMoreFunctionsView: View {
.frame(width: 34, height: 34)
}
private func menuItem(for uri: String) -> HomeMenuItem? {
let availableURIs = Set(viewModel.menuItems.map(\.uri))
let resolvedUri = HomeMenuRouter.canonicalURI(for: uri, availableURIs: availableURIs)
guard let existing = viewModel.menuItems.first(where: { $0.uri == resolvedUri }) else {
return nil
}
return HomeMenuItem(
title: HomeMenuRouter.displayTitle(for: resolvedUri, fallback: existing.title),
uri: resolvedUri,
iconSrc: existing.iconSrc
)
}
private func isCommonURI(_ uri: String) -> Bool {
let aliasKey = HomeMenuRouter.menuAliasKey(for: uri)
return commonUris.contains { HomeMenuRouter.menuAliasKey(for: $0) == aliasKey }
}
private func openMenu(_ item: HomeMenuItem) {
switch HomeMenuRouter.resolve(uri: item.uri, title: item.title) {
case .tab(let tab):
@ -174,19 +134,49 @@ struct HomeMoreFunctionsView: View {
}
}
///
private func updateCommonUris(isCommon: Bool, uri: String) {
let roleCode = permissionContext.currentAppRole?.rawValue
let topLevelURIs = permissionContext.topLevelPermissionURIs(for: roleCode)
if isCommon {
commonUris = commonMenuStore.remove(
uri,
current: commonUris,
roleCode: roleCode,
accountScope: accountContext.accountCachePrefix
)
} else {
commonUris = commonMenuStore.add(
uri,
current: commonUris,
topLevelPermissionURIs: topLevelURIs,
roleCode: roleCode,
accountScope: accountContext.accountCachePrefix
)
}
applySnapshot(commonURIs: commonUris)
}
private func rebuildMenus() {
let roleCode = permissionContext.currentAppRole?.rawValue
let legacyRoleId = permissionContext.currentRole?.id
viewModel.buildMenus(
from: permissionContext.rolePermissions,
currentRoleCode: roleCode
)
let topLevelPermissions = permissionContext.topLevelPermissions(for: roleCode)
commonUris = commonMenuStore.load(
menuItems: viewModel.menuItems,
menuItems: [],
roleCode: roleCode,
accountScope: accountContext.accountCachePrefix,
legacyRoleId: legacyRoleId,
topLevelPermissionURIs: permissionContext.topLevelPermissionURIs(for: roleCode)
topLevelPermissionURIs: topLevelPermissions.map(\.uri)
)
applySnapshot(commonURIs: commonUris)
}
/// URI
private func applySnapshot(commonURIs: [String]) {
let roleCode = permissionContext.currentAppRole?.rawValue
snapshot = HomeAllFunctionsBuilder.build(
topLevelPermissions: permissionContext.topLevelPermissions(for: roleCode),
commonURIs: commonURIs
)
}
}