Files
2026-07-24 15:24:14 +08:00

8.0 KiB
Raw Permalink Blame History

CardHarmonyOS

CardHarmonyOS 是期货首页卡片的 HarmonyOS ArkTS 示例工程,使用 ArkUI 声明式 UI 实现 AI 观点、市场排名和 AI 选期三张业务卡片。首页入口为 entry/src/main/ets/pages/Index.ets

环境要求

  • DevEco Studio(支持 HarmonyOS API 20 及以上)
  • HarmonyOS SDK 6.0.0 或更高版本
  • ohpm
  • HarmonyOS 手机或模拟器

项目目标 SDK 为 HarmonyOS 6.1.0API 23),兼容 SDK 为 6.0.0API 20)。

快速开始

  1. 使用 DevEco Studio 打开仓库根目录。
  2. 执行 ohpm install 安装依赖。
  3. File > Project Structure > Signing Configs 中配置本机调试签名。
  4. 选择 entry 模块和 default product。
  5. 连接设备或启动模拟器,点击 Run 构建并安装应用。

单元测试位于 entry/src/test/,设备测试位于 entry/src/ohosTest/,可在 DevEco Studio 中右键测试文件执行。

目录结构

AppScope/                         应用级配置与资源
entry/src/main/ets/
├── pages/                        首页及详情页
├── ai-view/                      AI 观点卡片
├── market-ranking/               市场排名卡片
├── ai-pick/                      AI 选期卡片
└── common/                       卡片容器、数据模型及行情字段常量
entry/src/main/resources/         文案、颜色、图片和页面配置
doc/                              HTTP 与 4106 行情接口文档

业务卡片通常由 ModelsDataFetcherNodeComponent 和 Mock 数据组成。 市场排名与 AI 选期分别通过独立的 HqRequestClient 构造行情订阅参数,共享 common/HqFieldId.ets 中的 4106 字段 ID。

MarketRanking 生命周期

MarketRankingNodeComponent 出现时读取卡片配置、注册 tcpReconnect 事件监听,并在 firstPageVisibletrue 时获取当前 Tab 的 contracts。contracts 返回后先生成占位列表, 再由 MarketRankingHqRequestClient 发起行情订阅,行情回调会整体替换 CardData

flowchart TD
    appear["aboutToAppear"] --> config["读取卡片配置"]
    config --> listen["监听 tcpReconnect"]
    listen --> visible{"firstPageVisible?"}
    visible -- 否 --> idle["等待页面恢复可见"]
    visible -- 是 --> fetch["获取当前 Tab 的 contracts"]
    fetch --> placeholder["填充合约占位列表"]
    placeholder --> stillVisible{"页面仍然可见?"}
    stillVisible -- 否 --> idle
    stillVisible -- 是 --> subscribe["订阅行情"]
    subscribe --> update["行情回调更新 CardData"]
    update --> waiting["等待下一次行情推送"]
    waiting --> update

    refresh["refreshTrigger 变化"] --> stop["停止旧行情订阅"]
    tab["Tab 切换"] --> stop
    stop --> clear["清空列表"]
    clear --> fetch

    hidden["firstPageVisible = false"] --> stopOnly["停止行情订阅"]
    shown["firstPageVisible = true"] --> hasContracts{"已有 contracts?"}
    hasContracts -- 是 --> subscribe
    hasContracts -- 否 --> fetch

    reconnect["tcpReconnect"] --> reconnectVisible{"页面可见?"}
    reconnectVisible -- 否 --> idle
    reconnectVisible -- 是 --> reconnectStop["停止旧行情订阅"]
    reconnectStop --> hasContracts

    disappear["aboutToDisappear"] --> unlisten["解绑 tcpReconnect"]
    unlisten --> stopOnly

运行期间按以下规则更新:

  • refreshTrigger:由父组件通过 @Link 传入;变化后停止旧行情、重新获取 contracts, 并在可见时重新订阅。
  • firstPageVisible:由父组件通过 @Provide 提供,组件通过 @Consume 监听,默认 为 true。变为不可见时立即停止行情;恢复可见时优先使用已有 contracts 重新订阅, 没有 contracts 才重新请求。
  • tcpReconnect:组件通过公共 emitter 监听。重连且页面可见时停止旧行情并重新订阅; 页面不可见时忽略,恢复可见后再订阅。
  • Tab 切换:停止旧行情、清空列表、获取新 Tab 的 contracts,再订阅对应行情。

aboutToDisappear 会解绑 TCP 重连监听并停止行情订阅。HTTP 请求等待期间如果页面变为 不可见,contracts 仍可更新,但不会创建行情订阅。

当前异常与恢复处理

异常或状态 处理方式
HTTP 获取 contracts 失败 updateCardData 捕获异常并清空列表
TCP 连接恢复 收到 tcpReconnect 后,仅在页面可见时停止旧行情并重新订阅
TCP 重连时没有 contracts 重新请求 contracts,请求成功后再订阅行情
TCP 重连时页面不可见 忽略重连事件,页面恢复可见后再订阅
页面变为不可见 立即停止行情订阅
页面恢复可见 优先使用已有 contracts 恢复订阅;没有数据时重新请求
手动刷新 停止旧行情、重新请求 contracts,并在可见时重新订阅
Tab 切换 停止旧行情、清空旧列表、请求新 Tab 数据并重新订阅
HTTP 返回时页面已隐藏 更新 contracts,但不建立行情订阅
组件消失 解绑 TCP 重连监听并停止行情订阅

当前异常处理仍属于基础兜底:尚未实现 HTTP 自动重试、错误提示、请求取消、请求序号校验, 以及行情订阅失败后的延迟重试。快速切换 Tab 时,较早发出的请求仍可能晚于新请求返回; 首次加载使用的延迟任务也尚未在组件消失时取消。

卡片跳转链接

下表只记录页面跳转,不包含图片、HTTP 数据接口或行情接口。{...} 表示运行时参数。

卡片 触发入口 目标链接模板 当前本地路由 当前状态
MarketRanking 点击合约 client://client.html?action=ymtz^webid=2205^stockcode={code}^marketid={market} pages/Detail clientUrl 仅作为参数传入本地 Mock 页
MarketRanking 点击标题 cardConfig.card_url.android,为空时使用 card_url.ios pages/StrategyDetail 当前 Mock 配置为空,不跳转
AiPick 点击合约 client://client.html?action=ymtz^webid=2205^stockcode={contract}^marketid={market} pages/Detail clientUrl 仅作为参数传入本地 Mock 页
AiPick 点击标题 cardConfig.card_url.android,为空时使用 card_url.ios pages/StrategyDetail 当前 Mock 配置为空,不跳转
AiPick 一句话定制策略 client://client.html?action=ymtz^ishiddenbar=1^mode=new^webid=2804^url=https://fupage.10jqka.com.cn/ai-web/ai-diagnosis-home.html?sync=1^title=AI选期 pages/StrategyDetail 尚未调用客户端能力
AiPick 点击策略卡片 client://client.html?action=ymtz^ishiddenbar=1^mode=new^webid=2804^url=https://fupage.10jqka.com.cn/ai-web/ai-diagnosis-detail.html?id={id}&type={periodType}&name={name}^title=AI选期 pages/StrategyDetail name 使用 URL 编码;尚未调用客户端能力
AiPick 点击策略标签 client://client.html?action=ymtz^ishiddenbar=1^mode=new^webid=2804^url=https://fupage.10jqka.com.cn/ai-web/ai-diagnosis-label.html?id={id}&type={periodType}&label={label}^title=AI选期 pages/StrategyDetail label 使用 URL 编码;尚未调用客户端能力

数据与接口

当前 HTTP Fetcher 仅构造请求参数,行情客户端也尚未连接真实客户端桥接层;页面使用 Mock 数据并以 2.5 秒间隔模拟行情更新。接入真实服务前请阅读:

不要在源码或提交中新增 Cookie、Token、证书、私钥或本机签名密码。签名材料应通过 DevEco Studio 在本机配置。

开发约定

  • 使用 ArkTS 显式类型,组件采用 ArkUI 声明式写法。
  • 类型和类使用 PascalCase,变量和方法使用 camelCase,常量使用 UPPER_SNAKE_CASE。
  • 公共行情字段统一维护在 HqFieldId,避免在业务卡片中硬编码字段 ID。
  • 新增接口或修改 4106 参数时,同步更新 doc/ 下对应文档。