From 33c9f0e030fe6c1c7bcb80f79c782e5995214915 Mon Sep 17 00:00:00 2001 From: YANG JIANKUAN Date: Fri, 31 Jul 2026 18:13:44 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E5=87=BA=E6=B8=AF?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E9=A1=B5=E9=9D=A25.5=E5=AF=B8=E6=89=8B?= =?UTF-8?q?=E6=9C=BA=E7=AB=AF=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 列表/详情/运单追踪三页同名布局双变体(平板移 layout-sw600dp/,Kotlin 零设备分支) - 列表:搜索行 + 三格统计(总票数/已入库/已离港,已加载数据客户端计数)+ 状态标签卡片 (已离港/已入库/未入库,前端按 fclose/opDate 推断)+ 9 项底部筛选弹层(特码改下拉) - 详情:3 Tab 复用 ViewPager2+Fragment,PhoneKvItem 网格;入库件数/重量按 warehouseList 求和 - 运单追踪:公共页 LogDetailActivity 双变体首例,手机竖排时间线动态构建,平板横向步骤条不动 - 修复 PhoneFilterPanel 筛选项超屏时底部按钮被挤出屏幕(内容插槽加 ScrollView) - PhoneKvItem 新增 tagColor 绿色高亮(海关放行),占位符不套标签底 - 手机首页国际 Tab 加出港查询入口;后端缺口 #21/#22 登记问题清单 - 双端实机验证通过(内网真实数据 + Proxyman Map Local 补验未入库兜底态) - skill 新增 references/proxyman.md:抓包/直调 A/B/Mock 与 api-doc 配合规范 Co-Authored-By: Claude Fable 5 --- .claude/skills/phone-adapt/SKILL.md | 17 +- .../skills/phone-adapt/references/api-doc.md | 8 + .../phone-adapt/references/components.md | 8 +- .../skills/phone-adapt/references/proxyman.md | 76 ++ CHANGELOG.md | 31 + CLAUDE.md | 14 +- app/src/debug/AndroidManifest.xml | 18 + .../page/log/detail/LogDetailActivity.kt | 107 ++- .../layout-sw600dp/activity_log_detail.xml | 231 ++++++ .../main/res/layout/activity_log_detail.xml | 271 ++---- documents/后端接口对接问题清单.xlsx | Bin 19513 -> 20336 bytes .../lukouguoji/module_base/bean/GjcMaWb.kt | 14 + .../ui/weight/phone/PhoneKvItem.kt | 20 +- .../ui/weight/phone/PhoneWidgetKtx.kt | 13 +- .../main/res/drawable/bg_phone_dot_blue.xml | 6 + .../main/res/drawable/bg_phone_dot_gray.xml | 6 + .../main/res/drawable/ic_phone_package.xml | 11 + .../src/main/res/drawable/ic_phone_tag.xml | 11 + .../res/layout/layout_phone_filter_panel.xml | 20 +- .../gjc/activity/GjcQueryActivity.kt | 36 +- .../gjc/viewModel/GjcQueryDetailsViewModel.kt | 50 ++ .../gjc/viewModel/GjcQueryViewModel.kt | 44 + .../res/layout-sw600dp/activity_gjc_query.xml | 237 ++++++ .../activity_gjc_query_details.xml | 125 +++ .../fragment_gjc_query_storage.xml | 137 ++++ .../fragment_gjc_query_warehouse.xml | 157 ++++ .../fragment_gjc_query_waybill.xml | 319 ++++++++ .../res/layout-sw600dp/item_gjc_query.xml | 318 ++++++++ .../layout-sw600dp/item_gjc_query_storage.xml | 99 +++ .../item_gjc_query_warehouse.xml | 119 +++ .../layout_gjc_query_filter.xml | 0 .../main/res/layout/activity_gjc_query.xml | 440 ++++++---- .../res/layout/activity_gjc_query_details.xml | 262 +++--- .../res/layout/fragment_gjc_query_storage.xml | 190 ++--- .../layout/fragment_gjc_query_warehouse.xml | 210 ++--- .../res/layout/fragment_gjc_query_waybill.xml | 771 ++++++++++-------- .../src/main/res/layout/item_gjc_query.xml | 490 +++++------ .../res/layout/item_gjc_query_storage.xml | 212 ++--- .../res/layout/item_gjc_query_warehouse.xml | 255 +++--- .../sixin/module_p/ui/enter/gj/GjViewModel.kt | 6 + .../res/drawable-xxhdpi/gjc_query_icon.png | Bin 0 -> 32301 bytes 41 files changed, 3730 insertions(+), 1629 deletions(-) create mode 100644 .claude/skills/phone-adapt/references/proxyman.md create mode 100644 app/src/main/res/layout-sw600dp/activity_log_detail.xml create mode 100644 module_base/src/main/res/drawable/bg_phone_dot_blue.xml create mode 100644 module_base/src/main/res/drawable/bg_phone_dot_gray.xml create mode 100644 module_base/src/main/res/drawable/ic_phone_package.xml create mode 100644 module_base/src/main/res/drawable/ic_phone_tag.xml create mode 100644 module_gjc/src/main/res/layout-sw600dp/activity_gjc_query.xml create mode 100644 module_gjc/src/main/res/layout-sw600dp/activity_gjc_query_details.xml create mode 100644 module_gjc/src/main/res/layout-sw600dp/fragment_gjc_query_storage.xml create mode 100644 module_gjc/src/main/res/layout-sw600dp/fragment_gjc_query_warehouse.xml create mode 100644 module_gjc/src/main/res/layout-sw600dp/fragment_gjc_query_waybill.xml create mode 100644 module_gjc/src/main/res/layout-sw600dp/item_gjc_query.xml create mode 100644 module_gjc/src/main/res/layout-sw600dp/item_gjc_query_storage.xml create mode 100644 module_gjc/src/main/res/layout-sw600dp/item_gjc_query_warehouse.xml rename module_gjc/src/main/res/{layout => layout-sw600dp}/layout_gjc_query_filter.xml (100%) create mode 100644 module_p/src/main/res/drawable-xxhdpi/gjc_query_icon.png diff --git a/.claude/skills/phone-adapt/SKILL.md b/.claude/skills/phone-adapt/SKILL.md index 8a6fe6a..f2f520a 100644 --- a/.claude/skills/phone-adapt/SKILL.md +++ b/.claude/skills/phone-adapt/SKILL.md @@ -66,6 +66,10 @@ python3 $S/design_shots.py --html "…/出库交接.html" --out /tmp/design \ 返回同一批数据,一度误判为「后端不支持」;后查 api-doc 才发现正确参数名是 `handoverState`—— 后端对不认识的参数是**静默忽略**,不报错,实测只能证明「这个名字不对」,证不出「后端没这能力」。 +「参数是否真的生效」的 A/B 验证优先走 Proxyman MCP(`create_compose_http_from_flow` 复制 +真实请求改参重发,token 自动带上),分工与流程见 `references/proxyman.md`: +**api-doc 管契约(该有什么),Proxyman 管事实(实际发/回了什么)**。 + 核对完把结论落两处(模板与格式见 `references/api-doc.md`): - 后端真实缺口(缺入参/缺出参/数据不回填)→ 记入 `documents/后端接口对接问题清单.xlsx`, @@ -232,9 +236,12 @@ $P tap-text "已交接" # 按文字点击,比手算坐标可靠 $P texts # 用文字变化断言点击确实生效(如底部条应消失) $P shot /tmp/p1.png $P crash # 必须为 0 -$P req pageQuery # 核对请求体参数确实带上了新字段 ``` +核对请求/响应体优先用 Proxyman MCP(`filter_flows` + `get_flow_detail`,比 `req` 的 +logcat 抓包完整可靠;模拟器代理一行命令接入,见 `references/proxyman.md`); +Proxyman 不可用时兜底 `$P req pageQuery`。 + 逐项走查:列表/卡片两种形态、详情页、筛选弹层(重置+确认)、Tab 切换、单选与全选联动、 下拉真实取数、扫码入口。每步 `crash` 都要为 0。 @@ -253,7 +260,12 @@ $P req pageQuery # 核对请求体参数确实带上了新字段 **空值兜底**(真实数据空字段很常见——出库交接就出现过「库位」为空时橙色高亮标签只剩一个孤零零的 小色块,需要空值时不套标签底)。 -服务端当天没数据时(列表空)先放宽条件重查;仍为空就临时在 Activity 里注入样例 Bean 截图比对: +服务端当天没数据时(列表空)先放宽条件重查;仍为空、或要覆盖真实数据凑不出的形态 +(空字段、超长文本、罕见状态标签),**首选 Proxyman Map Local 造 mock**——零代码改动、 +零重构建,见 `references/proxyman.md` 场景 3(2026-07-31 出港查询用它一次验完 +已离港/已入库/未入库三种卡片形态)。验证完 `delete_rule` + 清模拟器代理。 + +Proxyman 不可用时才退回老办法:Activity 里临时注入样例 Bean 截图比对: ```kotlin // import com.lukouguoji.module_base.ktx.commonAdapter @@ -287,6 +299,7 @@ binding.rv.postDelayed({ ## 参考文件 - `references/api-doc.md` — api-doc MCP 连接与逐接口核对流程、后端缺口记录规范、已核对字段语义(阶段 2 前读) +- `references/proxyman.md` — Proxyman MCP 抓包/直调 A/B/Map Local mock 的接入与四个场景(阶段 2、5、6 用;与 api-doc 的分工:契约 vs 事实) - `references/components.md` — 7 个手机版公共组件的属性表、用法与封装新组件的规矩(写布局前读) - `references/pad-safety.md` — 布局变体约束、Pad 零破坏模式、易崩点(写代码前读) - `references/verification.md` — 双端 adb 命令、登录与直启、已知环境坑(验证前读) diff --git a/.claude/skills/phone-adapt/references/api-doc.md b/.claude/skills/phone-adapt/references/api-doc.md index 6570f2e..057ce55 100644 --- a/.claude/skills/phone-adapt/references/api-doc.md +++ b/.claude/skills/phone-adapt/references/api-doc.md @@ -77,6 +77,14 @@ curl -s -X POST "$URL" -H "$AUTH" -H "Content-Type: application/json" \ 分单补充收发货人信息**后端完全没有对应接口**(`search_endpoints` 对 `IntExpArrive`/`HaWb` 关键字均搜不到分单更新接口,只有国际进港的 `IntImpAirManifest/complete`), 实机调用拟定路径 `IntExpArrive/haWb/supplement` 确认 404(缺口 #19) +- `IntExpSearch`(出港查询,2026-07-31 内网实测):查询入参 `outState`/`fno`/`dest`/`spCode`/`awbType`/ + `businessType`/`goodsCn`/`beginDate`/`endDate`/`agentCode`/`wbNo` 全部真实生效(平板既有口径); + 文档定义的 `isFclose`(筛选航班是否关闭)**pageQuery 与 pageQueryTotal 均静默忽略**(A/B 对照 + 全量 72 票与单日两组,加参前后结果完全一致,缺口 #21);`pageQueryTotal` 出参无已入库/已离港 + 分项计数(#21);`detail` 出参 Map 无 `lockStatus`(锁定状态)与计费重量字段(#22); + 详情「入库件数/入库重量」= `warehouseList` 各批次 pc/weight 求和(mock 与实测均吻合); + 卡片状态推断口径:`fclose` 非空=已离港、否则 `opDate` 非空=已入库; + 特码字典沿用 `DictUtils.getSpecialCodeList(flag=1, ieFlag="")`(ieFlag 必须空串) - `IntExpCheckIn`(出港计重,2026-07-29 内网实测):`likeNo` **并非任意模糊**——按 8 位 `no` 匹配(11 位 wbNo 或部分号均 0 条),11 位全号必须走 `wbNo`;`checkIn`/`checkInList` 文档有定义但 `pageQuery`/`pageQueryTotal` **均静默忽略**(缺口 #12,待计重/计重中计数依赖); diff --git a/.claude/skills/phone-adapt/references/components.md b/.claude/skills/phone-adapt/references/components.md index bc747d4..75a4710 100644 --- a/.claude/skills/phone-adapt/references/components.md +++ b/.claude/skills/phone-adapt/references/components.md @@ -16,13 +16,17 @@ | `PhoneFilterPanel` | 底部筛选弹层(遮罩 + 面板 + 重置/确认) | `title`、`panelVisible`、`setOnResetClick`、`setOnConfirmClick`、`setOnDismissClick` | | `PhoneBottomBar` | 底部操作条(全选 + 已选统计 + 主按钮) | `allChecked`、`countText`、`actionText`、`setOnAllCheckClick`、`setOnActionClick` | | `PhoneStatBox` | 卡片内 2~4 列统计框,未传 label 的列自动隐藏 | `label1..4`、`value1..4` | -| `PhoneKvItem` | 详情页字段项(灰标签 + 数值) | `title`、`value`、`tag`(true → 橙色高亮标签) | +| `PhoneKvItem` | 详情页字段项(灰标签 + 数值) | `title`、`value`、`tag`(true → 高亮标签)、`tagColor`("orange" 默认 / "green" 放行正常态);占位符 "-"/"--" 不套标签底 | | `PhoneFormRow` | 行式表单项(左标签 minWidth 110dp + 右值 + 1px 分隔线),覆盖新增/修改/详情三态表单 | `title`、`hint`、`type`(`PhoneFormRowType.INPUT`/`SELECT`/`DATE`/`TEXT`)、`value`(双向)、`list`(SELECT 选项)、`required`、`enable`、`numeric`、`setRefreshCallBack` | `PhoneFormRow` 要点:SELECT 内置 XPopup 底部选择面板(点击整行弹出,无需页面代码);TEXT 为只读右对齐、 空值自动占位 "--"(详情态);type 用三元按 `pageType` 切换即可一套布局覆盖三态页面(参考 `app/res/layout/activity_uld_edit.xml`)。`PhoneBottomBar` 的 `actionDanger="@{true}"` 切浅红删除按钮。 +`PhoneFilterPanel` 内容插槽已内置 ScrollView(2026-07-31 加):筛选项少时行为不变; +筛选项多到超屏(出港查询 9 项)时内容区收缩滚动,底部「重置/确认」按钮始终可见—— +此前无滚动时按钮会被挤出屏幕外且毫无报错,只表现为"点不到确认"。 + ⚠️ 两个已踩坑: - **FAB 盖住弹层**:浮动按钮带 elevation 时会浮在 `PhoneFilterPanel` 之上,弹层实例要加 `android:elevation="8dp"`(> FAB 的 6dp) @@ -129,6 +133,8 @@ android.util.Log.d("DBG", "value '$field' -> '$v'", Throwable("trace")) `ic_phone_chevron_right/down` `ic_phone_calendar` `ic_phone_close` `ic_phone_check_round_checked/unchecked`(圆形复选框) `ic_phone_clipboard`(剪贴板,白色 FAB 用)`ic_phone_weight`(砝码,可 tint) + `ic_phone_package`(件数)`ic_phone_tag`(特码/标签) +- 圆点:`bg_phone_dot_green/blue/gray`(状态指示点;蓝=出港查询卡片头,灰=时间线未达节点) - 复用 Pad 的矢量图:`img_search` `img_scan` `img_filter`(可 `app:tint` 染色) 设计稿里的 MDI 图标若缺失,直接写 24×24 的 vector(用 MDI 官方 path),比找位图靠谱且能染色。 diff --git a/.claude/skills/phone-adapt/references/proxyman.md b/.claude/skills/phone-adapt/references/proxyman.md new file mode 100644 index 0000000..185056b --- /dev/null +++ b/.claude/skills/phone-adapt/references/proxyman.md @@ -0,0 +1,76 @@ +# Proxyman MCP:抓包 / 直调 / Mock(阶段 2、5、6 的调试利器) + +Proxyman 桌面端 + `mcp__proxyman__*` 工具(会话内直接可用,缺 schema 时用 ToolSearch +`select:mcp__proxyman__get_flows,...` 加载)。**2026-07-31 已在出港查询页全链路实测**: +抓包核对请求体、Map Local mock 三种卡片形态(含真实数据不存在的「未入库」兜底态)一次跑通。 + +## 与 api-doc 的分工(先契约后事实) + +| | api-doc MCP | Proxyman MCP | +|---|---|---| +| 回答什么 | **契约**:接口该有什么入参/出参、参数名叫什么 | **事实**:App 实际发了什么、后端实际回了什么 | +| 用在何时 | 阶段 2 开工前逐接口核对 | 阶段 5/6 实机验证与 corner case 补测 | + +标准配合流程: +api-doc 拿权威参数名 → 前端实现 → Proxyman flow 核对请求体确实带上了 → +compose 改参 A/B 验证后端认不认 → 不认 → 记问题清单(附 `export_flow_curl` 证据)→ +map local 造 mock 补 UI corner case 验证。 + +## 接入(一次性,实测步骤) + +```bash +# 1) 确认 Proxyman 在跑(返回 Recording: Active + 端口,默认 9090) +# mcp__proxyman__get_proxy_status +# 2) 模拟器全局代理指向宿主机(模拟器视角宿主机 = 10.0.2.2) +adb -s shell settings put global http_proxy 10.0.2.2:9090 +# 3) 验证完【必须】清掉,否则 Proxyman 一关模拟器就断网,下次验证莫名全挂 +adb -s shell settings put global http_proxy :0 +``` + +本项目内网服务是**纯 HTTP**(192.168.1.250:8093)→ 不需要装证书,明文直接可见。 +(若未来切 HTTPS,才需要 `install_certificate` + `enable_ssl_proxying`。) + +## 场景 1:核对请求/响应(替代 `ui_probe req`) + +logcat 抓 OkHttp 多行 pretty JSON 脆弱且要人肉拼接;Proxyman 一步到位: + +- `filter_flows`(key=url, value="IntExpSearch")→ 拿 flow ID 列表 +- `get_flow_detail`(flow_id)→ 完整请求体 + 响应体 + headers(Authorization 自动脱敏) + +**出参无文档定义时(如 `IntExpSearch/detail` 返回裸 Map),用真实 flow 的 responseBody +直接盘点字段清单**——判定「锁定状态/计费重量是否存在」这类问题的最快路径。 + +## 场景 2:直调后端 A/B 验证(替代 run-as 提 token + 手写 curl) + +`create_compose_http_from_flow`(从真实 flow 复制请求,**token 自动带上,不用碰 +shared_prefs**)→ `update_compose_http` 改一个参数 → `send_compose_http` 看结果对比。 +isFclose 这类「参数是否生效」的 A/B 实验用这条链。给后端提缺口时用 +`export_flow_curl` 导出可复现的 curl 附进问题清单。 + +## 场景 3:Map Local 造 mock 验证 corner case(替代代码注入样例 Bean) + +老流程「Activity 临时注入 Bean → 截图 → 删码 → 重构建」彻底淘汰:**零代码改动、零重构建**。 + +- `create_map_local`:url 精确到接口路径,method=POST,response_body 直接写目标 JSON + (构造空字段/超长文本/罕见状态,比如出港查询的 fclose+opDate 双空「未入库」兜底态) +- 改真实响应个别字段更省事时用 `create_map_local_from_flow` +- 验证完 `delete_rule`(rule_type=maplocal)+ 清代理,**规则残留会污染后续真实数据验证** + +响应结构照抄真实 flow 的顶层结构(如 pageQuery 是裸 PageInfo:`{total, list, pages, ...}`, +不要包 `{status, data}`)。 + +⚠️ 实测坑:mock 响应到达后 UI 渲染可能滞后(冷启动首帧 Davey 卡顿 2s+), +**截图断言前先 `ui_probe texts` 确认数据已上屏**——这次就因截图太早误判过一轮「mock 没生效」, +其实 `get_flow_detail` 里 `matchedTools: ["Map Local"]` 早已证明规则命中,UI 只是还没画完。 + +## 场景 4:环境模拟(按需) + +- `create_network_condition`:弱网/高延迟,验证 loading 弹窗与超时提示 +- `create_breakpoint`:单次拦截改包(比 map local 更临时的一次性实验) +- `create_map_remote`:把请求转发到另一环境(如后端修复验证用的测试实例) + +## 验证收尾清单 + +- [ ] `list_rules` 确认无本次遗留规则(maplocal/breakpoint/network_condition) +- [ ] 模拟器代理已清(`settings get global http_proxy` 应为 `:0` 或空) +- [ ] 用真实数据再过一遍被 mock 过的页面,确认无假数据残影 diff --git a/CHANGELOG.md b/CHANGELOG.md index ae283ce..bb6c835 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,37 @@ ## [Unreleased] ### 新增 (Added) +- 「出港查询」5.5 寸手机端适配(设计稿 06_出港查询,含列表/详情/运单追踪三页): + 列表 `GjcQueryActivity` 手机布局 = PhoneSearchBar(运单号 + 扫码 + 筛选)+ 三格统计 + (总票数/已入库/已离港,彩色左边条卡片)+ 状态标签卡片(已离港绿/已入库橙/未入库灰, + 前端推断口径:fclose 非空=已离港,否则 opDate 非空=已入库);筛选弹层 9 项(平板搜索行的 + 日期起止/代理并入弹层,特码按设计稿改下拉,字典 `getSpecialCodeList(flag=1, ieFlag="")`, + 仅手机形态经 `initPhoneExtras()` 加载);详情 `GjcQueryDetailsActivity` 3 Tab 全部复用 + ViewPager2 + Fragment,手机变体以 PhoneKvItem 网格呈现「基本信息/件重信息/回执信息」, + 比平板多展示承运人/始发站/中转站/目的站/UN编号,入库件数/入库重量 = warehouseList 各批次求和; + 仓库/库位 Tab 改批次/库位卡片;「运单追踪」为公共页 `LogDetailActivity` 双变体首例—— + 手机竖排流转时间线(Activity `buildVerticalSteps` 动态构建,节点绿=已达/灰=未达 + 环节时间), + 平板横向步骤条零改动,手机标题按形态显示「运单追踪」 +- 手机首页「国际」Tab 增加「出港查询」入口(权限 AppIntExpSearch,图标复用 Pad 端 gjc_query_icon) +- `PhoneKvItem` 新增 `tagColor` 属性("green" 绿色高亮,海关放行正常态;默认 "orange"), + 且占位符 "-"/"--" 不再套高亮标签底 +- `GjcMaWb` 新增 `isQueryDeparted`/`isQueryStored`/`orDash` 手机版计算属性 +- 新增手机版资源:`ic_phone_package`(件数)、`ic_phone_tag`(特码)、`bg_phone_dot_blue/gray` +- 后端缺口 2 项登记问题清单 #21~#22(isFclose 入参实测被 pageQuery/pageQueryTotal 静默忽略且 + 无已入库/已离港分项统计出参;detail 出参无锁定状态/计费重量字段) + +### 修复 (Fixed) +- **`PhoneFilterPanel` 底部按钮被挤出屏幕**:面板高度 wrap_content 且内容插槽无滚动,筛选项多 + (出港查询 9 项)时「重置/确认」按钮直接超出屏幕外且无任何报错。修复:内容插槽外包 + ScrollView(weight=1),筛选项少时行为不变,超屏时内容区收缩滚动、按钮始终可见 + (已回归出港计重 4 项弹层,行为不变) + +### 验证 (Verified) +- 出港查询双端实机验证通过(2026-07-31,内网真实数据 2026-06-09 共 14 票): + 手机端登录→国际 Tab→出港查询菜单入口、列表加载/状态标签/三格统计(10+4=14 与卡片一致)、 + 筛选弹层(日期滚轮、特码/代理下拉真实取数、重置、确认后重新查询)、运单号搜索、扫码拉起、 + 详情 3 Tab(含仓库批次卡与库位空态)、运单追踪时间线、冷启动方向恒竖屏(mRotation=0×8 采样)、 + 全程 FATAL 0;平板端回归:列表 5 搜索条 + 底部统计 + 侧滑筛选面板 + 详情表格样式均与改造前一致 - 「出港运抵」5.5 寸手机端适配(主列表 + 3 个手机专属新页,设计稿 04_出港运抵): 主列表 `IntExpArriveActivity` 新增「待运抵/已运抵」Tab(客户端按 declareStatus 是否为空拆分数据集, 接口无此查询参数)+ 卡片长按浮层(待运抵→补充、已运抵→重置+回执,纯 UI 长按)+ 底部全选/已选/申报 diff --git a/CLAUDE.md b/CLAUDE.md index d8503b5..e7ae668 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1053,7 +1053,7 @@ DataBinding 适配器统一放在 `PhoneWidgetKtx.kt`(同名属性按控件类 | `PhoneFilterPanel` | 底部筛选弹层(遮罩 + 面板 + 重置/确认) | `title`、`panelVisible`、`setOnResetClick`、`setOnConfirmClick`、`setOnDismissClick` | | `PhoneBottomBar` | 底部操作条:全选 + 已选统计 + 主按钮 | `allChecked`、`countText`、`actionText`、`setOnAllCheckClick`、`setOnActionClick` | | `PhoneStatBox` | 卡片内 2~4 列统计框(未传 label 的列自动隐藏) | `label1..4`、`value1..4` | -| `PhoneKvItem` | 详情页字段项(灰标签 + 数值),`tag=true` 转橙色高亮 | `title`、`value`、`tag` | +| `PhoneKvItem` | 详情页字段项(灰标签 + 数值),`tag=true` 转高亮标签(占位符 "-"/"--" 不套底) | `title`、`value`、`tag`、`tagColor`("orange" 默认/"green") | | `PhoneFormRow` | 行式表单项(左标签+右值+分隔线),`PhoneFormRowType` = `INPUT`/`SELECT`(内置底部选择面板)/`DATE`/`TEXT`(只读右对齐,空值 "--") | `title`、`hint`、`type`、`value`(双向)、`list`、`required`、`enable`、`numeric`、`setRefreshCallBack` | `PhoneBottomBar` 追加 `actionDanger` 属性:true 时主按钮转浅红底红字 + 垃圾桶图标(ULD 管理批量删除)。 @@ -1061,6 +1061,9 @@ DataBinding 适配器统一放在 `PhoneWidgetKtx.kt`(同名属性按控件类 `ic_phone_trash`、`ic_phone_edit`、色值 `phone_danger_bg/text`。 出港计重追加:`bg_phone_btn_weak`(浅蓝弱按钮,卡片内提前运抵)、`bg_phone_card_top_accent` (卡片顶部主色描边条)、`ic_phone_clipboard`(FAB 剪贴板)、`ic_phone_weight`(砝码图标,可 tint)。 +出港查询追加:`ic_phone_package`(件数)、`ic_phone_tag`(特码)、`bg_phone_dot_blue/gray`(状态圆点); +`PhoneFilterPanel` 内容插槽已内置 ScrollView(筛选项超屏时收缩滚动,底部按钮始终可见—— +9 个筛选项曾把「重置/确认」挤出屏幕)。 ⚠️ **弹层与浮动按钮的层级**:`PhoneFilterPanel` 默认无 elevation,页面里有带 elevation 的浮动按钮(FAB)时 会穿透到弹层之上——给弹层实例加 `android:elevation="8dp"`(大于 FAB 的 6dp)。 @@ -1129,6 +1132,15 @@ override fun dispatchRestoreInstanceState(container: SparseArray) = `.checked.set(...)` 会崩溃——接收方 `initOnCreated` 必须对列表 `.map { it.copy() }` 补上。 2026-07-30 review 修正:状态重置弹框改手机底部弹层(弹框双变体首例,见改造步骤第 6 条)、 主列表/回执页补空态、分单浮层补「回执」、分单统计加分母、Tab 角标初始 0 + - 「出港查询」`GjcQueryActivity`(列表:三格统计 总票数/已入库/已离港 + 卡片状态标签, + 状态为前端推断:`fclose` 非空=已离港/`opDate` 非空=已入库;筛选弹层 9 项,日期起止与代理 + 从平板搜索行并入,特码改下拉 `getSpecialCodeList(flag=1, ieFlag="")`;分项统计为已加载 + 数据客户端计数,`isFclose` 实测被后端忽略,缺口 #21)+ `GjcQueryDetailsActivity`(3 Tab + 复用 ViewPager2+Fragment,手机变体 PhoneKvItem 网格;入库件数/重量= warehouseList 求和; + 锁定状态/计费重量后端无字段,缺口 #22)+ 「运单追踪」`LogDetailActivity`(app 模块公共页 + 双变体首例:手机竖排时间线由 Activity `buildVerticalSteps` 动态构建,平板横向步骤条不动; + 手机标题按形态切「运单追踪」)。平板侧滑筛选面板代码已判空守卫(手机变体无 filter_panel + include,Binding 字段为 @Nullable) - ⏳ **待办**: - `PhoneSearchBar` 接入 AutoQuery 联想(`AutoQueryManager` 目前只对接了 Pad 系组件) - 出库交接 Tab 角标恒 0:`IntExpOutHandover/pageQueryTotal` 出参恒 0(后端缺陷,问题清单 #6), diff --git a/app/src/debug/AndroidManifest.xml b/app/src/debug/AndroidManifest.xml index a169c60..a344348 100644 --- a/app/src/debug/AndroidManifest.xml +++ b/app/src/debug/AndroidManifest.xml @@ -104,5 +104,23 @@ android:exported="true" tools:replace="android:exported" /> + + + + + + + + + diff --git a/app/src/main/java/com/lukouguoji/aerologic/page/log/detail/LogDetailActivity.kt b/app/src/main/java/com/lukouguoji/aerologic/page/log/detail/LogDetailActivity.kt index 5c254a0..9214019 100644 --- a/app/src/main/java/com/lukouguoji/aerologic/page/log/detail/LogDetailActivity.kt +++ b/app/src/main/java/com/lukouguoji/aerologic/page/log/detail/LogDetailActivity.kt @@ -19,6 +19,7 @@ import com.lukouguoji.module_base.base.BaseBindingActivity import com.lukouguoji.module_base.bean.LogBean import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.router.ARouterConstants +import com.lukouguoji.module_base.util.DeviceUtil @Route(path = ARouterConstants.ACTIVITY_URL_LOG_DETAIL) class LogDetailActivity : BaseBindingActivity() { @@ -34,7 +35,8 @@ class LogDetailActivity : BaseBindingActivity, + activeCodes: Set, + latestCode: String + ) { + val container = binding.llSteps + container.removeAllViews() + container.orientation = LinearLayout.VERTICAL + + val logs = viewModel.statusLogList.value ?: emptyList() + val colorGreen = 0xFF16A34A.toInt() + val colorGray = 0xFF9CA3AF.toInt() + val colorLine = 0xFFE5E7EB.toInt() + + for (i in steps.indices) { + val step = steps[i] + val isActive = step.code in activeCodes + val isLast = i == steps.size - 1 + val time = logs.lastOrNull { it.status == step.code }?.opDate ?: "" + + val row = LinearLayout(this).apply { + orientation = LinearLayout.HORIZONTAL + layoutParams = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ) + } + + // 左列:圆点 + 连接竖线 + val dotColumn = LinearLayout(this).apply { + orientation = LinearLayout.VERTICAL + gravity = Gravity.CENTER_HORIZONTAL + layoutParams = LinearLayout.LayoutParams(dp(20), LinearLayout.LayoutParams.MATCH_PARENT) + } + val dot = View(this).apply { + setBackgroundResource( + if (isActive) com.lukouguoji.module_base.R.drawable.bg_phone_dot_green + else com.lukouguoji.module_base.R.drawable.bg_phone_dot_gray + ) + layoutParams = LinearLayout.LayoutParams( + dp(if (isActive) 12 else 8), dp(if (isActive) 12 else 8) + ).apply { topMargin = dp(if (isActive) 2 else 4) } + } + dotColumn.addView(dot) + if (!isLast) { + val line = View(this).apply { + setBackgroundColor(colorLine) + layoutParams = LinearLayout.LayoutParams(dp(2), 0).apply { + weight = 1f + topMargin = dp(2) + bottomMargin = dp(2) + } + } + dotColumn.addView(line) + } + row.addView(dotColumn) + + // 右列:步骤名 + 时间 + val content = LinearLayout(this).apply { + orientation = LinearLayout.VERTICAL + layoutParams = LinearLayout.LayoutParams( + 0, LinearLayout.LayoutParams.WRAP_CONTENT + ).apply { + weight = 1f + leftMargin = dp(10) + } + setPadding(0, 0, 0, if (isLast) 0 else dp(24)) + } + content.addView(TextView(this).apply { + text = step.name + setTextSize(TypedValue.COMPLEX_UNIT_SP, 15f) + setTextColor(if (isActive) colorGreen else colorGray) + if (isActive) setTypeface(typeface, android.graphics.Typeface.BOLD) + }) + if (time.isNotEmpty()) { + content.addView(TextView(this).apply { + text = time + setTextSize(TypedValue.COMPLEX_UNIT_SP, 12f) + setTextColor(colorGray) + layoutParams = LinearLayout.LayoutParams( + LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT + ).apply { topMargin = dp(4) } + }) + } + row.addView(content) + + container.addView(row) + } } private fun buildStepProgressBar( diff --git a/app/src/main/res/layout-sw600dp/activity_log_detail.xml b/app/src/main/res/layout-sw600dp/activity_log_detail.xml new file mode 100644 index 0000000..2f55b92 --- /dev/null +++ b/app/src/main/res/layout-sw600dp/activity_log_detail.xml @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_log_detail.xml b/app/src/main/res/layout/activity_log_detail.xml index 2f55b92..577c215 100644 --- a/app/src/main/res/layout/activity_log_detail.xml +++ b/app/src/main/res/layout/activity_log_detail.xml @@ -1,6 +1,22 @@ + + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> @@ -12,7 +28,7 @@ @@ -20,208 +36,99 @@ + android:fillViewport="true" + android:overScrollMode="never"> + android:padding="12dp"> - + + android:background="@drawable/bg_phone_card" + android:orientation="vertical" + android:padding="16dp"> - - - - - - - - - - + + android:gravity="center_vertical" + android:orientation="horizontal"> - + android:layout_weight="1" + android:text="@{viewModel.waybillNo}" + android:textColor="@color/phone_text_title" + android:textSize="20sp" + android:textStyle="bold" + tools:text="78133358743" /> - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_gravity="center_horizontal" + android:layout_marginTop="24dp" + android:layout_marginBottom="16dp" + android:letterSpacing="0.3" + android:text="查询信息已触底" + android:textColor="@color/phone_text_hint" + android:textSize="12sp" /> diff --git a/documents/后端接口对接问题清单.xlsx b/documents/后端接口对接问题清单.xlsx index 4f3435e7a82d1799b566aae0660d3ce7e0b19ff8..59eab0a388cca601ea761164e2e749f40b5fc4e5 100644 GIT binary patch delta 10109 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 T_1~=>{0fWw2!=foE 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 e0^MJXIUE4+mzn if (declareStatus.isNullOrEmpty()) "" else "amber" } + /** + * 5.5寸手机版-出港查询:卡片状态标签。 + * 已离港 = 航班关闭时间(fclose)非空;已入库 = 入库时间(opDate)非空;都为空 = 未入库(灰)。 + * 接口无独立状态出参,此判定为前端推断(与卡片「入库时间/离港时间」两列同源)。 + */ + val isQueryDeparted: Boolean + get() = !fclose.isNullOrEmpty() + + val isQueryStored: Boolean + get() = !opDate.isNullOrEmpty() + + /** 5.5寸手机版:空值统一占位 "--"(空串与 null 都兜底,布局绑定用) */ + fun orDash(value: String?): String = if (value.isNullOrEmpty()) "--" else value + // ==================== 状态转换扩展属性 ==================== /** * 计重状态中文 diff --git a/module_base/src/main/java/com/lukouguoji/module_base/ui/weight/phone/PhoneKvItem.kt b/module_base/src/main/java/com/lukouguoji/module_base/ui/weight/phone/PhoneKvItem.kt index aaa1ac0..bb78c80 100644 --- a/module_base/src/main/java/com/lukouguoji/module_base/ui/weight/phone/PhoneKvItem.kt +++ b/module_base/src/main/java/com/lukouguoji/module_base/ui/weight/phone/PhoneKvItem.kt @@ -56,13 +56,25 @@ class PhoneKvItem @JvmOverloads constructor( applyStyle() } + /** 高亮标签配色:"orange"(默认,如库位)/ "green"(如海关放行正常态) */ + var tagColor: String = "orange" + set(v) { + field = v + applyStyle() + } + /** - * 空值不套高亮标签底 —— 否则占位符 "-" 会显示成一个孤零零的橙色小方块。 + * 空值不套高亮标签底 —— 否则占位符 "-"/"--" 会显示成一个孤零零的色块。 */ private fun applyStyle() { - if (tag && value.isNotEmpty()) { - tvValue.setBackgroundResource(R.drawable.bg_phone_value_orange) - tvValue.setTextColor(ContextCompat.getColor(context, R.color.phone_orange_text)) + if (tag && value.isNotEmpty() && value != "-" && value != "--") { + if (tagColor == "green") { + tvValue.setBackgroundResource(R.drawable.bg_phone_tag_green) + tvValue.setTextColor(ContextCompat.getColor(context, R.color.phone_tag_green_text)) + } else { + tvValue.setBackgroundResource(R.drawable.bg_phone_value_orange) + tvValue.setTextColor(ContextCompat.getColor(context, R.color.phone_orange_text)) + } tvValue.setTypeface(tvValue.typeface, android.graphics.Typeface.BOLD) val padH = (4 * resources.displayMetrics.density).toInt() tvValue.setPadding(padH, 0, padH, 0) diff --git a/module_base/src/main/java/com/lukouguoji/module_base/ui/weight/phone/PhoneWidgetKtx.kt b/module_base/src/main/java/com/lukouguoji/module_base/ui/weight/phone/PhoneWidgetKtx.kt index 0134839..a5438c3 100644 --- a/module_base/src/main/java/com/lukouguoji/module_base/ui/weight/phone/PhoneWidgetKtx.kt +++ b/module_base/src/main/java/com/lukouguoji/module_base/ui/weight/phone/PhoneWidgetKtx.kt @@ -219,10 +219,17 @@ fun setPhoneStatBoxAttrs( // PhoneKvItem /////////////////////////////////////////////////////////////////////////// -@BindingAdapter("title", "value", "tag", requireAll = false) -fun setPhoneKvItemAttrs(item: PhoneKvItem, title: String?, value: String?, tag: Boolean?) { +@BindingAdapter("title", "value", "tag", "tagColor", requireAll = false) +fun setPhoneKvItemAttrs( + item: PhoneKvItem, + title: String?, + value: String?, + tag: Boolean?, + tagColor: String? +) { title?.let { item.title = it } - // tag 需先于 value 生效,确保样式切换后再填内容 + // tag/tagColor 需先于 value 生效,确保样式切换后再填内容 + tagColor?.let { item.tagColor = it } tag?.let { item.tag = it } item.value = value.orEmpty() } diff --git a/module_base/src/main/res/drawable/bg_phone_dot_blue.xml b/module_base/src/main/res/drawable/bg_phone_dot_blue.xml new file mode 100644 index 0000000..f076187 --- /dev/null +++ b/module_base/src/main/res/drawable/bg_phone_dot_blue.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/module_base/src/main/res/drawable/bg_phone_dot_gray.xml b/module_base/src/main/res/drawable/bg_phone_dot_gray.xml new file mode 100644 index 0000000..204e516 --- /dev/null +++ b/module_base/src/main/res/drawable/bg_phone_dot_gray.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/module_base/src/main/res/drawable/ic_phone_package.xml b/module_base/src/main/res/drawable/ic_phone_package.xml new file mode 100644 index 0000000..45bfe57 --- /dev/null +++ b/module_base/src/main/res/drawable/ic_phone_package.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/module_base/src/main/res/drawable/ic_phone_tag.xml b/module_base/src/main/res/drawable/ic_phone_tag.xml new file mode 100644 index 0000000..8db7a99 --- /dev/null +++ b/module_base/src/main/res/drawable/ic_phone_tag.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/module_base/src/main/res/layout/layout_phone_filter_panel.xml b/module_base/src/main/res/layout/layout_phone_filter_panel.xml index 1499ea2..f4e714a 100644 --- a/module_base/src/main/res/layout/layout_phone_filter_panel.xml +++ b/module_base/src/main/res/layout/layout_phone_filter_panel.xml @@ -44,12 +44,24 @@ - - + + android:layout_weight="1" + android:overScrollMode="never" + android:scrollbars="none"> + + + + - if (visible) showFilterPanel() else hideFilterPanel() + // 平板变体才有侧滑筛选面板(filter_panel/filter_overlay 手机变体不存在,Binding 字段为 null) + val padFilterPanel = binding.filterPanel + if (padFilterPanel != null) { + // 观察筛选面板显示状态(滑入/滑出动画) + viewModel.filterVisible.observe(this) { visible -> + if (visible) showFilterPanel() else hideFilterPanel() + } + + // 航班号:大写字母+数字 + padFilterPanel.filterFlightNo.et.setUpperCaseAlphanumericFilter() + // 目的港:仅大写字母 + padFilterPanel.filterDest.et.setUpperCaseLetterFilter() + } else { + // 手机变体:PhoneFilterPanel 的显隐由 XML 直接绑定 viewModel.filterVisible,无需动画代码 + binding.phoneFilterFlightNo?.et?.setUpperCaseAlphanumericFilter() + binding.phoneFilterDest?.et?.setUpperCaseLetterFilter() } - // 航班号:大写字母+数字 - binding.filterPanel.filterFlightNo.et.setUpperCaseAlphanumericFilter() - // 目的港:仅大写字母 - binding.filterPanel.filterDest.et.setUpperCaseLetterFilter() + // 手机形态专属:特码下拉字典 + 已入库/已离港统计 + if (DeviceUtil.isPhone()) { + viewModel.initPhoneExtras() + } // 初始加载 viewModel.refresh() } private fun showFilterPanel() { - val panel = binding.filterPanel.root - val overlay = binding.filterOverlay + val panel = binding.filterPanel?.root ?: return + val overlay = binding.filterOverlay ?: return val panelWidth = window.decorView.width / 3 panel.layoutParams = (panel.layoutParams as FrameLayout.LayoutParams).apply { @@ -86,8 +100,8 @@ class GjcQueryActivity : } private fun hideFilterPanel() { - val panel = binding.filterPanel.root - val overlay = binding.filterOverlay + val panel = binding.filterPanel?.root ?: return + val overlay = binding.filterOverlay ?: return if (panel.visibility != View.VISIBLE) return diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcQueryDetailsViewModel.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcQueryDetailsViewModel.kt index c9bec27..e77286e 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcQueryDetailsViewModel.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcQueryDetailsViewModel.kt @@ -34,6 +34,11 @@ class GjcQueryDetailsViewModel : BaseViewModel() { // 库位列表 (storageUseList) val storageUseList = MutableLiveData>>(emptyList()) + // ==================== 5.5寸手机版专属(展示用,平板布局不绑定) ==================== + // 入库件数/入库重量 = warehouseList 各批次求和(设计稿「件重信息」区块) + val inPcTotal = MutableLiveData("--") + val inWeightTotal = MutableLiveData("--") + // ==================== Fragment列表 ==================== val fragmentList by lazy { listOf( @@ -59,6 +64,40 @@ class GjcQueryDetailsViewModel : BaseViewModel() { currentTab.value = index } + // ==================== 5.5寸手机版取值帮助方法(布局绑定用) ==================== + // 表达式里必须把 map(maWbData)作为参数传入,DataBinding 才能追踪依赖并在数据到达后刷新 + + /** + * 从详情 Map 取字符串展示值;数字自动去掉无意义的 .0;空值兜底 "--" + */ + fun str(map: Map?, key: String): String { + val v = map?.get(key) ?: return "--" + val s = when (v) { + is Double -> if (v % 1.0 == 0.0) v.toLong().toString() else v.toString() + else -> v.toString() + } + return s.ifBlank { "--" } + } + + /** + * 依次取第一个非空 key 的展示值(如 agentName 优先于 agentCode) + */ + fun strOr(map: Map?, key: String, fallbackKey: String): String { + val first = str(map, key) + return if (first != "--") first else str(map, fallbackKey) + } + + /** + * 取重量类数值(保留小数形式),空值兜底 "--" + */ + fun dec(map: Map?, key: String): String { + val v = map?.get(key) ?: return "--" + return when (v) { + is Double -> v.toString() + else -> v.toString().ifBlank { "--" } + } + } + /** * 加载详情数据 */ @@ -111,6 +150,17 @@ class GjcQueryDetailsViewModel : BaseViewModel() { val whList = data["warehouseList"] as? List> ?: emptyList() warehouseList.value = whList + // 手机版「入库件数/入库重量」= 各批次求和(Gson 反序列化数字均为 Double) + if (whList.isNotEmpty()) { + val pcSum = whList.sumOf { (it["pc"] as? Double) ?: 0.0 } + val weightSum = whList.sumOf { (it["weight"] as? Double) ?: 0.0 } + inPcTotal.value = pcSum.toLong().toString() + inWeightTotal.value = weightSum.toString() + } else { + inPcTotal.value = "--" + inWeightTotal.value = "--" + } + // 解析 storageUseList 列表 @Suppress("UNCHECKED_CAST") val suList = data["storageUseList"] as? List> ?: emptyList() diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcQueryViewModel.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcQueryViewModel.kt index 69034e8..d5c112b 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcQueryViewModel.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcQueryViewModel.kt @@ -7,6 +7,7 @@ import androidx.lifecycle.MutableLiveData import com.lukouguoji.gjc.R import com.lukouguoji.gjc.holder.GjcQueryViewHolder import com.lukouguoji.module_base.base.BasePageViewModel +import com.lukouguoji.module_base.bean.GjcMaWb import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.http.net.NetApply import com.lukouguoji.module_base.ktx.launchCollect @@ -76,6 +77,31 @@ class GjcQueryViewModel : BasePageViewModel() { val businessType = MutableLiveData("") // 业务类型 val goodsCn = MutableLiveData("") // 品名(中) + // ==================== 5.5寸手机版专属 ==================== + // 特码下拉列表(设计稿筛选弹层为下拉;平板筛选为文本输入,不加载) + val specialCodeList = MutableLiveData>(emptyList()) + + // 三格统计:已入库 / 已离港(总票数复用 totalCount,为服务端全量口径) + // 后端无分项统计出参,且文档定义的 isFclose 入参实测被 pageQuery/pageQueryTotal 静默忽略 + // (2026-07-31 内网 A/B 验证,见接口问题清单)——已入库/已离港暂为「已加载数据」客户端计数口径 + val storedCount = MutableLiveData("0") + val departedCount = MutableLiveData("0") + + private var phoneExtrasEnabled = false + private var phoneLoadedList: List = emptyList() + + /** + * 手机形态专属初始化(Activity 在 DeviceUtil.isPhone() 时调用)。 + * 平板端不调用,请求次数与行为零变化。 + */ + fun initPhoneExtras() { + phoneExtrasEnabled = true + // flag=1 国际;ieFlag 必须留空——传 "E" 后端返回空数组(与既有国际出港页面口径一致) + DictUtils.getSpecialCodeList(addAll = false, flag = 1, ieFlag = "") { list -> + specialCodeList.postValue(listOf(KeyValue("全部", "")) + list) + } + } + // 是否有筛选条件(任意一个非空则为 true,用于筛选按钮红点) val hasFilter: MediatorLiveData = MediatorLiveData().apply { val update = { _: Any? -> @@ -201,6 +227,14 @@ class GjcQueryViewModel : BasePageViewModel() { onSuccess = { pageInfo -> // ⚠️ 核心:使用toBaseListBean()转换PageInfo为BaseListBean pageModel.handleListBean(pageInfo.toBaseListBean()) + + // 手机三格统计:对已加载数据做客户端计数(平板不触发) + if (phoneExtrasEnabled) { + val pageItems = pageInfo.list ?: emptyList() + phoneLoadedList = + if (pageModel.page <= 1) pageItems else phoneLoadedList + pageItems + updatePhoneCounts() + } } } @@ -217,6 +251,16 @@ class GjcQueryViewModel : BasePageViewModel() { } } + /** + * 手机三格统计(已入库/已离港):与卡片状态标签同一判定口径(fclose / opDate), + * 统计范围为已加载的列表数据。 + */ + private fun updatePhoneCounts() { + departedCount.value = phoneLoadedList.count { it.isQueryDeparted }.toString() + storedCount.value = + phoneLoadedList.count { !it.isQueryDeparted && it.isQueryStored }.toString() + } + /** * 处理扫码结果 */ diff --git a/module_gjc/src/main/res/layout-sw600dp/activity_gjc_query.xml b/module_gjc/src/main/res/layout-sw600dp/activity_gjc_query.xml new file mode 100644 index 0000000..1b60f63 --- /dev/null +++ b/module_gjc/src/main/res/layout-sw600dp/activity_gjc_query.xml @@ -0,0 +1,237 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout-sw600dp/activity_gjc_query_details.xml b/module_gjc/src/main/res/layout-sw600dp/activity_gjc_query_details.xml new file mode 100644 index 0000000..34b34b7 --- /dev/null +++ b/module_gjc/src/main/res/layout-sw600dp/activity_gjc_query_details.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout-sw600dp/fragment_gjc_query_storage.xml b/module_gjc/src/main/res/layout-sw600dp/fragment_gjc_query_storage.xml new file mode 100644 index 0000000..43d5ba2 --- /dev/null +++ b/module_gjc/src/main/res/layout-sw600dp/fragment_gjc_query_storage.xml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout-sw600dp/fragment_gjc_query_warehouse.xml b/module_gjc/src/main/res/layout-sw600dp/fragment_gjc_query_warehouse.xml new file mode 100644 index 0000000..c9f7f93 --- /dev/null +++ b/module_gjc/src/main/res/layout-sw600dp/fragment_gjc_query_warehouse.xml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout-sw600dp/fragment_gjc_query_waybill.xml b/module_gjc/src/main/res/layout-sw600dp/fragment_gjc_query_waybill.xml new file mode 100644 index 0000000..0917122 --- /dev/null +++ b/module_gjc/src/main/res/layout-sw600dp/fragment_gjc_query_waybill.xml @@ -0,0 +1,319 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout-sw600dp/item_gjc_query.xml b/module_gjc/src/main/res/layout-sw600dp/item_gjc_query.xml new file mode 100644 index 0000000..3f4902f --- /dev/null +++ b/module_gjc/src/main/res/layout-sw600dp/item_gjc_query.xml @@ -0,0 +1,318 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout-sw600dp/item_gjc_query_storage.xml b/module_gjc/src/main/res/layout-sw600dp/item_gjc_query_storage.xml new file mode 100644 index 0000000..7eec041 --- /dev/null +++ b/module_gjc/src/main/res/layout-sw600dp/item_gjc_query_storage.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout-sw600dp/item_gjc_query_warehouse.xml b/module_gjc/src/main/res/layout-sw600dp/item_gjc_query_warehouse.xml new file mode 100644 index 0000000..09418f9 --- /dev/null +++ b/module_gjc/src/main/res/layout-sw600dp/item_gjc_query_warehouse.xml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout/layout_gjc_query_filter.xml b/module_gjc/src/main/res/layout-sw600dp/layout_gjc_query_filter.xml similarity index 100% rename from module_gjc/src/main/res/layout/layout_gjc_query_filter.xml rename to module_gjc/src/main/res/layout-sw600dp/layout_gjc_query_filter.xml diff --git a/module_gjc/src/main/res/layout/activity_gjc_query.xml b/module_gjc/src/main/res/layout/activity_gjc_query.xml index 1b60f63..e1aefee 100644 --- a/module_gjc/src/main/res/layout/activity_gjc_query.xml +++ b/module_gjc/src/main/res/layout/activity_gjc_query.xml @@ -1,208 +1,201 @@ + + - + + - + android:background="@color/phone_page_bg"> - - - - - + android:layout_height="match_parent" + android:orientation="vertical"> - + + + + android:layout_height="wrap_content" + android:background="@color/white" + android:orientation="vertical" + android:paddingHorizontal="16dp" + android:paddingTop="16dp" + android:paddingBottom="12dp"> - - + + + + + + + + - - + - - - - - - - - - - - - - + android:orientation="vertical" + android:paddingHorizontal="12dp" + android:paddingVertical="10dp"> - - + - - - - - - - - + - - - - - - - - + + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="10dp" + android:layout_weight="1" + android:background="@drawable/bg_phone_card" + android:orientation="horizontal"> + + - + android:orientation="vertical" + android:paddingHorizontal="12dp" + android:paddingVertical="10dp"> + android:text="已入库" + android:textColor="@color/phone_text_body" + android:textSize="12sp" /> + tools:text="2" /> + + + + + + + + + + + + + + tools:text="2" /> @@ -210,28 +203,131 @@ - - + + android:layout_height="0dp" + android:layout_weight="1"> - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - diff --git a/module_gjc/src/main/res/layout/activity_gjc_query_details.xml b/module_gjc/src/main/res/layout/activity_gjc_query_details.xml index 34b34b7..99ccbf2 100644 --- a/module_gjc/src/main/res/layout/activity_gjc_query_details.xml +++ b/module_gjc/src/main/res/layout/activity_gjc_query_details.xml @@ -1,125 +1,137 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout/fragment_gjc_query_storage.xml b/module_gjc/src/main/res/layout/fragment_gjc_query_storage.xml index 43d5ba2..4211277 100644 --- a/module_gjc/src/main/res/layout/fragment_gjc_query_storage.xml +++ b/module_gjc/src/main/res/layout/fragment_gjc_query_storage.xml @@ -1,137 +1,53 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout/fragment_gjc_query_warehouse.xml b/module_gjc/src/main/res/layout/fragment_gjc_query_warehouse.xml index c9f7f93..4a16117 100644 --- a/module_gjc/src/main/res/layout/fragment_gjc_query_warehouse.xml +++ b/module_gjc/src/main/res/layout/fragment_gjc_query_warehouse.xml @@ -1,157 +1,53 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout/fragment_gjc_query_waybill.xml b/module_gjc/src/main/res/layout/fragment_gjc_query_waybill.xml index 0917122..1c106f1 100644 --- a/module_gjc/src/main/res/layout/fragment_gjc_query_waybill.xml +++ b/module_gjc/src/main/res/layout/fragment_gjc_query_waybill.xml @@ -1,319 +1,452 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout/item_gjc_query.xml b/module_gjc/src/main/res/layout/item_gjc_query.xml index 3f4902f..def293b 100644 --- a/module_gjc/src/main/res/layout/item_gjc_query.xml +++ b/module_gjc/src/main/res/layout/item_gjc_query.xml @@ -1,318 +1,226 @@ + + xmlns:tools="http://schemas.android.com/tools"> + + + - - - - - - - - + android:layout_height="wrap_content" + android:layout_marginHorizontal="16dp" + android:layout_marginTop="12dp" + android:background="@drawable/bg_phone_card" + android:orientation="vertical" + android:padding="14dp"> + + android:gravity="center_vertical" + android:orientation="horizontal"> - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:layout_weight="1" + android:text="@{bean.wbNo}" + android:textColor="@color/phone_text_title" + android:textSize="16sp" + android:textStyle="bold" + tools:text="78133363396" /> - - + + - + + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - diff --git a/module_gjc/src/main/res/layout/item_gjc_query_storage.xml b/module_gjc/src/main/res/layout/item_gjc_query_storage.xml index 7eec041..dcf07d5 100644 --- a/module_gjc/src/main/res/layout/item_gjc_query_storage.xml +++ b/module_gjc/src/main/res/layout/item_gjc_query_storage.xml @@ -1,99 +1,113 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout/item_gjc_query_warehouse.xml b/module_gjc/src/main/res/layout/item_gjc_query_warehouse.xml index 09418f9..acac4de 100644 --- a/module_gjc/src/main/res/layout/item_gjc_query_warehouse.xml +++ b/module_gjc/src/main/res/layout/item_gjc_query_warehouse.xml @@ -1,119 +1,136 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_p/src/main/java/com/sixin/module_p/ui/enter/gj/GjViewModel.kt b/module_p/src/main/java/com/sixin/module_p/ui/enter/gj/GjViewModel.kt index 77a6405..dfbba7b 100644 --- a/module_p/src/main/java/com/sixin/module_p/ui/enter/gj/GjViewModel.kt +++ b/module_p/src/main/java/com/sixin/module_p/ui/enter/gj/GjViewModel.kt @@ -60,6 +60,12 @@ class GjViewModel : BaseViewModel() { Constant.AuthName.GjcIntExpArrive, ARouterConstants.ACTIVITY_URL_INT_EXP_ARRIVE ), + ActionBean( + "出港查询", + R.drawable.gjc_query_icon, + Constant.AuthName.GjcQueryListActivity, + ARouterConstants.ACTIVITY_URL_GJC_QUERY_LIST + ), // ULD管理属综合管理业务(Pad 端在「综合管理」菜单组),手机端首页暂无综合 Tab,挂在国际 Tab 下 ActionBean( "ULD管理", diff --git a/module_p/src/main/res/drawable-xxhdpi/gjc_query_icon.png b/module_p/src/main/res/drawable-xxhdpi/gjc_query_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..76433e263a328f5efa873e2227c5ef34c3896d06 GIT binary patch literal 32301 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