Files
suixinkan_ios_new/suixinkan/Features/Home/AllFunctions.md

7.2 KiB
Raw Blame History

「全部功能」页业务逻辑

Android 工程对应文档:zhiflyfollow/docs/home/AllFunctions.md

模块职责

「全部功能」页(HomeMoreFunctionsView)展示当前角色可用的功能入口,分为两个分区:

  • 常用应用:已加入首页常用的入口,支持移除(-
  • 更多功能:其余可用入口,支持添加为常用(+

常用应用的增删会同步写入本地持久化,并与首页「常用应用」网格共用同一套配置(HomeCommonMenuStore)。

本页数据构建规则与 Android AllFunctionsViewModel 对齐,复用首页 HomeViewModel 的 flatten + preferredOrder 逻辑。


涉及文件

文件 职责
Views/HomeMoreFunctionsView.swift 页面 UI、增删常用、触发重建
Services/HomeAllFunctionsBuilder.swift 菜单列表构建与常用/更多拆分
Services/HomeCommonMenuStore.swift 常用 URI 持久化与默认生成
Services/HomeAllFunctionsDiagnostics.swift Debug 诊断日志
App/State/PermissionContext.swift 提供当前角色顶层权限
Routing/HomeMenuRouter.swift 点击入口后的路由解析

数据流

flowchart TD
    API[role-permission 接口] --> PC[PermissionContext]
    PC --> TLP[topLevelPermissions 顶层节点]
    TLP --> BUILDER[HomeAllFunctionsBuilder.build]
    CMS[HomeCommonMenuStore.load] --> COMMON[commonURIs]
    COMMON --> BUILDER
    BUILDER --> ALL[allFunctions]
    BUILDER --> CF[commonFunctions]
    BUILDER --> MF[moreFunctions]
    CF --> UI1[常用应用网格]
    MF --> UI2[更多功能网格]

触发重建的时机

HomeMoreFunctionsView.rebuildMenus() 在以下情况执行:

  1. 页面首次进入(.task
  2. 当前角色 roleCode 变化
  3. rolePermissions 数量变化

用户点击 + / - 时只更新 commonUris 并调用 applySnapshot,不重新走持久化读取(除非权限上下文同时变化)。


第一步:读取顶层权限

数据来源:PermissionContext.topLevelPermissions(for: roleCode)

  • 仅取当前匹配角色的 role.permission 顶层数组
  • 递归展开 children 子节点
  • 顺序与 API 返回一致,不做本地重排
  • 过滤掉 URI 为空的节点

对应 AndroidappStore.getPermission() 中保存的顶层权限列表MMKV 快照)。


第二步:白名单过滤(可用入口)

HomeAllFunctionsBuilder.allMenuItems(from:) 执行:

allFunctions = 顶层权限
    .按 API 顺序遍历
    .保留 uri ∈ HomeCommonMenuStore.androidHomeMenuURIs 的项
    .映射为 HomeMenuItem

androidHomeMenuURIs 与 Android Constants.menuList 登记 URI 一致。已登记且会出现在「全部功能」页的 URI 包括 location_reportphotographer_report(举报摄影师)、walletmessage_center 等。

以下典型 URI 不会出现在「全部功能」页,即使接口返回了顶层权限:

  • basic_infophotographer_statsphotographer_orders
  • location_infoscan_qrpayment_qr
  • album_listmaterial_upload 等未登记 URI

子权限 URI 也不会出现(未 flatten


第三步:菜单项字段映射

每个保留的 PermissionItem 转为 HomeMenuItem

字段 规则
uri 权限节点原始 URI精确字符串
title API name 非空时用 name;否则 HomeMenuRouter.title(for:);再经 HomeMenuRouter.displayTitle 统一部分同义入口文案
iconSrc API icon_src;为空时 UI 层用 HomeIconCatalog SF Symbol 兜底

Android 端标题/icon 来自本地 Constants.menuList drawableiOS 优先接口字段 + 本地图标兜底。


第四步:读取常用 URI

HomeCommonMenuStore.load 提供 commonUris,规则详见 Home.md「常用应用」章节,核心要点:

  • 存储 keyhome.common.menu.uris.account.{accountScope}.role.{roleCode}(无 accountScope 时用 home.common.menu.uris.role.{roleCode}
  • 首次无 saved按顶层前 4 个 URI 与 menuList 求交生成默认,并落库
  • 已有 saved精确 URI 匹配当前可用顶层权限;全部失效时返回空,不回退默认
  • 增删常用:精确 URI 匹配(不使用 menuAliasKey

第五步:拆分为常用 / 更多

HomeAllFunctionsBuilder.build(topLevelPermissions:commonURIs:)

commonSet = Set(commonURIs)

commonFunctions = allFunctions.filter { commonSet.contains($0.uri) }
moreFunctions   = allFunctions.filter { !commonSet.contains($0.uri) }

要点:

  • 匹配方式:精确 URI,不做别名归一
  • 常用区顺序:跟随 allFunctions 列表顺序API 顺序 ∩ 白名单后的顺序),不是 commonUris 数组的存储顺序
  • 更多区顺序:同样跟随 allFunctions 剩余项顺序

与 Android 一致:

val common = functions.filter { it.uri in commonUris }
val more   = functions.filter { it.uri !in commonUris }

展示层

布局

  • 两节标题:「常用应用」「更多功能」
  • 每节 3 列 LazyVGrid,卡片高度 112pt
  • 卡片右上角:常用 显示红色 -更多 显示蓝色 +

点击行为

  • 点击卡片主体:HomeMenuRouter.resolve(uri:title:) 解析路由
    • Tab 切换、订单 Tab、Home 子路由、占位页等
    • more_functions URI 在页内忽略(防循环)
  • 点击 -HomeCommonMenuStore.removeapplySnapshot
  • 点击 +HomeCommonMenuStore.add(校验 URI 在顶层可用白名单内)→ applySnapshot

与首页的关系

维度 首页常用应用网格 全部功能页
数据源 HomeCommonMenuStore + HomeViewModel(展示标题/icon HomeAllFunctionsBuilder
列表范围 仅 common URIs + 「更多功能」入口 全部可用入口分 common / more
排序 common 按 store 顺序映射 common/more 均按 allFunctions API 顺序
持久化 共用 HomeCommonMenuStore 共用 HomeCommonMenuStore

与 HomeViewModel 的区别

HomeViewModel(首页等) HomeAllFunctionsBuilder(全部功能)
权限范围 递归 flatten 整棵权限树 仅顶层
白名单 androidHomeMenuURIs
排序 preferredOrder 硬编码权重 API 顶层顺序
去重 menuAliasKey 别名去重 无(顶层 URI 精确保留)

「全部功能」页不应调用 HomeViewModel.buildMenus()


诊断日志

Debug 构建下可用 Xcode Console 过滤 HomeAllFunctions

step 含义
allFunctions 白名单过滤后的完整 URI 列表
commonFunctions 常用分区 URI
moreFunctions 更多分区 URI

常用应用持久化链路仍使用 HomeCommonMenu tagHomeCommonMenuStore / 首页 HomeView 日志。


测试

单元测试:suixinkanTests/HomeAllFunctionsBuilderTests.swift

覆盖场景:

  • menuList 白名单过滤
  • API 顶层顺序保留(非 preferredOrder
  • 不展开子权限
  • 精确 URI 拆分 common / more
  • 常用区顺序跟随 allFunctions
  • 与 Android 样例账号27 顶层 → 21 可用 → 3 常用 + 18 更多)一致