- 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>
17 KiB
平板 + 5.5 寸手机合入主干后的交接
日期:2026-10-11 | 基线提交:
origin/main @ 131eb03| 在线版:https://claude.ai/artifact/N8cWdTcMAzk9N86NSPevTC本文描述合并当天的状态。分支、版本号等信息如有变化,以仓库为准。
接手前先知道这几件事
- 只有一条开发分支:
main。 手机适配分支feature/phone-ui-adaptation已于 2026-10-11 合入,平板和 5.5 寸手机以后都在main上一起开发。 - 业务以平板为准,手机只做界面。 两端共用 ViewModel、接口、表单项、筛选入参和默认值;差异只能出现在布局(View)层。
- 同一个页面有两份同名布局:
res/layout-sw600dp/是平板,res/layout/是手机。改平板页面时要同时检查手机布局和这个页面的所有弹框。 - 有两件事等人拍板: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按设备锁方向。
平板改了一个已适配页面,标准步骤
- 改平板布局(
layout-sw600dp/)和 ViewModel。 - 打开同名手机布局(
layout/),补上同样的字段、筛选项和操作入口。平板的批量按钮在手机上可以改成卡片按钮或PhoneBottomBar的次按钮(subAction1Text/subAction2Text)。 - 检查这个页面用到的每一个 DialogModel,新弹框要做手机变体。
- 手机 Tab 角标、计数这类只有手机用的额外请求,放在
phoneExtrasEnabled一类的开关后面,不能改变平板的请求。 - 两台模拟器各走一遍,再编译
./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. 容易踩的坑
- API 文档的 token 提交进了仓库。
.mcp.json里写着 api-doc MCP 的Authorization: Bearer …,并且已被 git 跟踪。建议轮换这个 token,改为从环境变量或本地未跟踪的配置读取。 - 换行符混用,没有
.gitattributes。 main 原有文件多为 CRLF,手机分支新建的文件是 LF。编辑时保持文件原有换行符,否则会出现整文件 diff,合并和 review 都会很难看。 - 没有手机变体的平板页面,在手机上会直接显示平板布局。 给手机首页加入口前,必须先做手机布局。
- 后端会静默忽略不认识的参数。 猜错参数名会得出「后端不支持」的误判。入参出参一律用 api-doc MCP 核对,流程见
.claude/skills/phone-adapt/references/api-doc.md。 - XML 里
??兜底不生效。 网络层会把 JSON null 转成空串,??只判断 null。要在 Bean 上写计算属性(如agentDisplay、opUserDisplay)。 - RecyclerView 里给 item 设
GONE不会收起高度。 Tab 过滤要在数据层过滤后整体refresh。 - Intent 传递的 Bean 里
@Transient字段会变成 null(checked、showMore等)。接收方要.map { it.copy() }。 - 同页多个手机复合组件会串状态。 新写同类组件要覆写
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。
# 启动模拟器(模拟器可执行文件在 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 |
平板首页菜单,手机入口的权限串和路由要以它为准。 |