docs: 新增双端合入主干交接文档,修正 CLAUDE.md 过期信息
- documents/双端合入主干交接文档.md:分支状态、平板/手机开发状态、合并内容、 开发规则、验证覆盖、待决事项与注意事项 - CLAUDE.md:版本 1.8.7 (87);JDK 17 运行 / Java 1.8 编译目标;模拟器路径与 AVD 名(AeroLogic_Phone sw=394dp / AeroLogic_Tablet);运抵长按浮层与已删除的 补充信息页;分支约定处链接交接文档 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
219
documents/双端合入主干交接文档.md
Normal file
219
documents/双端合入主干交接文档.md
Normal file
@@ -0,0 +1,219 @@
|
||||
# 平板 + 5.5 寸手机合入主干后的交接
|
||||
|
||||
> 日期:2026-10-11 | 基线提交:`origin/main @ 131eb03` | 在线版:https://claude.ai/artifact/N8cWdTcMAzk9N86NSPevTC
|
||||
>
|
||||
> 本文描述合并当天的状态。分支、版本号等信息如有变化,以仓库为准。
|
||||
|
||||
## 接手前先知道这几件事
|
||||
|
||||
1. **只有一条开发分支:`main`。** 手机适配分支 `feature/phone-ui-adaptation` 已于 2026-10-11 合入,平板和 5.5 寸手机以后都在 `main` 上一起开发。
|
||||
2. **业务以平板为准,手机只做界面。** 两端共用 ViewModel、接口、表单项、筛选入参和默认值;差异只能出现在布局(View)层。
|
||||
3. **同一个页面有两份同名布局**:`res/layout-sw600dp/` 是平板,`res/layout/` 是手机。改平板页面时要同时检查手机布局和这个页面的所有弹框。
|
||||
4. **有两件事等人拍板**:ULD 保存可能报 500(问题清单 #36),以及手机独有的几个界面功能留不留(见第 6 节)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 仓库与分支
|
||||
|
||||
| 分支 / 位置 | 提交 | 状态 | 建议 |
|
||||
|---|---|---|---|
|
||||
| `origin/main` | 131eb03 | 唯一开发分支 | 以后所有开发从这里拉分支、合回这里。 |
|
||||
| 本地 `main`(主 checkout `~/Development/Projects/aerologic-app`) | 871fa4c | 落后 30 个提交 | 合并是在另一个 worktree 里推送的,主 checkout 还没同步。到那个目录执行 `git pull --ff-only`。 |
|
||||
| `feature/phone-ui-adaptation`(本地 + 远端) | 42647c2 | 已完整合入 | 不要再往上提交。确认无人使用后可以删除(删除远端分支前先跟团队确认)。 |
|
||||
| `worktree/phone-adaptation`(仅本地) | 42647c2 | 已完整合入 | 可删除。 |
|
||||
| `merge/phone-into-main`(仅本地,worktree `~/.herdr/worktrees/aerologic-app/worktree-phone-adaptation` 当前检出) | 131eb03 | 与 main 相同 | 合并时用的临时分支。可以 `git worktree remove` 这个 worktree 后删除分支。 |
|
||||
|
||||
合并提交 `131eb03` 的第一父提交是原 main(`871fa4c`),第二父提交是手机分支(`42647c2`),所以 `git log --first-parent main` 仍然是平板的历史。两条线的分叉点是 `9c4588e`:分叉后 main 有 58 个平板提交,手机分支有 29 个提交,合并时共 45 个文件冲突。
|
||||
|
||||
## 2. 平板与手机的开发状态
|
||||
|
||||
**平板(10 寸横屏)**
|
||||
|
||||
- 功能完整,即合并前 main 上的全部功能。
|
||||
- 合并没有改平板的业务逻辑。冲突的平板布局用三方合并放进了 `layout-sw600dp/`,内容就是 main 最新版。
|
||||
- 已有手机变体的页面:20 个 Activity 布局 + 11 个弹框布局在 `layout-sw600dp/`。
|
||||
- 其余平板页面(舱单、理货、组装、航班管理等)只有一份布局,放在 `res/layout/`,没有手机版。
|
||||
|
||||
**手机(5.5 寸竖屏)**
|
||||
|
||||
- 设计稿 01~11 的 11 个入口全部完成,并已按 main 的新平板功能补齐(见第 3 节)。
|
||||
- 手机首页是 `module_p` 的 `PDAEnterActivity`,菜单是手写清单(`GjViewModel` / `GnViewModel`),按登录权限串过滤。
|
||||
- 设计参考:`documents/5.5寸手持端设计文件/`,技术方案 `documents/5.5寸手持端适配技术方案.md`。
|
||||
|
||||
### 手机已适配页面
|
||||
|
||||
| 首页入口 | 页面(Activity) | 模块 | 说明 |
|
||||
|---|---|---|---|
|
||||
| 国际 · 出港移库 | `IntExpMoveActivity`、`IntExpMoveEditActivity` | gjc | 详情 / 编辑与平板共用同一个 Activity,手机布局为「运单详情」样式。 |
|
||||
| 国际 · 出库交接 | `IntExpOutHandoverActivity`、`IntExpOutHandoverDetailActivity` | gjc | 底部栏带「允许装机」「配运」次按钮。 |
|
||||
| 国际 · 出港计重 | `GjcWeighingListActivity`、`GjcWeighingStartActivity`、`GjcWeighingRecordListActivity`、`GjcWeighingRecordDetailsActivity` | gjc | 另有手机专属 `GjcWeighingWbDetailActivity`(运单详情)。 |
|
||||
| 国际 · 出港运抵 | `IntExpArriveActivity` | gjc | 手机专属 `IntExpArriveSubOrderActivity`(分单明细)、`IntExpArriveReceiptActivity`(分单回执);主单回执用两端共用的 `CustomsResponseActivity`。 |
|
||||
| 国际 · 出港查询 | `GjcQueryActivity`、`GjcQueryDetailsActivity`、`LogDetailActivity`(运单追踪) | gjc / app | |
|
||||
| 国际 · 出港仓库 | `IntExpStorageUseActivity` | gjc | 平板的「勾选 + 底部批量」在手机上改为卡片四按钮:清仓 / 修改库位 / 出库 / 入库。 |
|
||||
| 国际 · 进港仓库 | `IntImpStorageUseActivity`、`IntImpQueryDetailsActivity` | gjj | 接口前缀是 `IntImpStorage`,不是 `IntImpStorageUse`。 |
|
||||
| 国际 · 进港查询 | `IntImpQueryActivity` | gjj | |
|
||||
| 国际 · 提取出库 | `IntImpPickUpDLVActivity` | gjj | 手机专属 `IntImpPickUpDetailActivity`。 |
|
||||
| 国际 · ULD 管理 | `UldListActivity`、`UldEditActivity` | app | 一套编辑布局覆盖新增 / 修改 / 详情。 |
|
||||
| 国内 · 进港移库 | `GnjMoveStashListActivity` | app | 业务归属国内进港移库(DomImpMove)。手机专属 `GnjMoveStashDetailActivity`、`GnjMoveStashPhotoActivity`。 |
|
||||
|
||||
手机首页还有一批旧的 PDA 竖屏入口(国际:普货收运、板箱组装、板箱过磅、进港理货;国内:出港收运、出港复磅、出港存放、进港卸机、货物转运、转运记录、事故签证、单证交接)。它们是 `module_p` 原有页面,不在这次设计稿范围内,合并没有改动,也没有验证。
|
||||
|
||||
## 3. 这次合并做了什么
|
||||
|
||||
### 冲突处理原则
|
||||
|
||||
- **布局**:平板布局取 main 最新版,三方合并进 `layout-sw600dp/`,没有冲突残留。手机布局保留原样,再逐页补上 main 新增的业务字段和操作。
|
||||
- **Bean / ViewModel**:一律取平板逻辑。手机只保留它额外需要的展示字段(如 `opUserDisplay`、统计字段)。
|
||||
- **Manifest**:取手机分支版本(屏幕方向统一为 `unspecified`),再补上 main 新增的 Activity。
|
||||
|
||||
### main 的平板功能同步到手机
|
||||
|
||||
| 页面 | 同步到手机的内容 |
|
||||
|---|---|
|
||||
| 出港运抵 | 卡片显示海关放行、运单类型;筛选加分单号;回执改走平板同一接口和回执页;长按菜单加「删除申报」(手机底部弹框)。 |
|
||||
| 出库交接 | 卡片显示装机状态;底部栏加「允许装机」「配运」;配运弹框做了手机变体。 |
|
||||
| 出港移库 | 详情和编辑改用平板的 `IntExpMoveEditActivity`,删除手机专属 `IntExpMoveDetailActivity`;卡片加「编辑」;筛选加卸货站。 |
|
||||
| 出港 / 进港仓库 | 清仓弹框加备注,卡片显示清仓备注;入库、出库弹框可填件数和重量(出库弹框新做了手机变体);进港卡片件数取 `pcLabel`。 |
|
||||
| 开始计重 | ViewModel 整体取平板版本:加运单号、地磅重量、平板车、托盘信息,运抵重量按平板公式自动计算;航班日期 / 航班号 / 航程可编辑。 |
|
||||
| 计重 / 计重记录 | 计重列表加「新增」按钮;计重记录加航班号筛选,卡片加「运抵申报」入口。 |
|
||||
| 计重明细 | 重量与托盘自重按平板逻辑联动(和恒定),同时保留手机的输入原文处理(避免光标跳动)。 |
|
||||
| 进港查询 | 筛选加出库状态。 |
|
||||
| ULD | 采用平板的来源列表与 HFE 默认值;卡片显示所在港 / 位置。 |
|
||||
|
||||
### 手机按平板收敛的地方(使用上能感觉到)
|
||||
|
||||
- 删除了平板不传的查询入参:`likeNo`(8 位运单号模糊查询)、进港移库的航班日期 / 航班号 / 特码、出港移库的特码。
|
||||
- 恢复平板默认查询值:计重、计重记录、提取出库等页面默认查当天,首次打开常常是空列表,属于预期行为。
|
||||
- 补齐平板有而手机缺的筛选项:运抵分单号、进港查询出库状态、计重记录航班号、进港移库承运人、出港移库卸货站。
|
||||
- ULD 编辑去掉平板没有的「进港航班号」和手机额外加的必填校验(影响见 #36)。
|
||||
|
||||
## 4. 以后怎么开发
|
||||
|
||||
项目根目录的 `CLAUDE.md`「5.5 寸手持端双形态适配规范」一节是完整规范,`.claude/skills/phone-adapt/` 是手机适配流程。下面是最常用的几条。
|
||||
|
||||
### 布局双变体的硬性约束
|
||||
|
||||
- 两个变体**文件同名**:平板 `layout-sw600dp/xxx.xml`,手机 `layout/xxx.xml`。禁止用 `xxx_phone.xml` 加代码判断,那样会生成另一个 Binding 类,进页面就 `ClassCastException`。
|
||||
- 两个变体的 `<variable>` 名称和类型必须一致。
|
||||
- Kotlin 里引用的控件 id 两边都要有;只有一边有的 id 在 Binding 里是可空的,代码里要写 `binding.xxx?.`。
|
||||
- 弹框同样做双变体,并在构造参数里切换位置:`BaseDialogModel(if (DeviceUtil.isPhone()) DIALOG_TYPE_BOTTOM else DIALOG_TYPE_CENTER)`。
|
||||
- Manifest 新 Activity 的 `screenOrientation` 写 `unspecified`,由 `BaseActivity` 按设备锁方向。
|
||||
|
||||
### 平板改了一个已适配页面,标准步骤
|
||||
|
||||
1. 改平板布局(`layout-sw600dp/`)和 ViewModel。
|
||||
2. 打开同名手机布局(`layout/`),补上同样的字段、筛选项和操作入口。平板的批量按钮在手机上可以改成卡片按钮或 `PhoneBottomBar` 的次按钮(`subAction1Text` / `subAction2Text`)。
|
||||
3. 检查这个页面用到的每一个 DialogModel,新弹框要做手机变体。
|
||||
4. 手机 Tab 角标、计数这类只有手机用的额外请求,放在 `phoneExtrasEnabled` 一类的开关后面,不能改变平板的请求。
|
||||
5. 两台模拟器各走一遍,再编译 `./gradlew assembleDebug`。
|
||||
|
||||
### 手机端不能做的事
|
||||
|
||||
- 不能新增平板没有的查询入参(后端口径:手机筛选一律与平板一致,后端不认识的参数会被静默忽略)。
|
||||
- 不能改写平板的默认查询值(如默认当天)。
|
||||
- 不能少平板的表单项或校验,也不能多加平板没有的校验。
|
||||
|
||||
### 新做一个手机页面
|
||||
|
||||
按 `CLAUDE.md`「手机版页面改造步骤」:`git mv` 平板布局到 `layout-sw600dp/` → 写同名手机布局 → 优先复用 `module_base/.../ui/weight/phone/` 下的组件(`PhoneSearchBar`、`PhoneFormRow`、`PhoneBottomBar` 等)→ 到 `GjViewModel` / `GnViewModel` 加首页菜单入口(最容易忘,忘了在手机上就进不去)。
|
||||
|
||||
## 5. 已验证与未验证
|
||||
|
||||
验证环境:手机模拟器 `AeroLogic_Phone`(720×1440,API 31,sw=394dp),平板模拟器 `AeroLogic_Tablet`(1280×800,sw=800dp),连内网测试服务。
|
||||
|
||||
| 项目 | 结果 | 说明 |
|
||||
|---|---|---|
|
||||
| Debug 编译 | ✅ 通过 | 合并后 `assembleDebug` 成功。 |
|
||||
| 手机 11 个入口主流程 | ✅ 已验证 | 列表、Tab、筛选、详情、弹框打开,无崩溃。 |
|
||||
| 平板回归(已适配的页面) | ✅ 已验证 | 主要页面打开、筛选、弹框,无崩溃,布局为 main 最新版。 |
|
||||
| 开始计重自动计算 | ✅ 已验证 | 地磅 500、托盘 2 个 × 18 → 运抵重量 464,与平板公式一致。新增模式头部不再显示 "null kg"。 |
|
||||
| 手机新弹框(出库 / 入库 / 清仓 / 配运 / 删除申报) | ⚠️ 只打开过 | 样式和字段都确认了,没有点提交,以免改动测试数据。 |
|
||||
| 所有写操作(申报、出入库、清仓、保存、移库、拍照上传) | ⚠️ 未提交验证 | 合并后没有真实提交过。建议用测试数据逐个点一次提交,平板和手机都要。 |
|
||||
| 海关回执页有内容时的显示 | ❌ 未验证 | 测试数据里没有带回执的运单。 |
|
||||
| ULD 管理、国内进港移库 | ❌ 只编译过 | 合并后的改动没在模拟器上点过。 |
|
||||
| 手机首页旧 PDA 入口 | ❌ 未验证 | 不在本次范围。 |
|
||||
| Release 包、真机(交付手持机 / 平板) | ❌ 未验证 | 只在模拟器上跑过 Debug 包。 |
|
||||
|
||||
## 6. 已知问题与待决事项
|
||||
|
||||
### 需要决定
|
||||
|
||||
- **ULD 保存可能报 500(问题清单 #36)。** 后端 `saveUld` 在缺少最大装载容积 / 最大载重时返回 500。之前只有手机做了必填拦截;按「以平板为准」去掉之后,两端都可能报错。可选做法:让后端修,或者在平板加同样的必填校验(再同步到手机)。
|
||||
- **手机独有的界面功能目前保留。** 它们只在手机上发请求,不影响平板,所以合并时留下了:
|
||||
- 各列表的「待 / 已」Tab,以及 Tab 角标额外发的统计请求;
|
||||
- 进港移库「已移库」Tab(调用平板不用的 `searchMoved` 接口);
|
||||
- 出港运抵分单明细页、分单回执页;ULD 状态显示为「可用 / 维修」;ULD 入库时间保存时补 `00:00:00`。
|
||||
|
||||
如果要求两端严格一致,需要逐项删除。
|
||||
|
||||
### 对用户的行为变化(属于预期)
|
||||
|
||||
- 手机列表默认查当天,首次打开常常为空,要在筛选里清掉日期。
|
||||
- 手机输入 8 位运单号不再能模糊查到(去掉了 `likeNo`),和平板一致。
|
||||
|
||||
### 后端缺口(问题清单 #35~#41,待后端处理)
|
||||
|
||||
- ULD 列表按 uld 搜索返回 500;`saveUld` 缺 maxVolume / maxWeight 返回 500(#36)。
|
||||
- `IntImpStorage/pageQuery` 列表过滤全部不生效。
|
||||
- 出港仓库列表与统计的口径不一致。
|
||||
- 已移库数据没有 `mawbId`,无法补传照片。
|
||||
|
||||
完整内容和每一项的后端答复在 `documents/后端接口对接问题清单.xlsx`。这份表是和后端对接的正式文档,新发现的缺口要继续记在里面。
|
||||
|
||||
### 其他待办
|
||||
|
||||
- `PhoneSearchBar` 还没接 AutoQuery 联想(`AutoQueryManager` 只接了平板组件)。
|
||||
|
||||
## 7. 容易踩的坑
|
||||
|
||||
1. **API 文档的 token 提交进了仓库。** `.mcp.json` 里写着 api-doc MCP 的 `Authorization: Bearer …`,并且已被 git 跟踪。建议轮换这个 token,改为从环境变量或本地未跟踪的配置读取。
|
||||
2. **换行符混用,没有 `.gitattributes`。** main 原有文件多为 CRLF,手机分支新建的文件是 LF。编辑时保持文件原有换行符,否则会出现整文件 diff,合并和 review 都会很难看。
|
||||
3. **没有手机变体的平板页面,在手机上会直接显示平板布局。** 给手机首页加入口前,必须先做手机布局。
|
||||
4. **后端会静默忽略不认识的参数。** 猜错参数名会得出「后端不支持」的误判。入参出参一律用 api-doc MCP 核对,流程见 `.claude/skills/phone-adapt/references/api-doc.md`。
|
||||
5. **XML 里 `??` 兜底不生效。** 网络层会把 JSON null 转成空串,`??` 只判断 null。要在 Bean 上写计算属性(如 `agentDisplay`、`opUserDisplay`)。
|
||||
6. **RecyclerView 里给 item 设 `GONE` 不会收起高度。** Tab 过滤要在数据层过滤后整体 `refresh`。
|
||||
7. **Intent 传递的 Bean 里 `@Transient` 字段会变成 null**(`checked`、`showMore` 等)。接收方要 `.map { it.copy() }`。
|
||||
8. **同页多个手机复合组件会串状态。** 新写同类组件要覆写 `dispatchSaveInstanceState` / `dispatchRestoreInstanceState`(见 CLAUDE.md)。
|
||||
|
||||
第 5~8 条在 CLAUDE.md「常见编译错误速查」里都有详细说明和修复方式。
|
||||
|
||||
## 8. 环境与工具
|
||||
|
||||
- **工具链**:Gradle 用 Java 17 运行(`mise.toml`),编译目标是 Java 1.8;当前版本 1.8.7(versionCode 87)。
|
||||
- **内网**:测试服务器在内网,模拟器要在内网环境下才能拉到数据,否则提示「接口访问失败」。测试账号向项目负责人索取(不写在文档里)。
|
||||
- **登录不保留**:冷启动后要重新登录。
|
||||
- **Debug 直达页面**:`app/src/debug/AndroidManifest.xml` 把适配页设为 exported,可以直接拉起(只在 Debug 包生效)。
|
||||
- **平板模拟器没有物理按键**,`adb shell monkey` 拉起会失败,改用 `am start`。
|
||||
- **手机模拟器**上软键盘弹出时按返回键,有时会被吞掉并退出到桌面,不是崩溃。
|
||||
- **mobile-mcp** 偶尔识别不到 `emulator-5554`,可以直接用 adb。
|
||||
|
||||
```bash
|
||||
# 启动模拟器(模拟器可执行文件在 Homebrew 的 android-commandlinetools 下)
|
||||
/opt/homebrew/share/android-commandlinetools/emulator/emulator -avd AeroLogic_Phone &
|
||||
/opt/homebrew/share/android-commandlinetools/emulator/emulator -avd AeroLogic_Tablet &
|
||||
|
||||
# 编译安装
|
||||
./gradlew assembleDebug
|
||||
adb -s emulator-5554 install -r app/build/outputs/apk/debug/*.apk
|
||||
|
||||
# 拉起登录页(平板没有物理键时用这个)
|
||||
adb -s emulator-5556 shell am start -n com.lukouguoji.aerologic/com.lukouguoji.module_base.LoginActivity
|
||||
|
||||
# 确认设备形态识别
|
||||
adb -s emulator-5554 logcat -d -s BaseActivity:D # PHONE(sw=394dp) / TABLET(sw=800dp)
|
||||
```
|
||||
|
||||
## 9. 关键文件索引
|
||||
|
||||
| 文件 | 用途 |
|
||||
|---|---|
|
||||
| `CLAUDE.md` | 项目规范总入口,包括双形态适配规范、分支约定、常见错误速查。 |
|
||||
| `CHANGELOG.md` | [Unreleased] 下「手机适配分支合入主干 · 2026-10-11」是本次合并的完整记录。 |
|
||||
| `documents/后端接口对接问题清单.xlsx` | 与后端对接的正式问题清单(#1~#41)。 |
|
||||
| `documents/5.5寸手持端设计文件/` | 手机设计稿(HTML)。 |
|
||||
| `.claude/skills/phone-adapt/` | 手机适配流程,含 api-doc、组件、平板安全、验证等参考。 |
|
||||
| `module_base/.../util/DeviceUtil.kt` | 手机 / 平板判定(sw ≥ 600dp 为平板)。 |
|
||||
| `module_base/.../ui/weight/phone/` | 手机公共组件,适配器在 `PhoneWidgetKtx.kt`。 |
|
||||
| `module_base/.../MyApplication.kt` | AutoSize 设计基准(手机竖屏 390×844,平板横屏 1152×720)。 |
|
||||
| `module_p/.../ui/enter/gj/GjViewModel.kt`、`gn/GnViewModel.kt` | 手机首页国际 / 国内菜单清单。 |
|
||||
| `app/.../HomeFragment.kt` | 平板首页菜单,手机入口的权限串和路由要以它为准。 |
|
||||
Reference in New Issue
Block a user