Compare commits

...

2 Commits

Author SHA1 Message Date
33c9f0e030 feat: 完成出港查询页面5.5寸手机端适配
- 列表/详情/运单追踪三页同名布局双变体(平板移 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 <noreply@anthropic.com>
2026-07-31 18:13:44 +08:00
436202f15b fix: 出港运抵手机端对照设计稿review修正与重置弹框适配
- 状态重置弹框改手机底部弹层:dialog 布局同名双变体(Pad 移 layout-sw600dp),
  弹出位置按形态切 DIALOG_TYPE_BOTTOM/CENTER,为弹框适配首例
- 主列表补空态(文案按 Tab 切换)、回执页补「暂无回执内容」兜底
- 分单明细长按浮层按设计稿补「回执」按钮;底部统计加分母「已选 N / M 项」
- Tab 角标初始显示 0
- PhoneStatusTab/PhoneFilterPanel 补 dispatchSave/RestoreInstanceState 状态屏蔽(历史遗漏)
- 双端实机验证:手机端各修正点与设计稿一致且 crash=0;平板端列表与批量重置弹框回归无变化

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 23:21:33 +08:00
53 changed files with 4078 additions and 1730 deletions

View File

@@ -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 <phone> tap-text "已交接" # 按文字点击,比手算坐标可靠
$P <phone> texts # 用文字变化断言点击确实生效(如底部条应消失)
$P <phone> shot /tmp/p1.png
$P <phone> crash # 必须为 0
$P <phone> req pageQuery # 核对请求体参数确实带上了新字段
```
核对请求/响应体优先用 Proxyman MCP`filter_flows` + `get_flow_detail`,比 `req`
logcat 抓包完整可靠;模拟器代理一行命令接入,见 `references/proxyman.md`
Proxyman 不可用时兜底 `$P <phone> req pageQuery`
逐项走查:列表/卡片两种形态、详情页、筛选弹层(重置+确认、Tab 切换、单选与全选联动、
下拉真实取数、扫码入口。每步 `crash` 都要为 0。
@@ -253,7 +260,12 @@ $P <phone> req pageQuery # 核对请求体参数确实带上了新字段
**空值兜底**(真实数据空字段很常见——出库交接就出现过「库位」为空时橙色高亮标签只剩一个孤零零的
小色块,需要空值时不套标签底)。
服务端当天没数据时(列表空)先放宽条件重查;仍为空就临时在 Activity 里注入样例 Bean 截图比对:
服务端当天没数据时(列表空)先放宽条件重查;仍为空、或要覆盖真实数据凑不出的形态
(空字段、超长文本、罕见状态标签),**首选 Proxyman Map Local 造 mock**——零代码改动、
零重构建,见 `references/proxyman.md` 场景 32026-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 命令、登录与直启、已知环境坑(验证前读)

View File

@@ -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,待计重/计重中计数依赖);

View File

@@ -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` 内容插槽已内置 ScrollView2026-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比找位图靠谱且能染色。

View File

@@ -44,6 +44,26 @@ com/lukouguoji/gjc/databinding/ItemXxxBinding.java
`activity_xxx_phone.xml` 会生成 `ActivityXxxPhoneBinding`,而字段声明的类型是
`ActivityXxxBinding`。泛型擦除让**编译期查不出来**,一进页面就 `ClassCastException`
### 弹框BaseDialogModel也要双变体最容易漏
页面布局适配完,长按/批量操作弹出的 DialogModel 仍会以 Pad 居中样式出现在手机上
(出港运抵的「状态重置」就漏过)。做法与页面完全同构:
1. dialog 布局 `git mv``layout-sw600dp/``layout/` 下写同名手机版(设计稿通常是底部弹层:
`bg_phone_panel_top` + 居中标题 + `ic_phone_close` + 全宽 `bg_phone_btn_primary` 确定键)
2. 弹出位置在构造参数按形态切换XPopup 位置与布局是两回事,都要改):
```kotlin
class XxxDialogModel(...) : BaseDialogModel<DialogXxxBinding>(
if (DeviceUtil.isPhone()) DIALOG_TYPE_BOTTOM else DIALOG_TYPE_CENTER
)
```
3. 两变体 `<variable>` 一致imports 不要求一致)
参考:`IntExpArriveResetDialogModel` + `dialog_int_exp_arrive_reset.xml` 双变体。
**适配收尾时逐个 grep 该页 ViewModel 里 `DialogModel(` 的调用点**,每个弹框都过一遍。
## 业务层零破坏的三个模式
### 新增查询维度:默认空值 + 仅非空进请求

View File

@@ -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 <serial> shell settings put global http_proxy 10.0.2.2:9090
# 3) 验证完【必须】清掉,否则 Proxyman 一关模拟器就断网,下次验证莫名全挂
adb -s <serial> 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→ 完整请求体 + 响应体 + headersAuthorization 自动脱敏)
**出参无文档定义时(如 `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 附进问题清单。
## 场景 3Map Local 造 mock 验证 corner case替代代码注入样例 Bean
老流程「Activity 临时注入 Bean → 截图 → 删码 → 重构建」彻底淘汰:**零代码改动、零重构建**。
- `create_map_local`url 精确到接口路径method=POSTresponse_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 过的页面,确认无假数据残影

View File

@@ -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~#22isFclose 入参实测被 pageQuery/pageQueryTotal 静默忽略且
无已入库/已离港分项统计出参detail 出参无锁定状态/计费重量字段)
### 修复 (Fixed)
- **`PhoneFilterPanel` 底部按钮被挤出屏幕**:面板高度 wrap_content 且内容插槽无滚动,筛选项多
(出港查询 9 项)时「重置/确认」按钮直接超出屏幕外且无任何报错。修复:内容插槽外包
ScrollViewweight=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 长按)+ 底部全选/已选/申报
@@ -22,6 +53,12 @@
- 新增手机版资源:`bg_phone_tag_indigo`/`bg_phone_tag_amber`(申报状态三色标签)、
`bg_phone_fab_purple`/`bg_phone_fab_amber`/`bg_phone_fab_green`(长按浮层圆形操作按钮)
- 后端缺口 2 项登记问题清单 #19~#20分单补充信息保存接口不存在、Tab 无申报状态查询参数)
- 「出港运抵」对照设计稿 review 修正:状态重置弹框手机端改为设计稿底部弹层
**弹框适配首个先例**`dialog_int_exp_arrive_reset.xml` 同名布局双变体Pad 版移至
`layout-sw600dp/``IntExpArriveResetDialogModel` 构造参数按 `DeviceUtil.isPhone()`
`DIALOG_TYPE_BOTTOM`/`CENTER`);主列表补空态(图标 + 文案按 Tab 切换「暂无待/已运抵的运单」);
回执页补空态兜底「暂无回执内容」(单分单入口常无回执,避免纯白屏);分单明细长按浮层按设计稿
补「回执」按钮(单分单跳回执页);分单页底部统计加分母「已选 N / M 项」Tab 角标初始显示 0
### 修复 (Fixed)
- **RecyclerView + Tab 过滤新坑**:给 item 根节点加 `visibility="@{...}"` 切 Tab 会在列表里
@@ -33,12 +70,18 @@
修饰符Java 序列化Intent 传递机制)会跳过其恢复,反序列化后为 null切换选中状态时
NullPointerException 崩溃。修复:接收方 `initOnCreated` 对列表 `.map { it.copy() }` 重新
触发类体初始化补上(已实机崩溃复现并验证修复)
- `PhoneStatusTab`/`PhoneFilterPanel` 补上遗漏的 `dispatchSaveInstanceState`/
`dispatchRestoreInstanceState` 屏蔽覆写(其余 5 个手机版复合组件均已重写,这两个是历史遗漏;
同页多实例时子控件状态可能按 id 跨实例串档)
### 验证 (Verified)
- 出港运抵双端实机验证通过:手机端 Tab 切换(角标/卡片双向正确)/全选/单选/长按菜单/查看分单
/分单明细全选与长按重置/补充信息(真实数据回填+下拉字典+提交请求体完整+后端404如实呈现/
回执页 全链路 crash=0、方向无闪屏平板端布局与交互4 搜索条+分单内嵌展开+底部 5 元素操作栏)
与改造前逐项一致
- 出港运抵 review 修正双端实机验证通过:手机端重置底部弹层(长按→重置→下拉展开选项)/主列表空态
/回执页空态/分单浮层重置+回执双按钮/「已选 0 / 2 项」分母 全部与设计稿一致且 crash=0
平板端回归:列表、批量「状态重置」弹框仍为居中 Pad 样式,行为与改造前一致
- 「出港计重」5.5 寸手机端适配(首个全链路 4+1 页模块,设计稿 03_出港计重
待计重列表(三格统计 总票数/待计重/计重中 + 卡片状态标签 未计重/计重中 + 卡片内单票「提前运抵」+
FAB 进计重记录 + 筛选弹层 通道号/承运人/运单类型/代理人)、开始计重(头部预配统计卡 + PhoneFormRow 表单,

View File

@@ -975,7 +975,12 @@ Manifest 写死 `userLandscape` 时,即使 `BaseActivity` 在 `super.onCreate`
3. **Kotlin 侧不动**`layoutId()``itemLayoutId`、ViewHolder 全部保持原样
4. **纯 UI 交互**Tab 切换、弹层显隐)写在 Activity不污染 ViewModel状态过滤优先复用 ViewModel 既有字段
5. 手机布局顶部 `<include layout="@layout/title_tool_bar" />` 不变(变体自动切换)
6. **回到手机端首页加菜单入口**(最易遗忘,见下节)——不加的话页面在手机上根本进不去
6. **弹框BaseDialogModel同样要适配**dialog 布局照样走同名双变体Pad 版移 `layout-sw600dp/`
手机版在 `layout/` 写设计稿的底部弹层样式),弹出位置在构造参数按形态切换:
`BaseDialogModel<XxxBinding>(if (DeviceUtil.isPhone()) DIALOG_TYPE_BOTTOM else DIALOG_TYPE_CENTER)`
(参考 `IntExpArriveResetDialogModel` + `dialog_int_exp_arrive_reset.xml` 双变体)。
页面适配完要**逐个排查该页所有 DialogModel**,漏掉的会在手机上弹出 Pad 居中样式
7. **回到手机端首页加菜单入口**(最易遗忘,见下节)——不加的话页面在手机上根本进不去
### 手机端首页菜单入口(适配完必须加,否则没入口)
@@ -1048,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 管理批量删除)。
@@ -1056,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
@@ -1121,7 +1129,18 @@ override fun dispatchRestoreInstanceState(container: SparseArray<Parcelable>) =
visibility 绑定(实机截图验证过,见「常见编译错误速查」);② 通过 `Intent.putExtra(Serializable)`
传递的 `GjcHaWb`/`GjcMaWb`,其 `checked`/`showMore`/`actionMenuVisible` 字段标了
`@Transient`= JVM `transient`Java 序列化会跳过),反序列化后为 null直接
`.checked.set(...)` 会崩溃——接收方 `initOnCreated` 必须对列表 `.map { it.copy() }` 补上
`.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
includeBinding 字段为 @Nullable
-**待办**
- `PhoneSearchBar` 接入 AutoQuery 联想(`AutoQueryManager` 目前只对接了 Pad 系组件)
- 出库交接 Tab 角标恒 0`IntExpOutHandover/pageQueryTotal` 出参恒 0后端缺陷问题清单 #6

View File

@@ -104,5 +104,23 @@
android:exported="true"
tools:replace="android:exported" />
<!-- 出港查询(手机版适配验证页) -->
<activity
android:name="com.lukouguoji.gjc.activity.GjcQueryActivity"
android:exported="true"
tools:replace="android:exported" />
<!-- 出港查询-详情(手机版适配验证页) -->
<activity
android:name="com.lukouguoji.gjc.activity.GjcQueryDetailsActivity"
android:exported="true"
tools:replace="android:exported" />
<!-- 运单追踪/操作日志详情(手机版适配验证页) -->
<activity
android:name="com.lukouguoji.aerologic.page.log.detail.LogDetailActivity"
android:exported="true"
tools:replace="android:exported" />
</application>
</manifest>

View File

@@ -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<ActivityLogDetailBinding, LogDetailViewModel>() {
@@ -34,7 +35,8 @@ class LogDetailActivity : BaseBindingActivity<ActivityLogDetailBinding, LogDetai
}
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("操作日志详情")
// 手机版设计稿标题为「运单追踪」,平板保持原标题
setBackArrow(if (DeviceUtil.isPhone()) "运单追踪" else "操作日志详情")
binding.viewModel = viewModel
// 配置操作详情 RecyclerView垂直时间线
@@ -58,8 +60,109 @@ class LogDetailActivity : BaseBindingActivity<ActivityLogDetailBinding, LogDetai
val activeCodes = viewModel.activeStepCodes.value ?: emptySet()
val latestCode = viewModel.latestStepCode.value ?: ""
if (steps.isEmpty()) return
// 手机布局是竖排时间线layout/activity_log_detail.xml平板保持横向步骤条
if (DeviceUtil.isPhone()) {
buildVerticalSteps(steps, activeCodes, latestCode)
} else {
buildStepProgressBar(steps, activeCodes, latestCode)
}
}
/**
* 手机版竖排流转时间线(对应设计稿「运单追踪」):
* 每个节点 = 左侧圆点 + 连接竖线,右侧步骤名 + 该环节最新操作时间。
* 已发生节点绿色,未发生节点灰色。
*/
private fun buildVerticalSteps(
steps: List<StepInfo>,
activeCodes: Set<String>,
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(
steps: List<StepInfo>,

View File

@@ -0,0 +1,231 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="com.lukouguoji.aerologic.page.log.detail.LogDetailViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_f2"
android:orientation="vertical">
<include layout="@layout/title_tool_bar" />
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="15dp">
<!-- 运单信息 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- 标题区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@drawable/bg_white_radius_top_8"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单信息"
android:textColor="#333333"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 分割线(贯穿卡片宽度) -->
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#E7E7E7" />
<!-- 内容区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginEnd="15dp"
android:layout_marginVertical="12dp"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单号:"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.waybillNo}"
android:textColor="#333333"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单类型:"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.waybillType}"
android:textColor="#333333"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- 流转状态 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:orientation="vertical">
<!-- 标题区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@drawable/bg_white_radius_top_8"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="流转状态"
android:textColor="#333333"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 分割线 -->
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#E7E7E7" />
<!-- 内容区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical">
<LinearLayout
android:id="@+id/ll_steps"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="23dp"
android:layout_marginEnd="15dp"
android:layout_marginVertical="12dp"
android:orientation="horizontal" />
</LinearLayout>
</LinearLayout>
<!-- 操作详情 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:orientation="vertical">
<!-- 标题区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@drawable/bg_white_radius_top_8"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="操作详情"
android:textColor="#333333"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 分割线 -->
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#E7E7E7" />
<!-- 内容区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_timeline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:paddingStart="8dp"
android:nestedScrollingEnabled="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
</layout>

View File

@@ -1,6 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
操作日志详情(运单追踪)—— 手机版布局5.5 寸手持端,最小宽度 < 600dp 时生效)
平板版为同名文件 layout-sw600dp/activity_log_detail.xml横向步骤条 + 操作详情时间线),
两者是同一布局的资源变体DataBinding 因此生成同一个 ActivityLogDetailBinding 类。
变体之间必须满足:
· DataBinding 变量完全一致viewModel
· 保留 Activity 引用的控件 idll_steps / rv_timeline
手机版按设计稿「运单追踪」呈现:
· 顶卡:运单号 + 运单类型标签
· 流转状态竖排时间线LogDetailActivity 手机分支 buildVerticalSteps 动态填充 ll_steps
· 平板的「操作详情」时间线列表在手机设计稿中不存在rv_timeline 保留 id 但隐藏
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
@@ -12,7 +28,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_f2"
android:background="@color/phone_page_bg"
android:orientation="vertical">
<include layout="@layout/title_tool_bar" />
@@ -20,208 +36,99 @@
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="15dp">
android:padding="12dp">
<!-- 运单信息 -->
<!-- ==================== 运单卡片 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:background="@drawable/bg_phone_card"
android:orientation="vertical"
android:padding="16dp">
<!-- 标题区 -->
<!-- 运单号 + 运单类型标签 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@drawable/bg_white_radius_top_8"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{viewModel.waybillNo}"
android:textColor="@color/phone_text_title"
android:textSize="20sp"
android:textStyle="bold"
tools:text="78133358743" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单信息"
android:textColor="#333333"
android:textSize="16sp"
android:textStyle="bold" />
android:layout_height="22dp"
android:layout_marginStart="8dp"
android:background="@drawable/bg_phone_tag_indigo"
android:gravity="center"
android:paddingHorizontal="10dp"
android:text="@{viewModel.waybillType}"
android:textColor="@color/phone_tag_indigo_text"
android:textSize="12sp"
tools:text="国际出港" />
</LinearLayout>
<!-- 分割线(贯穿卡片宽度) -->
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#E7E7E7" />
<!-- 内容区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginEnd="15dp"
android:layout_marginVertical="12dp"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单号:"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.waybillNo}"
android:textColor="#333333"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单类型:"
android:textColor="#666666"
android:textSize="14sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.waybillType}"
android:textColor="#333333"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- 流转状态 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:orientation="vertical">
<!-- 标题区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@drawable/bg_white_radius_top_8"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
android:layout_height="1px"
android:layout_marginTop="14dp"
android:layout_marginBottom="14dp"
android:background="@color/phone_divider" />
<!-- 流转状态标题 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="流转状态"
android:textColor="#333333"
android:textSize="16sp"
android:textColor="@color/phone_text_title"
android:textSize="15sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 分割线 -->
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#E7E7E7" />
<!-- 内容区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical">
<!-- 竖排时间线Activity 手机分支动态填充) -->
<LinearLayout
android:id="@+id/ll_steps"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="23dp"
android:layout_marginEnd="15dp"
android:layout_marginVertical="12dp"
android:orientation="horizontal" />
</LinearLayout>
</LinearLayout>
<!-- 操作详情 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:orientation="vertical">
<!-- 标题区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@drawable/bg_white_radius_top_8"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="操作详情"
android:textColor="#333333"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 分割线 -->
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#E7E7E7" />
<!-- 内容区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical">
android:layout_marginTop="14dp"
android:orientation="vertical" />
<!-- 平板的操作详情时间线,手机设计稿无此区块,保留 id 但隐藏 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_timeline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:paddingStart="8dp"
android:nestedScrollingEnabled="false"
android:visibility="gone"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
</LinearLayout>
<!-- 触底提示 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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" />
</LinearLayout>

View File

@@ -148,6 +148,20 @@ data class GjcMaWb(
else -> 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
// ==================== 状态转换扩展属性 ====================
/**
* 计重状态中文

View File

@@ -1,7 +1,9 @@
package com.lukouguoji.module_base.ui.weight.phone
import android.content.Context
import android.os.Parcelable
import android.util.AttributeSet
import android.util.SparseArray
import android.view.View
import android.widget.FrameLayout
import android.widget.ImageView
@@ -42,6 +44,18 @@ class PhoneFilterPanel @JvmOverloads constructor(
defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {
/**
* 同一页面可能出现多个含内部 id 的手机版复合组件,系统按 id 保存/恢复视图状态会跨实例串档。
* 这里只保存/恢复自身状态、不下发给子控件;筛选值由 ViewModel + DataBinding 持有,无需视图级恢复。
*/
override fun dispatchSaveInstanceState(container: SparseArray<Parcelable>) {
dispatchFreezeSelfOnly(container)
}
override fun dispatchRestoreInstanceState(container: SparseArray<Parcelable>) {
dispatchThawSelfOnly(container)
}
val llPanel: LinearLayout
val llContent: LinearLayout
val tvTitle: TextView

View File

@@ -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()) {
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)

View File

@@ -1,7 +1,9 @@
package com.lukouguoji.module_base.ui.weight.phone
import android.content.Context
import android.os.Parcelable
import android.util.AttributeSet
import android.util.SparseArray
import android.view.Gravity
import android.view.View
import android.widget.LinearLayout
@@ -37,6 +39,18 @@ class PhoneStatusTab @JvmOverloads constructor(
defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {
/**
* 同一页面可能出现多个含内部 id 的手机版复合组件,系统按 id 保存/恢复视图状态会跨实例串档。
* 这里只保存/恢复自身状态、不下发给子控件;选中值由 ViewModel + DataBinding 持有,无需视图级恢复。
*/
override fun dispatchSaveInstanceState(container: SparseArray<Parcelable>) {
dispatchFreezeSelfOnly(container)
}
override fun dispatchRestoreInstanceState(container: SparseArray<Parcelable>) {
dispatchThawSelfOnly(container)
}
/** 双向绑定回调 */
var onChangeListener: InverseBindingListener? = null

View File

@@ -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()
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 手机版状态圆点:主色蓝(出港查询卡片运单号前的指示点) -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/phone_primary" />
</shape>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 手机版状态圆点:灰色(运单追踪时间线未到达节点) -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/phone_text_hint" />
</shape>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 手机版件数图标MDI package-variant-closed默认灰色可 tint -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#9CA3AF"
android:pathData="M21,16.5C21,16.88 20.79,17.21 20.47,17.38L12.57,21.82C12.41,21.94 12.21,22 12,22C11.79,22 11.59,21.94 11.43,21.82L3.53,17.38C3.21,17.21 3,16.88 3,16.5V7.5C3,7.12 3.21,6.79 3.53,6.62L11.43,2.18C11.59,2.06 11.79,2 12,2C12.21,2 12.41,2.06 12.57,2.18L20.47,6.62C20.79,6.79 21,7.12 21,7.5V16.5M12,4.15L10.11,5.22L16,8.61L17.96,7.5L12,4.15M6.04,7.5L12,10.85L13.96,9.75L8.08,6.35L6.04,7.5M5,15.91L11,19.29V12.58L5,9.21V15.91M19,15.91V9.21L13,12.58V19.29L19,15.91Z" />
</vector>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 手机版特码/标签图标MDI tag-outline默认灰色可 tint -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#9CA3AF"
android:pathData="M21.41,11.58L12.41,2.58C12.05,2.22 11.55,2 11,2H4C2.9,2 2,2.9 2,4V11C2,11.55 2.22,12.05 2.59,12.42L11.59,21.42C11.95,21.78 12.45,22 13,22C13.55,22 14.05,21.78 14.41,21.41L21.41,14.41C21.78,14.05 22,13.55 22,13C22,12.45 21.77,11.94 21.41,11.58M13,20L4,11V4H11L20,13M6.5,5C7.33,5 8,5.67 8,6.5C8,7.33 7.33,8 6.5,8C5.67,8 5,7.33 5,6.5C5,5.67 5.67,5 6.5,5Z" />
</vector>

View File

@@ -44,13 +44,25 @@
</FrameLayout>
<!-- 内容插槽:筛选条件项由使用方在 XML 中声明 -->
<!-- 内容插槽:筛选条件项由使用方在 XML 中声明
外包 ScrollView + weight=1筛选项少时行为不变wrap 高度),
筛选项多到超屏时内容区收缩滚动,保证底部「重置/确认」按钮始终可见
(出港查询 9 个筛选项时曾把按钮挤出屏幕) -->
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:overScrollMode="never"
android:scrollbars="none">
<LinearLayout
android:id="@+id/ll_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
<!-- 底部按钮行 -->
<LinearLayout
android:layout_width="match_parent"

View File

@@ -18,6 +18,7 @@ import com.lukouguoji.module_base.ktx.getLifecycleOwner
import com.lukouguoji.module_base.ktx.setUpperCaseAlphanumericFilter
import com.lukouguoji.module_base.ktx.setUpperCaseLetterFilter
import com.lukouguoji.module_base.router.ARouterConstants
import com.lukouguoji.module_base.util.DeviceUtil
/**
* 国际出港查询列表页
@@ -48,23 +49,36 @@ class GjcQueryActivity :
viewModel.initAgentList()
viewModel.initFilterLists()
// 观察筛选面板显示状态
// 平板变体才有侧滑筛选面板filter_panel/filter_overlay 手机变体不存在Binding 字段为 null
val padFilterPanel = binding.filterPanel
if (padFilterPanel != null) {
// 观察筛选面板显示状态(滑入/滑出动画)
viewModel.filterVisible.observe(this) { visible ->
if (visible) showFilterPanel() else hideFilterPanel()
}
// 航班号:大写字母+数字
binding.filterPanel.filterFlightNo.et.setUpperCaseAlphanumericFilter()
padFilterPanel.filterFlightNo.et.setUpperCaseAlphanumericFilter()
// 目的港:仅大写字母
binding.filterPanel.filterDest.et.setUpperCaseLetterFilter()
padFilterPanel.filterDest.et.setUpperCaseLetterFilter()
} else {
// 手机变体PhoneFilterPanel 的显隐由 XML 直接绑定 viewModel.filterVisible无需动画代码
binding.phoneFilterFlightNo?.et?.setUpperCaseAlphanumericFilter()
binding.phoneFilterDest?.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

View File

@@ -67,6 +67,12 @@ class IntExpArriveSubOrderActivity :
viewModel.resetSingleClick(bean)
}
/** 长按菜单「回执」(单条):复用回执只读页,仅传当前分单 */
fun openReceipt(bean: GjcHaWb) {
bean.actionMenuVisible.set(false)
IntExpArriveReceiptActivity.start(this, viewModel.wbNo, arrayListOf(bean))
}
fun toggleFilterPanel() {
filterPanelVisible.set(!filterPanelVisible.get())
}

View File

@@ -6,14 +6,20 @@ import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.DialogIntExpArriveResetBinding
import com.lukouguoji.module_base.base.BaseDialogModel
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import com.lukouguoji.module_base.util.DeviceUtil
import dev.utils.app.info.KeyValue
/**
* 国际出港运抵 - 状态重置对话框
*
* 布局按资源限定符自动切换:手机 layout/(底部弹层)、平板 layout-sw600dp/(居中弹框),
* 弹出位置随形态选择 BOTTOM/CENTER。
*/
class IntExpArriveResetDialogModel(
private val callback: (IntExpArriveResetDialogModel) -> Unit
) : BaseDialogModel<DialogIntExpArriveResetBinding>(DIALOG_TYPE_CENTER) {
) : BaseDialogModel<DialogIntExpArriveResetBinding>(
if (DeviceUtil.isPhone()) DIALOG_TYPE_BOTTOM else DIALOG_TYPE_CENTER
) {
// 重置状态列表
val resetStatusList = MutableLiveData<List<KeyValue>>()

View File

@@ -34,6 +34,11 @@ class GjcQueryDetailsViewModel : BaseViewModel() {
// 库位列表 (storageUseList)
val storageUseList = MutableLiveData<List<Map<String, Any>>>(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寸手机版取值帮助方法(布局绑定用) ====================
// 表达式里必须把 mapmaWbData作为参数传入DataBinding 才能追踪依赖并在数据到达后刷新
/**
* 从详情 Map 取字符串展示值;数字自动去掉无意义的 .0;空值兜底 "--"
*/
fun str(map: Map<String, Any>?, 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<String, Any>?, key: String, fallbackKey: String): String {
val first = str(map, key)
return if (first != "--") first else str(map, fallbackKey)
}
/**
* 取重量类数值(保留小数形式),空值兜底 "--"
*/
fun dec(map: Map<String, Any>?, 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<Map<String, Any>> ?: 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<Map<String, Any>> ?: emptyList()

View File

@@ -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<List<KeyValue>>(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<GjcMaWb> = 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<Boolean> = MediatorLiveData<Boolean>().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()
}
/**
* 处理扫码结果
*/

View File

@@ -65,7 +65,11 @@ class IntExpArriveViewModel : BasePageViewModel() {
)
/** 两个 Tab 的角标计数(当前已加载数据的客户端统计,非全量,见接口问题清单) */
val arriveTabCounts = MutableLiveData(listOf("", ""))
val arriveTabCounts = MutableLiveData(listOf("0", "0"))
/** 手机版空态(当前 Tab 过滤后无数据时显示,对应设计稿 empty-pending */
val emptyVisiblePhone = MutableLiveData(false)
val emptyTextPhone = MutableLiveData("暂无待运抵的运单")
/** 手机版全选状态(仅统计待运抵 Tab 内的项,与 Pad 端 [isAllChecked] 统计口径不同) */
val isAllCheckedPhone = MutableLiveData(false)
@@ -116,6 +120,8 @@ class IntExpArriveViewModel : BasePageViewModel() {
val isPendingTab = currentTab.value == "pending"
val filtered = allLoadedList.filter { it.isPending == isPendingTab }
pageModel.rv?.commonAdapter()?.refresh(filtered)
emptyVisiblePhone.value = filtered.isEmpty()
emptyTextPhone.value = if (isPendingTab) "暂无待运抵的运单" else "暂无已运抵的运单"
updateCheckAllStatusPhone()
}

View File

@@ -0,0 +1,237 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<import type="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType" />
<variable
name="viewModel"
type="com.lukouguoji.gjc.viewModel.GjcQueryViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_f2"
android:orientation="vertical">
<!-- 标题栏(始终在最上层,不被遮挡) -->
<include layout="@layout/title_tool_bar" />
<!-- 内容区域FrameLayout 包裹,筛选面板和遮罩只在此区域内) -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<!-- 原有内容 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 搜索区域 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<!-- 航班日期起 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
hint='@{"请选择开始日期"}'
icon="@{@drawable/img_date}"
type="@{SearchLayoutType.DATE}"
value="@={viewModel.flightDateStart}" />
<!-- 航班日期止 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
hint='@{"请选择结束日期"}'
icon="@{@drawable/img_date}"
type="@{SearchLayoutType.DATE}"
value="@={viewModel.flightDateEnd}" />
<!-- 代理人 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
hint='@{"请选择代理"}'
list="@{viewModel.agentList}"
type="@{SearchLayoutType.SPINNER}"
value="@={viewModel.agentId}" />
<!-- 出库状态 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
hint='@{"请选择出库状态"}'
list="@{viewModel.outStatusList}"
type="@{SearchLayoutType.SPINNER}"
value="@={viewModel.outStatus}" />
<!-- 运单号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
hint='@{"请输入运单号"}'
icon="@{@drawable/img_scan}"
setOnIconClickListener="@{()-> viewModel.waybillScanClick()}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.waybillNo}"
autoQueryEnabled="@{true}"
autoQueryUrl="@{`/IntExpSearch/queryWbNoList`}"
autoQueryParamKey="@{`wbNo`}"
autoQueryMinLength="@{4}"
autoQueryMaxLength="@{8}"
autoQueryTitle="@{`选择运单号`}" />
<!-- 搜索和筛选按钮 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical|start"
android:orientation="horizontal"
android:paddingHorizontal="24dp">
<!-- 搜索按钮 -->
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:onClick="@{()-> viewModel.searchClick()}"
android:padding="2dp"
android:src="@drawable/img_search" />
<!-- 筛选按钮(含红点) -->
<FrameLayout
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginLeft="16dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="@{()-> viewModel.filterClick()}"
android:padding="5dp"
android:src="@drawable/img_filter" />
<View
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_gravity="top|end"
android:background="@drawable/bg_red_dot"
android:visibility="@{viewModel.hasFilter ? View.VISIBLE : View.GONE}" />
</FrameLayout>
</LinearLayout>
</LinearLayout>
<!-- 列表区域 -->
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/srl"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_gjc_query" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<!-- 底部统计信息 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/white"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<!-- 统计信息 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{`合计:` + viewModel.totalCount + `票`}'
android:textColor="@color/bottom_tool_tips_text_color"
android:textSize="16sp"
android:textStyle="bold"
tools:text="合计3票" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text='@{`总件数:` + viewModel.totalPc}'
android:textColor="@color/bottom_tool_tips_text_color"
android:textSize="16sp"
android:textStyle="bold"
tools:text="总件数100" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text='@{`总重量:` + viewModel.totalWeight}'
android:textColor="@color/bottom_tool_tips_text_color"
android:textSize="16sp"
android:textStyle="bold"
tools:text="总重量100" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- 遮罩层(只覆盖内容区域) -->
<View
android:id="@+id/filter_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80000000"
android:clickable="true"
android:focusable="true"
android:onClick="@{()-> viewModel.closeFilter()}"
android:visibility="gone" />
<!-- 筛选面板(从右侧滑入,只在内容区域内) -->
<include
android:id="@+id/filter_panel"
layout="@layout/layout_gjc_query_filter"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:visibility="gone"
app:viewModel="@{viewModel}" />
</FrameLayout>
</LinearLayout>
</layout>

View File

@@ -0,0 +1,125 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<variable
name="viewModel"
type="com.lukouguoji.gjc.viewModel.GjcQueryDetailsViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_f2"
android:orientation="vertical">
<!-- 标题栏 -->
<include layout="@layout/title_tool_bar" />
<!-- Tab栏 (自定义,文字Tab + 底线) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginHorizontal="15dp"
android:layout_marginTop="15dp"
android:background="@drawable/bg_white_radius_top_8"
android:orientation="horizontal">
<!-- Tab1: 运单信息 -->
<LinearLayout
android:layout_width="100dp"
android:layout_height="match_parent"
android:gravity="center"
android:onClick="@{()->viewModel.onTabClick(0)}"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:text="运单信息"
android:textStyle="bold"
android:textColor="@{viewModel.currentTab == 0 ? @color/colorPrimary : @color/text_gray}"
android:textSize="16sp" />
<!-- 选中底线 -->
<View
android:layout_width="60dp"
android:layout_height="3dp"
android:background="@{viewModel.currentTab == 0 ? @color/colorPrimary : @color/transparent}"
android:visibility="@{viewModel.currentTab == 0 ? View.VISIBLE : View.INVISIBLE}" />
</LinearLayout>
<!-- Tab2: 仓库信息 -->
<LinearLayout
android:layout_width="100dp"
android:layout_height="match_parent"
android:gravity="center"
android:onClick="@{()->viewModel.onTabClick(1)}"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:textStyle="bold"
android:text="仓库信息"
android:textColor="@{viewModel.currentTab == 1 ? @color/colorPrimary : @color/text_gray}"
android:textSize="16sp" />
<View
android:layout_width="60dp"
android:layout_height="3dp"
android:background="@{viewModel.currentTab == 1 ? @color/colorPrimary : @color/transparent}"
android:visibility="@{viewModel.currentTab == 1 ? View.VISIBLE : View.INVISIBLE}" />
</LinearLayout>
<!-- Tab3: 库位信息 -->
<LinearLayout
android:layout_width="100dp"
android:layout_height="match_parent"
android:gravity="center"
android:onClick="@{()->viewModel.onTabClick(2)}"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:textStyle="bold"
android:text="库位信息"
android:textColor="@{viewModel.currentTab == 2 ? @color/colorPrimary : @color/text_gray}"
android:textSize="16sp" />
<View
android:layout_width="60dp"
android:layout_height="3dp"
android:background="@{viewModel.currentTab == 2 ? @color/colorPrimary : @color/transparent}"
android:visibility="@{viewModel.currentTab == 2 ? View.VISIBLE : View.INVISIBLE}" />
</LinearLayout>
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="23dp"
android:background="@color/color_f2" />
<!-- ViewPager2 -->
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/vp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</layout>

View File

@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType"/>
<variable
name="model"
type="com.lukouguoji.gjc.dialog.IntExpArriveResetDialogModel" />
</data>
<LinearLayout
android:layout_width="480dp"
android:layout_height="wrap_content"
android:background="@drawable/bg_dialog_f2_radius_10"
android:gravity="center_horizontal"
android:orientation="vertical">
<!-- 标题栏 -->
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/bg_primary_radius_top_10"
android:gravity="center"
android:text="状态重置"
android:textColor="@color/white"
android:textSize="18sp"
android:textStyle="bold" />
<!-- 表单内容 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="30dp"
android:layout_marginTop="30dp"
android:orientation="vertical">
<!-- 重置状态 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="重置状态:"
android:textColor="@color/text_normal"
android:textSize="16sp" />
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
type="@{SearchLayoutType.SPINNER}"
hint='@{"请选择重置状态"}'
list="@{model.resetStatusList}"
value="@={model.selectedResetStatus}" />
</LinearLayout>
</LinearLayout>
<!-- 底部按钮 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:layout_marginBottom="20dp">
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()->model.dismiss()}"
android:text="取消" />
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()->model.onSaveClick()}"
android:text="确定" />
</LinearLayout>
</LinearLayout>
</layout>

View File

@@ -0,0 +1,137 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingHorizontal="15dp"
android:paddingBottom="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical">
<!-- tab 与表头分割线 -->
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/line" />
<!-- 表头 (白色背景) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@color/white"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="10dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center"
android:text="序号"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="center"
android:text="库位号"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="入库人"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="center"
android:text="入库时间"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="出库人"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="center"
android:text="出库时间"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 表头与内容分割线 -->
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/line" />
<!-- 数据列表 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_storage_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:nestedScrollingEnabled="true"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<!-- 暂无数据提示 (数据为空时显示) -->
<LinearLayout
android:id="@+id/ll_empty"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暂无数据"
android:textColor="@color/text_gray"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</layout>

View File

@@ -0,0 +1,157 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingHorizontal="15dp"
android:paddingBottom="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical">
<!-- tab 与表头分割线 -->
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/line" />
<!-- 表头 (白色背景) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@color/white"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="10dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center"
android:text="序号"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.2"
android:gravity="center"
android:text="集装器"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="件数"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="重量(KG)"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="航班日期"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="航班号"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="航程"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="分批"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 表头与内容分割线 -->
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/line" />
<!-- 数据列表 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_warehouse_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:nestedScrollingEnabled="true"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<!-- 暂无数据提示 (数据为空时显示) -->
<LinearLayout
android:id="@+id/ll_empty"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暂无数据"
android:textColor="@color/text_gray"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</layout>

View File

@@ -0,0 +1,319 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="com.lukouguoji.module_base.ui.weight.data.layout.DataLayoutType" />
<import type="android.view.View" />
<variable
name="viewModel"
type="com.lukouguoji.gjc.viewModel.GjcQueryDetailsViewModel" />
</data>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_f2"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="15dp"
android:paddingBottom="15dp">
<!-- 运单信息卡片 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical"
android:padding="15dp">
<!-- 第1行: 运单号、代理人、特码 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"运单号"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("wbNo")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"代理人"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("agentCode")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"特码"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("spCode")}' />
</LinearLayout>
<!-- 第2行: 运单件数、运单重量、体积 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"运单件数"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.maWbData.get("pc") != null ? String.valueOf((int)Math.round(((Double)viewModel.maWbData.get("pc")))) : ``}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"运单重量"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.maWbData.get("weight") != null ? String.valueOf(viewModel.maWbData.get("weight")) : ``}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"体积"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.maWbData.get("volume") != null ? String.valueOf(viewModel.maWbData.get("volume")) : ``}' />
</LinearLayout>
<!-- 第3行: 包装类型、运单类型、业务类型 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"包装类型"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("packageType")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"运单类型"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("awbName")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"业务类型"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("businessName")}' />
</LinearLayout>
<!-- 第4行: 品名(英) - 占整行 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="match_parent"
android:layout_height="wrap_content"
enable="@{false}"
title='@{"品名(英)"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("goods")}' />
</LinearLayout>
<!-- 第5行: 品名(中) - 占整行 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="match_parent"
android:layout_height="wrap_content"
enable="@{false}"
title='@{"品名(中)"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("goodsCn")}' />
</LinearLayout>
<!-- 第6行: 海关指令、预配舱单、运抵报告 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"海关指令"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("customsCommand")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"预配舱单"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("mftStatus")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"运抵报告"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("arrivalStatus")}' />
</LinearLayout>
<!-- 第7行: 装载舱单、理货报告、入库时间 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"装载舱单"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("loadStatus")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"理货报告"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("tallyStatus")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"入库时间"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("opDate")}' />
</LinearLayout>
<!-- 第8行: 省直辖市、地级市、行政区 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"省直辖市"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("proName")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"地级市"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("cityName")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"行政区"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("areaName")}' />
</LinearLayout>
<!-- 第9行: 备注 - 多行输入 -->
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
enable="@{false}"
inputHeight="@{80}"
title='@{"备注"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("remark")}' />
</LinearLayout>
</LinearLayout>
</ScrollView>
</layout>

View File

@@ -0,0 +1,318 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/apk/res/android">
<data>
<variable
name="bean"
type="com.lukouguoji.module_base.bean.GjcMaWb" />
</data>
<com.mcxtzhang.swipemenulib.SwipeMenuLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 主内容区 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="5dp"
android:background="@drawable/bg_item"
android:orientation="horizontal"
android:paddingVertical="20dp"
android:paddingHorizontal="10dp">
<!-- 左侧图标 -->
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:src="@drawable/img_plane" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="10dp"
android:orientation="vertical">
<!-- 第一行数据:运单号、件数、重量、代理人、入库时间 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 运单号 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{4}"
android:text="运单号:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.wbNo}"
android:textColor="@color/colorPrimary"
android:textSize="15sp"
tools:text="78109081212" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 件数 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{4}"
android:text="件数:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{String.valueOf(bean.pc)}'
android:textSize="15sp"
tools:text="10" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 重量 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{3}"
android:text="重量:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{String.valueOf(bean.weight)}'
android:textSize="15sp"
tools:text="200" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 代理人 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.2"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="代理人:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.agentName ?? bean.agentCode}'
android:textSize="15sp"
tools:text="SF" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 入库时间 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.2"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="入库时间:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.opDate ?? ""}'
android:textSize="15sp"
tools:text="2024-05-13 17:10:22" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 第二行数据:航班、目的港、特码、运单类型、离港时间 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<!-- 航班 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{4}"
android:text="航班:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.flight}"
android:textSize="15sp"
tools:text="20240513/MU2026" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 目的港 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{4}"
android:text="目的港:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.dest}"
android:textSize="15sp"
tools:text="PEK" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 特码 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{3}"
android:text="特码:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.spCode}"
android:textSize="15sp"
tools:text="NOR" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 运单类型 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.2"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="运单类型:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.awbName ?? bean.awbType}'
android:textSize="15sp"
tools:text="国际出港(直航)" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 离港时间 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.2"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="离港时间:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.fclose ?? ""}'
android:textSize="15sp"
tools:text="2024-05-13 17:10:22" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</LinearLayout>
<!-- 右侧箭头 -->
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:src="@drawable/img_pda_right"
android:layout_marginLeft="10dp" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 侧滑菜单区 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:id="@+id/btnEdit"
style="@style/tv_item_action"
android:background="@color/colorPrimary"
android:text="修改" />
</androidx.appcompat.widget.LinearLayoutCompat>
</com.mcxtzhang.swipemenulib.SwipeMenuLayout>
</layout>

View File

@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="bean"
type="com.lukouguoji.module_base.bean.GjcStorageUse" />
<variable
name="position"
type="Integer" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="40dp"
android:orientation="horizontal"
android:paddingHorizontal="10dp"
android:paddingVertical="8dp">
<!-- 序号 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center"
android:text="@{String.valueOf(position + 1)}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 库位号 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="center"
android:text="@{bean.location ?? `--`}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 入库人 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@{bean.inOpId ?? `--`}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 入库时间 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="center"
android:text="@{bean.inDate != null &amp;&amp; String.valueOf(bean.inDate).length() >= 16 ? String.valueOf(bean.inDate).substring(0, 16) : (bean.inDate != null &amp;&amp; String.valueOf(bean.inDate).length() > 0 ? String.valueOf(bean.inDate) : `--`)}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 出库人 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@{bean.outOpId ?? `--`}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 出库时间 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="center"
android:text="@{bean.outDate != null &amp;&amp; String.valueOf(bean.outDate).length() >= 16 ? String.valueOf(bean.outDate).substring(0, 16) : (bean.outDate != null &amp;&amp; String.valueOf(bean.outDate).length() > 0 ? String.valueOf(bean.outDate) : `--`)}"
android:textColor="@android:color/black"
android:textSize="14sp" />
</LinearLayout>
<!-- 内容分割线 -->
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/line" />
</LinearLayout>
</layout>

View File

@@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="bean"
type="com.lukouguoji.module_base.bean.GjcWarehouse" />
<variable
name="position"
type="Integer" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="40dp"
android:orientation="horizontal"
android:paddingHorizontal="10dp"
android:paddingVertical="8dp">
<!-- 序号 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center"
android:text="@{String.valueOf(position + 1)}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 集装器 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.2"
android:gravity="center"
android:text="@{bean.location}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 件数 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="@{String.valueOf(bean.pc)}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 重量 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="@{String.valueOf(bean.weight)}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 航班日期 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@{bean.fdate}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 航班号 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@{bean.fno}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 航程 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="@{bean.range}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 分批 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="@{`1`}"
android:textColor="@android:color/black"
android:textSize="14sp" />
</LinearLayout>
<!-- 内容分割线 -->
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/line" />
</LinearLayout>
</layout>

View File

@@ -1,148 +1,209 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
国际出港查询 —— 手机版布局5.5 寸手持端,最小宽度 < 600dp 时生效)
平板版为同名文件 layout-sw600dp/activity_gjc_query.xml两者是同一布局的资源变体
DataBinding 因此生成同一个 ActivityGjcQueryBinding 类。
变体之间必须满足:
· DataBinding 变量完全一致viewModel
· 保留 Activity 中引用的控件 idsrl / rv
· 平板独有的 filter_overlay / filter_panel侧滑筛选手机版不提供
Binding 基类中自动变 @NullableGjcQueryActivity 已判空处理
交互差异(均复用既有 GjcQueryViewModel 字段与接口):
· 平板 5 个横排搜索条 → 手机顶部搜索框(运单号)+ 底部筛选弹层
(航班日期起/止、代理从搜索行移入弹层;设计稿无「出库状态」项,未提供)
· 三格统计(总票数/已入库/已离港后两格为手机专属统计请求initPhoneExtras 开启)
· 筛选弹层显隐直接绑既有 viewModel.filterVisible无需平板的滑入动画代码
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<import type="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType" />
<import type="com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayoutType" />
<variable
name="viewModel"
type="com.lukouguoji.gjc.viewModel.GjcQueryViewModel" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/phone_page_bg">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_f2"
android:orientation="vertical">
<!-- 标题栏(始终在最上层,不被遮挡) -->
<include layout="@layout/title_tool_bar" />
<!-- 内容区域FrameLayout 包裹,筛选面板和遮罩只在此区域内) -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<!-- 原有内容 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 搜索区域 -->
<!-- ==================== 搜索行 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:background="@color/white"
android:orientation="vertical"
android:paddingHorizontal="16dp"
android:paddingTop="16dp"
android:paddingBottom="12dp">
<com.lukouguoji.module_base.ui.weight.phone.PhoneSearchBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"搜索运单号"}'
setOnFilterClickListener="@{(v)-> viewModel.filterClick()}"
setOnScanClickListener="@{(v)-> viewModel.waybillScanClick()}"
setRefreshCallBack="@{viewModel::searchClick}"
value="@={viewModel.waybillNo}" />
</LinearLayout>
<!-- ==================== 三格统计:总票数 / 已入库 / 已离港 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<!-- 航班日期起 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
hint='@{"请选择开始日期"}'
icon="@{@drawable/img_date}"
type="@{SearchLayoutType.DATE}"
value="@={viewModel.flightDateStart}" />
<!-- 航班日期止 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
hint='@{"请选择结束日期"}'
icon="@{@drawable/img_date}"
type="@{SearchLayoutType.DATE}"
value="@={viewModel.flightDateEnd}" />
<!-- 代理人 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
hint='@{"请选择代理"}'
list="@{viewModel.agentList}"
type="@{SearchLayoutType.SPINNER}"
value="@={viewModel.agentId}" />
<!-- 出库状态 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
hint='@{"请选择出库状态"}'
list="@{viewModel.outStatusList}"
type="@{SearchLayoutType.SPINNER}"
value="@={viewModel.outStatus}" />
<!-- 运单号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
hint='@{"请输入运单号"}'
icon="@{@drawable/img_scan}"
setOnIconClickListener="@{()-> viewModel.waybillScanClick()}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.waybillNo}"
autoQueryEnabled="@{true}"
autoQueryUrl="@{`/IntExpSearch/queryWbNoList`}"
autoQueryParamKey="@{`wbNo`}"
autoQueryMinLength="@{4}"
autoQueryMaxLength="@{8}"
autoQueryTitle="@{`选择运单号`}" />
<!-- 搜索和筛选按钮 -->
<!-- 总票数(蓝) -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical|start"
android:orientation="horizontal"
android:paddingHorizontal="24dp">
<!-- 搜索按钮 -->
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:onClick="@{()-> viewModel.searchClick()}"
android:padding="2dp"
android:src="@drawable/img_search" />
<!-- 筛选按钮(含红点) -->
<FrameLayout
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginLeft="16dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="@{()-> viewModel.filterClick()}"
android:padding="5dp"
android:src="@drawable/img_filter" />
android:background="@drawable/bg_phone_card"
android:orientation="horizontal">
<View
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_gravity="top|end"
android:background="@drawable/bg_red_dot"
android:visibility="@{viewModel.hasFilter ? View.VISIBLE : View.GONE}" />
android:layout_width="4dp"
android:layout_height="match_parent"
android:layout_marginVertical="12dp"
android:background="@color/phone_primary" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="12dp"
android:paddingVertical="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="总票数"
android:textColor="@color/phone_text_body"
android:textSize="12sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="@{viewModel.totalCount}"
android:textColor="@color/phone_primary"
android:textSize="20sp"
android:textStyle="bold"
tools:text="4" />
</LinearLayout>
</LinearLayout>
<!-- 列表区域 -->
<!-- 已入库(橙) -->
<LinearLayout
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">
<View
android:layout_width="4dp"
android:layout_height="match_parent"
android:layout_marginVertical="12dp"
android:background="@color/phone_tag_orange_text" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="12dp"
android:paddingVertical="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="已入库"
android:textColor="@color/phone_text_body"
android:textSize="12sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="@{viewModel.storedCount}"
android:textColor="@color/phone_tag_orange_text"
android:textSize="20sp"
android:textStyle="bold"
tools:text="2" />
</LinearLayout>
</LinearLayout>
<!-- 已离港(绿) -->
<LinearLayout
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">
<View
android:layout_width="4dp"
android:layout_height="match_parent"
android:layout_marginVertical="12dp"
android:background="@color/phone_tag_green_text" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="12dp"
android:paddingVertical="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="已离港"
android:textColor="@color/phone_text_body"
android:textSize="12sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="@{viewModel.departedCount}"
android:textColor="@color/phone_tag_green_text"
android:textSize="20sp"
android:textStyle="bold"
tools:text="2" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- ==================== 列表 ==================== -->
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/srl"
android:layout_width="match_parent"
@@ -153,85 +214,120 @@
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:overScrollMode="never"
android:paddingTop="4dp"
android:paddingBottom="24dp"
itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="3"
tools:listitem="@layout/item_gjc_query" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<!-- 底部统计信息 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/white"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<!-- 统计信息 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{`合计:` + viewModel.totalCount + `票`}'
android:textColor="@color/bottom_tool_tips_text_color"
android:textSize="16sp"
android:textStyle="bold"
tools:text="合计3票" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text='@{`总件数:` + viewModel.totalPc}'
android:textColor="@color/bottom_tool_tips_text_color"
android:textSize="16sp"
android:textStyle="bold"
tools:text="总件数100" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text='@{`总重量:` + viewModel.totalWeight}'
android:textColor="@color/bottom_tool_tips_text_color"
android:textSize="16sp"
android:textStyle="bold"
tools:text="总重量100" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- 遮罩层(只覆盖内容区域) -->
<View
android:id="@+id/filter_overlay"
<!-- ==================== 筛选弹层(绑既有 filterVisible ==================== -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneFilterPanel
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#80000000"
android:clickable="true"
android:focusable="true"
android:onClick="@{()-> viewModel.closeFilter()}"
android:visibility="gone" />
android:elevation="8dp"
panelVisible="@{viewModel.filterVisible}"
setOnConfirmClick="@{(v)-> viewModel.confirmFilter()}"
setOnDismissClick="@{(v)-> viewModel.closeFilter()}"
setOnResetClick="@{(v)-> viewModel.resetFilter()}"
title='@{"筛选条件"}'>
<!-- 筛选面板(从右侧滑入,只在内容区域内 -->
<include
android:id="@+id/filter_panel"
layout="@layout/layout_gjc_query_filter"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:visibility="gone"
app:viewModel="@{viewModel}" />
<!-- 航班日期起(平板搜索行字段,手机移入弹层 -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"请选择航班日期"}'
title='@{"航班日期起"}'
type="@{PhoneDataLayoutType.DATE}"
value="@={viewModel.flightDateStart}" />
<!-- 航班日期止 -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"请选择航班日期"}'
title='@{"航班日期止"}'
type="@{PhoneDataLayoutType.DATE}"
value="@={viewModel.flightDateEnd}" />
<!-- 航班号 -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:id="@+id/phone_filter_flight_no"
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"请输入航班号"}'
title='@{"航班号"}'
type="@{PhoneDataLayoutType.INPUT}"
value="@={viewModel.flightNo}" />
<!-- 代理(平板搜索行字段,手机移入弹层) -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"请选择代理"}'
list="@{viewModel.agentList}"
title='@{"代理"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.agentId}" />
<!-- 特码(设计稿为下拉,字典由 initPhoneExtras 加载;平板为文本输入) -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"请选择特码"}'
list="@{viewModel.specialCodeList}"
title='@{"特码"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.spCode}" />
<!-- 目的港 -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:id="@+id/phone_filter_dest"
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"请输入目的港"}'
title='@{"目的港"}'
type="@{PhoneDataLayoutType.INPUT}"
value="@={viewModel.dest}" />
<!-- 运单类型 -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"请选择运单类型"}'
list="@{viewModel.awbTypeList}"
title='@{"运单类型"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.awbType}" />
<!-- 业务类型 -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"请选择业务类型"}'
list="@{viewModel.businessTypeList}"
title='@{"业务类型"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.businessType}" />
<!-- 品名(中) -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"请输入中文品名"}'
title='@{"品名(中)"}'
type="@{PhoneDataLayoutType.INPUT}"
value="@={viewModel.goodsCn}" />
</com.lukouguoji.module_base.ui.weight.phone.PhoneFilterPanel>
</FrameLayout>
</LinearLayout>
</layout>

View File

@@ -1,6 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!--
国际出港查询详情 —— 手机版布局5.5 寸手持端,最小宽度 < 600dp 时生效)
平板版为同名文件 layout-sw600dp/activity_gjc_query_details.xml两者是同一布局的资源变体
DataBinding 因此生成同一个 ActivityGjcQueryDetailsBinding 类。
变体之间必须满足:
· DataBinding 变量完全一致viewModel
· 保留 Activity 中引用的控件 idvp
→ Tab 切换 / ViewPager2 / 3 个 Fragment 全部复用Fragment 布局各自有手机变体
与平板差异Tab 栏通栏白底、三等分、选中蓝字 + 底部指示条(设计稿样式)
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
@@ -14,27 +26,25 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_f2"
android:background="@color/phone_page_bg"
android:orientation="vertical">
<!-- 标题栏 -->
<include layout="@layout/title_tool_bar" />
<!-- Tab栏 (自定义,文字Tab + 底线) -->
<!-- ==================== Tab 栏:运单信息 / 仓库信息 / 库位信息 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginHorizontal="15dp"
android:layout_marginTop="15dp"
android:background="@drawable/bg_white_radius_top_8"
android:layout_height="42dp"
android:background="@color/white"
android:orientation="horizontal">
<!-- Tab1: 运单信息 -->
<LinearLayout
android:layout_width="100dp"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:onClick="@{()->viewModel.onTabClick(0)}"
android:onClick="@{()-> viewModel.onTabClick(0)}"
android:orientation="vertical">
<TextView
@@ -43,24 +53,25 @@
android:layout_weight="1"
android:gravity="center"
android:text="运单信息"
android:textStyle="bold"
android:textColor="@{viewModel.currentTab == 0 ? @color/colorPrimary : @color/text_gray}"
android:textSize="16sp" />
android:textColor="@{viewModel.currentTab == 0 ? @color/phone_primary : @color/phone_text_body}"
android:textSize="14sp"
android:textStyle="bold" />
<!-- 选中底线 -->
<View
android:layout_width="60dp"
android:layout_width="28dp"
android:layout_height="3dp"
android:background="@{viewModel.currentTab == 0 ? @color/colorPrimary : @color/transparent}"
android:background="@color/phone_primary"
android:visibility="@{viewModel.currentTab == 0 ? View.VISIBLE : View.INVISIBLE}" />
</LinearLayout>
<!-- Tab2: 仓库信息 -->
<LinearLayout
android:layout_width="100dp"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:onClick="@{()->viewModel.onTabClick(1)}"
android:onClick="@{()-> viewModel.onTabClick(1)}"
android:orientation="vertical">
<TextView
@@ -68,24 +79,26 @@
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:textStyle="bold"
android:text="仓库信息"
android:textColor="@{viewModel.currentTab == 1 ? @color/colorPrimary : @color/text_gray}"
android:textSize="16sp" />
android:textColor="@{viewModel.currentTab == 1 ? @color/phone_primary : @color/phone_text_body}"
android:textSize="14sp"
android:textStyle="bold" />
<View
android:layout_width="60dp"
android:layout_width="28dp"
android:layout_height="3dp"
android:background="@{viewModel.currentTab == 1 ? @color/colorPrimary : @color/transparent}"
android:background="@color/phone_primary"
android:visibility="@{viewModel.currentTab == 1 ? View.VISIBLE : View.INVISIBLE}" />
</LinearLayout>
<!-- Tab3: 库位信息 -->
<LinearLayout
android:layout_width="100dp"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:onClick="@{()->viewModel.onTabClick(2)}"
android:onClick="@{()-> viewModel.onTabClick(2)}"
android:orientation="vertical">
<TextView
@@ -93,26 +106,25 @@
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:textStyle="bold"
android:text="库位信息"
android:textColor="@{viewModel.currentTab == 2 ? @color/colorPrimary : @color/text_gray}"
android:textSize="16sp" />
android:textColor="@{viewModel.currentTab == 2 ? @color/phone_primary : @color/phone_text_body}"
android:textSize="14sp"
android:textStyle="bold" />
<View
android:layout_width="60dp"
android:layout_width="28dp"
android:layout_height="3dp"
android:background="@{viewModel.currentTab == 2 ? @color/colorPrimary : @color/transparent}"
android:background="@color/phone_primary"
android:visibility="@{viewModel.currentTab == 2 ? View.VISIBLE : View.INVISIBLE}" />
</LinearLayout>
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="23dp"
android:background="@color/color_f2" />
android:layout_height="1px"
android:background="@color/phone_divider" />
<!-- ViewPager2 -->
<androidx.viewpager2.widget.ViewPager2

View File

@@ -89,6 +89,10 @@
android:layout_height="0dp"
android:layout_weight="1">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
@@ -103,6 +107,34 @@
tools:itemCount="2"
tools:listitem="@layout/item_int_exp_arrive" />
<!-- 空态(对应设计稿 empty-pending图标 + 文案,按当前 Tab 切换) -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical"
android:visibility="@{viewModel.emptyVisiblePhone ? View.VISIBLE : View.GONE}">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_phone_clipboard"
android:tint="@color/phone_text_hint" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@{viewModel.emptyTextPhone}"
android:textColor="@color/phone_text_hint"
android:textSize="14sp"
tools:text="暂无待运抵的运单" />
</LinearLayout>
</FrameLayout>
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<!-- ==================== 底部操作条(仅待运抵 Tab 显示) ==================== -->

View File

@@ -11,6 +11,8 @@
<data>
<import type="android.view.View" />
<variable
name="viewModel"
type="com.lukouguoji.gjc.viewModel.IntExpArriveReceiptViewModel" />
@@ -24,11 +26,15 @@
<include layout="@layout/title_tool_bar" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:clipToPadding="false"
android:overScrollMode="never"
android:paddingTop="12dp"
@@ -39,6 +45,33 @@
tools:itemCount="3"
tools:listitem="@layout/item_int_exp_arrive_receipt" />
<!-- 空态兜底(设计稿未覆盖:单分单入口常无回执内容,避免纯白屏) -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical"
android:visibility="@{viewModel.receiptList.empty ? View.VISIBLE : View.GONE}">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_phone_clipboard"
android:tint="@color/phone_text_hint" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="暂无回执内容"
android:textColor="@color/phone_text_hint"
android:textSize="14sp" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
</layout>

View File

@@ -82,7 +82,7 @@
android:layout_height="wrap_content"
actionText='@{"申报"}'
allChecked="@{viewModel.isAllChecked}"
countText='@{"已选 " + viewModel.selectedCount + " 项"}'
countText='@{"已选 " + viewModel.selectedCount + " / " + viewModel.displayList.size() + " 项"}'
setOnActionClick="@{(v)-> viewModel.declareClick()}"
setOnAllCheckClick="@{(v)-> activity.checkAllClick()}" />

View File

@@ -1,8 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
状态重置弹框手机版5.5 寸手持端)
对应设计稿 04_出港运抵/main.html 的 reset-sheet 底部弹层:
标题「重置状态」+ 右上关闭 + 「状态」下拉 + 全宽主色「确定」按钮。
平板变体layout-sw600dp/dialog_int_exp_arrive_reset.xml居中弹框
弹出位置由 IntExpArriveResetDialogModel 按设备形态选择 BOTTOM/CENTER。
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType"/>
<import type="com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayoutType" />
<variable
name="model"
@@ -11,77 +19,60 @@
</data>
<LinearLayout
android:layout_width="480dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_dialog_f2_radius_10"
android:gravity="center_horizontal"
android:orientation="vertical">
android:background="@drawable/bg_phone_panel_top"
android:orientation="vertical"
android:paddingHorizontal="20dp"
android:paddingTop="24dp"
android:paddingBottom="32dp">
<!-- 标题行:标题居中 + 右上关闭 -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp">
<!-- 标题栏 -->
<TextView
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/bg_primary_radius_top_10"
android:layout_height="wrap_content"
android:gravity="center"
android:text="状态重置"
android:textColor="@color/white"
android:text="重置状态"
android:textColor="@color/phone_text_strong"
android:textSize="18sp"
android:textStyle="bold" />
<!-- 表单内容 -->
<LinearLayout
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="end|center_vertical"
android:onClick="@{()-> model.dismiss()}"
android:src="@drawable/ic_phone_close" />
</FrameLayout>
<!-- 状态下拉 -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="30dp"
android:layout_marginTop="30dp"
android:orientation="vertical">
<!-- 重置状态 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="重置状态:"
android:textColor="@color/text_normal"
android:textSize="16sp" />
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
type="@{SearchLayoutType.SPINNER}"
hint='@{"请选择重置状态"}'
hint='@{"请选择状态"}'
list="@{model.resetStatusList}"
title='@{"状态"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={model.selectedResetStatus}" />
</LinearLayout>
</LinearLayout>
<!-- 底部按钮 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:layout_marginBottom="20dp">
<!-- 确定按钮 -->
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()->model.dismiss()}"
android:text="取消" />
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()->model.onSaveClick()}"
android:text="确定" />
</LinearLayout>
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="32dp"
android:background="@drawable/bg_phone_btn_primary"
android:gravity="center"
android:onClick="@{()-> model.onSaveClick()}"
android:text="确定"
android:textColor="@color/white"
android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout>
</layout>

View File

@@ -1,4 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
国际出港查询详情-库位信息 —— 手机版布局5.5 寸手持端,最小宽度 < 600dp 时生效)
平板版为同名文件 layout-sw600dp/fragment_gjc_query_storage.xml表格样式
手机版改为库位卡片列表item_gjc_query_storage.xml 手机变体)。
变体之间必须满足:
· <data> 一致(无 variable仅 import
· 保留 Fragment 引用的控件 idrv_storage_list / ll_empty
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
@@ -7,117 +17,25 @@
<import type="android.view.View" />
</data>
<LinearLayout
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingHorizontal="15dp"
android:paddingBottom="15dp">
android:background="@color/phone_page_bg">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical">
<!-- tab 与表头分割线 -->
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/line" />
<!-- 表头 (白色背景) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@color/white"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="10dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center"
android:text="序号"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="center"
android:text="库位号"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="入库人"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="center"
android:text="入库时间"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="出库人"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="center"
android:text="出库时间"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 表头与内容分割线 -->
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/line" />
<!-- 数据列表 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_storage_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:nestedScrollingEnabled="true"
android:layout_height="match_parent"
android:clipToPadding="false"
android:overScrollMode="never"
android:paddingBottom="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<!-- 暂无数据提示 (数据为空时显示) -->
<!-- 数据提示 -->
<LinearLayout
android:id="@+id/ll_empty"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
@@ -126,12 +44,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暂无数据"
android:textColor="@color/text_gray"
android:textSize="16sp" />
</LinearLayout>
android:textColor="@color/phone_text_hint"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
</layout>

View File

@@ -1,4 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
国际出港查询详情-仓库信息 —— 手机版布局5.5 寸手持端,最小宽度 < 600dp 时生效)
平板版为同名文件 layout-sw600dp/fragment_gjc_query_warehouse.xml表格样式
手机版改为批次卡片列表item_gjc_query_warehouse.xml 手机变体)。
变体之间必须满足:
· <data> 一致(无 variable仅 import
· 保留 Fragment 引用的控件 idrv_warehouse_list / ll_empty
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
@@ -7,137 +17,25 @@
<import type="android.view.View" />
</data>
<LinearLayout
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingHorizontal="15dp"
android:paddingBottom="15dp">
android:background="@color/phone_page_bg">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_white_radius_bottom_8"
android:orientation="vertical">
<!-- tab 与表头分割线 -->
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/line" />
<!-- 表头 (白色背景) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@color/white"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="10dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center"
android:text="序号"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.2"
android:gravity="center"
android:text="集装器"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="件数"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="重量(KG)"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="航班日期"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="航班号"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="航程"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="分批"
android:textColor="@color/black"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 表头与内容分割线 -->
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/line" />
<!-- 数据列表 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_warehouse_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:nestedScrollingEnabled="true"
android:layout_height="match_parent"
android:clipToPadding="false"
android:overScrollMode="never"
android:paddingBottom="16dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<!-- 暂无数据提示 (数据为空时显示) -->
<!-- 数据提示 -->
<LinearLayout
android:id="@+id/ll_empty"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="gone">
@@ -146,12 +44,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暂无数据"
android:textColor="@color/text_gray"
android:textSize="16sp" />
</LinearLayout>
android:textColor="@color/phone_text_hint"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
</layout>

View File

@@ -1,9 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
国际出港查询详情-运单信息 —— 手机版布局5.5 寸手持端,最小宽度 < 600dp 时生效)
平板版为同名文件 layout-sw600dp/fragment_gjc_query_waybill.xml两者是同一布局的资源变体
DataBinding 因此生成同一个 FragmentGjcQueryWaybillBinding 类。
变体之间必须满足:
· DataBinding 变量完全一致viewModel
· Fragment 代码未引用任何控件 id无共用 id 约束
数据全部来自既有 viewModel.maWbDataIntExpSearch/detail 的 maWb+maWbM 合并 Map
取值统一走 viewModel.str()/dec() 帮助方法(空值兜底 "-")。
按设计稿新增展示的字段(承运人/始发站/中转站/目的站/UN编号/锁定状态/计费重量),
其中锁定状态lockStatus与计费重量cashWeight在接口文档中无定义实机核对后如缺失记入问题清单。
入库件数/入库重量为 warehouseList 各批次求和viewModel.inPcTotal/inWeightTotal
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="com.lukouguoji.module_base.ui.weight.data.layout.DataLayoutType" />
<import type="android.view.View" />
<variable
name="viewModel"
type="com.lukouguoji.gjc.viewModel.GjcQueryDetailsViewModel" />
@@ -12,304 +27,422 @@
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_f2"
android:fillViewport="true">
android:background="@color/phone_page_bg"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="15dp"
android:paddingBottom="15dp">
android:padding="12dp">
<!-- 运单信息卡片 -->
<!-- ==================== 卡片1基本信息 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_bottom_8"
android:background="@drawable/bg_phone_card"
android:orientation="vertical"
android:padding="15dp">
android:paddingHorizontal="14dp"
android:paddingBottom="14dp">
<!-- 第1行: 运单号、代理人、特码 -->
<!-- 卡片头 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingVertical="12dp">
<View
android:layout_width="4dp"
android:layout_height="16dp"
android:background="@color/phone_primary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="基本信息"
android:textColor="@color/phone_text_title"
android:textSize="15sp"
android:textStyle="bold" />
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginBottom="12dp"
android:background="@color/phone_divider" />
<!-- 运单号 | 代理人 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"运单号"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("wbNo")}' />
value='@{viewModel.str(viewModel.maWbData, "wbNo")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"代理人"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("agentCode")}' />
value='@{viewModel.strOr(viewModel.maWbData, "agentName", "agentCode")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
</LinearLayout>
<!-- 特码 | 承运人 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"特码"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("spCode")}' />
value='@{viewModel.str(viewModel.maWbData, "spCode")}' />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"承运人"}'
value='@{viewModel.strOr(viewModel.maWbData, "by0", "by1")}' />
</LinearLayout>
<!-- 第2行: 运单件数、运单重量、体积 -->
<!-- 始发站 | 中转站 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"运单件数"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.maWbData.get("pc") != null ? String.valueOf((int)Math.round(((Double)viewModel.maWbData.get("pc")))) : ``}' />
title='@{"始发站"}'
value='@{viewModel.str(viewModel.maWbData, "dep")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"运单重量"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.maWbData.get("weight") != null ? String.valueOf(viewModel.maWbData.get("weight")) : ``}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"体积"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.maWbData.get("volume") != null ? String.valueOf(viewModel.maWbData.get("volume")) : ``}' />
title='@{"中转站"}'
value='@{viewModel.str(viewModel.maWbData, "dest1")}' />
</LinearLayout>
<!-- 第3行: 包装类型、运单类型、业务类型 -->
<!-- 目的站 | UN编号 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"目的站"}'
value='@{viewModel.str(viewModel.maWbData, "dest")}' />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"UN编号"}'
value='@{viewModel.str(viewModel.maWbData, "unNumber")}' />
</LinearLayout>
<!-- 锁定状态 | 包装类型 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"锁定状态"}'
value='@{viewModel.str(viewModel.maWbData, "lockStatus")}' />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"包装类型"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("packageType")}' />
value='@{viewModel.str(viewModel.maWbData, "packageType")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
</LinearLayout>
<!-- 业务类型 | 入库时间 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"运单类型"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("awbName")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"业务类型"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("businessName")}' />
value='@{viewModel.str(viewModel.maWbData, "businessName")}' />
</LinearLayout>
<!-- 第4行: 品名(英) - 占整行 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="match_parent"
android:layout_height="wrap_content"
enable="@{false}"
title='@{"品名(英)"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("goods")}' />
</LinearLayout>
<!-- 第5行: 品名(中) - 占整行 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="match_parent"
android:layout_height="wrap_content"
enable="@{false}"
title='@{"品名(中)"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("goodsCn")}' />
</LinearLayout>
<!-- 第6行: 海关指令、预配舱单、运抵报告 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"海关指令"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("customsCommand")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"预配舱单"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("mftStatus")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"运抵报告"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("arrivalStatus")}' />
</LinearLayout>
<!-- 第7行: 装载舱单、理货报告、入库时间 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"装载舱单"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("loadStatus")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"理货报告"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("tallyStatus")}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"入库时间"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("opDate")}' />
value='@{viewModel.str(viewModel.maWbData, "opDate")}' />
</LinearLayout>
<!-- 第8行: 省直辖市、地级市、行政区 -->
<!-- 运单类型(整行) -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
title='@{"运单类型"}'
value='@{viewModel.str(viewModel.maWbData, "awbName")}' />
<!-- 品名(中)(整行) -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
title='@{"品名(中)"}'
value='@{viewModel.str(viewModel.maWbData, "goodsCn")}' />
<!-- 品名(英)(整行) -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
title='@{"品名(英)"}'
value='@{viewModel.str(viewModel.maWbData, "goods")}' />
<!-- 备注(整行) -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
title='@{"备注"}'
value='@{viewModel.str(viewModel.maWbData, "remark")}' />
</LinearLayout>
<!-- ==================== 卡片2件重信息 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
android:layout_marginTop="12dp"
android:background="@drawable/bg_phone_card"
android:orientation="vertical"
android:paddingHorizontal="14dp"
android:paddingBottom="14dp">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"省直辖市"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("proName")}' />
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingVertical="12dp">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"地级市"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("cityName")}' />
<View
android:layout_width="4dp"
android:layout_height="16dp"
android:background="@color/phone_primary" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"行政区"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("areaName")}' />
android:layout_marginStart="8dp"
android:text="件重信息"
android:textColor="@color/phone_text_title"
android:textSize="15sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 第9行: 备注 - 多行输入 -->
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginBottom="12dp"
android:background="@color/phone_divider" />
<!-- 运单件数 | 运单重量 | 计费重量 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
enable="@{false}"
inputHeight="@{80}"
title='@{"备注"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("remark")}' />
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"运单件数"}'
value='@{viewModel.str(viewModel.maWbData, "pc")}' />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"运单重量"}'
value='@{viewModel.dec(viewModel.maWbData, "weight")}' />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"计费重量"}'
value='@{viewModel.dec(viewModel.maWbData, "cashWeight")}' />
</LinearLayout>
<!-- 入库件数 | 入库重量 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"入库件数"}'
value="@{viewModel.inPcTotal}" />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"入库重量"}'
value="@{viewModel.inWeightTotal}" />
<!-- 占位对齐第三列 -->
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
<!-- ==================== 卡片3回执信息 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:background="@drawable/bg_phone_card"
android:orientation="vertical"
android:paddingHorizontal="14dp"
android:paddingBottom="14dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingVertical="12dp">
<View
android:layout_width="4dp"
android:layout_height="16dp"
android:background="@color/phone_primary" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:text="回执信息"
android:textColor="@color/phone_text_title"
android:textSize="15sp"
android:textStyle="bold" />
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginBottom="12dp"
android:background="@color/phone_divider" />
<!-- 预配舱单 | 运抵报告 | 海关放行 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"预配舱单"}'
value='@{viewModel.str(viewModel.maWbData, "mftStatus")}' />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"运抵报告"}'
value='@{viewModel.str(viewModel.maWbData, "arrivalStatus")}' />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
tag="@{true}"
tagColor='@{"green"}'
title='@{"海关放行"}'
value='@{viewModel.str(viewModel.maWbData, "customsCommand")}' />
</LinearLayout>
<!-- 装载舱单 | 理货报告 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"装载舱单"}'
value='@{viewModel.str(viewModel.maWbData, "loadStatus")}' />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"理货报告"}'
value='@{viewModel.str(viewModel.maWbData, "tallyStatus")}' />
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>

View File

@@ -1,318 +1,226 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
国际出港查询 —— 列表项手机版布局5.5 寸手持端,最小宽度 < 600dp 时生效)
平板版为同名文件 layout-sw600dp/item_gjc_query.xml两者是同一布局的资源变体
DataBinding 因此生成同一个 ItemGjcQueryBinding 类。
变体之间必须满足:
· DataBinding 变量完全一致bean
· 保留 GjcQueryViewHolder 引用的控件 idll整卡点击进详情
· 平板侧滑「修改」按钮btnEdit手机版不提供设计稿无编辑入口
ViewHolder 里 findViewById(btnEdit) 已判空,安全
状态标签按 bean 计算属性切换(前端推断,见 GjcMaWb.isQueryDeparted 注释):
· 已离港(绿)= fclose 非空
· 已入库(橙)= opDate 非空
· 未入库(灰)= 兜底
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/apk/res/android">
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable
name="bean"
type="com.lukouguoji.module_base.bean.GjcMaWb" />
</data>
<com.mcxtzhang.swipemenulib.SwipeMenuLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 主内容区 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="5dp"
android:background="@drawable/bg_item"
android:orientation="horizontal"
android:paddingVertical="20dp"
android:paddingHorizontal="10dp">
<!-- 左侧图标 -->
android:layout_marginHorizontal="16dp"
android:layout_marginTop="12dp"
android:background="@drawable/bg_phone_card"
android:orientation="vertical"
android:padding="14dp">
<!-- ==================== 头行:蓝点 + 运单号 + 状态标签 + 箭头 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<View
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/bg_phone_dot_blue" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{bean.wbNo}"
android:textColor="@color/phone_text_title"
android:textSize="16sp"
android:textStyle="bold"
tools:text="78133363396" />
<!-- 已离港(绿) -->
<TextView
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_marginStart="8dp"
android:background="@drawable/bg_phone_tag_green"
android:gravity="center"
android:paddingHorizontal="8dp"
android:text="已离港"
android:textColor="@color/phone_tag_green_text"
android:textSize="11sp"
android:visibility="@{bean.isQueryDeparted ? View.VISIBLE : View.GONE}" />
<!-- 已入库(橙) -->
<TextView
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_marginStart="8dp"
android:background="@drawable/bg_phone_tag_orange"
android:gravity="center"
android:paddingHorizontal="8dp"
android:text="已入库"
android:textColor="@color/phone_tag_orange_text"
android:textSize="11sp"
android:visibility="@{!bean.isQueryDeparted &amp;&amp; bean.isQueryStored ? View.VISIBLE : View.GONE}" />
<!-- 未入库(灰,兜底) -->
<TextView
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_marginStart="8dp"
android:background="@drawable/bg_phone_tag_gray"
android:gravity="center"
android:paddingHorizontal="8dp"
android:text="未入库"
android:textColor="@color/phone_tag_gray_text"
android:textSize="11sp"
android:visibility="@{!bean.isQueryDeparted &amp;&amp; !bean.isQueryStored ? View.VISIBLE : View.GONE}" />
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:src="@drawable/img_plane" />
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginStart="6dp"
android:src="@drawable/ic_phone_chevron_right" />
</LinearLayout>
<!-- ==================== 字段网格:件数/重量 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="10dp"
android:orientation="vertical">
android:gravity="center_vertical"
android:orientation="horizontal">
<!-- 第一行数据:运单号、件数、重量、代理人、入库时间 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 运单号 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:src="@drawable/ic_phone_package" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{4}"
android:text="运单号:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.wbNo}"
android:textColor="@color/colorPrimary"
android:textSize="15sp"
tools:text="78109081212" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 件数 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{4}"
android:text="件数:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{String.valueOf(bean.pc)}'
android:textSize="15sp"
tools:text="10" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 重量 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{3}"
android:text="重量:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{String.valueOf(bean.weight)}'
android:textSize="15sp"
tools:text="200" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 代理人 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.2"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="代理人:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.agentName ?? bean.agentCode}'
android:textSize="15sp"
tools:text="SF" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 入库时间 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.2"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="入库时间:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.opDate ?? ""}'
android:textSize="15sp"
tools:text="2024-05-13 17:10:22" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 第二行数据:航班、目的港、特码、运单类型、离港时间 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<!-- 航班 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{4}"
android:text="航班:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.flight}"
android:textSize="15sp"
tools:text="20240513/MU2026" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 目的港 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{4}"
android:text="目的港:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.dest}"
android:textSize="15sp"
tools:text="PEK" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 特码 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{3}"
android:text="特码:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.spCode}"
android:textSize="15sp"
tools:text="NOR" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 运单类型 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.2"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="运单类型:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.awbName ?? bean.awbType}'
android:textSize="15sp"
tools:text="国际出港(直航)" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 离港时间 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.2"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="离港时间:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.fclose ?? ""}'
android:textSize="15sp"
tools:text="2024-05-13 17:10:22" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
android:layout_marginStart="6dp"
android:text='@{"件数:" + (bean.pc != null ? String.valueOf(bean.pc) : "--")}'
android:textColor="@color/phone_text_body"
android:textSize="13sp"
tools:text="件数444" />
</LinearLayout>
<!-- 右侧箭头 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:src="@drawable/img_pda_right"
android:layout_marginLeft="10dp" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 侧滑菜单区 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="wrap_content"
android:layout_height="match_parent">
android:layout_width="14dp"
android:layout_height="14dp"
android:src="@drawable/ic_phone_weight" />
<TextView
android:id="@+id/btnEdit"
style="@style/tv_item_action"
android:background="@color/colorPrimary"
android:text="修改" />
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:text='@{"重量:" + (bean.weight != null ? String.valueOf(bean.weight) : "--")}'
android:textColor="@color/phone_text_body"
android:textSize="13sp"
tools:text="重量555" />
</LinearLayout>
</LinearLayout>
<!-- ==================== 字段网格:代理人/特码 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:src="@drawable/ic_phone_person" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:text='@{"代理人:" + bean.orDash(bean.agentName ?? bean.agentCode)}'
android:textColor="@color/phone_text_body"
android:textSize="13sp"
tools:text="代理人:中外运" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:src="@drawable/ic_phone_tag" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:text='@{"特码:" + bean.orDash(bean.spCode)}'
android:textColor="@color/phone_text_body"
android:textSize="13sp"
tools:text="特码DGR" />
</LinearLayout>
</LinearLayout>
</androidx.appcompat.widget.LinearLayoutCompat>
</com.mcxtzhang.swipemenulib.SwipeMenuLayout>
</layout>

View File

@@ -1,5 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<!--
国际出港查询详情-库位信息列表项 —— 手机版布局5.5 寸手持端)
平板版为同名文件 layout-sw600dp/item_gjc_query_storage.xml表格行样式
手机版为库位卡片(设计稿:库位号头行 + 入库人/入库时间/出库人/出库时间 两列网格)。
变体之间必须满足:
· DataBinding 变量完全一致bean / position
· GjcQueryStorageViewHolder 未引用控件 id无共用 id 约束
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
@@ -15,85 +26,88 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical">
android:layout_marginHorizontal="12dp"
android:layout_marginTop="12dp"
android:background="@drawable/bg_phone_card"
android:orientation="vertical"
android:paddingHorizontal="14dp"
android:paddingBottom="14dp">
<!-- 头行:蓝点 + 库位号 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="40dp"
android:orientation="horizontal"
android:paddingHorizontal="10dp"
android:paddingVertical="8dp">
android:paddingVertical="12dp">
<!-- 序号 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center"
android:text="@{String.valueOf(position + 1)}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<View
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/bg_phone_dot_blue" />
<!-- 库位号 -->
<TextView
android:layout_width="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="center"
android:text="@{bean.location ?? `--`}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 入库人 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@{bean.inOpId ?? `--`}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 入库时间 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="center"
android:text="@{bean.inDate != null &amp;&amp; String.valueOf(bean.inDate).length() >= 16 ? String.valueOf(bean.inDate).substring(0, 16) : (bean.inDate != null &amp;&amp; String.valueOf(bean.inDate).length() > 0 ? String.valueOf(bean.inDate) : `--`)}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 出库人 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@{bean.outOpId ?? `--`}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 出库时间 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="center"
android:text="@{bean.outDate != null &amp;&amp; String.valueOf(bean.outDate).length() >= 16 ? String.valueOf(bean.outDate).substring(0, 16) : (bean.outDate != null &amp;&amp; String.valueOf(bean.outDate).length() > 0 ? String.valueOf(bean.outDate) : `--`)}"
android:textColor="@android:color/black"
android:textSize="14sp" />
android:text='@{bean.location ?? "--"}'
android:textColor="@color/phone_text_title"
android:textSize="15sp"
android:textStyle="bold"
tools:text="A-01-001" />
</LinearLayout>
<!-- 内容分割线 -->
<View
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/line" />
android:layout_marginBottom="12dp"
android:background="@color/phone_divider" />
<!-- 入库人 | 入库时间 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"入库人"}'
value="@{bean.inOpId}" />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"入库时间"}'
value="@{bean.inDate != null &amp;&amp; bean.inDate.length() >= 16 ? bean.inDate.substring(0, 16) : bean.inDate}" />
</LinearLayout>
<!-- 出库人 | 出库时间 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"出库人"}'
value="@{bean.outOpId}" />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"出库时间"}'
value="@{bean.outDate != null &amp;&amp; bean.outDate.length() >= 16 ? bean.outDate.substring(0, 16) : bean.outDate}" />
</LinearLayout>
</LinearLayout>
</layout>

View File

@@ -1,5 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<!--
国际出港查询详情-仓库信息列表项 —— 手机版布局5.5 寸手持端)
平板版为同名文件 layout-sw600dp/item_gjc_query_warehouse.xml表格行样式
手机版为批次卡片(设计稿:批次号头行 + 件数/重量/航班日期/航班号/始发站/目的站 两列网格)。
变体之间必须满足:
· DataBinding 变量完全一致bean / position
· GjcQueryWarehouseViewHolder 未引用控件 id无共用 id 约束
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
@@ -15,105 +26,111 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical">
android:layout_marginHorizontal="12dp"
android:layout_marginTop="12dp"
android:background="@drawable/bg_phone_card"
android:orientation="vertical"
android:paddingHorizontal="14dp"
android:paddingBottom="14dp">
<!-- 头行:蓝点 + 批次号 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:minHeight="40dp"
android:orientation="horizontal"
android:paddingHorizontal="10dp"
android:paddingVertical="8dp">
android:paddingVertical="12dp">
<!-- 序号 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center"
android:text="@{String.valueOf(position + 1)}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<View
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/bg_phone_dot_blue" />
<!-- 集装器 -->
<TextView
android:layout_width="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1.2"
android:gravity="center"
android:text="@{bean.location}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 件数 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="@{String.valueOf(bean.pc)}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 重量 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="@{String.valueOf(bean.weight)}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 航班日期 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@{bean.fdate}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 航班号 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@{bean.fno}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 航程 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="@{bean.range}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 分批 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="@{`1`}"
android:textColor="@android:color/black"
android:textSize="14sp" />
android:text='@{"批次号: " + String.valueOf(position + 1)}'
android:textColor="@color/phone_text_title"
android:textSize="15sp"
android:textStyle="bold"
tools:text="批次号: 1" />
</LinearLayout>
<!-- 内容分割线 -->
<View
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/line" />
android:layout_marginBottom="12dp"
android:background="@color/phone_divider" />
<!-- 件数 | 重量 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"件数"}'
value="@{String.valueOf(bean.pc)}" />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"重量"}'
value='@{String.valueOf(bean.weight) + " kg"}' />
</LinearLayout>
<!-- 航班日期 | 航班号 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"航班日期"}'
value="@{bean.fdate}" />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"航班号"}'
value="@{bean.fno}" />
</LinearLayout>
<!-- 始发站 | 目的站 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"始发站"}'
value="@{bean.dep}" />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"目的站"}'
value="@{bean.dest}" />
</LinearLayout>
</LinearLayout>
</layout>

View File

@@ -2,7 +2,7 @@
<!--
国际出港运抵-分单明细 - 分单卡片5.5寸手机版专属页面)
对应设计稿卡片:分单号 + 申报状态标签 + 件数/重量,长按弹出「重置」单条操作。
对应设计稿卡片:分单号 + 申报状态标签 + 件数/重量,长按弹出「重置」+「回执」单条操作。
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
@@ -102,7 +102,7 @@
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- ==================== 长按操作浮层:「重置」 ==================== -->
<!-- ==================== 长按操作浮层:「重置」+「回执」(对应设计稿双圆按钮) ==================== -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
@@ -111,10 +111,15 @@
android:onClick="@{()-> activity.hideActionMenu(bean)}"
android:visibility="@{bean.actionMenuVisible ? View.VISIBLE : View.GONE}">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_gravity="center"
android:background="@drawable/bg_phone_fab_amber"
android:gravity="center"
android:onClick="@{()-> activity.resetSingleClick(bean)}"
@@ -123,6 +128,20 @@
android:textSize="12sp"
android:textStyle="bold" />
<TextView
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_marginStart="24dp"
android:background="@drawable/bg_phone_fab_green"
android:gravity="center"
android:onClick="@{()-> activity.openReceipt(bean)}"
android:text="回执"
android:textColor="@color/white"
android:textSize="12sp"
android:textStyle="bold" />
</LinearLayout>
</FrameLayout>
</FrameLayout>

View File

@@ -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管理",

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB