# HarmonyOS NEXT 客户端 · 架构设计文档 > 项目:`harmony-client`(ArkTS + ArkUI,SDK 6.0.2 / API 22,仅 phone) > 业务形态:对接自有后端的通用业务客户端(HTTP + 鉴权 + CRUD) --- ## 1. 背景与目标 本工程从 DevEco 空脚手架起步,目标是建立一套**可持续演进、可测试、低耦合**的客户端架构骨架,为后续业务开发打底。设计依据来自一轮 deep-research 调研(交叉验证华为官方文档与社区实践,9 条结论全部通过对抗式验证)。 核心决策: | 决策点 | 选择 | 理由 | |---|---|---| | 工程结构 | 官方三层 commons / features / products | 单向依赖、官方白皮书推荐 | | 模块化 | **单 HAP + 多 HAR** | HAR 编译期打包、可裁剪;HSP 仅按需加载 | | 代码分层 | **MVVM + 独立 data 层** | 官方指南 + 网络/数据解耦 | | 状态管理 | **全量 StateManagement V2** | API 22 下 V2 能力完整,字段级精准刷新 | --- ## 2. 模块划分与依赖 ``` harmony-client/ ├── entry/ HAP 应用壳 + 业务功能(唯一入口,EntryAbility) ├── common/ HAR 基础设施层(网络 / 日志 / 状态 / 工具,无业务、无 UI 组件) └── uikit/ HAR 通用 UI 组件库 + 主题(无业务、无网络依赖) ``` 依赖方向严格单向,禁止反向/循环: ``` entry ──依赖──▶ common entry ──依赖──▶ uikit common / uikit 各自独立,互不依赖 ``` - **common**:`HttpClient`、鉴权拦截器、统一错误模型、`Logger`、`SessionStore`(PersistenceV2 持久化)、工具函数。 - **uikit**:主题 token(`AppColor/AppSpacing/AppFontSize`)、通用组件(`AppButton/LoadingView/EmptyView`)。 - **entry**:应用壳装配、路由、DI 容器、MVVM 分层业务代码。 --- ## 3. 分层与目录结构(entry 内) 采用官方 MVVM 指南的**层优先**结构,叠加独立 `data/` 层与横切的 `router/`、`di/`: ``` entry/src/main/ets/ ├── entryability/ │ └── EntryAbility.ets # 生命周期装配:Logger / ServiceLocator / SessionStore ├── router/ │ ├── RouteMap.ets # 路由名常量 + name→页面 分发 │ └── AppRouter.ets # Navigation 导航封装(push/replace/pop/...) ├── di/ │ └── ServiceLocator.ets # 轻量服务定位器(ArkTS 无反射,手动注册/解析) ├── model/ # 领域模型:@ObservedV2 + @Trace 实体 ├── data/ │ ├── api/ # DTO + 请求服务(调 common 的 HttpClient) │ └── repository/ # 数据仓库契约(抽象类)+ 实现 ├── viewmodel/ # @ObservedV2 状态容器(data/loading/error 三态) ├── view/ # 可复用 UI 组件(@ComponentV2) └── pages/ # 页面,仅编排(组合 view + viewmodel) ``` **单向数据流**: ``` pages → viewmodel → repository(契约) → api → HttpClient → 后端 ↑ 状态回传由 @Trace 触发自动刷新 ``` --- ## 4. 状态管理约定(全量 V2,禁用 V1) | 场景 | 使用 | |---|---| | 组件/页面 | `@ComponentV2` | | 组件内部状态 | `@Local` | | 父→子输入 | `@Param` | | 子→父输出/回调 | `@Event`(**不用 `@Link`**;需双向时用 `@Param` 的 `!!` 语法糖) | | 类/模型可观察 | `@ObservedV2` 类 + `@Trace` 字段 | | 跨层共享 | `@Provider` / `@Consumer` | | 变化监听 | `@Monitor` | | 全局会话 | `SessionStore`(`@ObservedV2` 单例,见 `common/state/SessionStore.ets`) | | 轻量持久化 | `PersistenceV2.globalConnect(...)`;结构化数据后续用 relationalStore(RDB) | **核心约定**:ViewModel 是 `@ObservedV2` 类,持有 `@Trace` 的 `data/loading/error` 三态;页面只读状态、调方法,不直接碰 Repository / 网络层。 --- ## 5. 网络与数据层 ### 5.1 网络层(`common/src/main/ets/network/`) - `HttpClient`:封装 `@kit.NetworkKit` 的 http,统一超时/请求头,支持**拦截器链**。 - `HttpInterceptor`:拦截器接口(`onRequest` / `onResponse`)。 - `AuthInterceptor`:请求前注入 `Authorization: Bearer `;401 时清空会话。 ### 5.2 鉴权流程 ``` 请求 → AuthInterceptor.onRequest 注入 token → 发出 → AuthInterceptor.onResponse 检查 401 → (当前) 清空 SessionStore,由上层跳登录 → (TODO) token 刷新 + 原请求重放(防并发刷新),需后端 refresh 接口约定后实现 ``` ### 5.3 Repository 模式 - `data/repository/` 中定义**抽象类契约**,ViewModel 只依赖契约,实现可替换(真实 / mock)。 - 用抽象类而非 interface,是为了在 `ServiceLocator` 中做 `Object → 契约` 强转时兼容 ArkTS。 - `data/api/` 返回 DTO,Repository 负责 **DTO → 领域模型** 映射。 ### 5.4 统一响应与错误 - `ApiResult`:`{ code, message, data }`,`code === 0` 为成功。 - `ApiError`:区分网络异常 / HTTP 状态码 / 业务错误码。 --- ## 6. 横切关注点 ### 6.1 依赖注入 `di/ServiceLocator.ets`:`Map` 单例注册表。启动时在 `EntryAbility.onCreate` 注册 `HttpClient`、各 Repository、`SessionStore`;业务侧 `get(key)` 后强转。 > ArkTS 无反射,用字符串 key + 显式强转;若后续规模增大可引入类型安全的 key 常量或轻量注入容器。 ### 6.2 导航 `Navigation` + `NavPathStack`(官方推荐,替代旧 Router)。`RouteMap.ets` 定义路由名常量与 `name→页面` 分发;`AppRouter` 持有全局 `NavPathStack` 提供 `push/replace/pop/popToName/clear`。HAR 不承载路由。 ### 6.3 日志 `common/logging/Logger.ets`:封装 `hilog`,统一 DOMAIN,后续可加等级开关/上报。 ### 6.4 持久化 - `PersistenceV2`:轻量 KV(token / 用户偏好),`@Trace` 字段自动落盘。 - `relationalStore(RDB)`:结构化数据(订单、列表缓存等),后续引入。 --- ## 7. 编码规范 1. **状态管理只用 V2**:新组件一律 `@ComponentV2`,禁止混入 V1 装饰器。 2. **单向数据流**:父→子用 `@Param`,子→父用 `@Event`;页面不直接改 ViewModel 之外的全局状态。 3. **页面只编排**:`pages/` 下只做组件组合与 ViewModel 调用,业务逻辑进 ViewModel,数据进 Repository/Api。 4. **跨模块引用走 `Index.ets`**:entry 只 `import { ... } from 'common'/'uikit'`,不直接引 HAR 内部路径。 5. **魔法值收敛到 `uikit/theme/Theme.ets`**:颜色/间距/字号统一取 token。 --- ## 8. 演进指南 ### 8.1 抽取 feature HAR(业务领域明确后) 当某个业务领域(如订单、支付)足够独立时,新增 `feature_xxx` HAR: ``` feature_order/ ├── src/main/ets/{model,data,viewmodel,view,pages} └── oh-package.json5 (name: feature_order, main: Index.ets) ``` - 根 `build-profile.json5` 的 `modules` 增加该模块。 - 依赖它的模块在其 `oh-package.json5` 增加 `"feature_order": "file:../feature_order"`。 - 依赖方向:`entry → feature_xxx → common/uikit`,禁止 feature 之间横向依赖(确实需共享时下沉到 `common`)。 ### 8.2 迁移到 feature-first 当 feature 数量增多、单层目录过深时,可将 `model/data/viewmodel/view/pages` 按 feature 重组: ``` ets/features//{model,data,viewmodel,view,pages} ets/shared/… # 跨 feature 共享 ``` 迁移原则:先把稳定边界抽 HAR,再在 HAR 内部做 feature 分组。 --- ## 9. 调研结论摘要与引用 - 官方 MVVM(StateManagement V2)指南给出 `model/viewmodel/view/pages` 分层。 - 官方三层工程结构:commons(禁止反向依赖)/ features / products(不可横向调用),打包形态 HAR/HSP/Feature HAP/Entry HAP。 - V2 装饰器映射:`@State→@Local`、`@Prop→@Param`、`@Link→@Param+@Event`、`@Observed→@ObservedV2+@Trace`、`@Watch→@Monitor`、`AppStorage→AppStorageV2`、`PersistentStorage→PersistenceV2`。 - V1/V2 不可混用(编译错误);API 19+ 提供 `UIUtils.enableV2Compatibility/makeV1Observed` 放宽混合约束。 主要引用: - https://developer.huawei.com/consumer/en/doc/harmonyos-guides/arkts-mvvm-v2 - https://developer.huawei.com/consumer/cn/doc/HarmonyOS-Guides/arkts-decorator-overview - https://device.harmonyos.com/en/docs/apiref/harmonyos-guides/arkts-v1-v2-update-difference - https://github.com/openharmony/docs(arkts-v1-v2-migration-application / mixusage / inner-component) - https://github.com/OpeNopEn2007/arkts-patterns --- ## 10. 边界与后续 - 本次为**骨架级**交付,未实现真实后端对接与具体业务(保留示例链路)。 - 未新增 feature HAR(无业务领域),仅写入抽取指南。 - 未做多设备适配(已确认仅 phone)。 - 后续待办:token 刷新策略、RDB 持久化、自动化测试基建、环境配置注入(BASE_URL)。