683 lines
17 KiB
Markdown
683 lines
17 KiB
Markdown
# 应用启动流程与接口数据存储梳理
|
||
|
||
本文按当前 iOS 工程代码梳理应用从冷启动到各首屏展示期间发生的初始化、接口调用顺序,以及接口数据和本地状态的存储方式。范围仅覆盖当前 iOS 实现,不额外补充 Android 中存在但 iOS 尚未接入的能力。
|
||
|
||
## 1. 冷启动立即发生
|
||
|
||
冷启动入口在 `AppDelegate.application(_:didFinishLaunchingWithOptions:)`。
|
||
|
||
1. 调用 `UmengBootstrap.configureIfNeeded()`。
|
||
- 友盟初始化受 `AppStore.shared.privacyAgreementAccepted` 控制。
|
||
- 未同意隐私协议时直接返回,不初始化 SDK。
|
||
2. 调用 `WeChatManager.shared.registerIfNeeded()`。
|
||
- 校验 Universal Link。
|
||
- 调用微信 SDK `WXApi.registerApp` 注册 AppID。
|
||
3. 若 `AppStore.shared.privacyAgreementAccepted == true` 且 `AppStore.shared.token` 非空,则调用 `AMapBootstrap.configureIfNeeded()`。
|
||
- 写入高德隐私合规状态。
|
||
- 设置 `AMapServices.shared().apiKey` 和 HTTPS。
|
||
4. 此阶段不直接调用任何业务后端接口。
|
||
|
||
随后系统进入 `SceneDelegate.scene(_:willConnectTo:options:)`。
|
||
|
||
1. 调用 `AppNavigationBarAppearance.applyGlobalAppearance()` 设置全局导航栏样式。
|
||
2. 创建 `UIWindow`。
|
||
3. 设置 `window.rootViewController = AppRouter.makeRootViewController()`。
|
||
4. `AppRouter` 通过 `AppStore.shared.isLoggedIn` 判断根页面:
|
||
- token 非空:进入 `MainTabBarController`。
|
||
- token 为空:进入 `UINavigationController(rootViewController: LoginViewController())`。
|
||
5. 注册全局通知:
|
||
- `sessionDidExpire`:清除登录态并切回登录页。
|
||
- `userDidLogout`:清除登录态并切回登录页。
|
||
- `userDidLogin`:切到主 Tab。
|
||
|
||
## 2. 网络依赖初始化
|
||
|
||
`NetworkServices.shared` 是全局网络依赖容器,不在 `AppDelegate` 中主动创建,而是在页面或 Tab 首次访问业务 API 时懒加载。
|
||
|
||
初始化顺序如下:
|
||
|
||
1. 创建 `APIClient(environment: .current)`。
|
||
2. 用同一个 `APIClient` 创建各业务 API:
|
||
- `AuthAPI`
|
||
- `ProfileAPI`
|
||
- `StatisticsAPI`
|
||
- `OrderAPI`
|
||
- `HomeAPI`
|
||
- 以及其他业务模块 API。
|
||
3. 创建 `OSSUploadService(configService: uploadAPI)`。
|
||
4. 调用 `client.bindAuthTokenProvider`,从 `AppStore.shared.token` 读取 token。
|
||
|
||
`APIClient` 的公共请求规则:
|
||
|
||
- `APIEnvironment.current`
|
||
- Debug:`https://api-test.zhifly.cn`
|
||
- Release:`https://api.zhifly.cn`
|
||
- 每个请求默认写入 Header:
|
||
- `Content-Type: application/json`
|
||
- `Accept: application/json`
|
||
- `X-APP-VERSION`
|
||
- `X-OS-TYPE: iOS`
|
||
- token 非空时写入 `token`
|
||
- 响应通过 `APIEnvelope` 解包。
|
||
- 成功业务码:`100000`
|
||
- 非成功业务码抛出 `APIError.serverCode`
|
||
- 认证失效时广播 `sessionDidExpire`,由 `SceneDelegate` 清会话并回登录页。
|
||
|
||
## 3. 未登录启动与登录流程
|
||
|
||
未登录时根页面为登录页。
|
||
|
||
### 3.1 登录页展示前
|
||
|
||
`LoginViewController.setupUI` 会调用 `viewModel.applyStoredPreferences()`,从 `AppStore` 读取:
|
||
|
||
- `lastLoginUsername`
|
||
- `privacyAgreementAccepted`
|
||
|
||
这一步只恢复本地表单状态,不调用后端接口。
|
||
|
||
### 3.2 登录页出现后
|
||
|
||
`LoginViewController.viewDidAppear` 调用:
|
||
|
||
```text
|
||
GET /api/app/config
|
||
```
|
||
|
||
调用链:
|
||
|
||
```text
|
||
LoginViewController.viewDidAppear
|
||
-> LoginViewModel.loadAppConfig(authAPI:)
|
||
-> AuthAPI.getAppConfig()
|
||
```
|
||
|
||
用途:
|
||
|
||
- 读取 App 配置。
|
||
- 当前只使用 `enableRegister` 控制验证码登录/注册入口显隐。
|
||
- 配置加载失败会静默忽略,不影响密码登录。
|
||
- 该结果只保存在 `LoginViewModel.enableRegister` 内存态,不写入 `AppStore`。
|
||
|
||
### 3.3 点击登录后的接口顺序
|
||
|
||
用户点击登录按钮后,先做本地校验:
|
||
|
||
- 手机号必须是 11 位且以 `1` 开头。
|
||
- 密码不能为空。
|
||
- 必须勾选隐私协议。
|
||
|
||
校验通过后发起登录:
|
||
|
||
```text
|
||
POST /api/app/v9/login
|
||
```
|
||
|
||
调用链:
|
||
|
||
```text
|
||
LoginViewController.performLogin()
|
||
-> LoginViewModel.login(authAPI:)
|
||
-> AuthAPI.login(username:password:)
|
||
```
|
||
|
||
返回数据包含临时 token 和可选账号列表。随后根据账号数量分流:
|
||
|
||
- 只有一个账号:立即调用 `set-user` 换正式 token。
|
||
- 多个账号:展示账号选择弹窗,用户确认后再调用 `set-user`。
|
||
|
||
正式账号选择接口:
|
||
|
||
```text
|
||
POST /api/app/v9/set-user
|
||
```
|
||
|
||
调用链:
|
||
|
||
```text
|
||
单账号:
|
||
LoginViewModel.resolveLoginResponse(...)
|
||
-> AuthAPI.setUser(..., tokenOverride: 临时 token)
|
||
|
||
多账号:
|
||
LoginViewController.selectAccount(_:)
|
||
-> LoginViewModel.selectAccount(_:authAPI:)
|
||
-> AuthAPI.setUser(..., tokenOverride: 临时 token)
|
||
```
|
||
|
||
### 3.4 登录完成后的存储与跳转
|
||
|
||
登录完成调用:
|
||
|
||
```text
|
||
AuthSessionHelper.completeLogin(...)
|
||
```
|
||
|
||
写入 `AppStore` 的内容:
|
||
|
||
- `token`
|
||
- `lastLoginUsername`
|
||
- `privacyAgreementAccepted`
|
||
- `userId`
|
||
- `userName`
|
||
- `realName`
|
||
- `avatar`
|
||
- `phone`
|
||
- `accountType`
|
||
- `accountDisplayName`
|
||
- `roleCode`
|
||
- `roleName`
|
||
- `currentScenicId`
|
||
- `currentScenicName`
|
||
- `currentStoreId`
|
||
|
||
其中账号上下文来自 `AccountSwitchAccount`、`V9ScenicUser` 或 `V9StoreUser`。
|
||
|
||
如果用户已同意隐私协议,还会再次触发:
|
||
|
||
- `AMapBootstrap.configureIfNeeded()`
|
||
- `UmengBootstrap.configureIfNeeded()`
|
||
|
||
最后发送:
|
||
|
||
```text
|
||
NotificationName.userDidLogin
|
||
```
|
||
|
||
`SceneDelegate.handleUserDidLogin()` 收到通知后调用:
|
||
|
||
```text
|
||
AppRouter.setRoot(.mainTab, on: window)
|
||
```
|
||
|
||
根页面切换到主 Tab。
|
||
|
||
## 4. 已登录启动与默认首页首次展示
|
||
|
||
已登录时,`AppRouter.makeRootViewController()` 创建 `MainTabBarController`。
|
||
|
||
### 4.1 主 Tab 创建
|
||
|
||
`MainTabBarController.viewDidLoad` 顺序:
|
||
|
||
1. 设置 `delegate`。
|
||
2. 配置 TabBar 外观。
|
||
3. 调用 `configureTabs()` 创建五个 Tab slot:
|
||
- 首页:`HomeViewController`
|
||
- 订单:`OrdersViewController`
|
||
- 中间扫码占位页
|
||
- 数据:`StatisticsViewController`
|
||
- 我的:`ProfileViewController`
|
||
4. 绑定订单角标 ViewModel。
|
||
5. 绑定扫码处理器。
|
||
6. 调用 `badgeViewModel.refreshPendingWriteOffCount()`。
|
||
|
||
注意:`MainTabBadgeViewModel.refreshPendingWriteOffCount()` 当前仅执行:
|
||
|
||
```text
|
||
pendingWriteOffCount = nil
|
||
```
|
||
|
||
代码注释标明“接口未接入前保持为空”,因此这里不记录为真实后端接口调用。
|
||
|
||
### 4.2 默认首页首次出现
|
||
|
||
默认选中首页。`HomeViewController.viewDidAppear` 首次出现时调用:
|
||
|
||
```text
|
||
initializeHome()
|
||
```
|
||
|
||
调用顺序:
|
||
|
||
1. 展示全局 loading。
|
||
2. `HomeViewModel.initialize(api:)`
|
||
3. 隐藏 loading。
|
||
4. 刷新首页 UI。
|
||
5. 延迟评估弹窗。
|
||
|
||
`HomeViewModel.initialize(api:)` 内部顺序:
|
||
|
||
1. `locationStateStore.restoreStateIfNeeded()`
|
||
- 从 `AppStore` 恢复在线状态、上次位置上报时间、提醒分钟数。
|
||
- 如果上次在线状态已过期,会清除在线状态和上次上报时间。
|
||
- 不调用后端接口。
|
||
2. `refreshLocalDisplayState()`
|
||
- 从 `AppStore` 读取当前景区、当前角色。
|
||
- 无有效景区时清空 `currentScenicId/currentScenicName`。
|
||
3. 强制调用 `loadPermissions(api:force: true)`。
|
||
|
||
权限接口:
|
||
|
||
```text
|
||
GET /api/yf-handset-app/role-permission
|
||
```
|
||
|
||
调用链:
|
||
|
||
```text
|
||
HomeViewModel.initialize(api:)
|
||
-> HomeViewModel.loadPermissions(api:force: true)
|
||
-> HomeAPI.rolePermissions()
|
||
```
|
||
|
||
权限返回后的存储:
|
||
|
||
- 完整角色权限列表:`AppStore.saveRolePermissionList(_:)`
|
||
- 当前匹配角色的景区列表:`AppStore.saveRoleScenicList(_:)`
|
||
- 当前匹配角色的扁平权限:`AppStore.savePermissionItems(_:)`
|
||
- 匹配角色名:必要时写入 `AppStore.roleName`
|
||
|
||
这些权限数据都按账号作用域 key 写入 `UserDefaults`,值为 JSON Data。
|
||
|
||
随后首页重建常用应用:
|
||
|
||
- 从 `AppStore.permissionItems()` 读取权限。
|
||
- `HomeMenuCatalog.visibleMenus(from:)` 生成可见菜单。
|
||
- `HomeCommonMenuStore` 读取或写入常用应用 URI。
|
||
- 常用应用 key 由 `accountScope + roleCode` 组成。
|
||
|
||
### 4.3 首页门店接口
|
||
|
||
权限加载完成后会调用:
|
||
|
||
```text
|
||
HomeViewModel.loadStoreListIfNeeded(api:)
|
||
```
|
||
|
||
只有同时满足以下条件才会请求门店:
|
||
|
||
- 当前角色为 `storeAdmin`
|
||
- `AppStore.currentScenicId > 0`
|
||
|
||
接口:
|
||
|
||
```text
|
||
GET /api/app/store/all
|
||
```
|
||
|
||
调用链:
|
||
|
||
```text
|
||
HomeViewModel.loadStoreListIfNeeded(api:)
|
||
-> HomeAPI.storeList()
|
||
```
|
||
|
||
返回后的处理:
|
||
|
||
- 根据 `currentScenicId` 和已保存的 `currentStoreId` 匹配当前门店。
|
||
- 匹配结果保存在 `HomeViewModel.storeItem`。
|
||
- 若匹配到门店,写入 `AppStore.currentStoreId`。
|
||
- 门店列表本身不持久化。
|
||
|
||
### 4.4 首页弹窗评估与位置详情接口
|
||
|
||
首页 UI 刷新后调用:
|
||
|
||
```text
|
||
evaluateDialogsWithDelay()
|
||
-> HomeViewModel.evaluateDialogs(api:)
|
||
```
|
||
|
||
弹窗优先级:
|
||
|
||
1. 权限弹窗。
|
||
2. 景区弹窗。
|
||
3. 位置超时弹窗。
|
||
|
||
如果不需要权限弹窗、不需要景区弹窗、不是简化顶部角色,并且本地设置了位置提醒分钟数,则可能调用位置详情接口:
|
||
|
||
```text
|
||
GET /api/yf-handset-app/photog/loacation/detail?staff_id=...
|
||
```
|
||
|
||
调用链:
|
||
|
||
```text
|
||
HomeViewModel.evaluateDialogs(api:)
|
||
-> HomeViewModel.checkLocationTimeout(api:)
|
||
-> HomeAPI.locationDetail(staffId:)
|
||
```
|
||
|
||
返回后的处理:
|
||
|
||
- 只用于判断是否展示位置超时提醒。
|
||
- 结果不写入 `AppStore`。
|
||
- 弹窗状态保存在 `HomeViewModel.showLocationTimeoutDialog` 等内存属性中。
|
||
|
||
## 5. 其他 Tab 首次展示时的接口
|
||
|
||
其他 Tab 的根控制器会在 `MainTabBarController.configureTabs()` 时创建,但各自的数据接口通常在首次展示时才调用。
|
||
|
||
### 5.1 订单 Tab
|
||
|
||
`OrdersViewController.viewDidAppear` 首次出现时调用:
|
||
|
||
```text
|
||
initializeList()
|
||
```
|
||
|
||
按当前角色选择接口。
|
||
|
||
摄影师:
|
||
|
||
```text
|
||
GET /api/yf-handset-app/photog/order/listv2
|
||
```
|
||
|
||
景区管理员:
|
||
|
||
```text
|
||
GET /api/app/scenic-admin/order/list
|
||
```
|
||
|
||
门店管理员:
|
||
|
||
```text
|
||
GET /api/app/store/order/list
|
||
```
|
||
|
||
调用链:
|
||
|
||
```text
|
||
OrdersViewController.initializeList()
|
||
-> OrderListViewModel.refreshOrderList(api:)
|
||
-> OrderAPI.photographerOrderList(...) 或 OrderAPI.scenicAdminOrderList(...)
|
||
|
||
或
|
||
|
||
OrdersViewController.initializeList()
|
||
-> DepositOrderListViewModel.refreshOrderList(api:)
|
||
-> OrderAPI.storeOrderList(...)
|
||
```
|
||
|
||
数据存储:
|
||
|
||
- 摄影师/景区管理员订单列表保存在 `OrderListViewModel.orderList`。
|
||
- 门店管理员订单列表保存在 `DepositOrderListViewModel.orderList`。
|
||
- 分页状态、筛选状态、搜索状态都保存在对应 ViewModel 内存属性中。
|
||
- 首屏订单列表不写入 `AppStore`。
|
||
|
||
### 5.2 数据 Tab
|
||
|
||
`StatisticsViewController.viewDidAppear` 首次出现时调用:
|
||
|
||
```text
|
||
initializeStatistics()
|
||
-> StatisticsViewModel.initStatistics(api:)
|
||
```
|
||
|
||
内部顺序:
|
||
|
||
1. 加载汇总数据。
|
||
2. 设置日明细日期范围为今日并刷新列表。
|
||
|
||
摄影师汇总:
|
||
|
||
```text
|
||
GET /api/yf-handset-app/photog/analyse/user
|
||
```
|
||
|
||
摄影师日明细:
|
||
|
||
```text
|
||
GET /api/yf-handset-app/photog/analyse/user/daily
|
||
```
|
||
|
||
景区管理员汇总:
|
||
|
||
```text
|
||
GET /api/app/scenic-admin/analyse
|
||
```
|
||
|
||
景区管理员日明细:
|
||
|
||
```text
|
||
GET /api/app/scenic-admin/analyse/daily
|
||
```
|
||
|
||
门店管理员汇总:
|
||
|
||
```text
|
||
GET /api/app/store/analyse
|
||
```
|
||
|
||
门店管理员日明细:
|
||
|
||
```text
|
||
GET /api/app/store/analyse/daily
|
||
```
|
||
|
||
数据存储:
|
||
|
||
- 汇总数据保存在 `StatisticsViewModel.statistics`。
|
||
- 日明细列表保存在 `StatisticsViewModel.statisticsList`。
|
||
- 当前周期、日期范围、分页状态保存在 `StatisticsViewModel` 内存属性中。
|
||
- 统计数据不写入 `AppStore`。
|
||
|
||
### 5.3 我的 Tab
|
||
|
||
`ProfileViewController.viewWillAppear` 每次出现都会调用:
|
||
|
||
```text
|
||
reloadProfile(showGlobalLoading:)
|
||
-> ProfileViewModel.reload(api:)
|
||
```
|
||
|
||
第一步固定调用用户资料接口:
|
||
|
||
```text
|
||
GET /api/yf-handset-app/userinfo
|
||
```
|
||
|
||
调用链:
|
||
|
||
```text
|
||
ProfileViewModel.reload(api:)
|
||
-> ProfileAPI.userInfo()
|
||
```
|
||
|
||
返回后的处理:
|
||
|
||
- 保存在 `ProfileViewModel.userInfo`。
|
||
- 调用 `AppStore.applyUserInfo(_:)` 回写展示字段:
|
||
- `userName`
|
||
- `realName`
|
||
- `avatar`
|
||
- `phone`
|
||
- `roleName`,仅在本地为空时由 `applyUserInfo` 写入;随后 `ProfileViewModel.reload` 也会在接口 `roleName` 非空时写入。
|
||
|
||
如果当前为摄影师角色,则并发调用:
|
||
|
||
```text
|
||
GET /api/yf-handset-app/photog/real-name/info
|
||
GET /api/yf-handset-app/photog/wallet/bank-card/info
|
||
```
|
||
|
||
调用链:
|
||
|
||
```text
|
||
async let realName = api.realNameInfo()
|
||
async let bankCard = api.bankCardInfo()
|
||
```
|
||
|
||
返回后的处理:
|
||
|
||
- 实名信息保存在 `ProfileViewModel.realNameInfo`。
|
||
- 银行卡信息保存在 `ProfileViewModel.bankCardInfo`。
|
||
- 这两个结果不写入 `AppStore`。
|
||
|
||
## 6. 数据存储总览
|
||
|
||
### 6.1 AppStore / UserDefaults
|
||
|
||
`AppStore` 是本地会话和业务快照的统一入口,底层使用 `UserDefaults`。
|
||
|
||
非账号作用域的主要 key:
|
||
|
||
- `key_in_token`
|
||
- `key_last_login_username`
|
||
- `key_privacy_agreement_accepted`
|
||
- `key_in_user_id`
|
||
- `key_in_user_name`
|
||
- `key_in_real_name`
|
||
- `key_in_avatar`
|
||
- `key_in_phone`
|
||
- `key_in_account_type`
|
||
- `key_in_account_display_name`
|
||
- `key_in_role_code`
|
||
- `key_in_role_name`
|
||
- `key_in_current_scenic_id`
|
||
- `key_in_current_scenic_name`
|
||
- `key_in_current_store_id`
|
||
|
||
账号作用域由 `accountCachePrefix` 生成:
|
||
|
||
```text
|
||
userId_accountType
|
||
```
|
||
|
||
如果没有 userId,则使用 `guest`。账号作用域 key 用于存储:
|
||
|
||
- 旧版角色 ID:`key_in_role_id`
|
||
- 完整 role-permission 列表:`key_role_permission_list`
|
||
- 当前角色扁平权限:`key_in_permission`
|
||
- 当前角色可选景区列表:`key_current_role_scenic_list`
|
||
- 在线状态:`key_online_status`
|
||
- 上次位置上报时间:`key_last_location_report_time`
|
||
- 位置提醒分钟数:`key_location_reminder_minutes`
|
||
- 收款到账语音播报开关:`key_is_open_receive_voice`
|
||
- 排队叫号相关本地设置。
|
||
|
||
权限和景区列表以 JSON Data 写入 `UserDefaults`:
|
||
|
||
- `saveRolePermissionList(_:)`
|
||
- `savePermissionItems(_:)`
|
||
- `saveRoleScenicList(_:)`
|
||
|
||
### 6.2 HomeCommonMenuStore
|
||
|
||
首页常用应用由 `HomeCommonMenuStore` 单独管理,底层也是 `UserDefaults`。
|
||
|
||
存储 key:
|
||
|
||
```text
|
||
{accountScope}_role_{roleCode}_common_uris
|
||
```
|
||
|
||
值为 URI 字符串数组。
|
||
|
||
首次有权限但没有常用应用记录时,会从权限列表生成最多 4 个默认常用入口并写入本地。
|
||
|
||
### 6.3 HomeLocationStateStore
|
||
|
||
`HomeLocationStateStore` 负责首页在线状态和 2 小时位置上报倒计时。
|
||
|
||
持久化到 `AppStore` 的字段:
|
||
|
||
- `onlineStatus`
|
||
- `lastLocationReportTime`
|
||
- `locationReminderMinutes`
|
||
|
||
内存态字段:
|
||
|
||
- `isOnline`
|
||
- `elapsedSeconds`
|
||
- `nextReportCountdownSeconds`
|
||
- `reminderMinutes`
|
||
- 倒计时 `Task`
|
||
|
||
启动恢复逻辑:
|
||
|
||
- 如果本地 `onlineStatus == false`,停止倒计时。
|
||
- 如果没有 `lastLocationReportTime`,清除在线状态。
|
||
- 如果距离上次上报已超过 2 小时,清除在线状态和上次上报时间。
|
||
- 否则恢复倒计时。
|
||
|
||
### 6.4 ViewModel 内存态
|
||
|
||
多数页面接口结果只保存在 ViewModel 内存属性中,不持久化。
|
||
|
||
典型示例:
|
||
|
||
- 登录配置:`LoginViewModel.enableRegister`
|
||
- 首页门店卡片:`HomeViewModel.storeItem`
|
||
- 首页弹窗状态:`HomeViewModel.showPermissionDialog`、`showScenicDialog`、`showLocationTimeoutDialog`
|
||
- 订单列表:`OrderListViewModel.orderList`、`DepositOrderListViewModel.orderList`
|
||
- 数据统计:`StatisticsViewModel.statistics`、`statisticsList`
|
||
- 我的页面实名/银行卡状态:`ProfileViewModel.realNameInfo`、`bankCardInfo`
|
||
|
||
例外是明确调用 `AppStore` 的数据:
|
||
|
||
- 登录 token 与账号上下文。
|
||
- 用户资料展示字段。
|
||
- 权限、景区、角色相关快照。
|
||
- 门店当前 ID。
|
||
- 位置在线状态与倒计时锚点。
|
||
|
||
## 7. 启动接口顺序速查
|
||
|
||
### 7.1 未登录冷启动
|
||
|
||
```text
|
||
AppDelegate.didFinishLaunching
|
||
-> 友盟/微信/高德 SDK 条件初始化
|
||
-> SceneDelegate.willConnect
|
||
-> AppRouter.makeRootViewController()
|
||
-> LoginViewController.setupUI
|
||
-> LoginViewController.viewDidAppear
|
||
-> GET /api/app/config
|
||
```
|
||
|
||
点击登录后:
|
||
|
||
```text
|
||
POST /api/app/v9/login
|
||
-> POST /api/app/v9/set-user
|
||
-> AppStore 写入登录态和账号上下文
|
||
-> userDidLogin
|
||
-> AppRouter.setRoot(.mainTab)
|
||
```
|
||
|
||
### 7.2 已登录冷启动默认首页
|
||
|
||
```text
|
||
AppDelegate.didFinishLaunching
|
||
-> 友盟/微信/高德 SDK 条件初始化
|
||
-> SceneDelegate.willConnect
|
||
-> AppRouter.makeRootViewController()
|
||
-> MainTabBarController.viewDidLoad
|
||
-> HomeViewController.viewDidAppear
|
||
-> HomeLocationStateStore.restoreStateIfNeeded()
|
||
-> GET /api/yf-handset-app/role-permission
|
||
-> 条件满足时 GET /api/app/store/all
|
||
-> 条件满足时 GET /api/yf-handset-app/photog/loacation/detail?staff_id=...
|
||
```
|
||
|
||
### 7.3 用户首次切到订单 Tab
|
||
|
||
```text
|
||
OrdersViewController.viewDidAppear
|
||
-> 摄影师 GET /api/yf-handset-app/photog/order/listv2
|
||
或 景区管理员 GET /api/app/scenic-admin/order/list
|
||
或 门店管理员 GET /api/app/store/order/list
|
||
```
|
||
|
||
### 7.4 用户首次切到数据 Tab
|
||
|
||
```text
|
||
StatisticsViewController.viewDidAppear
|
||
-> 按角色 GET 汇总接口
|
||
-> 按角色 GET 日明细接口
|
||
```
|
||
|
||
### 7.5 用户切到我的 Tab
|
||
|
||
```text
|
||
ProfileViewController.viewWillAppear
|
||
-> GET /api/yf-handset-app/userinfo
|
||
-> 摄影师角色并发:
|
||
GET /api/yf-handset-app/photog/real-name/info
|
||
GET /api/yf-handset-app/photog/wallet/bank-card/info
|
||
```
|