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>
This commit is contained in:
2026-07-31 18:13:44 +08:00
parent 436202f15b
commit 33c9f0e030
41 changed files with 3730 additions and 1629 deletions

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
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/ll"
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" />
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="12dp"
android:background="@drawable/bg_phone_card"
android:orientation="vertical"
android:padding="14dp">
<!-- ==================== 头行:蓝点 + 运单号 + 状态标签 + 箭头 ==================== -->
<LinearLayout
android:layout_width="0dp"
android:layout_width="match_parent"
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">
<View
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginEnd="8dp"
android:background="@drawable/bg_phone_dot_blue" />
<!-- 运单号 -->
<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"
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
android:layout_weight="1"
android:text="@{bean.wbNo}"
android:textColor="@color/phone_text_title"
android:textSize="16sp"
android:textStyle="bold"
tools:text="78133363396" />
<!-- 航班 -->
<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="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="wrap_content"
completeSpace="@{4}"
android:text="航班:"
android:textSize="15sp" />
<!-- 已入库(橙) -->
<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="wrap_content"
android:text="@{bean.flight}"
android:textSize="15sp"
tools:text="20240513/MU2026" />
<!-- 未入库(灰,兜底) -->
<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}" />
</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>
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginStart="6dp"
android:src="@drawable/ic_phone_chevron_right" />
</LinearLayout>
<!-- 右侧箭头 -->
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:src="@drawable/img_pda_right"
android:layout_marginLeft="10dp" />
<!-- ==================== 字段网格:件数/重量 ==================== -->
<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:gravity="center_vertical"
android:orientation="horizontal">
<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"
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="14dp"
android:layout_height="14dp"
android:src="@drawable/ic_phone_weight" />
<TextView
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>
</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>