Files
meida/docs/客户端开发交接-新机器.md
T
xsl 256f850a61 docs: 客户端开发交接文档(新机器开工自包含)
客户端开发将转移到另一台机器,本文沉淀本机全部实操经验:
- 环境搭建 + CLI 构建 + 首次自动签名(Account Kit 前置,signingConfigs 现为空)
- AGC 现状:App ID 6917613748100335131 已建、包名核对一致;待办三步
  (自动签名→指纹录入→开 Account Kit 标准登录)
- 后端联调:后端在原开发机 WSL 8666 端口,两种连法(局域网直连/自建);
  DEFAULT_BASE_URL(127.0.0.1:8000) 已过时的说明;dev-token 为主力调试通道
- ArkTS 铁律七条(新增 @Builder 按值传参不随 @State 刷新的 2488 教训)
- hdc/uitest 实测命令与坑(MSYS_NO_PATHCONV、相对路径、dumpLayout 解析法)
- 真机修过的五个坑清单 + 待办任务与开工验收基线
2026-08-15 22:00:12 +08:00

9.8 KiB
Raw Blame History

客户端开发交接文档(新机器)

创建:2026-08-15 | 用途:客户端(鸿蒙 FE)开发转移到另一台机器,本文自包含开工所需的一切。 上游文档:docs/开发任务包/README-FE批次.md(FE 协作规程与 API 速查)、docs/本地联调指南.md(后端起停)、docs/前置开通清单-云资源与资质.md(AGC 与外部资源)。


0. 一句话现状

FE 骨架已完成并通过真机验证的闭环:dev-token 登录 → 首页配额/对话 → 报告创建(校验/提交/轮询)→ 结果页 32 维渲染 → 40920"本期已生成"对话框。全部代码在 main 分支,直接 clone 即得。

仓库 地址 内容
主仓库 https://git.xiangsilian.com/xsl/meida.git 文档 + 客户端工程(app/)
后端仓库 https://git.xiangsilian.com/xsl/meida_backend.git FastAPI 后端(原开发机 WSL 运行中)

1. 新机器环境搭建

1.1 装软件

  1. DevEco Studio(含 HarmonyOS SDK,API 6.1.1(24))——默认装到 C:\Program Files\Huawei\DevEco Studio\
  2. 手机开启开发者模式 + USB 调试(设置 → 关于 → 连点版本号 → 开发者选项)

1.2 拿代码 + 用 DevEco 打开

git clone https://git.xiangsilian.com/xsl/meida.git
# 用 DevEco 打开 meida/app 工程(File → Open)

1.3 首次必做:自动签名(Account Kit 的前置)

工程当前 build-profile.json5 的 signingConfigs 为空(历史包都是 unsigned)。 DevEco Studio → File → Project Structure → Signing Configs → 勾选 "Automatically generate signature",登录华为开发者账号生成调试证书。没做这步,华为账号授权页拉不起来。

1.4 CLI 构建(可选,配了 IDE 签名后 CLI 包也会带签名)

cd <repo>/app
export DEVECO_SDK_HOME="C:/Program Files/Huawei/DevEco Studio/sdk"
"C:/Program Files/Huawei/DevEco Studio/tools/node/node.exe" \
  "C:/Program Files/Huawei/DevEco Studio/tools/hvigor/bin/hvigorw.js" \
  --mode module -p module=entry@default assembleHap --analyze=false --daemon=false
# BUILD SUCCESSFUL 即通过;产物 app/entry/build/default/outputs/default/

路径按新机器实际安装位置调整。"No signingConfigs" WARN 在未配签名时正常。


2. AGC / 华为侧配置

已完成:AGC 应用已创建——App ID 6917613748100335131,包名 com.xiangsilian.app(与工程 app/AppScope/app.json5 一致)。App ID 不需要写进代码(Account Kit 靠签名证书+包名识别应用)。

待办三步(详见前置开通清单 §1):

# 事项 位置
1 自动签名生成调试证书 DevEco(§1.3,做完告诉我/记录指纹)
2 调试证书 SHA256 指纹录入 AGC AGC「我的项目 → 应用信息 → 证书指纹」
3 开通 Account Kit(标准登录即可,别申请"获取手机号"权限——企业专属,申请必拒) AGC「我的项目 → 添加服务」

个人开发者权限边界:标准登录(UnionID/昵称/头像)✅;一键登录(手机号)❌ 企业专属。我们只需要 UnionID。


3. 后端联调(重点:后端不在新机器上)

后端跑在原开发机的 WSL(Ubuntu-22.04 /home/xsl/meida_backend),端口 8666(不是 8000)。两种连法:

方案 做法 适用
A. 连原机后端 新机器与原机同局域网;App 登录页输入 http://<原机局域网IP>:8666;原机需后端监听 0.0.0.0 + Windows 防火墙放行 8666 最快,推荐
B. 新机器自建后端 clone meida_backend,按 docs/本地联调指南.md 起(需 WSL + PG + Redis + .env 密钥) 需要独立调试后端时

baseUrl 机制:FE 登录页有"服务器地址"输入框,输一次持久化(preferences)。代码里 core/AuthStore.ets 的 DEFAULT_BASE_URL = 'http://127.0.0.1:8000' 已过时,实际一律用登录页输入 8666;真机别用 127.0.0.1(那是手机自己)。

联调期登录通道:POST /api/v1/auth/dev-token,请求体 {"device_key": "<任意字符串>"},无需华为/短信——FE 已封装(AuthStore.loginByDevToken),是主力调试通道。


4. 工程结构与已完成内容

app/entry/src/main/ets/
├── core/
│   ├── ApiClient.ets    # 信封解析(非200 HTTP 也先验 {code,...} 信封形状再判成败)
│   ├── ApiTypes.ets     # ApiError(唯一可抛异常类型)
│   └── AuthStore.ets    # 双令牌持久化 + dev-token 登录(postWithoutAuth 通道)
├── pages/
│   ├── LoginPage        # 地址输入 + dev-token 登录
│   ├── HomePage         # 配额卡片 + 报告入口
│   ├── ChatPage         # AI 对话(F4)
│   ├── ReportCreatePage # 问卷六字段 + 校验 + 提交 + 轮询(F3)
│   ├── ReportResultPage # 32 维渲染 + 重新生成(F3)
│   └── ProfilePage / TaskCenterPage(F1/F2)
└── components/f2 f3 f4/ # TaskPollingPanel(任务轮询)、ReportTypes 等公共件

路由注册在 entry/src/main/resources/base/profile/main_pages.json(新页面必须登记)。

真机修过的坑(别回退):

  1. dev-token 登录必须走 postWithoutAuth(带鉴权的 post 会因未登录自拦 40100)
  2. ApiClient 非 200 HTTP 状态(409/429 等)body 仍是统一信封,先验信封形状再判成败——业务错误 40920/40301/42910 靠这条透传
  3. DatePicker 默认折叠成"修改 ▼"(展开态半屏,会把必填项和提交键挤出视野)
  4. 轮询成功自动跳转有兜底:"查看报告"按钮 + replaceUrl().catch
  5. 表单校验三件套:汇总条点名缺失字段 + 自动滚动到首个错误 + 字段级红字(@Builder $$ 传参,见 §5.7)

5. ArkTS 严格模式铁律(实测踩坑,违反必炸编译/运行)

  1. 泛型调用必须显式类型参数:ApiClient.post<void>(...)——裸 post(...) 报 arkts-no-inferred-generic-params
  2. 请求体用具型 Record 字面量:const req: Record<string, Object> = { 'k': v };禁止 interface→Record 强转、禁止内联对象类型做泛型参数
  3. wire 响应类型用具名 interface,字段名对齐后端 JSON
  4. throw 只抛 ApiError;未知异常包 new ApiError(50000, '请求失败,请检查网络', '请稍后重试')
  5. 对象字面量必须有具名类型;async 逻辑放具名方法(箭头链泛型推断受限)
  6. router 从 @kit.ArkUI 导入(@ohos.router 编译不过)
  7. @Builder 按值传参不随 @State 刷新(2026-08-15 新踩):@Builder f(label: string, err: string) 的 err 永远停在初始值;必须 $$ 按引用传参——@Builder f($$: FieldLabelParams) + 调用传对象字面量 { label: '...', err: this.xxxErr, ... }

6. 真机调试工具箱(实测命令与坑)

HDC="C:/Program Files/Huawei/DevEco Studio/sdk/default/openharmony/toolchains/hdc.exe"

"$HDC" list targets                                    # 看设备
"$HDC" -t <target> shell aa start -a EntryAbility -b com.xiangsilian.app   # 拉起 App

cd <产物目录> && "$HDC" -t <t> install -r entry-default-*.hap   # 装(本地路径必须相对!绝对路径会被拼错)

# UI 注入(自动化验证主力)
"$HDC" -t <t> shell uitest uiInput click <x> <y>
"$HDC" -t <t> shell uitest uiInput inputText <x> <y> <文本>    # 偶发 Invalid parameters 时改用:
"$HDC" -t <t> shell uitest uiInput text <文本>                 # 输入到已聚焦输入框
"$HDC" -t <t> shell uitest uiInput keyEvent Back               # 收键盘
"$HDC" -t <t> shell uitest uiInput swipe <x1> <y1> <x2> <y2> 600   # 滚动=上滑

# 布局dump + 截图(拿坐标/验证UI状态)
MSYS_NO_PATHCONV=1 "$HDC" -t <t> shell uitest dumpLayout -p /data/local/tmp/layout.json
MSYS_NO_PATHCONV=1 "$HDC" -t <t> file recv /data/local/tmp/layout.json layout.json   # recv 到当前目录
MSYS_NO_PATHCONV=1 "$HDC" -t <t> shell snapshot_display -f /data/local/tmp/shot.jpeg

坑:

  • Git Bash 会把 /data/... 改写成 C:/Program Files/Git/data/...——所有带设备路径的命令前加 MSYS_NO_PATHCONV=1
  • install 的本地路径必须 cd 到目录后用相对路径,绝对路径会被 hdc 拼接错
  • dumpLayout 是 JSON,用 python 解析 attributes.bounds(格式 [x1,y1][x2,y2])取中心点坐标再注入点击
  • 键盘没收回时 dump 里会混入输入法节点,先 keyEvent Back

7. 待办任务(优先级序)

# 任务 前置 说明
1 FE 华为账号登录接入 §2 三步完成 @kit.AccountKit 的 AuthorizationButton / createAuthorizationCredential 拿 id_token → POST /api/v1/auth/huawei,请求体 {"id_token": "<JWT>"},返回与 dev-token 相同的双令牌结构。后端已就绪(OIDC 验签 + UnionID 映射 id_user_identity,packages/identity/huawei.py + apps/api/routers/auth.py:124)
2 FE 邮箱验证码登录 UI 后端 E1(邮箱登录,原机做) 输入邮箱→发码→验码;接口形态参照原 `/auth/sms/send
3 真实照片上传 后端 E2(本地存储驱动) 报告页"照片(模拟)"改真实上传;接口以 E2 实现为准
4 已知体验债 无 轮询完成自动跳转在部分场景仍依赖兜底按钮(@Builder 传函数真机失效的深层原因未根治);AppStorage 重启丢 lastReportId 时 40920 对话框无"查看报告"入口

8. 新机器开工验收基线(先复现,再开发)

  1. clone 后 CLI 构建 BUILD SUCCESSFUL
  2. 自动签名配置成功,装机跑起 App
  3. 原机后端 8666 可达(方案 A)→ 登录页输地址 + dev-token 登录成功
  4. 走通一次报告流(新用户周期内可完整生成;已生成过则 40920 对话框属正常)