在这里插入图片描述

一、功能概述

喝水记录应用的核心价值之一是“让数据说话”。用户不仅希望看到当天喝了多少水,还希望了解最近一周、一个月的整体趋势,以及不同类型、不同容器的喝水分布。本篇文章以“统计概览”页面为例,介绍如何在 Cordova Web 层 汇总多维度指标,并通过 OpenHarmony ArkTS 提供原生侧的简洁统计视图,为后续接入图表库或桌面卡片打下基础。文章继续采用一段代码一段说明的方式,避免出现大段难以理解的代码块。

二、Web 端统计概览页面结构

<div id="stats-page" class="page page-stats">
  <h1>统计概览</h1>

  <div class="stats-cards">
    <div class="card" id="card-week-total">
      <div class="card-title">近 7 天总饮水量</div>
      <div class="card-value" id="week-total-ml">0 ml</div>
    </div>
    <div class="card" id="card-month-total">
      <div class="card-title">本月总饮水量</div>
      <div class="card-value" id="month-total-ml">0 ml</div>
    </div>
  </div>
</div>

这段 HTML 定义了统计概览页面的基础结构。顶部是一个标题“统计概览”,下方使用两张卡片展示近 7 天与本月的总饮水量。每张卡片中,card-title 用于说明指标含义,card-value 显示具体数值。通过为数值部分添加唯一 id(如 week-total-mlmonth-total-ml),后续可以在 JavaScript 中轻松更新它们的文本内容。尽管示例只展示了两个指标,但页面结构很容易扩展以展示更多维度的信息。

.page-stats {
  padding: 16px 24px;
}

.stats-cards {
  display: flex;
  gap: 12px;
  margin-top: 16px;
}

.stats-cards .card {
  flex: 1;
  padding: 16px;
  border-radius: 8px;
  background-color: #1f2933;
  color: #fff;
}

CSS 部分为统计卡片提供了基础布局与视觉样式。.stats-cards 使用横向 flex 布局与间距,让多张卡片整齐排列;.card 通过内边距、圆角和深色背景塑造出统一的卡片视觉风格,与仪表板、类型管理等页面保持一致。这样的布局既适合在 PC 端展示,也方便在后续做响应式调整。

三、从 IndexedDB 汇总统计数据

async function loadStatsOverview() {
  const today = new Date();

  const weekStart = new Date(today);
  weekStart.setDate(today.getDate() - 6);

  const monthStart = new Date(today.getFullYear(), today.getMonth(), 1);

  const weekTotal = await db.getTotalAmountBetween(weekStart, today);
  const monthTotal = await db.getTotalAmountBetween(monthStart, today);

  document.getElementById('week-total-ml')!.textContent = `${weekTotal} ml`;
  document.getElementById('month-total-ml')!.textContent = `${monthTotal} ml`;

  syncStatsToNative({ weekTotal, monthTotal });
}

loadStatsOverview 函数负责从 IndexedDB 中汇总统计数据并更新页面显示。首先计算近 7 天的起始日期 weekStart(包含今天在内的连续 7 天),以及本月起始日期 monthStart。然后调用封装好的 db.getTotalAmountBetween 方法,在给定时间范围之间计算总饮水量。拿到结果后,直接更新两个卡片的数值文本,并调用 syncStatsToNative 将这两个统计指标发送给原生层。这样一来,Web 和原生可以共享同一份统计结果,避免重复计算。

document.addEventListener('DOMContentLoaded', () => {
  loadStatsOverview();
});

DOMContentLoaded 事件中调用 loadStatsOverview,确保页面结构准备就绪后再进行统计计算和渲染。统计操作通常涉及数据库扫描,放在页面初始化时执行既能保证数据的及时性,又不会阻塞整体应用启动流程。

四、通过 Cordova 同步统计概览到原生

function syncStatsToNative(stats) {
  if (!window.cordova) {
    console.warn('[Stats] cordova not ready, skip native sync');
    return;
  }

  cordova.exec(
    () => {
      console.info('[Stats] sync overview success');
    },
    (err) => {
      console.error('[Stats] sync overview failed', err);
    },
    'WaterTrackerStats',
    'setOverview',
    [stats]
  );
}

syncStatsToNative 函数展示了如何将统计概览数据通过 Cordova 桥接发送给 ArkTS 插件。函数内部对 window.cordova 进行检查,以避免在 Cordova 尚未就绪时调用;随后使用 cordova.exec 调用插件 WaterTrackerStatssetOverview 动作,并将包含 weekTotalmonthTotal 字段的对象作为参数传入。原生侧收到该对象后,就可以直接使用这些统计数据,而不必再重新遍历数据库。

五、OpenHarmony ArkTS 插件与统计存储

// entry/src/main/ets/plugins/WaterTrackerStatsPlugin.ets
import common from '@ohos.app.ability.common';

export interface StatsOverview {
  weekTotal: number;
  monthTotal: number;
}

export class StatsStore {
  private static _overview: StatsOverview = { weekTotal: 0, monthTotal: 0 };

  static setOverview(value: StatsOverview) {
    this._overview = value;
  }

  static get overview() {
    return this._overview;
  }
}

export default class WaterTrackerStatsPlugin {
  context: common.UIAbilityContext;

  constructor(ctx: common.UIAbilityContext) {
    this.context = ctx;
  }

  setOverview(args: Array<Object>, callbackId: number) {
    const overview = args[0] as StatsOverview;
    StatsStore.setOverview(overview);
    console.info(`[StatsPlugin] weekTotal=${overview.weekTotal}, monthTotal=${overview.monthTotal}`);
  }
}

这段 ArkTS 代码定义了统计插件 WaterTrackerStatsPlugin 与配套存储 StatsStoreStatsOverview 接口描述了统计概览对象包含的字段:近 7 天总饮水量和本月总饮水量。StatsStore 使用一个静态字段 _overview 缓存最新的统计结果,并提供 setOverviewoverview 两个方法用于更新和读取。插件类在 setOverview 方法中从 args[0] 解析出统计对象,并交给 StatsStore.setOverview 存储,同时打印日志。在 ArkUI 组件中,可以直接通过 StatsStore.overview 获取这两个指标,从而构建原生侧的统计视图。

六、ArkUI 中展示多维度统计信息

// entry/src/main/ets/pages/StatsOverviewPage.ets
import { StatsStore } from '../plugins/WaterTrackerStatsPlugin';

@Component
struct StatsOverviewView {
  build() {
    const overview = StatsStore.overview;

    Column() {
      Text('喝水统计概览')
        .fontSize(18)
        .margin({ bottom: 8 });

      Text(`近 7 天总饮水量:${overview.weekTotal} ml`)
        .fontSize(16);

      Text(`本月总饮水量:${overview.monthTotal} ml`)
        .fontSize(16)
        .margin({ top: 4 });
    }
    .padding(16)
  }
}

StatsOverviewView 是一个简单的 ArkUI 组件示例,用于在原生界面中展示近 7 天和本月总饮水量。组件在 build 方法中从 StatsStore.overview 中读取统计结果,并使用多行 Text 将其以自然语言的形式呈现出来。尽管这里只展示了两个基础指标,但已经足以为用户提供一个直观的总体印象。后续可以在此基础上接入图表库,在 Web 或原生侧进一步可视化这些数据,例如绘制柱状图、折线图等。

七、小结

本篇文章展示了“统计概览”功能在 Cordova&openharmony 混合应用中的一条完整实现路径。Web 层通过 loadStatsOverview 函数从 IndexedDB 汇总近 7 天和本月的饮水总量,并更新页面上的统计卡片;随后利用 syncStatsToNative 将统计结果同步给 OpenHarmony ArkTS 插件。原生侧通过 StatsStoreWaterTrackerStatsPlugin 缓存这些指标,并在 ArkUI 组件 StatsOverviewView 中提供原生统计视图。

通过一段代码一段说明的方式,本文强调了“先在 Web 层充分利用现有数据模型进行汇总,再把结果分享给原生层复用”的思路,避免在多个层级重复做同样的统计工作。你可以在此基础上继续扩展更多维度的统计,例如按类型、按容器的总量排行,或者按时间段的平均喝水量等,将“统计概览”打造为整个喝水记录应用的数据中枢。

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐