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

173 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 客户端开发交接文档(新机器)
> 创建: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 打开
```bash
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 包也会带签名)
```bash
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. 真机调试工具箱(实测命令与坑)
```bash
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|verify`(键名以 E1 实现为准) |
| 3 | 真实照片上传 | 后端 E2(本地存储驱动) | 报告页"照片(模拟)"改真实上传;接口以 E2 实现为准 |
| 4 | 已知体验债 | 无 | 轮询完成自动跳转在部分场景仍依赖兜底按钮(@Builder 传函数真机失效的深层原因未根治);AppStorage 重启丢 lastReportId 时 40920 对话框无"查看报告"入口 |
---
## 8. 新机器开工验收基线(先复现,再开发)
1. clone 后 CLI 构建 `BUILD SUCCESSFUL`
2. 自动签名配置成功,装机跑起 App
3. 原机后端 8666 可达(方案 A)→ 登录页输地址 + dev-token 登录成功
4. 走通一次报告流(新用户周期内可完整生成;已生成过则 40920 对话框属正常)