HarmonyOS-APP-todo-list:基于 HarmonyOS 与华为云 Serverless 的端云一体待办清单项目

本项目以「一句话需求」为输入,使用编码智能体,自动完成从需求分析到代码生成、云侧部署、端云联调的全链路开发;同时也提供手动部署的方式。核心是「多端云同步待办清单」:端侧只带 APIG 调试域名调云函数,业务校验与数据读写统一收口在云端,数据库凭据只存在云函数环境变量里。

Branch1Tags1

待办清单(云同步)鸿蒙端云一体 App

使用 ArkTS、FunctionGraph 与 RDS 构建一个支持多端云同步的 HarmonyOS 待办清单应用:注册登录、任务增删改、优先级与截止日期全部云端收口,多端 30s 轮询自动同步。

案例成品预览

项目 内容
适合谁 HarmonyOS 新手到进阶开发者;想了解「端云一体」从需求到上线全链路的读者
难度与耗时 进阶 · 新手预计 2-3 小时(含开通云服务与端云联调)
你将学到 端云一体架构与云函数基线规范(base64 解码、时区、幂等、冷启动);ArkTS 界面与 HTTP 封装;一键云部署脚本;云服务的基础知识和操作
你将完成 可多端云同步的待办清单 App + 8 个云函数 + 3 张数据表 + 一键部署脚本,并完成端云联调验收
验证环境 FunctionGraph Node.js 18.15 · RDS MySQL 8.0 · APIG 专享版 · ArkTS compile API 24 / 兼容 6.1.0(23) · 最后验证于 2026-08-27

选择你的阅读路线:想拉取现成代码、不写代码快速部署 → 快速部署 · 想从零开始写端侧+云侧代码 → 完整实践 · 遇到问题 → 验收与排障

1. 案例概览

本项目以「一句话需求」为输入,用编码智能体自动完成从需求分析到代码生成、云侧部署、端云联调的全链路开发,同时也提供纯手动部署。核心是多端云同步待办清单:端侧只带 APIG 调试域名调云函数,业务校验与数据读写统一收口在云端,数据库凭据只存在云函数环境变量里。学到的「HarmonyOS 端 + 华为云 Serverless」骨架,可复用到签到、记账等任何需要账号体系与云端存储的端云应用。

核心功能与体验

  1. 注册 / 登录 → 登录成功自动进入清单页,下次启动免登录。
  2. 新增 / 勾选完成 / 循环优先级(高·中·低)/ 设截止日期 / 删除任务 → 操作立即回显,重启后仍在。
  3. 两台设备登录同一账号 → 任一端修改,另一端 30s 内自动同步一致。

技术方案一览

flowchart LR
    A["HarmonyOS App(ArkTS)"] -->|"HTTPS · 统一前缀 /todo"| B["APIG 专享版(认证 / 限流 / 转发)"]
    B --> C["FunctionGraph 云函数(Node.js)"]
    C -->|"VPC 内网 TCP 3306"| D["RDS for MySQL(Todo_DB)"]

术语速览(首次接触华为云 Serverless 的读者):

  • APIG 专享版:华为云 API 网关,本案例唯一公网入口。所有请求统一加 /todo 前缀(如 /todo/login),由 APIG 转发给后端函数;同时负责认证与限流。
  • FunctionGraph:华为云无服务器函数平台,本案例 8 个云函数跑在这里(Node.js 运行时)。请求到达时按需执行,无流量时不计费。
  • VPC 内网 TCP 3306:VPC 是华为云虚拟私有云,相当于你的私有局域网。云函数与数据库挂同一 VPC,通过内网 3306 端口(MySQL 默认端口)互访,数据库不暴露公网。

一次登录操作:App 经 APIG 把请求转发到 login 云函数,函数在 VPC 内校验数据库中的账号密码哈希并签发 token,再经 APIG 原路返回。业务接口统一返回 {"code":0,"message":"ok","data":{...}};code:1 业务错误,code:2 未登录或会话失效。

层级 技术/产品 验证版本 作用
端侧 HarmonyOS ArkTS / ArkUI compile API 24,兼容与目标 6.1.0(23) Login / TodoList 两页 App;登录态持久化与任务列表
入口 APIG 专享版 专享版 唯一公网入口;负责认证、限流与请求转发。联调无认证(NONE),生产需切 APP 认证
云侧 FunctionGraph 云函数(Node.js) Node.js 18.15 8 个函数:注册登录、任务 CRUD、云同步、建表初始化、诊断
数据 RDS for MySQL MySQL 8.0(utf8mb4) users / sessions / tasks 三张表
工具 hcloud(KooCLI)· DevEco command-line-tools 6.x 自动部署编排 · 编译(hvigor)与安装(hdc)

边界说明

  • 本案例用于学习端云一体完整链路:演示环境默认无认证;APIG 侧使用调试域名,端侧以「APIG 公网入口地址(弹性 IP 地址 · ELB)+ Host 头」方式直连(BASE_URL 填公网入口地址、APIG_HOST 填调试域名,见 docs/BUILD.md §7.1)。跳过证书名校验为演示取舍,不适合直接作为生产上线方案。
  • 本案例未实现生产鉴权:端侧 ENABLE_SIGN 与 APP_KEY/APP_SECRET 仅为占位,HttpUtil.ets 未实现签名,切 APP 认证后请求无法通过;且 AppSecret 长期放可分发客户端无法保密。生产需自建可撤销身份机制(如用户会话/JWT、设备证明或服务端代理),并接入自有域名与可信证书。
  • 认证与会话为简化实现,不可直接上架:当前用自建 users 表 + scrypt 哈希做账号校验,会话 token 写入自建 sessions 表,未做:token 有效期与撤销/刷新、Authorization: Bearer 传输(现走 URL 查询参数)、HTTPS 自有域名与可信证书、接口级细粒度权限与越权校验、登录限流与审计。这些是上线前必须补齐的安全项,本案例仅用于学习端云链路,不覆盖生产安全要求。
  • 本案例已做的安全基线(超出"能跑通"的最小实现,但仍有上限):密码 scrypt 加盐哈希 + timingSafeEqual 校验;SQL 全参数化 + 写操作按会话归属过滤;DEBUG 日志自动剔除 password/token;登录对不存在邮箱执行等代价哈希(防时序枚举);错误响应不回传内部异常信息;注册不签发孤儿会话 token。完整的「已做 / 未做」对照见 §6 安全边界。
  • 云函数业务规则设计不在案例范围内(本案例负责"怎么部署、怎么排错")。

2. 开始之前

先确认下面的准备条件。通用安装教程优先链接官方文档(见参考与维护)。

环境与资源

项目 要求 检查或获取方式
基础知识 ArkTS 语法、HTTP/REST、关系型数据库基础 官方 ArkTS 入门;不了解可边做边学
开发环境 Windows / macOS;DevEco Studio 或 command-line-tools(hvigor 6.x);Node.js ≥ 18 node -v;hvigorw 用全路径调用
测试设备 HarmonyOS 模拟器或真机 hdc list targets
账号与服务 华为云账号(实名认证);FunctionGraph / APIG 专享版 / RDS / VPC 已开通 控制台逐个开通,区域全程一致
权限与网络 IAM AK/SK(仅自动部署需要);VPC / 子网 / 安全组放通 3306 「我的凭证」→ 访问密钥;VPC 控制台
自动化工具 hcloud(KooCLI) 官方一键安装;hcloud version 自检

费用与配额

资源 建议规格 计费方式 实践预计费用 结束后如何处理
RDS for MySQL 最小规格实例 按需 约数元 / 天量级(视时长) 联调完删除实例
APIG 专享版 最小规格实例 按需 / 包周期 约数元 / 天量级 删除实例与分组
FunctionGraph 256MB / 超时 30s 按调用次数 + 资源量计费 实践用量下通常不足 1 元 删除 8 个函数
弹性 IP(ELB 公网入口) 1 个(APIG 公网入口) 按需 按小时计费 释放

价格随区域与促销浮动,请以华为云价格页为准;本案例实践量小、用完即清理。

配置与敏感信息

占位符 含义 获取位置 安全存放位置
<ingress_ip> APIG 实例的公网入口地址(弹性 IP 地址 · ELB)(§5.3 开通公网入口时绑定;是「入口地址」,不是出口用的弹性公网 IP/EIP) APIG 实例详情 → 弹性 IP 地址(ELB) 端侧 Config.ets 的 BASE_URL(公开)
<apig_domain> APIG 调试域名(部署后抄下) docs/BUILD.md §5.8 端侧 Config.ets 的 APIG_HOST(公开)
<region> / <project_id> / <vpc_id> / <subnet_id> / <security_group_id> 区域与网络资源 ID 各服务控制台 harmony_cloud/deploy/.env
<db_host> / <db_user> / <db_password> RDS 内网地址 / 账号 / 密码 RDS 实例详情(用内网地址,不用公网) 仅 .env;再注入云函数环境变量
<app_key> / <app_secret> APIG 凭据(仅 APP 认证需要) APIG 凭据管理 Config.ets(端侧签名用)

<region> 区域代码怎么查

控制台网页选区域时显示的是中文名(如「华南-广州」),但 .env 和 hcloud 要的是区域代码(如 cn-south-1)。查法:华为云控制台 → 右上角头像 →「我的凭证」→「项目列表」,表中每行对应一个区域,同时给出区域代码和项目 ID(即 <project_id>),两个一起抄下来。常见对照:华北-北京四 cn-north-4、华南-广州 cn-south-1、华东-上海一 cn-east-3。全程只用一个区域,所有服务与 .env 保持一致。

  • .env、签名私钥、部署请求体(harmony_cloud/deploy/out/)和本地产物已加入 .gitignore,不入库。
  • 客户端不得包含 AK/SK 或数据库密码;AppSecret 仅在生产 APP 认证签名时由端侧持有。
  • 截图、日志、演示数据发布前必须脱敏(本仓库配置与 .env.example 已全部占位符化)。

后续我们以 华南-广州 cn-south-1 为例。

3. 快速部署

这条路线让 零开发的用户快速跑通端云链路:拉取已验证的源码(端侧 App + 云侧 8 个云函数已全部提供),本地不编写任何代码,仅通过 Agent(推荐)或手动 完成云侧部署,再编译安装端侧 App。前置条件见开始之前;想从零开始编写端侧、云侧代码的完整路径见完整实践。

禁止截图,禁止截图,禁止截图,如果需要确认云手机界面,通过 hdc 读取布局 / 模拟点击完成,详见 §5 · 虚拟环境下的 UI 自动验收。

1)获取已验证版本

git clone https://gitcode.com/harmony-practice-center/todo_list.git HarmonyOS-APP-todo
cd HarmonyOS-APP-todo

仓库已包含端侧 App 全部源码(harmony_app/)与云侧 8 个云函数(harmony_cloud/functions/),本路线全程无需编写代码。

完成标志:当前提交对应 v1.0.0,根目录存在 README.md、harmony_app/、harmony_cloud/ 与 docs/。

2)准备最小配置

选 方式 A(Agent 部署) 的话,此步可先跳过:助手会在部署时检查并逐项引导你确认 .env 的值。选 方式 B(手动) 按下面操作。

cd harmony_cloud/deploy
cp .env.example .env            # 字段说明见 docs/BUILD.md §3.1
  1. 将 <尖括号> 占位符替换为开始之前收集的值。
  2. 部署完成后把 APIG 公网入口地址(弹性 IP 地址 · ELB) 与 调试域名 填入端侧 harmony_app/entry/src/main/ets/utils/Config.ets(BASE_URL 填入口地址、APIG_HOST 填域名,见第 4 步)。

完成标志:.env 无未替换占位符;git status 中不出现 .env 与 out/。

3)部署云侧环境(二选一:Agent 或手动)

注意:云侧如果准备好了,直接看 4)云端资源配置,无需反复配置云侧环境,无需检查.env

方式 A:让「码道」部署(推荐,无需修改代码)

打开华为云码道(或其他编码智能体),选择鸿蒙开发智能体,新建空工作区并让助手把当前仓库同步进去,然后发送:

一次性前置:用 hcloud configure set --cli-access-key=<AK> --cli-secret-key=<SK> --cli-region=<region> 配置 KooCLI——方法与 AK/SK 获取见开始之前 · 环境与资源。

请按本地 docs/BUILD.md 完成云侧部署,无需我修改任何代码:
1. 从 harmony_cloud/deploy/.env.example 创建 harmony_cloud/deploy/.env,检查是否填齐;若未填齐或服务未开通,逐项告诉我需要确认的占位值(区域 / 项目 ID / VPC ID / 子网 ID / 安全组 ID / RDS 凭据),经我确认后再开通;
2. 敏感值(数据库密码、AK/SK)只放 .env 和华为云控制台,不要在回复和日志中显示原文;
3. 执行云侧部署:打包 8 个云函数 → 部署上云 → 创建触发器 → 发布 API → 调用 db-init 初始化数据库;
4. 部署完成后调用 login 接口验证返回 code:0,并返回一份部署报告(创建的资源清单、各函数 URN、APIG 调试域名、最终验证结果)。
涉及付费资源或真实密钥的操作,先说明影响并等我确认。

输出:智能体返回部署报告,其中的 <apig-domain>(调试域名)与 APIG 公网入口地址(弹性 IP 地址 · ELB,占位 <ingress_ip>)分别填入端侧 Config.ets 的 APIG_HOST 与 BASE_URL。

方式 B:手动部署

按 docs/BUILD.md §5(控制台)/ §6(脚本)操作,核心一步:

cd harmony_cloud/deploy
cp .env.example .env                  # 填入真实值(区域/项目 ID/资源 ID/库凭据,见 docs/BUILD.md §3.1)
bash deploy.sh --dry-run --yes        # 推荐先预演:只打印将执行的命令,不真正提交
bash deploy.sh                        # 一键:打包 → 部署 8 个函数 → 建触发器 → 发布 API → db-init

云侧脚本依赖 hcloud(KooCLI)与系统 zip,需在 Git Bash / WSL / macOS / Linux 下运行;想分步排障时按 docs/BUILD.md §6 执行(build → apply → db-init)。

完成标志:用以下命令登录,返回 code:0 即云侧已就绪(code:0 表示成功,code:1 业务错误,code:2 未登录);FunctionGraph 控制台 8 个函数状态 ready;APIG 调试域名可访问:

curl -k -X POST https://<ingress_ip>/todo/login -H 'Content-Type: application/json' \
  -H 'Host: <apig_domain>' \
  -d '{"email":"demo@example.com","password":"123456"}'

预期返回(首次 504 属冷启动,重试 2–5 次即恢复):

{"code":0,"message":"ok","data":{"token":"<64位hex>",...}}

4)云端资源配置

如果云侧就绪,端侧只需将 utils/Config.ets 里面的 APIG_HOST和BASE_URL填写完整。获取方式二选一:

A. 手动从官网获取
  1. 取 APIG_HOST(调试域名) → APIG 控制台 → API 分组,找到我们 FunctionGraph 触发器挂载的那个分组,点击,调试域名 就是 APIG_HOST。

  2. 取 BASE_URL(公网入口地址) → APIG 控制台 → 实例管理,点击对应的 APIG 实例,在 「地址管理」 栏里,有个 弹性IP地址(ELB),BASE_URL = https:// + 该 IP。

B. 命令行获取(hcloud)
  1. 查 APIG 实例 ID:

    hcloud APIG ListInstancesV2 --cli-region=cn-south-1 --cli-output=json
    
  2. 查分组,sl_domain 就是 APIG_HOST:

    hcloud APIG ListApiGroupsV2 --instance_id=<第1步的实例id> --cli-region=cn-south-1 --cli-output=json
    
  3. 查公网入口 IP,publicips[].ip_address 就是 BASE_URL(https:// + 该 IP):

    hcloud APIG ShowDetailsOfInstanceV2 --instance_id=<第1步的实例id> --cli-region=cn-south-1 --cli-output=json
    

.env/.env.example 文件是用来一键部署云端的,如果在云资源准备好的情况下,无需 查看 env.example 文件,请直接按照下述方式,直接 从 云端 获取APIG_HOST和BASE_URL APIG_HOST 是调试域名(作 Host 头,供 APIG 路由/证书识别)。 BASE_URL ← APIG 实例的公网入口地址(弹性 IP 地址 · ELB)(https://<ingress_ip>,仅到 host、不含路径;是「入口地址」,不是出口用的弹性公网 IP/EIP); BASE_URL 取值:APIG 实例详情 →「公网入口」→ 弹性 IP 地址(ELB);或 CLI 查 hcloud APIG ShowDetailsOfInstanceV2 --instance_id=<apig_instance_id> --cli-output=json 的 publicips[0].ip_address(见 docs/BUILD.md §5.3)。 ⚠️ 注意:publicips 在响应里位置靠后,要全量读取(或取后半段 / grep publicips),别只看头部;若 publicips 为空数组,说明实例还没开通公网入口。 完整说明见 docs/BUILD.md §5.3 / §7.1。 配置好后,无需curl连通测试,在步骤3我们已经测试过了

5)编译并运行端侧

  1. 编辑 harmony_app/entry/src/main/ets/utils/Config.ets,按上面填 BASE_URL(只到 host、不含路径)与 APIG_HOST。

注:也可以使用agent辅助,输入我现在部署好了云侧环境,请帮我和端侧结合起来。

  1. 编译 — 在 harmony_app 目录内,命令行走方式一/方式二之一(按本机装的工具链选那份,产出的 HAP 相同);也可用 DevEco 图形化(Build → Build HAP(s))或让 Agent 执行下面的命令:

先根据下述步骤,尝试直接编译,如果出现报错,再根据报错调整配置文件

方法 一句话 适用场景
A. 命令行 设环境变量 → hvigorw assembleHap 快速、无 IDE(见下方方式一/方式二)
B. DevEco Studio 打开 harmony_app → Build → Build HAP(s) 日常开发
C. Agent (CI/CD) 流水线中执行 hvigorw assembleHap 自动打包
命令行 · 方式一:装了 DevEco Studio

Windows (PowerShell):

$env:DEVECO_SDK_HOME = "<DevEco安装目录>\sdk"
$env:NODE_HOME       = "<DevEco安装目录>\tools\node"
$env:JAVA_HOME       = "<DevEco安装目录>\jbr"
$env:PATH = "$env:JAVA_HOME\bin;$env:NODE_HOME;<DevEco安装目录>\tools\ohpm\bin;<DevEco安装目录>\tools\hvigor\bin;$env:PATH"

cd harmony_app
hvigorw assembleHap --no-daemon --mode module -p product=default -p module=entry@default --console=plain

macOS / Linux (bash):

export DEVECO_SDK_HOME="/Applications/DevEco-Studio.app/Contents/sdk"
export NODE_HOME="/Applications/DevEco-Studio.app/Contents/tools/node"
export JAVA_HOME="/Applications/DevEco-Studio.app/Contents/jbr"
export PATH="$JAVA_HOME/bin:$NODE_HOME:/Applications/DevEco-Studio.app/Contents/tools/ohpm/bin:/Applications/DevEco-Studio.app/Contents/tools/hvigor/bin:$PATH"

cd harmony_app
hvigorw assembleHap --no-daemon --mode module -p product=default -p module=entry@default --console=plain
命令行 · 方式二:装了 command-line-tools

command-line-tools 在官方下载页提供 Windows (x86_64) / macOS / Linux (x86_64) 三平台包,选与当前环境一致的那份(DevEco Studio GUI 只有 Windows/macOS,Linux 上没有 GUI,只能走这份)。CLT 自带 sdk/、hvigor/、ohpm/、tool/node(不必装 DevEco;在线开发平台 / Linux 常用);JAVA_HOME 可不设。

Windows (PowerShell):

$clt = "E:\command-line-tools"     # 替换为你的 command-line-tools 安装目录
$env:DEVECO_SDK_HOME = "$clt\sdk"  # 必需,指向 ...\sdk 这一层
$env:NODE_HOME       = "$clt\tool\node"
$env:PATH = "$env:NODE_HOME;$clt\hvigor\bin;$clt\ohpm\bin;$env:PATH"

cd harmony_app
hvigorw assembleHap --no-daemon --mode module -p product=default -p module=entry@default --console=plain

macOS / Linux (bash):

CLT=/你的路径/command-line-tools
export DEVECO_SDK_HOME="$CLT/sdk"              # 必需,指向 .../sdk 这一层
export NODE_HOME="$CLT/tool/node"
export PATH="$CLT/tool/node:$CLT/hvigor/bin:$CLT/ohpm/bin:$PATH"
# harmony_app/local.properties:sdk.dir=$CLT/sdk/default/openharmony(与 DEVECO_SDK_HOME 同属 CLT)

cd harmony_app
hvigorw assembleHap --no-daemon --mode module -p product=default -p module=entry@default --console=plain

DEVECO_SDK_HOME 是必需的(缺失报 00303217),指向所用工具链的 sdk 这一层;local.properties 的 sdk.dir 指向 default/openharmony,两者同属一套工具链。切换 OpenHarmony 套件时 runtimeOS/compileSdkVersion 的差异见 docs/BUILD.md §7.3.2。详情见 docs/BUILD.md §7.4。

B. DevEco Studio — 日常开发
  1. 打开 harmony_app 目录(File → Open)
  2. 等待项目同步完成(右下角索引完毕)
  3. Build → Build HAP(s)
  4. 产物位于 harmony_app/entry/build/default/outputs/default/entry-default-unsigned.hap

如果已连接模拟器或真机,也可以直接点击绿色运行按钮 ▶️,自动完成编译 + 安装 + 启动。

C. Agent — 自动打包

在 Agent 中输入下述提示词:

按照下述命令的方式,帮我编译当前目录下的鸿蒙 App

# 设置环境变量(替换为本机路径)
export DEVECO_SDK_HOME="/path/to/sdk"
export NODE_HOME="/path/to/node"
export JAVA_HOME="/path/to/jbr"
export PATH="$JAVA_HOME/bin:$NODE_HOME:/path/to/ohpm/bin:/path/to/hvigor/bin:$PATH"

cd harmony_app
hvigorw assembleHap --no-daemon --mode module -p product=default -p module=entry@default --console=plain

不同开发环境的路径差异详见 docs/BUILD.md §7.4。

完成标志:产物 harmony_app/entry/build/default/outputs/default/entry-default-unsigned.hap 生成。

调试无需签名,上架才需要:build-profile.json5 默认 signingConfigs: [](空),CLT / 命令行调试直接产出未签名 HAP(如上),可安装到模拟器 / 云手机,无需登录华为账号、无需配置证书;未签名 HAP 无法安装到真机(提示签名校验失败)。需要上架应用平台(或在真机安装发布包)时,才配置签名——DevEco Studio「File → Project Structure → Signing Configs」,或走应用市场上架流程,详见 docs/BUILD.md §7.1.1。

  1. 启动设备并安装 HAP(二选一):
    • 图形化(推荐):DevEco Studio → 工具 → 设备管理器 → 启动匹配版本模拟器,把 entry/build/default/outputs/default/entry-default-unsigned.hap 拖进模拟器窗口自动安装。
    • 命令行:启动模拟器(先在 harmony_app/ 下执行,使相对路径生效)——cd harmony_app,再 hdc list targets 看到目标设备(模拟器默认 127.0.0.1:5555),最后 hdc install -r entry/build/default/outputs/default/entry-default-unsigned.hap。找不到 hdc 命令时见开始之前 · 环境与资源「测试设备」行的安装与 PATH 说明。

完成标志:模拟器桌面出现「待办清单」图标,打开后能进入登录页;用 demo@example.com / 123456 登录后进入清单页,新增一条任务立即回显。

全程无需截图:安装与启动是否成功,命令行直接验证——先 hdc list targets 确认设备在线,再执行 hdc shell aa start -b com.example.harmonytodo -a EntryAbility 命令返回 success(或无报错返回)即说明 HAP 已安装、应用已拉起;如果需要验收其他部分(界面交互、业务功能等),也无需截图——通过 hdc 读取布局 / 模拟点击完成,详见 §5 · 虚拟环境下的 UI 自动验收。

4. 完整实践

这条路线面向「理解并复现案例」的读者:从一句大白话的产品想法开始,用 AI 编程助手(vibecoding 对话式开发)从零生成全套端云代码。以下指令以华为云码道「鸿蒙开发智能体」为例,换成其他同类 AI 编程助手同样适用。

新手也不用怕:全程你只需用自己的话描述想法、回答 AI 的问题、确认它给出的方案;需求澄清、技术选型、任务拆分、验收标准这些复杂工作,都由 AI 通过提问引导你完成。每一步都有可观察的完成标志,手动执行的完整命令与故障细节见 docs/BUILD.md。

禁止截图,禁止截图,禁止截图,如果需要确认云手机界面,通过 hdc 读取布局 / 模拟点击完成,详见 §5 · 虚拟环境下的 UI 自动验收。

步骤 1:一句话提出想法,让 AI 帮你想清楚

你发给 AI:

你好,我想做一个鸿蒙待办清单 App:任务要存到云上,手机上能新建、勾选完成、设优先级和截止日期,多台手机登录同一账号还能自动同步。我不太懂技术,请你先问我几个问题,帮我把需求想清楚,讲得通俗一点。
我想用华为云 FunctionGraph(云函数)+ APIG(网关)+ RDS(云数据库)这样的端云一体方案。

提示:加上这最后一句,AI 就会围绕「华为云 FunctionGraph + APIG + RDS 端云一体」这个云方案来提问和设计,让最终结果与本案例保持一致;如果你不想限定云端方案,也可以删掉这句,让 AI 自己对比选型。

AI 会通过提问,用大白话帮你定下这几件事:目标用户、第一个版本做哪些功能、数据存在哪、要不要注册登录、多台设备怎么自动同步、以及「怎样算做完了」(验收标准)。有拿不准的地方,直接反问它「你建议呢」即可。

完成标志:你回答完问题,AI 把你的需求复述一遍,双方对「做什么 / 不做什么」达成一致。

步骤 2:让 AI 把需求整理成文档

你发给 AI:

把刚才确认的需求整理成 requirements.md,用我能看懂的话写清楚:
功能范围、不做什么、数据与隐私要求、以及每项功能「怎样算做对了」。
有不确定的地方继续问我。

提示:requirements.md 是需求文档的文件名,AI 都认识这个约定,你照抄即可;文档具体怎么写、怎么算完整,AI 会代劳并用大白话讲给你听。

完成标志:AI 生成需求文档,并把要点讲给你听;你确认无误后再进入下一步。

步骤 3:让 AI 设计技术方案

你发给 AI:

需求没问题,请设计一套便于学习和部署的端云方案:
数据存在哪、云函数做什么、App 怎么调、密钥放哪、怎么验收。
方案里有需要我做取舍的地方,用大白话讲清楚影响,我确认后再定。

AI 会基于你第 1 步定下的云端方案(华为云 FunctionGraph + APIG + RDS 端云一体,整体架构见第 1 章)来设计,用大白话回答「数据存哪、云函数做什么、端侧怎么调、密钥放哪、怎么验收」,并把需要你拍板的取舍讲清楚(比如要不要注册登录、多端同步怎么做);它通常会把方案整理成 design.md 文件留存。

完成标志:你听懂这套方案(数据存哪、云函数做什么、端侧怎么调、密钥放哪、怎么验收),并完成 AI 给出的取舍选择。

步骤 4:让 AI 拆成可持续推进的任务

你发给 AI:

方案可以。请把开发拆成几小批,每批做完能自己验证,做完一批再进下一批。
先给我任务清单,我确认后你再开始写代码。

提示:AI 会把这份任务清单整理成 tasks.md,并在每完成一批后更新它,方便你随时看到进度。

完成标志:AI 给出分批任务清单(每批写明做什么、怎么验证、完成标志),你确认后进入编码。

步骤 5:按批次生成和验证代码(本地可编译)

从这一步开始,所有「你发给 AI」的指令都可以直接照抄发送,你不用理解里面的术语(比如 hvigor、云侧脚本);第 5 步把批次信息填进模板,后面几步整段发送即可。遇到报错,也把现象直接发给 AI。

注意:这一步只在本地验证两端代码能否各自编译,不涉及真正的云端部署(云端部署在第 6 步)。

每一批使用下面的指令模板,将 {批次} 和 {本批范围} 换成任务清单中的内容:

现在开始第 {批次} 批:{本批范围}。
开始前请读取 requirements.md、design.md 和 tasks.md,确认本批依赖已经满足。
按照任务顺序创建或修改文件;每完成一项就更新 tasks.md。
完成本批后进行本地校验(云侧脚本语法检查、端侧 hvigor debug 构建),
先把编译问题就地修复到通过,再汇总:改了哪些文件、验证结果、已知问题、
下一批的前置条件,然后等待我确认。

完成标志:本批两端代码在本地可编译(端侧 BUILD SUCCESSFUL、云侧脚本语法通过);云端尚未部署,也不需要它参与。

步骤 6:让 AI 部署云侧并自测

你发给 AI:

本地代码已就绪。请先依据 docs/BUILD.md §3 给出云侧部署计划、所需费用和需要我确认的操作(账号实名与云服务开通、区域、RDS / APIG 实例规格),说明影响后等我确认。
确认后完成云侧部署:填好 harmony_cloud/deploy/.env;部署 8 个云函数、创建 APIG 触发器、发布 API;
调用 db-init 初始化数据库(建表 + 种子账号);最后调用 login 接口验证返回 code:0。
报错就在云端就地修复到通过。

提示:涉及付费资源和真实密钥的操作,先说明影响并等我确认后再执行。

完成标志:FunctionGraph 控制台 8 个云函数状态 ready,login 接口返回 code:0,APIG 调试域名可访问。

步骤 7:编译 App、装进模拟器,做端云联调验收

云端已在第 6 步就绪,这一步开始真正「端云打通」。

你发给 AI:

云端已就绪。请先把端侧指向已部署的云端,编译并安装到匹配版本的模拟器,然后执行一轮端云联调验收:
1. 注册账号 → 登录 → 新建任务(勾选完成 / 循环优先级 / 设截止日期 / 删除)→ 再用第二台模拟器登录同一账号,验证 30 秒内自动同步一致 → 退出并换账号登录,验证数据互不可见;
2. 重启 App,检查登录态保留与任务数据正常;
3. 检查 hilog 无 FATAL / JsError / CppCrash。
编译或联调报错时,定位代码、修复、重新编译并回归,直到全部通过。
最后输出端云联调验收表与仍建议人工体验的项目。

完成标志:App 在模拟器里完成一整套端云联调(注册登录 → 任务增删改 → 多端同步全通),AI 输出验收表。

调试无需签名:本步端侧编译 / 安装与 §3 第 5 步相同——使用 CLT / 命令行调试直接产出未签名 HAP,可安装到模拟器 / 云手机,无需配置签名;只有上架到应用平台时才需签名,详见 docs/BUILD.md §7.1.1。

步骤 8:最终复核与收尾(报告 / 安全 / 清理)

你发给 AI:

联调已全部通过。请做一轮最终验收与收尾:
1. 云端复核:login 接口返回 code:0,8 个云函数状态正常;
2. 安全与脱敏检查:.env 和含敏感信息的文件不入库,端侧只含公开的 APIG 调试域名,日志与截图无真实凭据;
3. 输出验收报告(验收环境 / 版本 / 结果),并给出清理与回滚步骤(如何删测试数据、停用或释放资源)。

完成标志:验收报告完整可执行,清理 / 回滚方法明确;任务数据已上云,App 可正常使用。

提示:实践过程中遇到任何报错或不符合预期的行为,直接把现象发给 AI,它会分析代码并修复——这种「描述 → 修改 → 编译 → 复查」的对话式开发,就是本案例推荐的 vibecoding 方式。

5. 验收与排障

业务验收

# 操作 预期结果 证据/检查方式
1 用 demo@example.com / 123456 登录 进入清单页 页面跳转
2 注册新账号 注册成功,需手动登录 显示"注册成功,请登录";users 表新增行,且 sessions 表无新行
3 添加任务 立即回显,重启后仍在 重启 App 后任务仍在
4 勾选完成 / 循环优先级 / 设截止日期 状态随操作变化 页面状态变化;30s 轮询后一致
5 删除任务 从列表消失,pull 后不再出现 刷新后不再回来
6 退出 → 用另一账号登录 数据相互隔离 两个账号任务列表互不可见
7 查看请求日志面板 有请求记录;冷启动 504 会重试后成功 页面底部日志
8 全程操作 无崩溃 hilog 无 FATAL / JsError / CppCrash

技术检查与验收环境

项目 内容
验证日期 2026-08-27(真实云资源全链路部署 + 端到端 API 验证) · 2026-08-19(首次端云联调)
分支 / 标签 / 提交 main @ v1.0.0(仓库整理与脱敏 2026-08-14)
设备与系统 HarmonyOS 模拟器(6.1.0(23))
云区域与关键版本 华为云(单一区域)· FunctionGraph Node.js 18.15 · RDS MySQL 8.0 · APIG 专享版
验收结论 8/8 通过;已知限制:演示环境为公网 IP 直连 + Host 头 + 无认证

虚拟环境下的 UI 自动验收

在模拟器、云手机等虚拟设备上,可以让 AI 通过模拟点击的方式直接完成 业务验收 的整套流程,验证我们的功能;不依赖图像处理 / 截图识别——读取实时布局定位控件,按坐标模拟点击,再读下一次布局断言状态。

每一轮验收 =「转储布局 → 定位控件 → 模拟点击 → 再转储断言」四步循环:

1. 获取布局:hdc shell uitest dumpLayout
   返回当前界面的控件树,含各控件的文本 text、id、控件类型与 bounds 坐标;
2. 定位目标:在布局输出中按文本(或 id / 类型)找到目标控件;
   bounds 形如 [x1,y1][x2,y2],点击点取中心 ((x1+x2)/2, (y1+y2)/2);
3. 模拟点击:hdc shell uitest uiInput click <x> <y>
4. 断言结果:再次 hdc shell uitest dumpLayout,对比前后布局是否符合预期
   (如页面跳转、任务回显、列表新增 / 删除)。

常用命令:

命令 作用
hdc shell uitest dumpLayout 转储当前界面布局(控件树),含 text / id / 控件类型与 bounds 坐标
hdc shell uitest uiInput click <x> <y> 按坐标模拟点击
hdc shell uitest uiInput inputText <text> 向焦点输入框输入文本(注册 / 登录等需填写内容的步骤)
hdc shell uitest uiInput keyEvent <keycode> 模拟按键(如 4 = 返回)
hdc shell uitest uiInput swipe <x1> <y1> <x2> <y2> 模拟滑动(长列表滚动、下拉刷新等可选场景)

给 AI 的操作约定:

  • 每步先重新 dumpLayout,按文本定位,不硬编码坐标:分辨率、状态栏高度、文案调整都会让坐标漂移,布局文本才是稳定依据。
  • 开始前用 hdc shell aa start -b com.example.harmonytodo -a EntryAbility 拉起 App;关键步骤(点登录 / 等云端响应)之间适当 sleep。
  • 登录首次冷启动可能稍慢,点击无响应属预期,稍等重试即可(端侧已内置 3 次重试)。
  • 云手机与模拟器分辨率不同,但每次 dumpLayout 都返回实时 bounds,流程自适应、可脚本化复现。
  • 业务验收 表的 1–8 步均可用上述方式执行,AI 以每步的布局断言作为「证据 / 检查方式」填入验收表。

高频问题

现象/错误码 环节 常见原因 处理与恢复标志
Unexpected token e in JSON 云函数 APIG 把 body base64 编码,函数未解码 加 parseBody();接口返回 code:0
Cannot find module 'mysql2/promise' 打包 依赖没打进 ZIP 重打包含 node_modules;函数能启动
APIG.0101 APIG API 未发布 / 改后未重发 发布 RELEASE;调用不再报 0101
FSS.1020 函数 VPC 委托填成 app_xrole 改配 xrole;函数能连库
首次调用 504 冷启动 VPC 冷启动 ~6s 超过 APIG 后端超时 重试(端侧已内置 3 次);反复 504 用 diag 判定实例劣化
00308018 EPERM 编译 sdk.dir 被 DevEco 改写 修 local.properties;编译通过
时间差 8 小时 联调 mysql2 转 UTC / 函数环境为 UTC dateStrings:true + getBeijingTime();时间显示正确
业务接口全报"服务器错误" 云函数 Todo_DB 库不存在;db-init 若预选库,CREATE DATABASE 永远执行不到 db-init 连接池不预选 database(docs/BUILD.md §6.4)

排查顺序:环境与版本 → 配置与权限 → 网络与资源状态 → 云侧日志 → 接口响应 → 端侧日志。

完整故障库(26 项,含实例劣化级联)与回滚指引:见 docs/BUILD.md §9–§10。

6. 安全边界与清理

安全边界:已做 / 未做

本案例是教学示范代码,不是生产代码。安全上遵循「适当加固 + 明确边界」原则:能以低成本做对的(注入防护、哈希、脱敏)已在代码层落实;需要引入额外服务或显著复杂度的(鉴权体系、密钥管理、限流审计)明确列为未做,留给生产改造。

代码层已做的安全基线:

项目 实现
密码存储 scrypt 加盐哈希(salt:hash hex),校验用 timingSafeEqual 防时序比较泄漏
SQL 注入 全部查询 ? 占位符参数化;动态 SET 子句用硬编码字段白名单
越权防护 所有读写按会话解析出的 user_id 过滤(WHERE user_id = ?),不信任客户端传入归属;taskCreate 幂等 upsert 的重复键路径也已先校验归属(他人任务拒绝)
DEBUG 日志 DEBUG_MODE=1 时日志自动剔除 password/token 字段,明文凭据不入 FunctionGraph 日志
时序枚举 登录对不存在邮箱也执行等代价 scrypt,响应时间不可区分邮箱是否存在
错误信息 catch 分支只回传统一文案"服务器错误",原始异常仅写 console.error
会话签发 仅登录签发 token;注册不产生会话,无孤儿凭证滞留 sessions 表
初始化入口 db-init 不建公网触发器,仅部署脚本内网直调,避免公开初始化入口

明确未做(生产前必须补齐):

未做项 现状与风险 生产改造方向
API 认证 APIG 无认证(NONE),端侧公网 IP 直连 + 跳过证书名校验;签名未实现(ENABLE_SIGN 为占位) APP/IAM 认证 + 自有域名可信证书;或自建可撤销身份机制
Token 生命周期 永不过期、不可撤销、走 URL 查询参数(会落入 APIG/FG 访问日志) expires_at + 刷新/撤销 + Authorization: Bearer 头传输
端侧存储 token 以明文存 Preferences(Session.ets),演示取舍 生产建议 Keystore / 加密存储 + 生物识别
登录限流与审计 无频率限制,可在线爆破;无访问审计 APIG 限流策略 / WAF;登录日志与告警
密码哈希强度 scrypt N=4096(FunctionGraph 受限 CPU 的降参取舍),低于 OWASP 当前推荐量级 迁移到更强 KDF 或提升函数规格后升参
凭据管理 DB 密码/AK-SK 明文环境变量、.env 本地文件 KMS/凭据管理服务,最小权限 + 定期轮换

实验配置与生产要求

项目 本案例演示配置 生产要求
API 认证 无认证(NONE)+ 调试域名(本案例未实现生产鉴权) 自建可撤销身份机制(用户会话/JWT、设备证明或服务端代理)+ 限流 + 审计
会话与授权 自建 users/sessions 表;token 永不过期、不可撤销,走 URL 查询参数;读写按会话归属过滤(已做越权防护) token 短期有效 + 刷新/撤销;Authorization: Bearer 传输;接口级细粒度权限
网络 HTTPS:公网 IP 直连 + Host 头 + remoteValidation:'skip'(跳过证书名校验,演示取舍) HTTPS、自有域名、可信证书
凭据 .env 明文环境变量(函数侧);DEBUG 日志已自动脱敏 password/token 密钥管理、最小权限、定期轮换
数据 演示种子 demo@example.com / 123456 隐私脱敏、备份、保留与删除策略
密码哈希 scrypt N=4096(受限 CPU 的降参数取舍);登录已做等代价哈希防时序枚举 按硬件能力升参并评估加盐

从演示到生产的最小改造清单

安全基线之上,下面 3 项是升级到生产前性价比最高的动手点(华为云服务语义以各自官方文档为准):

  1. Token 改走 Header 并加过期/撤销:当前 token 通过 URL 查询参数传递且永不过期,会落入 APIG / FunctionGraph 访问日志。生产应迁移到 Authorization: Bearer 头传输,sessions 表加 expires_at,实现短期 token + refresh token 轮换,并在服务端校验时判断过期。
  2. API 认证与 AppSecret 收口:生产环境 APIG 切 APP/IAM 认证,端侧需先在 HttpUtil.ets 实现签名;AppSecret 不应出现在端侧可分发代码中——应通过自建代理服务中转调用,或改用无需共享密钥的认证方案。
  3. 登录限流 + 审计:当前登录接口无频率限制。生产应在 APIG 配置限流策略(或接入 WAF),并记录登录成功/失败日志用于审计告警。

另两项常见改造——DEBUG 日志脱敏与错误信息脱敏——本案例已在代码层落实(见上文安全边界表),不再需要。

清理资源

清理会删除实验资源和数据。先核对资源名称、区域、项目与依赖关系,并导出需要保留的数据。

  1. 删除临时 diag 函数;若手动部署时为 db-init 建过公网触发器,一并删除(自动部署默认不建)。
  2. 删除 8 个云函数、RDS 实例、APIG 专享版实例及其分组。
  3. 释放弹性 IP 及其他持续计费资源。
  4. 撤销临时 AK/SK 与权限。
  5. 删除本地 .env、harmony_cloud/deploy/out/(含真实值)与脱敏前日志。

完成标志:计费控制台不再存在本案例的持续计费资源,临时凭据已撤销。

7. 项目导览与进阶

关键目录

HarmonyOS-APP-todo/
├── README.md                        # 案例入口与学习主线(本文件)
├── LICENSE                          # MIT 许可证
├── docs/
│   ├── BUILD.md                     # 完整构建、部署、回滚、清理与全量故障速查
│   └── images/                      # README 案例预览图(overview.png)
├── harmony_app/                     # 端侧:HarmonyOS ArkTS 工程
│   └── entry/src/main/ets/
│       ├── pages/Login.ets + TodoList.ets
│       ├── model/Models.ets         # 共享数据模型
│       └── utils/{HttpUtil, Session, Config}.ets
├── harmony_cloud/                   # 云侧:华为云 Serverless
│   ├── database/{schema.sql, seed.sql}
│   ├── functions/                   # 8 个云函数:login/register/taskCreate/taskUpdate/taskDelete/pull/db-init/diag
│   └── deploy/{deploy.sh, load_env.sh, .env.example, README.md}

完成回顾

完成本案例后,你已经:

  • 走通「端云一体」全链路:从云资源开通、云函数编写打包、一键自动部署,到端侧编译与端云联调验收。
  • 掌握云函数基线规范:base64 body 解码、时区与字符集、连接池、幂等 upsert、冷启动降频与重试。
  • 交付一个可多端云同步的待办清单 App,加上云侧 8 个函数、3 张表与一键部署脚本。

深入阅读与扩展

8. 参考与维护

官方资料与帮助

维护与版本

项目 内容
维护团队 鸿蒙实践案例开发团队
当前案例版本 v1.0.0
最后验证日期 2026-08-27
兼容范围 compile API 24 / 兼容与目标 6.1.0(23);FunctionGraph Node.js 18.15
  • v1.0.0(2026-08-14):端云联调验收通过,仓库整理与脱敏后对外发布。

许可证

本案例采用 MIT。第三方依赖及素材遵循各自许可证。

Introduction

本项目以「一句话需求」为输入,使用编码智能体,自动完成从需求分析到代码生成、云侧部署、端云联调的全链路开发;同时也提供手动部署的方式。核心是「多端云同步待办清单」:端侧只带 APIG 调试域名调云函数,业务校验与数据读写统一收口在云端,数据库凭据只存在云函数环境变量里。

Customize your domain