Refactor home to single collection view and add all-functions customization.
Replace scroll/stack layout with one UICollectionView, fix grid column math and Diffable item IDs so location report and quick actions render, and add the customizable all-functions page with persistence and tests. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -40,8 +40,18 @@ final class HomeCommonMenuStore {
|
||||
let saved = savedCommonURIs(accountScope: accountScope, roleCode: roleCode)
|
||||
let defaultURIs = Self.defaultCommonURIs(from: permissions)
|
||||
let commonURIs = saved.isEmpty ? defaultURIs : saved
|
||||
return Self.splitMenus(from: allMenus, commonURIs: commonURIs).common
|
||||
}
|
||||
|
||||
/// 按常用 URI 将菜单拆分为常用与更多两组。
|
||||
static func splitMenus(
|
||||
from allMenus: [HomeMenuItem],
|
||||
commonURIs: [String]
|
||||
) -> (common: [HomeMenuItem], more: [HomeMenuItem]) {
|
||||
let commonSet = Set(commonURIs)
|
||||
return allMenus.filter { commonSet.contains($0.uri) }
|
||||
let common = allMenus.filter { commonSet.contains($0.uri) }
|
||||
let more = allMenus.filter { !commonSet.contains($0.uri) }
|
||||
return (common, more)
|
||||
}
|
||||
|
||||
private func storageKey(accountScope: String, roleCode: String) -> String {
|
||||
|
||||
@ -13,9 +13,10 @@ enum HomeRouteHandler {
|
||||
static func open(
|
||||
uri: String,
|
||||
from viewController: UIViewController,
|
||||
storeItem: StoreItem?
|
||||
storeItem: StoreItem?,
|
||||
onCommonMenusChanged: (() -> Void)? = nil
|
||||
) {
|
||||
if uri == "pilot_controller" || uri == "more_functions" {
|
||||
if uri == "pilot_controller" {
|
||||
showDeveloping(from: viewController)
|
||||
return
|
||||
}
|
||||
@ -26,6 +27,10 @@ enum HomeRouteHandler {
|
||||
}
|
||||
|
||||
switch uri {
|
||||
case "more_functions":
|
||||
let controller = AllFunctionsViewController()
|
||||
controller.onDidCustomize = onCommonMenusChanged
|
||||
viewController.navigationController?.pushViewController(controller, animated: true)
|
||||
case "verification_order":
|
||||
selectTab(.orders, from: viewController)
|
||||
case "photographer_stats":
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
//
|
||||
// AllFunctionsViewModel.swift
|
||||
// suixinkan
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// 全部功能页 ViewModel,管理常用应用与更多功能的增删与持久化。
|
||||
final class AllFunctionsViewModel {
|
||||
|
||||
private(set) var commonMenus: [HomeMenuItem] = []
|
||||
private(set) var moreMenus: [HomeMenuItem] = []
|
||||
|
||||
var onStateChange: (() -> Void)?
|
||||
private(set) var didCustomize = false
|
||||
|
||||
private let appStore: AppStore
|
||||
private let commonMenuStore: HomeCommonMenuStore
|
||||
|
||||
init(
|
||||
appStore: AppStore = .shared,
|
||||
commonMenuStore: HomeCommonMenuStore = HomeCommonMenuStore()
|
||||
) {
|
||||
self.appStore = appStore
|
||||
self.commonMenuStore = commonMenuStore
|
||||
}
|
||||
|
||||
/// 加载全部功能并按常用配置拆分。
|
||||
func loadFunctions() {
|
||||
let permissions = appStore.permissionItems()
|
||||
let allMenus = HomeMenuCatalog.visibleMenus(from: permissions)
|
||||
let accountScope = appStore.accountCachePrefix
|
||||
let roleCode = appStore.roleCode
|
||||
let savedURIs = commonMenuStore.savedCommonURIs(accountScope: accountScope, roleCode: roleCode)
|
||||
let defaultURIs = HomeCommonMenuStore.defaultCommonURIs(from: permissions)
|
||||
let commonURIs = savedURIs.isEmpty ? defaultURIs : savedURIs
|
||||
|
||||
let split = HomeCommonMenuStore.splitMenus(from: allMenus, commonURIs: commonURIs)
|
||||
commonMenus = split.common
|
||||
moreMenus = split.more
|
||||
|
||||
if savedURIs.isEmpty, !split.common.isEmpty {
|
||||
commonMenuStore.saveCommonURIs(split.common.map(\.uri), accountScope: accountScope, roleCode: roleCode)
|
||||
}
|
||||
|
||||
notifyStateChange()
|
||||
}
|
||||
|
||||
/// 将菜单加入常用应用。
|
||||
func addToCommon(_ menu: HomeMenuItem) {
|
||||
guard !commonMenus.contains(where: { $0.uri == menu.uri }) else { return }
|
||||
commonMenus.append(menu)
|
||||
moreMenus.removeAll { $0.uri == menu.uri }
|
||||
persistCommonMenus()
|
||||
didCustomize = true
|
||||
notifyStateChange()
|
||||
}
|
||||
|
||||
/// 将菜单移出常用应用。
|
||||
func removeFromCommon(_ menu: HomeMenuItem) {
|
||||
guard commonMenus.contains(where: { $0.uri == menu.uri }) else { return }
|
||||
commonMenus.removeAll { $0.uri == menu.uri }
|
||||
if !moreMenus.contains(where: { $0.uri == menu.uri }) {
|
||||
moreMenus.append(menu)
|
||||
}
|
||||
persistCommonMenus()
|
||||
didCustomize = true
|
||||
notifyStateChange()
|
||||
}
|
||||
|
||||
private func persistCommonMenus() {
|
||||
commonMenuStore.saveCommonURIs(
|
||||
commonMenus.map(\.uri),
|
||||
accountScope: appStore.accountCachePrefix,
|
||||
roleCode: appStore.roleCode
|
||||
)
|
||||
}
|
||||
|
||||
private func notifyStateChange() {
|
||||
onStateChange?()
|
||||
}
|
||||
}
|
||||
@ -223,11 +223,20 @@ final class HomeViewModel {
|
||||
func rebuildCommonMenus() {
|
||||
let permissions = appStore.permissionItems()
|
||||
let allMenus = HomeMenuCatalog.visibleMenus(from: permissions)
|
||||
let accountScope = appStore.accountCachePrefix
|
||||
let roleCode = appStore.roleCode
|
||||
let savedURIs = commonMenuStore.savedCommonURIs(accountScope: accountScope, roleCode: roleCode)
|
||||
|
||||
if savedURIs.isEmpty, !permissions.isEmpty {
|
||||
let defaultURIs = HomeCommonMenuStore.defaultCommonURIs(from: permissions)
|
||||
commonMenuStore.saveCommonURIs(defaultURIs, accountScope: accountScope, roleCode: roleCode)
|
||||
}
|
||||
|
||||
commonMenus = commonMenuStore.commonMenus(
|
||||
from: allMenus,
|
||||
permissions: permissions,
|
||||
accountScope: appStore.accountCachePrefix,
|
||||
roleCode: appStore.roleCode
|
||||
accountScope: accountScope,
|
||||
roleCode: roleCode
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user