模块化 AppStore 并完善素材管理与个人空间设置。

将会话、权限、位置、收款与排队存储拆分为独立模块,同步更新各 ViewModel 与单元测试,并补充素材管理 UI 与个人空间设置交互。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-13 11:01:08 +08:00
parent ceca780ab3
commit 005349f8e6
128 changed files with 2953 additions and 1123 deletions

View File

@ -94,7 +94,7 @@ final class HomeViewModel {
/// role-permission
func loadPermissions(api: HomeAPI, force: Bool = false) async {
if !force, !appStore.permissionItems().isEmpty {
if !force, !appStore.permissions.permissionItems().isEmpty {
rebuildCommonMenus()
await loadStoreListIfNeeded(api: api)
notifyStateChange()
@ -104,21 +104,21 @@ final class HomeViewModel {
do {
let rolePermissionList = try await api.rolePermissions()
if rolePermissionList.isEmpty {
appStore.savePermissionItems([])
appStore.permissions.savePermissionItems([])
showPermissionDialog = true
rebuildCommonMenus()
notifyStateChange()
return
}
appStore.saveRolePermissionList(rolePermissionList)
let matched = appStore.matchRolePermissionItem(in: rolePermissionList) ?? rolePermissionList[0]
appStore.permissions.saveRolePermissionList(rolePermissionList)
let matched = appStore.permissions.matchRolePermissionItem(in: rolePermissionList) ?? rolePermissionList[0]
if !matched.role.name.isEmpty {
appStore.roleName = matched.role.name
appStore.session.roleName = matched.role.name
}
appStore.saveRoleScenicList(matched.scenic)
appStore.permissions.saveRoleScenicList(matched.scenic)
let permissions = matched.role.permission.map(HomePermissionItem.init)
appStore.savePermissionItems(permissions)
appStore.permissions.savePermissionItems(permissions)
showPermissionDialog = false
refreshLocalDisplayState()
rebuildCommonMenus()
@ -127,7 +127,7 @@ final class HomeViewModel {
} catch is CancellationError {
return
} catch {
appStore.savePermissionItems([])
appStore.permissions.savePermissionItems([])
showPermissionDialog = true
rebuildCommonMenus()
onShowMessage?(error.localizedDescription)
@ -142,7 +142,7 @@ final class HomeViewModel {
notifyStateChange()
return
}
guard appStore.currentScenicId > 0 else {
guard appStore.session.currentScenicId > 0 else {
storeItem = nil
notifyStateChange()
return
@ -150,13 +150,13 @@ final class HomeViewModel {
do {
let response = try await api.storeList()
let scenicId = appStore.currentScenicId
let savedStoreId = appStore.currentStoreId
let scenicId = appStore.session.currentScenicId
let savedStoreId = appStore.session.currentStoreId
let savedMatch = savedStoreId > 0 ? response.list.first { $0.id == savedStoreId } : nil
let matched = savedMatch ?? response.list.first { $0.scenicId == scenicId }
storeItem = matched
if let matched {
appStore.currentStoreId = matched.id
appStore.session.currentStoreId = matched.id
}
notifyStateChange()
} catch is CancellationError {
@ -173,7 +173,7 @@ final class HomeViewModel {
showScenicDialog = false
return
}
let hasScenic = appStore.currentScenicId > 0
let hasScenic = appStore.session.currentScenicId > 0
showScenicDialog = !hasScenic
if showScenicDialog || dismissedLocationTimeoutDialog {
showLocationTimeoutDialog = false
@ -196,7 +196,7 @@ final class HomeViewModel {
notifyStateChange()
return
}
let staffId = appStore.userId.trimmingCharacters(in: .whitespacesAndNewlines)
let staffId = appStore.session.userId.trimmingCharacters(in: .whitespacesAndNewlines)
guard !staffId.isEmpty else {
showLocationTimeoutDialog = true
notifyStateChange()
@ -225,25 +225,25 @@ final class HomeViewModel {
/// Android `initCurrentScenicName`
func refreshLocalDisplayState() {
let scenicId = appStore.currentScenicId
let scenicName = appStore.currentScenicName.trimmingCharacters(in: .whitespacesAndNewlines)
let scenicId = appStore.session.currentScenicId
let scenicName = appStore.session.currentScenicName.trimmingCharacters(in: .whitespacesAndNewlines)
if scenicId > 0, !scenicName.isEmpty {
currentScenicName = scenicName
} else {
currentScenicName = ""
appStore.currentScenicId = 0
appStore.currentScenicName = ""
appStore.session.currentScenicId = 0
appStore.session.currentScenicName = ""
}
currentAppRole = appStore.currentAppRole
currentAppRole = appStore.session.currentAppRole
isMinimalTopRole = currentAppRole?.usesHomeMinimalTopLayout ?? false
}
///
func rebuildCommonMenus() {
let permissions = appStore.permissionItems()
let permissions = appStore.permissions.permissionItems()
let allMenus = HomeMenuCatalog.visibleMenus(from: permissions)
let accountScope = appStore.accountCachePrefix
let roleCode = appStore.roleCode
let accountScope = appStore.session.accountCachePrefix
let roleCode = appStore.session.roleCode
let savedURIs = commonMenuStore.savedCommonURIs(accountScope: accountScope, roleCode: roleCode)
if savedURIs.isEmpty, !permissions.isEmpty {