HarmonyOS鸿蒙NEXT嘌呤智护宝

HarmonyOS鸿蒙NEXT嘌呤智护宝

前言

在移动应用开发的浪潮中,端云一体化开发已成为现代应用架构的重要趋势。本文将详细介绍如何使用华为云开发服务,结合HarmonyOS端云一体化开发能力,打造一款专业的健康管理应用——嘌呤智护宝。

项目概述

嘌呤智护宝是一款专注于痛风患者健康管理的移动应用,主要功能包括:

  • 用户登录与身份认证
  • 健康档案管理
  • 尿酸值记录与监控
  • 饮水量追踪
  • 饮食记录与嘌呤含量查询
  • 健康数据云端同步

技术架构

整体架构设计

本项目采用端云一体化架构,分为两个主要部分:

  1. 端侧工程 (/Application): 基于HarmonyOS开发的移动应用
  2. 云端工程 (/CloudProgram): 基于华为云开发的后端服务
嘌呤智护宝
├── Application/          # 端侧工程
│   ├── entry/           # 主模块
│   │   └── src/main/ets/
│   │       ├── Manager/     # 状态管理
│   │       ├── pages/       # 页面组件
│   │       ├── api/         # API接口
│   │       └── utils/       # 工具类
│   └── cloud_objects/   # 云对象
└── CloudProgram/        # 云端工程
    ├── cloudfunctions/  # 云函数
    └── clouddb/         # 云数据库

云数据库设计

用户数据模型

我们使用华为云数据库CloudDB来存储用户数据,首先定义用户数据模型:

// Application/entry/src/main/ets/pages/CloudDb/User.ts
import { cloudDatabase } from '@kit.CloudFoundationKit';

class User extends cloudDatabase.DatabaseObject {
  public id: string;
  public openId: string;
  public nickname: string;
  public gender: string;
  public birthDate: string;
  public height: string;
  public weight: string;
  public phoneNumber: string;
  public registerTime: string;
  public lastLoginTime: string;
  public targetUricAcid: string;
  public targetWaterIntake: string;
  public unionid: string;
  public avatar: string;

  public naturalbase_ClassName(): string {
    return 'User';
  }
}

export { User };

云数据库配置

{
    "defaultCloudDBZoneName": "default",
    "defaultDataStorageLocation": "CN"
}

云函数开发

用户管理云函数

// CloudProgram/cloudfunctions/user-func/userFunc.ts
import { UserService } from './UserService'

const userService = new UserService()

let myHandler = async function(event, context, callback, logger) {
  logger.info('Incoming event: ', event)
  let operation = event.body ? JSON.parse(event.body).operation : event.operation
  let records = event.body ? JSON.parse(event.body).records : event.records

  let result = {}

  try {
    switch (operation) {
      case 'createUser':
        result = await userService.createUser(records)
        break
      case 'updateUser':
        result = await userService.updateUser(records)
        break
      case 'getUserById':
        result = await userService.getUserById(records.id)
        break
      case 'getUserByOpenId':
        result = await userService.getUserByOpenId(records.openId)
        break
      case 'updateHealthArchive':
        result = await userService.updateHealthArchive(records)
        break
      default:
        result = { code: -1, message: 'Unsupported operation: ' + operation }
    }
  } catch (error) {
    logger.error('Error processing request:', error)
    result = { code: -1, message: 'Internal server error: ' + error.message }
  }

  callback(result)
}

export { myHandler }

登录认证云函数

// CloudProgram/cloudfunctions/login-func/loginFunc.ts
import { CloudDbZoneWrapper } from './CloudDBZoneWrapper';

let myHandler = async function(event, context, callback, logger) {
  logger.info(event);
  logger.info('event.body =====>', event.body);
  
  let result;
  let operation = event.body ? JSON.parse(event.body).operation : event.operation;
  let records = event.body ? JSON.parse(event.body).records : event.records;
  let cloudDBZoneWrapper = new CloudDbZoneWrapper();
 
  switch (operation) {
    case 'upsertUser':
      result = await cloudDBZoneWrapper.upsertUser(records);
      break;
    case 'delete':
      result = await cloudDBZoneWrapper.delete(records);
      break;
    case 'query':
      result = await cloudDBZoneWrapper.queryAll();
      break;
    case 'queryUser':
      result = await cloudDBZoneWrapper.queryUser(records.openId);
      break;
    default:
      callback({ code: -1, message: "SUCCESS" });
  }
  logger.info('result: ' + JSON.stringify(result))
  callback({ code: result, message: "SUCCESS" });
};

export { myHandler };

端侧应用开发

应用状态管理

我们使用单例模式的AppManager来管理全局应用状态:

// Application/entry/src/main/ets/Manager/AppManager.ets
import { PreferencesUtils } from '../utils/PreferencesUtils';
import { Context } from '@kit.AbilityKit';
import { User } from '../pages/CloudDb/User';
import cloud from '@hw-agconnect/cloud';

/**
 * 应用状态接口定义
 * 统一管理应用的全局状态数据
 */
interface AppState {
  userInfo: User; // 用户信息
  isLoggedIn: boolean; // 登录状态
  dataVersion: number; // 数据版本号,用于触发UI更新
}

/**
 * 应用状态管理器 - 单例模式
 * 负责管理全局用户状态、登录状态和数据同步
 * 使用 AppStorage 作为全局状态存储,确保跨页面状态一致性
 */
export class AppManager {
  private static instance: AppManager;
  private context: Context | null = null;

  /**
   * 私有构造函数,确保单例模式
   * 初始化时会设置 AppStorage 的默认值
   */
  private constructor() {
    console.log('AppManager 实例创建');
    // 初始化 AppStorage 中的全局状态
    this.initAppStorage();
  }

  /**
   * 获取 AppManager 单例实例
   * @returns AppManager 实例
   */
  public static getInstance(): AppManager {
    if (!AppManager.instance) {
      AppManager.instance = new AppManager();
    }
    return AppManager.instance;
  }

  /**
   * 初始化应用上下文
   * 必须在应用启动时调用,用于后续的数据持久化操作
   * @param context 应用上下文
   */
  public initContext(context: Context) {
    this.context = context;
    this.checkLoginStatus();
  }
}

华为账号登录集成

// Application/entry/src/main/ets/pages/LoginPage/LoginPage.ets
import { authentication, loginComponentManager, LoginWithHuaweiIDButton } from '@kit.AccountKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { util } from '@kit.ArkTS';

import { User } from '../CloudDb/User';
import { AppManager } from '../../Manager/AppManager';
import { UserApi } from '../../api/UserApi';

@Component
export struct LoginPage {
  @Consume('appPathStack') pageInfos: NavPathStack;
  // 构造LoginWithHuaweiIDButton组件的控制器
  controller: loginComponentManager.LoginWithHuaweiIDButtonController =
    new loginComponentManager.LoginWithHuaweiIDButtonController()
      .onClickLoginWithHuaweiIDButton(async (error: BusinessError,
        response: loginComponentManager.HuaweiIDCredential) => {
        if (error) {
          hilog.error(0x0000, 'testTag',
            `Failed to onClickLoginWithHuaweiIDButton. Code: ${error.code}, message: ${error.message}`);
          return;
        }
        if (response) {
          this.getUserAvatar()
        }
      })
  private user: User = new User()

  // 获取用户头像
  getUserAvatar() {
    // 创建授权请求,并设置参数
    const authRequest = new authentication.HuaweiIDProvider().createAuthorizationWithHuaweiIDRequest();
    // 获取头像昵称需要传如下scope
    authRequest.scopes = ['profile'];
    // 若开发者需要进行服务端开发,则需传如下permission获取authorizationCode
    authRequest.permissions = ['serviceauthcode'];
    // 用户是否需要登录授权,该值为true且用户未登录或未授权时,会拉起用户登录或授权页面
    authRequest.forceAuthorization = true;
    // 用于防跨站点请求伪造
    authRequest.state = util.generateRandomUUID();

    // 执行授权请求
    try {
      const controller = new authentication.AuthenticationController(getContext(this));
      controller.executeRequest(authRequest).then(async (data) => {
        const authorizationWithHuaweiIDResponse = data as authentication.AuthorizationWithHuaweiIDResponse;
        const state = authorizationWithHuaweiIDResponse.state;
        if (state && authRequest.state !== state) {
          hilog.error(0x0000, 'testTag', `Failed to authorize. The state is different, response state: ${state}`);
          this.pageInfos.pop()
          return;
        }
        hilog.info(0x0000, 'testTag', 'Succeeded in authentication.');
        const authorizationWithHuaweiIDCredential = authorizationWithHuaweiIDResponse.data!;
        const avatarUri = authorizationWithHuaweiIDCredential.avatarUri;
        const nickName = authorizationWithHuaweiIDCredential.nickName;
        const authorizationCode = authorizationWithHuaweiIDCredential.authorizationCode;
        // 获取用户的唯一标识
        const openId = authorizationWithHuaweiIDCredential.openID;

        // 开发者处理avatarUri, nickName, unionID,openID,authorizationCode
        console.log('avatarUri ===>', avatarUri)
        console.log('nickName ===>', nickName)
        console.log('openId ===>', openId)
        console.log('authorizationCode ===>', authorizationCode)

        try {
          // 使用 UserApi 创建或获取用户,这会保护现有用户数据
          const user = await UserApi.createUser({
            openId: openId || '',
            nickname: nickName,
            avatar: avatarUri,
            unionid: openId || ''
          });

          console.log('用户信息处理结果:', user);

          // 设置本地用户信息
          this.user.openId = user.openId;
          this.user.id = user.id;
          this.user.avatar = user.avatar;
          this.user.nickname = user.nickname;
          // 保留其他已有的用户信息
          this.user.gender = user.gender;
          this.user.birthDate = user.birthDate;
          this.user.height = user.height;
          this.user.weight = user.weight;
          this.user.phoneNumber = user.phoneNumber;
          this.user.targetUricAcid = user.targetUricAcid;
          this.user.targetWaterIntake = user.targetWaterIntake;

          // 使用 AppManager 统一管理登录状态
          const appManager = AppManager.getInstance();
          const loginSuccess = await appManager.login(this.user.openId);

          if (loginSuccess) {
            appManager.updateUserInfo(this.user);
            this.pageInfos.pop({ isLogin: true });
          } else {
            hilog.error(0x0000, 'testTag', 'Login failed through AppManager')
          }
        } catch (error) {
          console.error('用户登录处理失败:', error);
          hilog.error(0x0000, 'testTag', `User login processing failed: ${error.message}`);
        }
      }).catch((err: BusinessError) => {
        this.dealAllError(err);
      });
    } catch (error) {
      this.dealAllError(error);
    }
  }
}

API接口封装

// Application/entry/src/main/ets/api/UserApi.ets
import cloud from '@hw-agconnect/cloud';
import { User } from '../pages/CloudDb/User';

// 用户基本信息接口
interface UserBasicInfo {
  openId: string;
  nickname?: string;
  gender?: string;
  birthDate?: string;
  height?: string;
  weight?: string;
  phoneNumber?: string;
  targetUricAcid?: string;
  targetWaterIntake?: string;
  unionid?: string;
  avatar?: string;
}

export class UserApi {
  /**
   * 创建新用户
   * @param userInfo 用户基本信息
   * @returns Promise<User>
   */
  static async createUser(userInfo: UserBasicInfo): Promise<User> {
    try {
      const res = await cloud.callFunction({
        name: 'user-func',
        params: {
          operation: 'createUser',
          records: userInfo
        }
      });
      return res.getValue();
    } catch (error) {
      console.error('[UserApi] 创建用户失败:', error);
      return error.message
    }
  }

  /**
   * 更新用户信息
   * @param userInfo 用户更新信息
   * @returns Promise<User>
   */
  static async updateUser(userInfo: UserUpdateInfo): Promise<User> {
    try {
      const res = await cloud.callFunction({
        name: 'user-func',
        params: {
          operation: 'updateUser',
          records: userInfo
        }
      });
      return res.getValue();
    } catch (error) {
      console.error('[UserApi] 更新用户信息失败:', error);
      return error
    }
  }

  /**
   * 根据用户ID查询用户信息
   * @param userId 用户ID
   * @returns Promise<User>
   */
  static async getUserById(userId: string): Promise<User> {
    try {
      const res = await cloud.callFunction({
        name: 'user-func',
        params: {
          operation: 'getUserById',
          records: { id: userId }
        }
      });
      return res.getValue();
    } catch (error) {
      console.error('[UserApi] 查询用户失败:', error);
      return error;
    }
  }
}

核心功能实现

用户认证与状态管理

应用采用华为账号一键登录,结合云端用户数据管理,实现了完整的用户认证流程:

  1. 前端登录: 使用华为账号SDK获取用户基本信息
  2. 云端验证: 通过云函数验证用户身份并创建/更新用户记录
  3. 状态同步: 使用AppStorage实现全局状态管理
  4. 数据持久化: 本地存储用户登录状态,支持自动登录

数据云端同步

通过华为云数据库CloudDB实现数据的云端存储和同步:

  • 实时同步: 用户数据变更实时同步到云端
  • 离线支持: 本地缓存机制,支持离线使用
  • 数据一致性: 多端数据自动同步,保证数据一致性

健康数据管理

应用支持多种健康数据的记录和管理:

  • 尿酸值监控: 记录每日尿酸值,生成趋势图表
  • 饮水量追踪: 智能提醒,帮助用户养成良好饮水习惯
  • 饮食记录: 嘌呤含量查询,科学指导饮食
  • 健康档案: 完整的个人健康信息管理

开发优势与特色

端云一体化优势

  • 开发效率: 统一的开发工具链,减少学习成本
  • 数据同步: 自动化的数据同步机制,无需手动处理
  • 安全性: 华为云提供的企业级安全保障
  • 扩展性: 云端弹性扩容,支持业务快速增长

技术特色

  • 响应式设计: 基于ArkTS的声明式UI开发
  • 状态管理: 全局状态管理,确保数据一致性
  • 模块化架构: 清晰的代码结构,便于维护和扩展
  • 云原生: 充分利用云服务能力,提升应用性能

总结与展望

通过本项目的实践,我们深度体验了华为云开发和端云一体化开发的强大能力。主要收获包括:

  • 开发效率提升: 端云一体化开发大幅提升了开发效率
  • 技术栈统一: ArkTS语言在端云两侧的统一使用
  • 服务集成: 华为云服务的深度集成简化了复杂功能的实现
  • 用户体验: 流畅的数据同步和离线支持提升了用户体验

未来规划

  • AI能力集成: 接入华为云AI服务,提供智能健康建议
  • 多端适配: 扩展到更多HarmonyOS设备
  • 社交功能: 添加用户社区和经验分享功能
  • 数据分析: 深度挖掘健康数据,提供个性化服务

端云一体化开发为移动应用开发带来了新的可能性,华为云开发平台为开发者提供了强大的技术支撑。相信随着技术的不断发展,会有更多优秀的应用在这个平台上诞生。


参考资料:


界面如下


更多关于HarmonyOS鸿蒙NEXT嘌呤智护宝的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

HarmonyOS鸿蒙NEXT的"嘌呤智护宝"是华为针对健康监测场景推出的创新功能,基于分布式技术实现跨设备协同。该功能通过智能穿戴设备实时监测用户尿酸相关指标,采用鸿蒙原生的AI算法进行数据分析,数据流转遵循HarmonyOS隐私安全规范。系统级能力包括:

  1. 多设备数据自动同步;
  2. 低时延体征信号处理;
  3. 端云协同的健康预警机制。

技术实现依托鸿蒙的微内核架构和确定时延引擎,不依赖JVM或NDK环境。

更多关于HarmonyOS鸿蒙NEXT嘌呤智护宝的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


这是一个基于HarmonyOS和华为云开发的健康管理应用案例,展示了端云一体化开发的完整实践。从技术架构来看,项目采用了清晰的模块化设计:

  1. 前端使用ArkTS开发,实现了响应式UI和状态管理
  2. 后端采用华为云函数和CloudDB,提供数据存储和业务逻辑处理
  3. 通过云对象实现前后端数据交互

项目亮点包括:

  • 华为账号一键登录集成
  • 健康数据云端同步机制
  • 离线数据支持
  • 模块化的API设计

技术栈选择合理,充分利用了HarmonyOS的声明式UI和华为云的各项服务能力。代码结构清晰,展示了良好的工程实践,如:

  • 单例模式的状态管理
  • 统一的API封装层
  • 类型安全的接口定义

这个案例对于想学习HarmonyOS端云一体化开发的开发者很有参考价值,特别是健康类应用的实现方式。

回到顶部