Compare commits

..

5 Commits

Author SHA1 Message Date
49f11ef8e6 fix: 进港移库归属更正——删除误建IntImpMove,重新适配到国内进港DomImpMove
设计稿11「进港移库」经确认归属国内进港移库(DomImpMove后端8接口齐全),
此前误判为国际进港并预接了不存在的IntImpMove模块(问题清单#31作废)。

- 删除module_gjj的IntImpMove全套实现(3页面+Bean+Api+菜单+路由+权限串)
- GnjMoveStashListActivity双形态适配:待移库/已移库Tab走search/searchMoved
  双端点,Tab角标、筛选弹层4项、全选/批量移库复用平板既有链路
- 新增手机专属页:运单详情(Intent传bean零请求)+拍照上传(detail回填
  已有照片,modify最小体三字段提交,与平板移交编辑页同链路)
- 手机首页入口改挂国内Tab(GnViewModel补通用route跳转,权限串AppDomImpMove)
- 内网真实数据双端验证通过;Proxyman A/B:wbNo/awbType生效,
  fdate/fno/spCode被后端静默忽略(#32)、opId/opDate恒null(#33)
- 问题清单更正#31+新增#32~#34,CLAUDE.md/CHANGELOG/api-doc.md同步

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 12:17:10 +08:00
eb0655d3fc fix: 11模块设计稿全量走查修正——时间线状态pill/手机短标题/ULD字段顺序/计重卡片图标
设计稿逐态渲染对照走查(01~11 全模块)后的修正:
- 运单追踪竖排时间线为已发生节点补状态pill(绿底展示该环节日志content,超长省略)
- 11 页手机端标题按设计稿改短标题(DeviceUtil.isPhone 分支,平板长标题零变化):
  出库交接/出港待计重/计重记录/计重明细/开始计重/出港运抵/出港移库/出港查询/
  出港货物/进港查询/进港货物
- ULD 编辑表单「来源」移至「所在港」之后(设计稿顺序)
- 出港计重列表卡片与计重记录卡片补字段小图标(airplane/location/person/tag)

接口缺口台账复核:#31 进港移库整模块缺失成立(api-doc 全模块清单+报价单双重印证);
#19 修正定性——IntExpArrive/declare 入参已含收发货人全套字段,改登记为待确认提交口径;
#10 成立(单条 deleteUld 在、批量无)。

双端抽验:手机短标题三页生效(出港待计重/出库交接/进港货物),平板保持长标题,零崩溃。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 23:12:14 +08:00
a33776d959 feat: 完成进港查询与进港移库页面5.5寸手机端适配(设计稿11页全部完成)
进港查询(10,06出港查询的进港镜像):
- IntImpQueryActivity 手机布局:搜索行 + 三格统计(总票数/已入库/已出库客户端计数)
  + 状态标签卡片(dlvTime/inDate 前端推断)+ 筛选弹层9项(入参全部经api-doc核对存在)
- 详情页与运单追踪复用08/06已适配页零新增;平板侧滑筛选面板判空守卫,Pad端零变化
- 修复代理人空值兜底:转换器将JSON null归一为空串致DataBinding `??` 失效,
  改用Bean计算属性 agentDisplay(06出港查询同步修正)

进港移库(11,首个后端整模块缺失的设计稿页):
- 全新手机专属3页:列表(双Tab+角标/筛选4项/多选批量移库/卡片长按拍照浮层)
  + 运单详情(三卡片,Intent传bean零请求)+ 拍照上传(复用ImageSelectNewViewHolder,
  pic/originalPic/picNumber三字段规范)
- 后端无IntImpMove模块(api-doc核对),按IntExpMove同名约定预接四接口
  + 预定义权限串AppIntImpMove,后端交付后前端零改动生效(缺口#31)

其他:手机首页国际Tab新增进港查询/进港移库入口;新增资源bg_phone_btn_green/
bg_phone_card_header_orange/bg_phone_photo_add/phone_amber;问题清单登记#30~#31;
双端模拟器验证零崩溃(手机Map Local mock全交互链路,平板回归零变化)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 22:35:56 +08:00
b2a2cce585 feat: 完成提取出库页面5.5寸手机端适配
提取出库(09,module_gjj):
- IntImpPickUpDLVActivity 手机布局:搜索行+待出库/已出库状态Tab(outState 为
  pageQuery 文档定义入参 0/1,Tab 真实过滤+角标双 pageQueryTotal,抓包证实携带)
  +双形态卡片(isPickedUp=dlvTime非空:待出库勾选框+橙标签+库位行/已出库绿√+
  出库人·出库时间行)+卡片内 PhoneStatBox 三列+PhoneBottomBar(仅待出库Tab显示,
  复用既有 confirmOutbound)
- 手机专属新页 IntImpPickUpDetailActivity 运单详情:蓝头运单卡+绿头提货信息卡,
  Intent 传 Serializable bean 零新增请求
- 筛选弹层 4 项(航班日期为未定义入参预留传参);手机进入时清空平板默认
  「当天缴费日期」查全量,平板默认值不变
- IntImpPickUpDLVBean 增加 isPickedUp 计算属性;手机首页「国际」Tab 加入口

修复:checkAllClick 全选后底部「已选 N 项」不更新(批量勾选不走单卡 FlowBus
事件,需自行同步 selectedCountText),实测修复生效

验证:双端 Proxyman Map Local mock 口径验证通过,平板回归一致(含缴费日期默认值),
崩溃 0;后端缺口 2 项登记问题清单 #28~#29(无 fdate 入参、出参无车牌/目的港/
业务类型;outState 过滤与 dlvName=出库人语义待内网实测)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 21:31:58 +08:00
3b732c3aec feat: 完成出港仓库与进港仓库页面5.5寸手机端适配
出港仓库(07,module_gjc):
- IntExpStorageUseActivity 手机布局:搜索行+三格统计(总票数/未清仓/已清仓,
  clearNormal=0/1 双 pageQueryTotal 仅手机发起)+卡片级四操作按钮(清仓/修改
  库位/出库/入库,已清仓置灰),取代平板勾选+底部批量条,复用既有 performXxx 链路
- 详情/运单追踪复用出港查询已适配页(GjcQueryDetailsActivity/LogDetailActivity),零新增页面
- 清仓/入库/修改库位弹框双变体化(手机底部弹层);修改库位手机版增加「原库位」单选;
  出库确认 AlertDialog → ConfirmDialogModel(项目强制规范)

进港仓库(08,module_gjj,07 的进港镜像):
- IntImpStorageUseActivity 手机布局:搜索框「运单号/航班号」分流(含字母→fno,
  抓包证实)+始发站字段/筛选(fdep 入参)
- 进港详情 IntImpQueryDetailsActivity + 3 Fragment 首次手机适配(报文区 3 项,
  件重区直取 inPc/inWeight,库位卡片优先中文姓名)
- 修改库位手机弹层「原库位」只列未出库库位(沿用平板校验)

公共:GjcMaWb 增加 isCleared 计算属性;新增 bg_phone_btn_disabled;手机首页
「国际」Tab 增加出港仓库/进港仓库入口;debug manifest 直启项

验证:双端 Proxyman Map Local mock 口径验证通过(开发机不在内网),平板回归一致,
崩溃 0;后端缺口 5 项登记问题清单 #23~#27(筛选入参缺失/clearNormal 分项统计与
detail 推断字段待内网实测)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 20:49:59 +08:00
116 changed files with 11087 additions and 4590 deletions

View File

@@ -85,6 +85,52 @@ curl -s -X POST "$URL" -H "$AUTH" -H "Content-Type: application/json" \
详情「入库件数/入库重量」= `warehouseList` 各批次 pc/weight 求和mock 与实测均吻合); 详情「入库件数/入库重量」= `warehouseList` 各批次 pc/weight 求和mock 与实测均吻合);
卡片状态推断口径:`fclose` 非空=已离港、否则 `opDate` 非空=已入库; 卡片状态推断口径:`fclose` 非空=已离港、否则 `opDate` 非空=已入库;
特码字典沿用 `DictUtils.getSpecialCodeList(flag=1, ieFlag="")`ieFlag 必须空串) 特码字典沿用 `DictUtils.getSpecialCodeList(flag=1, ieFlag="")`ieFlag 必须空串)
- `IntExpStorageUse`出港仓库2026-07-31 文档核对,内网 A/B 未测——当日开发机不在内网):
`pageQuery`/`pageQueryTotal` 同一套入参 schema`fdate`/`fno`/`wbNo`/`likeNo`/`spCode`/`dest`/
`agentCode`/`location`/`clearNormal`/`checkIn`/`reviewStatus`/`dep`/`hno`/`prefix`;设计稿筛选的
**运单类型/业务类型/品名(中) 均无入参**`awbType`/`businessType`/`goodsCn`,缺口 #23
手机三格统计按 `clearNormal=0/1` 各调一次 `pageQueryTotal``wbNumber`,该过滤**是否真实生效
待内网 A/B**(缺口 #24,参照 isFclose 有定义但被忽略的先例);出参 `clearNormal` 0=未清仓/1=已清仓
(卡片标签与「清仓」按钮置灰按 ==\"1\" 判定);详情复用 `IntExpSearch/detail`maWbId Query 参数)
- `IntImpStorage`进港仓库2026-07-31 文档核对;**注意前端 Api.kt 路径前缀是 `IntImpStorage`
不是 `IntImpStorageUse`**api-doc 按后者搜不到):`pageQuery`/`pageQueryTotal` 同一套入参:
`fdate`/`fno`/`wbNo`/`hno`/`fdep`(始发站)/`location`/`clearNormal`/`fid`;比出港仓库还少
`agentCode`/`spCode`/`dest`——设计稿筛选的代理/特码/运单类型/业务类型/品名(中) **5 项均无入参**
(缺口 #25);分项统计与 clearNormal 过滤待实测同 #24(记为 #26);详情复用
`IntImpSearch/detail`Body 传 `prefix`+`no`,出参 `data.maWb` 无 schema字段 key 以平板绑定为准:
`awbPc`/`awbWeight`/`cashWeight`/`inPc`/`inWeight`/`lockState`(0/1 需转中文)/`mftStatus` 原始舱单/
`tallyStatus` 理货报告/`command` 海关放行/`by1` 承运人/`dlvTime` 出库时间;`dep`/`dest1`/`dest`/
`unNumber`/`opDate` 为按出港推断,待实测 #27
- `IntImpPickUpDlv`提取出库2026-07-31 文档核对):`pageQuery` 入参含 **`outState`
0 未出库/1 已出库)**——待出库/已出库 Tab 直接真实过滤(抓包证实携带,效果待内网 A/B #29
另有 `fno`/`dest`/`origin`/`carrier`/`awbType`/`businessType`/`goods`/`likeNo`/`pkId`/
`beginDate`/`endDate`+`dateType`(0 入库/1 离港)/`chargeFlag`(0 未提取/1 已提取)
**无 `fdate`(航班日期)入参**(缺口 #28);出参无车牌/目的港/业务类型名称(#28
运单号筛选参数名是 **`no`**(平板既有口径);`chargeName`/`chargeTime` = 柜台办理人/缴费(提取)时间,
`dlvTime` = 出库时间,`dlvName` 按提货人语义推断作「出库人」展示(待确认 #29
确认出库接口 `pickUpOut` 文档注明**需将全字段传至后端**(平板 `selectedItems.toRequestBody()` 已满足)
- `IntImpSearch`进港查询2026-07-31 文档核对):`pageQuery`/`pageQueryTotal` 分页参数名是
**`page`/`limit`**(不是 pageNum/pageSize手机筛选 9 项入参全部真实存在:`beginDate`/`endDate`/
`fno`/`agentCode`/`spCode`/`origin`(始发站)/`awbType`/`businessType`/`goods`(品名,**不是 goodsCn**
`outState`0 未出库/1 已出库)文档为 integer前端传字符串靠 Jackson 隐式转换;`pageQueryTotal`
出参无已入库/已出库分项计数(缺口 #30手机三格统计为客户端计数口径dlvTime 非空=已出库、
inDate 非空=已入库);出参含 `agentName`(中文名)+ `agentCode`agentName 可为 null
- 「进港移库」(设计稿 11**归属更正2026-08-03 用户确认):属国内进港移库 `DomImpMove`**
不是国际进港移库——「后端模块缺失」的旧结论(原缺口 #31)作废,原按 IntExpMove 约定预接的
IntImpMove 前端实现已整体删除。溯源api-doc 53 模块中移库仅 `DomImpMove`国内进港8 接口)与
`IntExpMove`国际出港4 接口移库按转关业务前缀划分DomImpMove 处理 `CI**`、IntExpMove
处理 `IO**`),设计稿详情卡的「国际进港」红标签实为 `awbType` 值(如「国际进港(国内中转)」),
不代表页面归属
- `DomImpMove`国内进港移库2026-08-03 内网实测):手机 Tab 双端点——待移库 `search` /
已移库 `searchMoved`(同一套入参 schema分页参数名 **`page`/`limit`**);入参 A/B 实测:
**`wbNo``awbType`(值为 CICO/CIII/CIIO 转关码)过滤生效;`fdate`/`fno`/`spCode` 文档有定义但
被静默忽略**(缺口 #32`searchMoved`/`detail` 出参 **`opId`/`opDate` 恒 null** 且无操作人姓名
字段(缺口 #33,移库人/移库时间显示"-"`moveId` 形如 `CICO240617155016` 疑似内嵌移库时间戳但无
文档语义;`searchMoved` 出参**无 pic 三字段**search 有)——拍照上传页统一先调 `GET detail`
回填已有照片(#34 前端已规避);照片提交走 `modify` 最小体
`{mawbId, remark, picNumber, pic, originalPic}`平板移交编辑页同链路removeEmptyOrNull
批量移库 `move` 入参 `{fid:"0", ids:[mawbId]}`;国内进港特码字典
`DictUtils.getSpecialCodeList(flag=0, ieFlag="I")` 实测取数正常
- `IntExpCheckIn`出港计重2026-07-29 内网实测):`likeNo` **并非任意模糊**——按 8 位 `no` - `IntExpCheckIn`出港计重2026-07-29 内网实测):`likeNo` **并非任意模糊**——按 8 位 `no`
匹配11 位 wbNo 或部分号均 0 条11 位全号必须走 `wbNo``checkIn`/`checkInList` 匹配11 位 wbNo 或部分号均 0 条11 位全号必须走 `wbNo``checkIn`/`checkInList`
文档有定义但 `pageQuery`/`pageQueryTotal` **均静默忽略**(缺口 #12,待计重/计重中计数依赖); 文档有定义但 `pageQuery`/`pageQueryTotal` **均静默忽略**(缺口 #12,待计重/计重中计数依赖);

View File

@@ -59,6 +59,10 @@ isFclose 这类「参数是否生效」的 A/B 实验用这条链。给后端提
响应结构照抄真实 flow 的顶层结构(如 pageQuery 是裸 PageInfo`{total, list, pages, ...}` 响应结构照抄真实 flow 的顶层结构(如 pageQuery 是裸 PageInfo`{total, list, pages, ...}`
不要包 `{status, data}`)。 不要包 `{status, data}`)。
⚠️ 实测坑2026-07-31 出港仓库mock `BaseResultBean` 包装的接口pageQueryTotal/detail 等)时,
**`status` 必须写 `"1"`**——`BaseResultBean.verifySuccess()``status == "1"`,写 "200" 会被当失败
静默丢弃UI 保持默认值,无任何报错,排查靠 flow 已命中但 UI 不变这一矛盾现象)。
⚠️ 实测坑mock 响应到达后 UI 渲染可能滞后(冷启动首帧 Davey 卡顿 2s+ ⚠️ 实测坑mock 响应到达后 UI 渲染可能滞后(冷启动首帧 Davey 卡顿 2s+
**截图断言前先 `ui_probe texts` 确认数据已上屏**——这次就因截图太早误判过一轮「mock 没生效」, **截图断言前先 `ui_probe texts` 确认数据已上屏**——这次就因截图太早误判过一轮「mock 没生效」,
其实 `get_flow_detail``matchedTools: ["Map Local"]` 早已证明规则命中UI 只是还没画完。 其实 `get_flow_detail``matchedTools: ["Map Local"]` 早已证明规则命中UI 只是还没画完。

View File

@@ -7,7 +7,124 @@
## [Unreleased] ## [Unreleased]
### 变更 (Changed)
- 【进港移库归属更正 · 2026-08-03】设计稿 11「进港移库」经确认归属**国内进港移库
DomImpMove后端 8 接口齐全Pad 首页「国内进港→进港移库」既有页面)**,此前误判为
国际进港并按 IntExpMove 约定预接不存在的 IntImpMove 模块(原问题清单 #31 作废)。处置:
① 删除 module_gjj 的 IntImpMove 全套前端实现3 Activity + 3 ViewModel + Holder + 4 布局 +
`IntImpMoveBean` + Api 4 方法 + 国际 Tab 菜单项 + 权限串/路由/双 Manifest 注册);
② 按 phone-adapt 流程重新适配到 `GnjMoveStashListActivity`app 模块):主列表双形态
Pad 布局移 layout-sw600dp 零改动;手机版 = PhoneSearchBar + 待移库/已移库 Tab
`DomImpMove/search`/`searchMoved` 双端点,`searchMoved` 无移库标识按端点打 `isMoved`+
角标(双端点 limit=1 取 total仅手机发起+ 筛选弹层 4 项 + 全选/已选计数 + 批量移库
(复用平板 `move` 链路)+ 卡片长按「拍照」浮层);新增手机专属页
`GnjMoveStashDetailActivity`Intent 传 bean 零请求,三卡片)与
`GnjMoveStashPhotoActivity`(先调 `detail` 回填已有照片,提交走 `modify` 最小体
三字段规范,与平板移交编辑页同链路);`MoveStashBean``agentName`/`isMoved`/
`actionMenuVisible`/`agentDisplay`/`orDash`;手机首页入口改挂**国内 Tab**`GnViewModel`
补通用 route 跳转,权限串 `GnjYiKu=AppDomImpMove` 与 Pad 一致,新路由
`/app/GnjMoveStashListActivity`)。
2026-08-03 内网真实数据双端验证通过(登录→国内 Tab→列表/Tab/详情/筛选/全选/长按拍照全链路
crash=0平板回归原行为零变化Proxyman A/B`wbNo`/`awbType` 过滤生效,
`fdate`/`fno`/`spCode` 被后端静默忽略(新缺口 #32)、`searchMoved`/`detail` 出参
`opId`/`opDate` 恒 null 且无姓名字段(#33)、`searchMoved` 无 pic 三字段(#34,前端已规避)
### 新增 (Added) ### 新增 (Added)
- 「进港查询」5.5 寸手机端适配(设计稿 10_进港查询06 出港查询的进港镜像;详情页与运单追踪
复用 08/06 已适配页零新增):列表 `IntImpQueryActivity`module_gjj首页菜单实际跳转页
旧版 `GjjQueryListActivity` 路由已注释弃用)手机布局 = PhoneSearchBar运单号+扫码+筛选)+
三格统计(总票数/已入库/已出库,已入库/已出库为已加载数据客户端计数,`pageQueryTotal` 无分项
出参,缺口 #30+ 状态标签卡片(前端推断:`dlvTime` 非空=已出库绿 / `inDate` 非空=已入库橙 /
兜底未入库灰)+ 卡片字段件数(inPc)/重量(inWeight)/代理人/特码;筛选弹层 9 项
(航班日期起止/航班号/代理/特码/始发站/运单类型/业务类型/品名中,**全部经 api-doc 核对为
pageQuery 真实入参**无缺口平板侧滑筛选面板代码判空守卫Pad 端行为零变化
- 「进港移库」5.5 寸手机端全新页面(设计稿 11_进港移库**首个后端整模块缺失的适配页**
api-doc 确认无 IntImpMove 模块、权限体系无对应 key缺口 #31
`IntImpMoveActivity`(待移库/已移库 Tab + 角标、搜索/扫码、筛选弹层 4 项(航班日期/航班号/
特码/运单类型)、多选 + 全选 + 批量移库ConfirmDialogModel 确认)、卡片长按浮层「拍照」)+
`IntImpMoveDetailActivity`(运单详情三卡片:蓝头基本信息/绿头移库信息(仅已移库)/橙头异常照片,
Intent 传 bean 零请求)+ `IntImpMovePhotoActivity`(拍照上传:图片网格复用 module_base
`ImageSelectNewViewHolder`,提交走 pic/originalPic/picNumber 三字段规范);
接口按 IntExpMove 同名约定预接四个pageQuery/pageQueryTotal/move/uploadPic权限串
`AppIntImpMove` 预定义后端交付后前端零改动生效权限串下发前手机首页无入口debug 直启验证)
- 新增 `IntImpMoveBean`(镜像 GjcMove + 航班/照片字段 + isMoved/flightInfo/orDash 计算属性);
`IntImpQueryBean` 新增 isQueryOutbound/isQueryStored/orDash/agentDisplay 计算属性;
手机首页「国际」Tab 增加「进港查询」(图标 gjj_query_icon与「进港移库」图标复用
gjc_yi_ku_icon入口
- 新增手机版资源:`bg_phone_btn_green`(绿色主按钮)、`bg_phone_card_header_orange`(橙色详情卡
表头)、`bg_phone_photo_add`(虚线加号槽位)、色值 `phone_amber`
### 修复 (Fixed)
- 【11 模块全量设计稿走查】修正 4 类差异2026-07-313 个并行审计 + 逐态渲染比对):
① 运单追踪手机竖排时间线补齐已发生节点的状态 pill绿底标签展示该环节日志 content
如「放行状态01」超长省略设计稿 06/08 运单追踪均有此元素);
② 11 个页面手机端标题对齐设计稿短标题(出库交接/出港待计重/计重记录/计重明细/开始计重/
出港运抵/出港移库/出港查询/出港货物/进港查询/进港货物),平板保持原长标题零变化;
③ ULD 编辑表单「来源」字段移至「所在港」之后(设计稿顺序);
④ 出港计重列表卡片(日期/航程/代理/特码)与计重记录卡片(代理)补齐字段小图标
(复用 ic_phone_airplane/location/person/tag与其余模块卡片风格统一
- 出港查询/进港查询卡片「代理人」空值兜底失效:转换器把 JSON null 归一成空串DataBinding
`??` 只判 null 不判空串导致 agentCode 回退永不生效;改用 Bean 计算属性 `agentDisplay`
isNullOrEmpty 双兜底),已同步修正 06 出港查询(`item_gjc_query.xml`
### 验证 (Verified)
- 进港查询手机端Map Local mock 验证三格统计计数、三种状态标签、空值 "--" 兜底、筛选弹层
9 项收缩滚动;平板端回归横排搜索条/侧滑筛选面板/底部统计栏零变化;全程崩溃数 0
- 进港移库手机端Map Local mock 验证双 Tab 角标、双形态卡片、单选/全选联动计数、空选拦截、
移库确认弹框、长按拍照浮层、运单详情、拍照上传页;全程崩溃数 0后端模块缺失接口联调待
后端交付,见问题清单 #31
- 「提取出库」5.5 寸手机端适配(设计稿 09_提取出库列表 `IntImpPickUpDLVActivity`module_gjj
手机布局 = PhoneSearchBar运单号+扫码+筛选)+ **PhoneStatusTab 待出库/已出库**`outState`
为 pageQuery 文档定义入参 0/1Tab 真实过滤 + 角标双 pageQueryTotal抓包证实携带+
双形态卡片(待出库:圆形勾选框+橙标签+库位行;已出库:绿 √ 标签+出库人·出库时间行,
`isPickedUp` = dlvTime 非空)+ 卡片内 PhoneStatBox 三列(代理人/件数/重量)+「查看详情」链接 +
PhoneBottomBar全选+已选 N 项+出库,仅待出库 Tab 显示,复用既有 confirmOutbound
筛选弹层 4 项(航班日期为 pageQuery 未定义入参预留;航班号 fno代理人/特码下拉);
手机端进入时清空平板默认「当天缴费日期」查全量initPhoneExtras平板默认值不变
- 手机专属新页「运单详情」`IntImpPickUpDetailActivity`:蓝头运单卡(红标签国际进港+品名大标题+
两列 KV+库位橙标签)+ 绿头提货信息卡(柜台办理人/时间,已出库追加出库人/出库时间行),
数据直接 Intent 传列表 beanSerializable零新增请求
- `IntImpPickUpDLVBean` 新增 `isPickedUp` 计算属性手机首页「国际」Tab 增加「提取出库」入口
(权限 AppIntImpPickUpDLV 对应权限串,图标复用 Pad 端 gjj_chu_ku_icon
- 后端缺口 2 项登记问题清单 #28~#29pageQuery 无 fdate 入参、出参无车牌/目的港/业务类型;
outState 过滤与 dlvName=出库人语义待内网实测)
- 「进港仓库」5.5 寸手机端适配(设计稿 08_进港仓库07 出港仓库的进港镜像 + 进港详情页首次适配):
列表 `IntImpStorageUseActivity`module_gjj首页菜单实际跳转页旧版 `GjjWareHouseActivity`
路由已注释弃用)手机布局 = PhoneSearchBarplaceholder「搜索运单号/航班号」,`phoneSearchClick`
分流含字母→fno、其余→wbNo实机抓包证实+ 三格统计(总票数/未清仓/已清仓clearNormal=0/1
双 total+ 卡片四操作按钮(清仓/修改库位/出库/入库,已清仓置灰)+ 卡片字段件数/重量/航班号/
**始发站**bean.dep出港为目的站筛选弹层 8 项(始发站走 fdep 入参;代理/特码/运单类型/
业务类型/品名中 5 项为后端未定义入参,预留传参)
- 进港详情页 `IntImpQueryDetailsActivity` + 3 Fragment运单/仓库/库位信息)首次手机适配:
移植 06 出港详情手机布局,报文区按设计稿 3 项(原始舱单 mftStatus/理货报告 tallyStatus/
海关放行 command件重区直取 detail 出参 awbPc/awbWeight/cashWeight/inPc/inWeight
进港自带无需求和库位卡片优先显示中文姓名inOpName/outOpName
ViewModel 增加 str/strOr/dec 取值帮助(与出港同口径)
- 进港版 3 个操作弹框双变体化(清仓/入库/修改库位,手机底部弹层);修改库位手机版增加
「原库位」单选且**只列未出库库位**(沿用平板「已出库不允许修改」校验,卡片级操作时全部已出库
toast 拦截),单库位默认选中
- 手机首页「国际」Tab 增加「进港仓库」入口(权限 AppGjjWareHouse=Constant.AuthName.GjjWareHouseActivity 对应权限串,图标复用出港仓库同款)
- 后端缺口 3 项登记问题清单 #25~#27pageQuery 无代理/特码/运单类型/业务类型/品名中 5 项筛选
入参clearNormal 分项统计待实测detail 出参 dep/dest1/dest/unNumber/opDate 字段待实测确认)
- 「出港仓库」5.5 寸手机端适配(设计稿 07_出港仓库详情/运单追踪复用已适配页零新增):
列表 `IntExpStorageUseActivity` 手机布局 = PhoneSearchBar运单号 + 扫码 + 筛选)+ 三格统计
(总票数/未清仓/已清仓,彩色左边条卡片;分项计数按同条件 + `clearNormal=0/1` 各调一次
`pageQueryTotal`,仅手机形态发起)+ 状态标签卡片(已清仓绿/未清仓橙,`clearNormal=="1"` 判定);
**卡片级四操作按钮**(清仓/修改库位/出库/入库,已清仓时清仓置灰拦截)取代平板的勾选+底部批量条,
语义等价于「勾选该主单+全部库位」复用既有 `performClear/performModifyStorage/performOutStorage/
performInStorage` 请求链路;卡片点击进详情(复用出港查询详情 `GjcQueryDetailsActivity` 3 Tab
运单/仓库/库位信息,运单追踪同样复用 `LogDetailActivity`);筛选弹层 8 项按设计稿完整实现
(航班日期/航班号/代理/特码/目的站/运单类型/业务类型/品名中,后三项为后端未定义入参,预留传参)
- 清仓/入库/修改库位三个操作弹框(`IntExpMoveClearDialogModel`/`IntExpInStorageDialogModel`/
`IntExpModifyStorageDialogModel`双变体化手机底部弹层PhoneDataLayout+ 平板居中弹框不变,
弹出位置按 `DeviceUtil.isPhone()` 切换;修改库位弹框手机版新增「原库位」单选
(卡片级操作时运单可能有多个库位,构造参数 `sourceStorageList` 传入,单库位默认选中,平板路径不受影响)
- 出库二次确认由系统 `AlertDialog` 改为项目规范的 `ConfirmDialogModel`(平板批量出库与手机卡片出库共用)
- 手机首页「国际」Tab 增加「出港仓库」入口(权限 AppIntExpStorageUse图标复用 Pad 端 gjc_cang_ku_icon
- `GjcMaWb` 新增 `isCleared` 手机版计算属性;新增手机版资源 `bg_phone_btn_disabled`(灰底禁用按钮)
- 后端缺口 2 项登记问题清单 #23~#24pageQuery/pageQueryTotal 无 awbType/businessType/goodsCn
筛选入参pageQueryTotal 的 clearNormal 分项统计过滤待内网 A/B 实测确认)
- 「出港查询」5.5 寸手机端适配(设计稿 06_出港查询含列表/详情/运单追踪三页): - 「出港查询」5.5 寸手机端适配(设计稿 06_出港查询含列表/详情/运单追踪三页):
列表 `GjcQueryActivity` 手机布局 = PhoneSearchBar运单号 + 扫码 + 筛选)+ 三格统计 列表 `GjcQueryActivity` 手机布局 = PhoneSearchBar运单号 + 扫码 + 筛选)+ 三格统计
(总票数/已入库/已离港,彩色左边条卡片)+ 状态标签卡片(已离港绿/已入库橙/未入库灰, (总票数/已入库/已离港,彩色左边条卡片)+ 状态标签卡片(已离港绿/已入库橙/未入库灰,
@@ -28,12 +145,36 @@
无已入库/已离港分项统计出参detail 出参无锁定状态/计费重量字段) 无已入库/已离港分项统计出参detail 出参无锁定状态/计费重量字段)
### 修复 (Fixed) ### 修复 (Fixed)
- 提取出库手机版底部条「已选 N 项」在点全选后不更新:`checkAllClick` 只改勾选状态未同步
`selectedCountText`(卡片单选走 FlowBus→updateCheckAllStatus 正常),补同步后实测「已选 3 项」正确
- **`PhoneFilterPanel` 底部按钮被挤出屏幕**:面板高度 wrap_content 且内容插槽无滚动,筛选项多 - **`PhoneFilterPanel` 底部按钮被挤出屏幕**:面板高度 wrap_content 且内容插槽无滚动,筛选项多
(出港查询 9 项)时「重置/确认」按钮直接超出屏幕外且无任何报错。修复:内容插槽外包 (出港查询 9 项)时「重置/确认」按钮直接超出屏幕外且无任何报错。修复:内容插槽外包
ScrollViewweight=1筛选项少时行为不变超屏时内容区收缩滚动、按钮始终可见 ScrollViewweight=1筛选项少时行为不变超屏时内容区收缩滚动、按钮始终可见
(已回归出港计重 4 项弹层,行为不变) (已回归出港计重 4 项弹层,行为不变)
### 验证 (Verified) ### 验证 (Verified)
- 提取出库双端验证通过2026-07-31Proxyman Map Local mock 口径):手机端菜单入口、
Tab 角标(双 total、双形态卡片含库位空值兜底、单选/全选与「已选 N 项」联动、
出库 ConfirmDialogModel、待出库/已出库两种详情页形态(出库人行按需显隐)、筛选弹层 4 项、
Tab 切换请求体抓包证实 outState=1 正确携带、冷启动方向恒竖屏、崩溃 0
平板端回归:缴费日期默认当天/5 搜索条/全选/底部统计/确认出库与改造前一致,崩溃 0。
**待内网补测**outState 过滤 A/B、dlvName=出库人语义、出库真实提交链路
- 进港仓库双端验证通过2026-07-31同出港仓库为 Proxyman Map Local mock 口径):
手机端登录→国际 Tab→进港仓库菜单入口、三格统计、三种卡片形态含空值 "--" 兜底)、
详情 3 Tab 全字段(锁定状态转中文、库位中文姓名、时间截断、空值兜底)、四操作弹框、
已出库库位过滤(双库位卡片原库位仅列未出库项并默认选中)、无库位/已清仓拦截、
筛选弹层 8 项、搜索分流实机抓包证实(输入 MU1111 → 请求体 fno="MU1111"、wbNo=null
冷启动方向恒竖屏、崩溃 0平板端回归5 搜索条/全选/底部统计/4 批量按钮与改造前一致,崩溃 0。
**待内网补测**clearNormal 分项统计 A/B、detail 推断字段dep/dest1/dest/unNumber/opDate
四操作真实提交链路
- 出港仓库双端验证通过2026-07-31开发机不在内网 → 全程 Proxyman Map Local mock 口径):
手机端登录→国际 Tab→出港仓库菜单入口、三格统计渲染、三种卡片形态已清仓置灰清仓/未清仓/
全空字段 "--" 兜底)、四操作按钮(清仓/入库底部弹层、修改库位弹层含原库位默认选中、
出库 ConfirmDialogModel 文案带运单号与库位数、无库位卡片 toast 拦截、已清仓清仓点击拦截)、
筛选弹层 8 项滚动 + 底部按钮可见、卡片点击进详情Proxyman flow 证实 maWbId 正确传参且
detail mock 命中、详情右上运单追踪跳转、冷启动方向恒竖屏ROTATION_0×3 采样)、崩溃 0
平板端同页面回归5 搜索条/全选/底部统计/4 批量按钮与改造前一致,崩溃 0。
**待内网补测**clearNormal 分项统计 A/B、agentCode/spCode/dest 筛选实测、四操作真实提交链路
- 出港查询双端实机验证通过2026-07-31内网真实数据 2026-06-09 共 14 票): - 出港查询双端实机验证通过2026-07-31内网真实数据 2026-06-09 共 14 票):
手机端登录→国际 Tab→出港查询菜单入口、列表加载/状态标签/三格统计10+4=14 与卡片一致)、 手机端登录→国际 Tab→出港查询菜单入口、列表加载/状态标签/三格统计10+4=14 与卡片一致)、
筛选弹层(日期滚轮、特码/代理下拉真实取数、重置、确认后重新查询)、运单号搜索、扫码拉起、 筛选弹层(日期滚轮、特码/代理下拉真实取数、重置、确认后重新查询)、运单号搜索、扫码拉起、

View File

@@ -1064,6 +1064,10 @@ DataBinding 适配器统一放在 `PhoneWidgetKtx.kt`(同名属性按控件类
出港查询追加:`ic_phone_package`(件数)、`ic_phone_tag`(特码)、`bg_phone_dot_blue/gray`(状态圆点); 出港查询追加:`ic_phone_package`(件数)、`ic_phone_tag`(特码)、`bg_phone_dot_blue/gray`(状态圆点);
`PhoneFilterPanel` 内容插槽已内置 ScrollView筛选项超屏时收缩滚动底部按钮始终可见—— `PhoneFilterPanel` 内容插槽已内置 ScrollView筛选项超屏时收缩滚动底部按钮始终可见——
9 个筛选项曾把「重置/确认」挤出屏幕)。 9 个筛选项曾把「重置/确认」挤出屏幕)。
出港仓库追加:`bg_phone_btn_disabled`(灰底禁用按钮,与 `bg_phone_btn_weak` 同 10dp 圆角,
卡片操作按钮禁用态配 `phone_tag_gray_text` 文字)。
进港移库追加:`bg_phone_btn_green`(绿色主按钮,拍照上传「确认提交」)、`bg_phone_card_header_orange`
(橙色详情卡表头,异常照片)、`bg_phone_photo_add`(虚线加号槽位)、色值 `phone_amber`
⚠️ **弹层与浮动按钮的层级**`PhoneFilterPanel` 默认无 elevation页面里有带 elevation 的浮动按钮FAB ⚠️ **弹层与浮动按钮的层级**`PhoneFilterPanel` 默认无 elevation页面里有带 elevation 的浮动按钮FAB
会穿透到弹层之上——给弹层实例加 `android:elevation="8dp"`(大于 FAB 的 6dp 会穿透到弹层之上——给弹层实例加 `android:elevation="8dp"`(大于 FAB 的 6dp
@@ -1132,6 +1136,50 @@ override fun dispatchRestoreInstanceState(container: SparseArray<Parcelable>) =
`.checked.set(...)` 会崩溃——接收方 `initOnCreated` 必须对列表 `.map { it.copy() }` 补上。 `.checked.set(...)` 会崩溃——接收方 `initOnCreated` 必须对列表 `.map { it.copy() }` 补上。
2026-07-30 review 修正:状态重置弹框改手机底部弹层(弹框双变体首例,见改造步骤第 6 条)、 2026-07-30 review 修正:状态重置弹框改手机底部弹层(弹框双变体首例,见改造步骤第 6 条)、
主列表/回执页补空态、分单浮层补「回执」、分单统计加分母、Tab 角标初始 0 主列表/回执页补空态、分单浮层补「回执」、分单统计加分母、Tab 角标初始 0
- 「提取出库」`IntImpPickUpDLVActivity`module_gjj类型2 多选批量页 + 手机专属详情新页
`IntImpPickUpDetailActivity`Intent 传 Serializable bean 零请求)。待出库/已出库 Tab 绑
**文档定义入参 `outState`**0/1抓包证实携带效果待内网 #29+ 角标双 pageQueryTotal
双形态卡片按 `isPickedUp`dlvTime 非空)切换;手机进入时清空平板默认「当天缴费日期」查全量;
缺口 #28:无 fdate 入参、出参无车牌(提货车辆)/目的港/业务类型。
⚠️ 踩坑:`checkAllClick` 全选后底部「已选 N 项」不更新——批量勾选不走 FlowBus 单卡事件,
必须在 checkAllClick 里同步 selectedCountText
- 「进港查询」`IntImpQueryActivity`module_gjj06 出港查询的进港镜像:三格统计
总票数/已入库/已出库为已加载数据客户端计数(`pageQueryTotal` 无分项出参,缺口 #30
卡片状态前端推断:`dlvTime` 非空=已出库(绿)/`inDate` 非空=已入库(橙)/兜底未入库(灰)
筛选弹层 9 项**入参全部经 api-doc 核对真实存在**(分页参数名 `page`/`limit`,品名参数名
`goods`);详情页与运单追踪复用 08/06 已适配页零新增;平板侧滑筛选面板代码已判空守卫。
⚠️ 踩坑:代理人绑定不能写 `bean.agentName ?? bean.agentCode`——转换器把 JSON null 归一成
空串,`??` 只判 null 不判空串,须用 Bean 计算属性 `agentDisplay`06 出港查询同步修正))
- 「进港移库」`GnjMoveStashListActivity`app 模块,**2026-08-03 归属更正后重做**:设计稿 11
实际归属**国内进港移库 DomImpMove**(后端 8 接口齐全、Pad 首页「国内进港→进港移库」既有页面),
最初误判为国际进港并按 IntExpMove 约定预接了不存在的 IntImpMove 模块(原缺口 #31),该套
module_gjj 前端实现已整体删除。现行实现主列表双形态Pad 布局移 layout-sw600dp 零改动),
待移库/已移库 Tab 走 **`search`/`searchMoved` 双端点**`searchMoved` 出参无移库标识,前端按
端点给 bean 打 `isMoved`Tab 角标 = 两端点各调一次 limit=1 取分页 total`initPhoneExtras`
开关,仅手机发起);手机专属新页 `GnjMoveStashDetailActivity`Intent 传 bean 零请求,三卡片:
基本信息/移库信息(仅已移库)/异常照片)+ `GnjMoveStashPhotoActivity`(进入先调 `detail` 回填
已有照片——`searchMoved` 出参无 pic 三字段 #34,提交走 **`modify` 最小体**
`{mawbId,remark,picNumber,pic,originalPic}`,与平板移交编辑页同链路);批量移库复用平板
`moveStashClick``move`fid+ids。手机首页入口在**国内 Tab**`GnViewModel`,权限串
`GnjYiKu=AppDomImpMove`,需补通用 route 跳转逻辑,图标从 module_gnj 复制);
GnjMoveStashListActivity 补 @Route `/app/GnjMoveStashListActivity`
2026-08-03 内网真实数据双端验证通过;筛选 A/B`wbNo`/`awbType` 生效,
`fdate`/`fno`/`spCode` 被后端静默忽略(#32)、`opId`/`opDate` 恒 null#33
- 「进港仓库」`IntImpStorageUseActivity`module_gjj07 出港仓库的进港镜像;**首页菜单实际跳转页,
旧版 `GjjWareHouseActivity` 路由已注释弃用**。差异:卡片/筛选用始发站fdep 入参)替代目的站;
搜索框「运单号/航班号」分流含字母→fno、其余→wbNo抓包证实筛选 5 项无入参(缺口 #25
比出港多 2 项);连带首次适配进港详情 `IntImpQueryDetailsActivity` + 3 Fragment报文区 3 项:
原始舱单/理货报告/海关放行,件重区直取 inPc/inWeight 无需求和detail keys 以平板绑定为准 +
dep/dest1/dest/unNumber/opDate 按出港推断待实测 #27);修改库位手机弹层「原库位」只列未出库
库位(沿用平板校验);**前端接口前缀是 `IntImpStorage` 不是 `IntImpStorageUse`**api-doc 按
后者搜不到)
- 「出港仓库」`IntExpStorageUseActivity`(嵌套多选列表页型的首个适配:平板「勾选主/子列表 +
底部批量操作」在手机上改为**卡片级四按钮**(清仓/修改库位/出库/入库,已清仓置灰),语义等价
「勾选该主单+全部库位」直接复用既有 performXxx 链路ViewHolder 对双侧独有 id 全判空;
三格统计 总票数/未清仓/已清仓(后两格 = 同条件 + `clearNormal=0/1` 各调一次 pageQueryTotal
过滤是否生效待内网 A/B缺口 #24);筛选弹层 8 项中运单类型/业务类型/品名(中) 为后端未定义
入参(缺口 #23,预留传参);三个操作弹框双变体化 + 手机版修改库位弹层加「原库位」单选;
出库确认 AlertDialog → ConfirmDialogModel详情与运单追踪完全复用出港查询已适配页零新增页面
- 「出港查询」`GjcQueryActivity`(列表:三格统计 总票数/已入库/已离港 + 卡片状态标签, - 「出港查询」`GjcQueryActivity`(列表:三格统计 总票数/已入库/已离港 + 卡片状态标签,
状态为前端推断:`fclose` 非空=已离港/`opDate` 非空=已入库;筛选弹层 9 项,日期起止与代理 状态为前端推断:`fclose` 非空=已离港/`opDate` 非空=已入库;筛选弹层 9 项,日期起止与代理
从平板搜索行并入,特码改下拉 `getSpecialCodeList(flag=1, ieFlag="")`;分项统计为已加载 从平板搜索行并入,特码改下拉 `getSpecialCodeList(flag=1, ieFlag="")`;分项统计为已加载
@@ -1141,8 +1189,11 @@ override fun dispatchRestoreInstanceState(container: SparseArray<Parcelable>) =
双变体首例:手机竖排时间线由 Activity `buildVerticalSteps` 动态构建,平板横向步骤条不动; 双变体首例:手机竖排时间线由 Activity `buildVerticalSteps` 动态构建,平板横向步骤条不动;
手机标题按形态切「运单追踪」)。平板侧滑筛选面板代码已判空守卫(手机变体无 filter_panel 手机标题按形态切「运单追踪」)。平板侧滑筛选面板代码已判空守卫(手机变体无 filter_panel
includeBinding 字段为 @Nullable includeBinding 字段为 @Nullable
-**设计稿 11 个入口01~11已于 2026-07-31 全部适配完成**
-**待办** -**待办**
- `PhoneSearchBar` 接入 AutoQuery 联想(`AutoQueryManager` 目前只对接了 Pad 系组件) - `PhoneSearchBar` 接入 AutoQuery 联想(`AutoQueryManager` 目前只对接了 Pad 系组件)
- 进港移库筛选三项(航班日期/航班号/特码)待后端实装 `fdate`/`fno`/`spCode` 入参(缺口 #32)、
移库人/移库时间待后端回填 `opId`/`opDate` 并补姓名出参(缺口 #33)后自动生效
- 出库交接 Tab 角标恒 0`IntExpOutHandover/pageQueryTotal` 出参恒 0后端缺陷问题清单 #6 - 出库交接 Tab 角标恒 0`IntExpOutHandover/pageQueryTotal` 出参恒 0后端缺陷问题清单 #6
后端修复后角标自动恢复(`handoverState` 过滤本身已于 2026-07-29 实机验证通过)生效 后端修复后角标自动恢复(`handoverState` 过滤本身已于 2026-07-29 实机验证通过)生效
- 📋 **接口对接**:适配中发现的后端接口缺口统一记录在 `documents/后端接口对接问题清单.xlsx` - 📋 **接口对接**:适配中发现的后端接口缺口统一记录在 `documents/后端接口对接问题清单.xlsx`
@@ -1235,6 +1286,9 @@ adb shell am start -n com.lukouguoji.aerologic/com.lukouguoji.gjc.activity.IntEx
| 平板先竖屏再转横屏 + 交互后 UI 放大约 1.6 倍 | Manifest 用了 `@integer/screen_orientation` 资源引用;系统解析 Manifest 不套用限定符全部取到竖屏值AutoSize 随之选了平板竖屏 720dp 基准 | Manifest 改回 `unspecified`(见「屏幕方向」小节的 ⛔ 说明) | | 平板先竖屏再转横屏 + 交互后 UI 放大约 1.6 倍 | Manifest 用了 `@integer/screen_orientation` 资源引用;系统解析 Manifest 不套用限定符全部取到竖屏值AutoSize 随之选了平板竖屏 720dp 基准 | Manifest 改回 `unspecified`(见「屏幕方向」小节的 ⛔ 说明) |
| Tab/分类切换后列表顶部留一大块空白,卡片数量却不对 | 给 item 根节点加了 `visibility="@{tab条件 ? VISIBLE : GONE}"`——RecyclerView/LinearLayoutManager 不会像普通 ViewGroup 那样让 GONE 的子项自动塌陷为 0 高度,仍按测量高度参与滚动区域计算 | 不要用 item 级 visibility 做过滤;在 ViewModel 里自行维护完整列表Tab 切换时把过滤后的子集整体 `commonAdapter()?.refresh(filteredList)` 给 adapter | | Tab/分类切换后列表顶部留一大块空白,卡片数量却不对 | 给 item 根节点加了 `visibility="@{tab条件 ? VISIBLE : GONE}"`——RecyclerView/LinearLayoutManager 不会像普通 ViewGroup 那样让 GONE 的子项自动塌陷为 0 高度,仍按测量高度参与滚动区域计算 | 不要用 item 级 visibility 做过滤;在 ViewModel 里自行维护完整列表Tab 切换时把过滤后的子集整体 `commonAdapter()?.refresh(filteredList)` 给 adapter |
| 通过 `Intent.putExtra(Serializable)` 传递的 Bean切换其 `checked`/`showMore` 等状态时崩溃 `NullPointerException: ... on a null object reference` | 这些字段标了 `@Transient`= JVM `transient`,本意是避免 Gson 网络请求序列化 `ObservableBoolean`),但 Java 对象序列化Intent 传递走的机制)会跳过 `transient` 字段的恢复,反序列化后是 null | 接收方 `initOnCreated` 里对列表做 `.map { it.copy() }`——`.copy()` 会重新走一遍类体初始化逻辑,用全新 `ObservableBoolean(false)` 补上 | | 通过 `Intent.putExtra(Serializable)` 传递的 Bean切换其 `checked`/`showMore` 等状态时崩溃 `NullPointerException: ... on a null object reference` | 这些字段标了 `@Transient`= JVM `transient`,本意是避免 Gson 网络请求序列化 `ObservableBoolean`),但 Java 对象序列化Intent 传递走的机制)会跳过 `transient` 字段的恢复,反序列化后是 null | 接收方 `initOnCreated` 里对列表做 `.map { it.copy() }`——`.copy()` 会重新走一遍类体初始化逻辑,用全新 `ObservableBoolean(false)` 补上 |
| 布局构建报 `Error: The string "--" is not permitted within comments` | XML 注释中出现连续双横线(如写"兜底 \"--\""XML 规范禁止 | 注释里改用文字描述(如「兜底双横线」),代码绑定表达式中的 `"--"` 不受影响 |
| 多选页手机版点「全选」后底部「已选 N 项」不更新(单卡勾选正常) | 批量勾选在 `checkAllClick` 里直接 set不走 FlowBus 的单卡 EVENT_CHECK_CHANGED 事件,`selectedCountText` 只在事件回调里更新 | `checkAllClick` 末尾自行同步 `selectedCountText`(平板布局不绑定该字段,无影响) |
| XML 里 `bean.a ?? bean.b` 兜底不生效,字段明明有值却显示占位符 | 网络层转换器把 JSON null 归一成空串 `""`DataBinding 的 `??` 只判 null 不判空串,永远取到左侧的空串 | 在 Bean 上加计算属性做 `isNullOrEmpty` 双兜底(如 `agentDisplay`XML 绑计算属性(进港查询/出港查询代理人已踩过) |
--- ---

View File

@@ -122,5 +122,59 @@
android:exported="true" android:exported="true"
tools:replace="android:exported" /> tools:replace="android:exported" />
<!-- 出港仓库(手机版适配验证页) -->
<activity
android:name="com.lukouguoji.gjc.activity.IntExpStorageUseActivity"
android:exported="true"
tools:replace="android:exported" />
<!-- 进港仓库(手机版适配验证页) -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpStorageUseActivity"
android:exported="true"
tools:replace="android:exported" />
<!-- 进港查询-详情(手机版适配验证页,进港仓库卡片点击进入) -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpQueryDetailsActivity"
android:exported="true"
tools:replace="android:exported" />
<!-- 提取出库(手机版适配验证页) -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpPickUpDLVActivity"
android:exported="true"
tools:replace="android:exported" />
<!-- 提取出库-运单详情(手机版适配验证页) -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpPickUpDetailActivity"
android:exported="true"
tools:replace="android:exported" />
<!-- 进港查询(手机版适配验证页) -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpQueryActivity"
android:exported="true"
tools:replace="android:exported" />
<!-- 进港移库(国内进港,手机版适配验证页) -->
<activity
android:name="com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListActivity"
android:exported="true"
tools:replace="android:exported" />
<!-- 进港移库-运单详情(手机版专属页) -->
<activity
android:name="com.lukouguoji.aerologic.page.gnj.move.stash.detail.GnjMoveStashDetailActivity"
android:exported="true"
tools:replace="android:exported" />
<!-- 进港移库-拍照上传(手机版专属页) -->
<activity
android:name="com.lukouguoji.aerologic.page.gnj.move.stash.photo.GnjMoveStashPhotoActivity"
android:exported="true"
tools:replace="android:exported" />
</application> </application>
</manifest> </manifest>

View File

@@ -375,6 +375,20 @@
android:name=".page.gnj.move.stash.list.GnjMoveStashListActivity" android:name=".page.gnj.move.stash.list.GnjMoveStashListActivity"
android:configChanges="orientation|keyboardHidden" android:configChanges="orientation|keyboardHidden"
android:screenOrientation="unspecified" /> android:screenOrientation="unspecified" />
<!-- 国内进港移库-运单详情5.5寸手机版专属) -->
<activity
android:name=".page.gnj.move.stash.detail.GnjMoveStashDetailActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="unspecified" />
<!-- 国内进港移库-拍照上传5.5寸手机版专属) -->
<activity
android:name=".page.gnj.move.stash.photo.GnjMoveStashPhotoActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="unspecified" />
<activity <activity
android:name=".page.gnj.stash.list.GnjStashListActivity" android:name=".page.gnj.stash.list.GnjStashListActivity"
android:configChanges="orientation|keyboardHidden" android:configChanges="orientation|keyboardHidden"
@@ -558,6 +572,13 @@
android:exported="false" android:exported="false"
android:screenOrientation="unspecified" /> android:screenOrientation="unspecified" />
<!-- 国际进港-提取出库-运单详情5.5寸手机版专属) -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpPickUpDetailActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="unspecified" />
<!-- 国际进港-进港查询 --> <!-- 国际进港-进港查询 -->
<activity <activity
android:name="com.lukouguoji.gjj.activity.IntImpQueryActivity" android:name="com.lukouguoji.gjj.activity.IntImpQueryActivity"

View File

@@ -0,0 +1,49 @@
package com.lukouguoji.aerologic.page.gnj.move.stash.detail
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.google.gson.Gson
import com.lukouguoji.aerologic.R
import com.lukouguoji.aerologic.databinding.ActivityGnjMoveStashDetailBinding
import com.lukouguoji.aerologic.page.gnj.move.stash.photo.GnjMoveStashPhotoActivity
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.bean.MoveStashBean
import com.lukouguoji.module_base.common.Constant
/**
* 国内进港移库「运单详情」5.5 寸手持端专属页面,无平板变体)
*
* 由列表卡片的「查看详情」进入;「异常照片」卡片的加号槽位跳拍照上传页。
* 展示字段全部由列表项带入Gson JSON零新增请求。
*/
class GnjMoveStashDetailActivity :
BaseBindingActivity<ActivityGnjMoveStashDetailBinding, GnjMoveStashDetailViewModel>() {
override fun layoutId() = R.layout.activity_gnj_move_stash_detail
override fun viewModelClass() = GnjMoveStashDetailViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("运单详情")
binding.viewModel = viewModel
binding.activity = this
viewModel.initOnCreated(intent)
}
/** 「异常照片」加号槽位 → 拍照上传页 */
fun openPhoto() {
viewModel.dataBean.value?.let {
GnjMoveStashPhotoActivity.start(this, it.mawbId, it.wbNo)
}
}
companion object {
@JvmStatic
fun start(context: Context, bean: MoveStashBean) {
context.startActivity(
Intent(context, GnjMoveStashDetailActivity::class.java)
.putExtra(Constant.Key.DATA, Gson().toJson(bean))
)
}
}
}

View File

@@ -0,0 +1,25 @@
package com.lukouguoji.aerologic.page.gnj.move.stash.detail
import android.content.Intent
import androidx.lifecycle.MutableLiveData
import com.google.gson.Gson
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.MoveStashBean
import com.lukouguoji.module_base.common.Constant
/**
* 国内进港移库「运单详情」ViewModel5.5 寸手持端专属页面)
*
* 列表项数据已包含详情页所需全部字段(含 isMoved 端点打标),直接由列表带入,不额外请求。
*/
class GnjMoveStashDetailViewModel : BaseViewModel() {
val dataBean = MutableLiveData(MoveStashBean())
fun initOnCreated(intent: Intent) {
val json = intent.getStringExtra(Constant.Key.DATA).orEmpty()
if (json.isNotEmpty()) {
dataBean.value = Gson().fromJson(json, MoveStashBean::class.java)
}
}
}

View File

@@ -1,36 +1,104 @@
package com.lukouguoji.aerologic.page.gnj.move.stash.list package com.lukouguoji.aerologic.page.gnj.move.stash.list
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import com.lukouguoji.aerologic.R import androidx.databinding.ObservableBoolean
import com.lukouguoji.aerologic.databinding.ActivityGnjMoveStashListBinding import com.alibaba.android.arouter.facade.annotation.Route
import com.lukouguoji.module_base.base.BaseBindingActivity import com.lukouguoji.aerologic.R
import com.lukouguoji.module_base.ktx.getLifecycleOwner import com.lukouguoji.aerologic.databinding.ActivityGnjMoveStashListBinding
import com.lukouguoji.aerologic.page.gnj.move.stash.photo.GnjMoveStashPhotoActivity
class GnjMoveStashListActivity : import com.lukouguoji.module_base.base.BaseBindingActivity
BaseBindingActivity<ActivityGnjMoveStashListBinding, GnjMoveStashListViewModel>() { import com.lukouguoji.module_base.bean.MoveStashBean
override fun layoutId() = R.layout.activity_gnj_move_stash_list import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.impl.FlowBus
override fun viewModelClass() = GnjMoveStashListViewModel::class.java import com.lukouguoji.module_base.impl.observe
import com.lukouguoji.module_base.ktx.getLifecycleOwner
override fun initOnCreate(savedInstanceState: Bundle?) { import com.lukouguoji.module_base.router.ARouterConstants
setBackArrow("国内进港移库") import com.lukouguoji.module_base.util.DeviceUtil
binding.viewModel = viewModel @Route(path = ARouterConstants.ACTIVITY_URL_GNJ_MOVE_STASH_LIST)
class GnjMoveStashListActivity :
viewModel.pageModel BaseBindingActivity<ActivityGnjMoveStashListBinding, GnjMoveStashListViewModel>() {
.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, getLifecycleOwner()) override fun layoutId() = R.layout.activity_gnj_move_stash_list
viewModel.refresh() override fun viewModelClass() = GnjMoveStashListViewModel::class.java
}
/** 筛选弹层显隐(仅手机 UI 状态,平板布局不绑定) */
companion object { val filterPanelVisible = ObservableBoolean(false)
@JvmStatic
fun start(context: Context) { override fun initOnCreate(savedInstanceState: Bundle?) {
val starter = Intent(context, GnjMoveStashListActivity::class.java) // 设计稿手机端标题为「进港移库」,平板保持原标题
context.startActivity(starter) setBackArrow(if (DeviceUtil.isPhone()) "进港移库" else "国内进港移库")
}
} binding.viewModel = viewModel
binding.activity = this
}
viewModel.pageModel
.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, getLifecycleOwner())
if (DeviceUtil.isPhone()) {
// 手机专属Tab 角标 + 特码字典等额外请求
viewModel.initPhoneExtras()
// 卡片勾选变化 → 更新全选状态与已选计数
FlowBus.with<String>(ConstantEvent.EVENT_CHECK_CHANGED).observe(this) {
viewModel.updateCheckAllStatus()
}
}
// 拍照上传等子页面完成后刷新列表(平板无发射方,观察无副作用)
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).observe(this) {
viewModel.refresh()
}
viewModel.refresh()
}
// ==================== 筛选弹层(仅手机) ====================
fun toggleFilterPanel() {
filterPanelVisible.set(!filterPanelVisible.get())
}
/** 筛选:重置(只清空弹层内条件,不影响 Tab 与顶部搜索框) */
fun resetFilter() {
viewModel.flightDate.value = ""
viewModel.flightNo.value = ""
viewModel.spCode.value = ""
viewModel.businessType.value = ""
}
fun confirmFilter() {
filterPanelVisible.set(false)
viewModel.refresh()
}
// ==================== 卡片长按「拍照」浮层(仅手机) ====================
/** 卡片长按展开操作浮层View.OnLongClickListener 要求返回 Boolean */
fun showCardActionPhone(bean: MoveStashBean): Boolean {
bean.actionMenuVisible.set(true)
return true
}
/** 点浮层空白处关闭 */
fun hideCardActionPhone(bean: MoveStashBean) {
bean.actionMenuVisible.set(false)
}
/** 浮层「拍照」→ 拍照上传页 */
fun openPhoto(bean: MoveStashBean) {
bean.actionMenuVisible.set(false)
GnjMoveStashPhotoActivity.start(this, bean.mawbId, bean.wbNo)
}
companion object {
@JvmStatic
fun start(context: Context) {
val starter = Intent(context, GnjMoveStashListActivity::class.java)
context.startActivity(starter)
}
}
}

View File

@@ -3,34 +3,64 @@ package com.lukouguoji.aerologic.page.gnj.move.stash.list
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
import com.lukouguoji.aerologic.databinding.ItemGnjMoveStashListBinding import com.lukouguoji.aerologic.databinding.ItemGnjMoveStashListBinding
import com.lukouguoji.aerologic.page.gnj.move.stash.detail.GnjMoveStashDetailActivity
import com.lukouguoji.gnj.page.yiku.handover.GnjYiKuHandoverActivity import com.lukouguoji.gnj.page.yiku.handover.GnjYiKuHandoverActivity
import com.lukouguoji.module_base.base.BaseViewHolder import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.MoveStashBean import com.lukouguoji.module_base.bean.MoveStashBean
import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.impl.FlowBus
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
/**
* 国内进港移库列表项 ViewHolder双形态共用
*
* 平板/手机布局差异较大,单侧独有的控件 id 在 Binding 基类中为 @Nullable
* 全部走判空调用平板swipe_menu/btn_edit/ll手机ll_detail
*/
class GnjMoveStashListViewHolder(view: View) : class GnjMoveStashListViewHolder(view: View) :
BaseViewHolder<MoveStashBean, ItemGnjMoveStashListBinding>(view) { BaseViewHolder<MoveStashBean, ItemGnjMoveStashListBinding>(view) {
override fun onBind(item: Any?, position: Int) { override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item)!! val bean = getItemBean(item)!!
binding.bean = bean binding.bean = bean
binding.position = position
binding.activity = itemView.context as? GnjMoveStashListActivity
// 勾选框(双形态共有):切换选中;手机端另行广播刷新全选/已选计数
binding.ivIcon.setOnClickListener { binding.ivIcon.setOnClickListener {
bean.checked.set(!bean.checked.get()) bean.checked.set(!bean.checked.get())
binding.executePendingBindings()
GlobalScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_CHECK_CHANGED).emit("check_changed")
}
} }
// ===== 平板独有交互 =====
// 点击列表项进入移交详情 // 点击列表项进入移交详情
binding.ll.setOnClickListener { binding.ll?.setOnClickListener {
GnjYiKuHandoverActivity.startForDetails(itemView.context, bean.mawbId) GnjYiKuHandoverActivity.startForDetails(itemView.context, bean.mawbId)
} }
// 侧滑菜单 - 编辑按钮 // 侧滑菜单 - 编辑按钮
binding.btnEdit.setOnClickListener { binding.btnEdit?.setOnClickListener {
binding.swipeMenu.quickClose() binding.swipeMenu?.quickClose()
if (bean.pickFlag == "1") { if (bean.pickFlag == "1") {
Toast.makeText(itemView.context, "已出库,不可编辑", Toast.LENGTH_SHORT).show() Toast.makeText(itemView.context, "已出库,不可编辑", Toast.LENGTH_SHORT).show()
return@setOnClickListener return@setOnClickListener
} }
GnjYiKuHandoverActivity.startForEdit(itemView.context, bean.mawbId) GnjYiKuHandoverActivity.startForEdit(itemView.context, bean.mawbId)
} }
// ===== 手机独有交互 =====
// 「查看详情」→ 手机版运单详情页
binding.llDetail?.setOnClickListener {
GnjMoveStashDetailActivity.start(itemView.context, bean)
}
binding.executePendingBindings()
} }
} }

View File

@@ -49,6 +49,41 @@ class GnjMoveStashListViewModel : BasePageViewModel() {
val number = MutableLiveData("0") val number = MutableLiveData("0")
val weight = MutableLiveData("0") val weight = MutableLiveData("0")
// ========== 5.5 寸手持端专属字段(平板布局不绑定,默认值保证平板行为零变化) ==========
/** 移库状态 Tab"0" 待移库DomImpMove/search/ "1" 已移库DomImpMove/searchMoved */
val moveState = MutableLiveData("0")
/** 手机筛选弹层:航班日期 / 航班号 / 特码(默认空 → 不进请求) */
val flightDate = MutableLiveData("")
val flightNo = MutableLiveData("")
val spCode = MutableLiveData("")
val spCodeList = MutableLiveData<List<KeyValue>>(emptyList())
val moveStateTabs = MutableLiveData(
listOf(KeyValue("待移库", "0"), KeyValue("已移库", "1"))
)
/** 状态 Tab 角标(与 [moveStateTabs] 等长,取两端点分页 total */
val moveStateCounts = MutableLiveData(listOf("", ""))
/** 底部操作条「已选 N 项」 */
val selectedCount = MutableLiveData("0")
/** 全选状态(手机 PhoneBottomBar 勾选图标) */
val isAllChecked = MutableLiveData(false)
/** 手机专属的额外请求Tab 角标、特码字典)开关,仅手机形态在 Activity 中开启 */
private var phoneExtrasEnabled = false
fun initPhoneExtras() {
phoneExtrasEnabled = true
// 特码字典flag=0 国内、ieFlag=I 进港(是否生效待实测,见问题清单)
DictUtils.getSpecialCodeList(addAll = false, flag = 0, ieFlag = "I") { list ->
spCodeList.postValue(listOf(KeyValue("全部", "")) + list)
}
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// 方法区 // 方法区
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@@ -95,25 +130,73 @@ class GnjMoveStashListViewModel : BasePageViewModel() {
} }
/** 查询条件分页参数除外search / searchMoved / searchTotal 三处共用同一套入参 */
private fun buildFilterParams(): Map<String, Any?> = mapOf(
"awbType" to businessType.value!!.ifEmpty { null },
"wbNo" to waybill.value!!.ifEmpty { null },
"carrier" to carrier.value!!.ifEmpty { null },
// 以下为手机筛选弹层字段,平板恒为空串 → 恒传 null行为不变
"fdate" to flightDate.value?.ifEmpty { null },
"fno" to flightNo.value?.ifEmpty { null },
"spCode" to spCode.value?.ifEmpty { null },
)
override fun getData() { override fun getData() {
val body = mapOf( val body = (buildFilterParams() + mapOf(
"page" to pageModel.page, "page" to pageModel.page,
"limit" to pageModel.limit, "limit" to pageModel.limit,
"awbType" to businessType.value!!.ifEmpty { null }, )).toRequestBody()
"wbNo" to waybill.value!!.ifEmpty { null }, val moved = moveState.value == "1"
"carrier" to carrier.value!!.ifEmpty { null },
).toRequestBody()
launchLoadingCollect({ launchLoadingCollect({
NetApply.api.getGnjMoveStashList( // 平板 moveState 恒为 "0" → 恒走 search原行为已移库 Tab 走 searchMoved
body if (moved) NetApply.api.getGnjMoveStashMovedList(body)
) else NetApply.api.getGnjMoveStashList(body)
}) { }) {
onSuccess = { onSuccess = {
pageModel.handleListBean(it) // searchMoved 出参无移库标识,按端点打标(卡片形态/详情移库信息卡依赖)
it.list?.forEach { bean -> bean.isMoved = moved }
pageModel.handleListBean(it) { updateCheckAllStatus() }
count.value = it.total count.value = it.total
} }
} }
getCountData(body) getCountData(body)
if (phoneExtrasEnabled) loadTabCounts()
}
/** Tab 角标search / searchMoved 各以 limit=1 查一次取分页 total仅手机形态发起 */
private fun loadTabCounts() {
val body = (buildFilterParams() + mapOf("page" to 1, "limit" to 1)).toRequestBody()
launchCollect({ NetApply.api.getGnjMoveStashList(body) }) {
onSuccess = { updateTabCount(0, it.total) }
}
launchCollect({ NetApply.api.getGnjMoveStashMovedList(body) }) {
onSuccess = { updateTabCount(1, it.total) }
}
}
private fun updateTabCount(index: Int, total: Int?) {
val current = moveStateCounts.value?.toMutableList() ?: mutableListOf("", "")
if (index < current.size) {
current[index] = (total ?: 0).toString()
moveStateCounts.value = current
}
}
// ========== 手机端全选 / 已选计数 ==========
fun toggleSelectAll() {
val list = pageModel.rv?.commonAdapter()?.items
?.filterIsInstance<MoveStashBean>() ?: return
CheckUtil.handleAllCheck(list)
updateCheckAllStatus()
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
}
fun updateCheckAllStatus() {
val list = pageModel.rv?.commonAdapter()?.items
?.filterIsInstance<MoveStashBean>() ?: return
isAllChecked.value = list.isNotEmpty() && list.all { it.checked.get() }
selectedCount.value = list.count { it.checked.get() }.toString()
} }
private fun getCountData(body: RequestBody) { private fun getCountData(body: RequestBody) {

View File

@@ -0,0 +1,45 @@
package com.lukouguoji.aerologic.page.gnj.move.stash.photo
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.lukouguoji.aerologic.R
import com.lukouguoji.aerologic.databinding.ActivityGnjMoveStashPhotoBinding
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.ktx.addOnItemClickListener
/**
* 国内进港移库「拍照上传」5.5 寸手持端专属页面,无平板变体)
*
* 由列表卡片长按浮层「拍照」或运单详情「异常照片」加号槽位进入。
* 已有照片经 DomImpMove/detail 回填,提交走 DomImpMove/modify
* mawbId + pic/originalPic/picNumber 三字段规范,与平板移交编辑页同一链路)。
*/
class GnjMoveStashPhotoActivity :
BaseBindingActivity<ActivityGnjMoveStashPhotoBinding, GnjMoveStashPhotoViewModel>() {
override fun layoutId() = R.layout.activity_gnj_move_stash_photo
override fun viewModelClass() = GnjMoveStashPhotoViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("拍照上传")
binding.viewModel = viewModel
viewModel.rv = binding.rv
binding.rv.addOnItemClickListener(viewModel)
viewModel.initOnCreated(intent)
}
companion object {
@JvmStatic
fun start(context: Context, mawbId: String, wbNo: String) {
context.startActivity(
Intent(context, GnjMoveStashPhotoActivity::class.java)
.putExtra(Constant.Key.ID, mawbId)
.putExtra(Constant.Key.CODE, wbNo)
)
}
}
}

View File

@@ -0,0 +1,174 @@
package com.lukouguoji.aerologic.page.gnj.move.stash.photo
import android.content.Intent
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import androidx.recyclerview.widget.RecyclerView
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.FileBean
import com.lukouguoji.module_base.bean.GnjYiKuBean
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.impl.ImageSelectNewViewHolder
import com.lukouguoji.module_base.interfaces.IOnItemClickListener
import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.launchLoadingCollect
import com.lukouguoji.module_base.ktx.noNull
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.util.MediaUtil
import com.lukouguoji.module_base.util.UploadUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
/**
* 国内进港移库「拍照上传」ViewModel5.5 寸手持端专属页面)
*
* 图片选择/预览/删除复用 module_base 的 ImageSelectNewViewHolder末位加号槽位
* 已有照片经 DomImpMove/detail 回填;提交走 DomImpMove/modify 最小体
* mawbId/remark/picNumber/pic/originalPic与平板移交编辑页同一链路。
*/
class GnjMoveStashPhotoViewModel : BaseViewModel(), IOnItemClickListener {
var mawbId = ""
/** 运单号(副标题展示,由列表带入) */
val wbNo = MutableLiveData("")
/** detail 回填的完整 bean提交时保留 remark 等原值) */
private var detailBean = GnjYiKuBean()
// 图片网格适配器配置(复用公共图片选择组件)
val itemViewHolder = ImageSelectNewViewHolder::class.java
val itemLayoutId = com.lukouguoji.module_base.R.layout.item_image_select_new
var rv: RecyclerView? = null
fun initOnCreated(intent: Intent) {
mawbId = intent.getStringExtra(Constant.Key.ID).orEmpty()
wbNo.value = intent.getStringExtra(Constant.Key.CODE).orEmpty()
// 已有照片回填pic 缩略图 + originalPic 原图),末位补加号槽位
launchCollect({ NetApply.api.getGnjMoveStashDetail(mawbId) }) {
onSuccess = {
detailBean = it.data ?: GnjYiKuBean()
val picList = detailBean.pic.split(",").filter { p -> p.isNotEmpty() }
val originalList = detailBean.originalPic.split(",").filter { p -> p.isNotEmpty() }
val images = picList.mapIndexed { index, picUrl ->
FileBean(
path = MediaUtil.fillUrl(picUrl),
url = picUrl,
originalPic = MediaUtil.fillUrl(originalList.getOrElse(index) { picUrl })
)
}
rv?.post {
rv?.commonAdapter()?.refresh(images + FileBean())
}
}
onFailed = { _, _ ->
// 详情取不到也允许直接新增照片
rv?.post { rv?.commonAdapter()?.refresh(listOf(FileBean())) }
}
}
}
/**
* 确认提交:先补传未上传的本地图片,再按三字段规范提交 modify
*/
fun submitClick() {
(rv?.commonAdapter()?.items ?: emptyList())
.asFlow()
.map { it as FileBean }
.filter { it.path.isNotEmpty() && it.url.isEmpty() }
.onEach {
val data = UploadUtil.upload(it.path).data
// UploadUtil 返回newName=原图(较大)zipFileName=缩略图(较小)
it.url = data?.zipFileName ?: ""
it.originalPic = data?.newName ?: ""
}
.flowOn(Dispatchers.IO)
.onStart { showLoading() }
.catch {
showToast(it.message.noNull("上传图片失败"))
dismissLoading()
}
.onCompletion {
launchLoadingCollect({
val list = (rv?.commonAdapter()?.items ?: emptyList())
.filterIsInstance<FileBean>()
.filter { it.path.isNotEmpty() }
// 最小体提交只更新图片三字段remark 保留 detail 原值),与平板移交编辑页一致
val params = mapOf(
"mawbId" to mawbId,
"remark" to detailBean.remark,
"picNumber" to list.size.toString(),
"pic" to list.joinToString(",") { MediaUtil.removeUrl(it.url) },
"originalPic" to list.joinToString(",") { MediaUtil.removeUrl(it.originalPic) },
).toRequestBody(removeEmptyOrNull = true)
NetApply.api.modifyGnjMoveStash(params)
}) {
onSuccess = {
showToast("提交成功")
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
getTopActivity().finish()
}
onFailed = { _, msg ->
showToast(msg.noNull("提交失败"))
}
}
}
.launchIn(viewModelScope)
}
/**
* 「拍照/上传」按钮:直接唤起图片选择(含拍照入口)
*/
fun pickClick() {
MediaUtil.pickImage(getTopActivity(), maxNum = 9) { results ->
val adapter = rv?.commonAdapter() ?: return@pickImage
results.forEach { result ->
// 在加号槽位(最后一项)之前插入
val insertPos = (adapter.items.size - 1).coerceAtLeast(0)
adapter.items.add(insertPos, FileBean(path = result.realPath))
adapter.notifyItemInserted(insertPos)
}
}
}
/**
* 图片网格点击回调(长按出删除角标 / 点删除角标移除)
*/
override fun onItemClick(position: Int, type: Int) {
val adapter = rv?.commonAdapter() ?: return
val bean = adapter.getItem(position) as? FileBean ?: return
when (type) {
com.lukouguoji.module_base.R.id.rl -> {
if (bean.path.isNotEmpty()) {
bean.canDelete.set(!bean.canDelete.get())
}
}
com.lukouguoji.module_base.R.id.iv_delete -> {
adapter.removeItem(position)
}
else -> {}
}
}
}

View File

@@ -91,7 +91,9 @@ class LogDetailActivity : BaseBindingActivity<ActivityLogDetailBinding, LogDetai
val step = steps[i] val step = steps[i]
val isActive = step.code in activeCodes val isActive = step.code in activeCodes
val isLast = i == steps.size - 1 val isLast = i == steps.size - 1
val time = logs.lastOrNull { it.status == step.code }?.opDate ?: "" val stepLog = logs.lastOrNull { it.status == step.code }
val time = stepLog?.opDate ?: ""
val statusContent = stepLog?.content ?: ""
val row = LinearLayout(this).apply { val row = LinearLayout(this).apply {
orientation = LinearLayout.HORIZONTAL orientation = LinearLayout.HORIZONTAL
@@ -141,12 +143,41 @@ class LogDetailActivity : BaseBindingActivity<ActivityLogDetailBinding, LogDetai
} }
setPadding(0, 0, 0, if (isLast) 0 else dp(24)) setPadding(0, 0, 0, if (isLast) 0 else dp(24))
} }
content.addView(TextView(this).apply { // 名称行:步骤名(左)+ 已发生节点的状态 pill设计稿如「放行状态01」
val nameRow = LinearLayout(this).apply {
orientation = LinearLayout.HORIZONTAL
gravity = Gravity.CENTER_VERTICAL
layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
}
nameRow.addView(TextView(this).apply {
text = step.name text = step.name
setTextSize(TypedValue.COMPLEX_UNIT_SP, 15f) setTextSize(TypedValue.COMPLEX_UNIT_SP, 15f)
setTextColor(if (isActive) colorGreen else colorGray) setTextColor(if (isActive) colorGreen else colorGray)
if (isActive) setTypeface(typeface, android.graphics.Typeface.BOLD) if (isActive) setTypeface(typeface, android.graphics.Typeface.BOLD)
layoutParams = LinearLayout.LayoutParams(
0, LinearLayout.LayoutParams.WRAP_CONTENT
).apply { weight = 1f }
}) })
if (isActive && statusContent.isNotEmpty()) {
nameRow.addView(TextView(this).apply {
text = statusContent
setTextSize(TypedValue.COMPLEX_UNIT_SP, 11f)
setTextColor(colorGreen)
setBackgroundResource(com.lukouguoji.module_base.R.drawable.bg_phone_tag_green)
setPadding(dp(8), dp(3), dp(8), dp(3))
maxLines = 1
ellipsize = android.text.TextUtils.TruncateAt.END
maxWidth = dp(180)
layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT
).apply { leftMargin = dp(8) }
})
}
content.addView(nameRow)
if (time.isNotEmpty()) { if (time.isNotEmpty()) {
content.addView(TextView(this).apply { content.addView(TextView(this).apply {
text = time text = time

View File

@@ -0,0 +1,153 @@
<?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="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType" />
<variable
name="viewModel"
type="com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListViewModel" />
<!-- 平板不使用,仅为与手机变体保持 <variable> 一致DataBinding 双变体强制约束) -->
<variable
name="activity"
type="com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListActivity" />
</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" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:gravity="center_vertical">
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请选择业务类型"}'
list="@{viewModel.businessTypeList}"
type="@{SearchLayoutType.SPINNER}"
value="@={viewModel.businessType}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请输入运单号"}'
icon="@{@drawable/img_scan}"
setInputWaybill="@{true}"
setOnIconClickListener="@{()-> viewModel.waybillScanClick()}"
setRefreshCallBack="@{viewModel::refresh}"
setSearchListRefresh="@{viewModel::getWayBillList}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.waybill}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请输入承运人"}'
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.carrier}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<ImageView
style="@style/iv_search_action"
android:onClick="@{()-> viewModel.refresh()}"
android:src="@drawable/img_search" />
</LinearLayout>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:onClick="@{()->viewModel.checkAllClick()}"
android:text="全选" />
<ImageView
android:id="@+id/checkIcon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="5dp"
android:onClick="@{()->viewModel.checkAllClick()}"
android:src="@drawable/img_check_all" />
</androidx.appcompat.widget.LinearLayoutCompat>
<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"
itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_gnj_move_stash_list" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/color_bottom_layout"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text='@{"合计:"+viewModel.count+"条,总件数:"+viewModel.number+",总重量:"+viewModel.weight+"KG"}'
android:textColor="@color/white"
android:textSize="18sp"
android:textStyle="bold"
tools:text="合计3条总件数212总重量342KG" />
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()-> viewModel.moveStashClick()}"
android:text="移库" />
</LinearLayout>
</LinearLayout>
</layout>

View File

@@ -0,0 +1,296 @@
<?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>
<variable
name="bean"
type="com.lukouguoji.module_base.bean.MoveStashBean" />
<!-- 以下两个变量平板不使用,仅为与手机变体保持 <variable> 一致DataBinding 双变体强制约束) -->
<variable
name="position"
type="Integer" />
<variable
name="activity"
type="com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListActivity" />
</data>
<!-- 外层容器承载间距 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="5dp"
android:orientation="vertical">
<!-- 侧滑布局 -->
<com.mcxtzhang.swipemenulib.SwipeMenuLayout
android:id="@+id/swipe_menu"
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:background="@drawable/bg_item"
android:orientation="horizontal"
android:padding="10dp">
<ImageView
android:id="@+id/iv_icon"
loadImage="@{bean.checked ? @drawable/img_plane_s : @drawable/img_plane}"
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_marginLeft="10dp"
android:layout_weight="1"
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
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单号:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.wbNo}"
android:textColor="@color/colorPrimary"
tools:text="789165431" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="件数:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.pc}' />
</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
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="重量:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.weight}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="代理人:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.agentCode}' />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单类型:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.awbType}' />
</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
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="航班:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.flight}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="始发港:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.origin}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="起始站:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.dep}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="目的港:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.dest}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="品名:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.goods}" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</LinearLayout>
<!-- 右侧箭头 -->
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:src="@drawable/img_pda_right" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 侧滑菜单区域 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- 编辑按钮 -->
<TextView
android:id="@+id/btn_edit"
style="@style/tv_item_action"
android:background="@color/colorPrimary"
android:text="编辑" />
</androidx.appcompat.widget.LinearLayoutCompat>
</com.mcxtzhang.swipemenulib.SwipeMenuLayout>
</LinearLayout>
</layout>

View File

@@ -0,0 +1,332 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
国内进港移库「运单详情」—— 5.5 寸手持端专属页面(无平板变体)
对应设计稿 11_进港移库 的「运单详情」页:
· 卡片一:蓝色表头(运单号 + 绿点 + 操作时间)+ 类型标签行(红「运单类型」+ 货物类型)
+ 品名大字 + 两列字段网格(件数/重量/特码/代理/出运路径/承运人)
· 卡片二:绿色表头「移库信息」+ 移库人 / 移库时间(仅已移库显示)
· 卡片三:橙色表头「异常照片」+ 三个虚线加号槽位(点击跳拍照上传页)
-->
<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.aerologic.page.gnj.move.stash.detail.GnjMoveStashDetailViewModel" />
<variable
name="activity"
type="com.lukouguoji.aerologic.page.gnj.move.stash.detail.GnjMoveStashDetailActivity" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/phone_page_bg"
android:orientation="vertical">
<include layout="@layout/title_tool_bar" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- ==================== 卡片一:运单基本信息 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_phone_card"
android:orientation="vertical">
<!-- 蓝色表头:运单号 + 绿点 + 操作时间 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_phone_card_header_blue"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="16dp"
android:paddingVertical="12dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{viewModel.dataBean.wbNo}"
android:textColor="@color/white"
android:textSize="17sp"
android:textStyle="bold" />
<View
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginEnd="6dp"
android:background="@drawable/bg_phone_dot_green" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.dataBean.orDash(viewModel.dataBean.opDate)}"
android:textColor="@color/white"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- 类型标签行:运单类型(红标签) + 货物类型 -->
<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="22dp"
android:background="@drawable/bg_phone_tag_red"
android:gravity="center"
android:paddingHorizontal="8dp"
android:text="@{viewModel.dataBean.orDash(viewModel.dataBean.awbType)}"
android:textColor="@color/phone_tag_red_text"
android:textSize="12sp"
android:textStyle="bold" />
<View
android:layout_width="1dp"
android:layout_height="14dp"
android:layout_marginHorizontal="10dp"
android:background="@color/phone_divider" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{viewModel.dataBean.orDash(viewModel.dataBean.cargoType)}"
android:textColor="@color/phone_text_body"
android:textSize="14sp" />
</LinearLayout>
<!-- 品名(主字段大字) -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:text="@{viewModel.dataBean.orDash(viewModel.dataBean.goods)}"
android:textColor="@color/phone_text_strong"
android:textSize="22sp"
android:textStyle="bold" />
<!-- 第 1 行:件数 / 重量 -->
<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.dataBean.orDash(viewModel.dataBean.pc)}" />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_weight="1"
title='@{"重量"}'
value='@{viewModel.dataBean.orDash(viewModel.dataBean.weight) + " kg"}' />
</LinearLayout>
<!-- 第 2 行:特码 / 代理 -->
<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.dataBean.spCode}" />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_weight="1"
title='@{"代理"}'
value="@{viewModel.dataBean.agentDisplay}" />
</LinearLayout>
<!-- 第 3 行:出运路径 / 承运人 -->
<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.dataBean.range}" />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_weight="1"
title='@{"承运人"}'
value="@{viewModel.dataBean.by1}" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- ==================== 卡片二:移库信息(仅已移库显示) ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/bg_phone_card"
android:orientation="vertical"
android:visibility="@{viewModel.dataBean.isMoved ? View.VISIBLE : View.GONE}">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_phone_card_header_green"
android:paddingHorizontal="16dp"
android:paddingVertical="10dp"
android:text="移库信息"
android:textColor="@color/white"
android:textSize="15sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingHorizontal="16dp"
android:paddingVertical="12dp">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"移库人"}'
value="@{viewModel.dataBean.opId}" />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_weight="1"
title='@{"移库时间"}'
value="@{viewModel.dataBean.opDate}" />
</LinearLayout>
</LinearLayout>
<!-- ==================== 卡片三:异常照片 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/bg_phone_card"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_phone_card_header_orange"
android:paddingHorizontal="16dp"
android:paddingVertical="10dp"
android:text="异常照片"
android:textColor="@color/white"
android:textSize="15sp"
android:textStyle="bold" />
<!-- 三个虚线加号槽位(等宽正方形由 weight + 固定高实现),点击进拍照上传页 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp">
<TextView
android:layout_width="0dp"
android:layout_height="96dp"
android:layout_weight="1"
android:background="@drawable/bg_phone_photo_add"
android:gravity="center"
android:onClick="@{()-> activity.openPhoto()}"
android:text="+"
android:textColor="@color/phone_text_hint"
android:textSize="24sp" />
<TextView
android:layout_width="0dp"
android:layout_height="96dp"
android:layout_marginStart="12dp"
android:layout_weight="1"
android:background="@drawable/bg_phone_photo_add"
android:gravity="center"
android:onClick="@{()-> activity.openPhoto()}"
android:text="+"
android:textColor="@color/phone_text_hint"
android:textSize="24sp" />
<TextView
android:layout_width="0dp"
android:layout_height="96dp"
android:layout_marginStart="12dp"
android:layout_weight="1"
android:background="@drawable/bg_phone_photo_add"
android:gravity="center"
android:onClick="@{()-> activity.openPhoto()}"
android:text="+"
android:textColor="@color/phone_text_hint"
android:textSize="24sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
</layout>

View File

@@ -1,148 +1,166 @@
<?xml version="1.0" encoding="utf-8"?> <?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 寸手持端布局(平板变体见 layout-sw600dp/ 同名文件)
xmlns:tools="http://schemas.android.com/tools">
对应设计稿 documents/5.5寸手持端设计文件/11_进港移库/进港移库.html
<data> · 顶部搜索框(运单号,含扫码)+ 筛选弹层(航班日期 / 航班号 / 特码 / 运单类型)
· 「待移库 / 已移库」Tab 绑定 viewModel.moveState"0"/"1"
<import type="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType" /> 分别走 DomImpMove/search 与 DomImpMove/searchMoved 两个端点
· 已移库 Tab 下隐藏底部操作条(与设计稿一致)
<variable · 卡片长按出「拍照」浮层(见 item_gnj_move_stash_list.xml
name="viewModel" -->
type="com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListViewModel" /> <layout xmlns:android="http://schemas.android.com/apk/res/android"
</data> xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:layout_width="match_parent" <data>
android:layout_height="match_parent"
android:background="@color/color_f2" <import type="android.view.View" />
android:orientation="vertical">
<import type="com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayoutType" />
<include layout="@layout/title_tool_bar" />
<variable
<LinearLayout name="viewModel"
android:layout_width="match_parent" type="com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListViewModel" />
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp" <variable
android:layout_marginTop="10dp" name="activity"
android:gravity="center_vertical"> type="com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListActivity" />
</data>
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请选择业务类型"}' <FrameLayout
list="@{viewModel.businessTypeList}" android:layout_width="match_parent"
type="@{SearchLayoutType.SPINNER}" android:layout_height="match_parent"
value="@={viewModel.businessType}" android:background="@color/phone_page_bg">
android:layout_width="0dp"
android:layout_height="wrap_content" <LinearLayout
android:layout_weight="1" /> android:layout_width="match_parent"
android:layout_height="match_parent"
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout android:orientation="vertical">
hint='@{"请输入运单号"}'
icon="@{@drawable/img_scan}" <include layout="@layout/title_tool_bar" />
setInputWaybill="@{true}"
setOnIconClickListener="@{()-> viewModel.waybillScanClick()}" <!-- ==================== 搜索行 ==================== -->
setRefreshCallBack="@{viewModel::refresh}" <LinearLayout
setSearchListRefresh="@{viewModel::getWayBillList}" android:layout_width="match_parent"
type="@{SearchLayoutType.INPUT}" android:layout_height="wrap_content"
value="@={viewModel.waybill}" android:background="@color/white"
android:layout_width="0dp" android:orientation="vertical"
android:layout_height="wrap_content" android:paddingHorizontal="16dp"
android:layout_weight="1" /> android:paddingTop="16dp"
android:paddingBottom="12dp">
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请输入承运人"}' <com.lukouguoji.module_base.ui.weight.phone.PhoneSearchBar
type="@{SearchLayoutType.INPUT}" android:layout_width="match_parent"
value="@={viewModel.carrier}" android:layout_height="wrap_content"
android:layout_width="0dp" hint='@{"搜索运单号"}'
android:layout_height="wrap_content" setOnFilterClickListener="@{(v)-> activity.toggleFilterPanel()}"
android:layout_weight="1" /> setOnScanClickListener="@{(v)-> viewModel.waybillScanClick()}"
setRefreshCallBack="@{viewModel::refresh}"
<LinearLayout upperCase="@{true}"
android:layout_width="0dp" value="@={viewModel.waybill}" />
android:layout_height="wrap_content"
android:layout_weight="1"> </LinearLayout>
<ImageView <!-- ==================== 待移库 / 已移库 Tab ==================== -->
style="@style/iv_search_action" <com.lukouguoji.module_base.ui.weight.phone.PhoneStatusTab
android:onClick="@{()-> viewModel.refresh()}" android:layout_width="match_parent"
android:src="@drawable/img_search" /> android:layout_height="wrap_content"
counts="@{viewModel.moveStateCounts}"
</LinearLayout> setOnTabChanged="@{viewModel::refresh}"
tabs="@{viewModel.moveStateTabs}"
<View value="@={viewModel.moveState}" />
android:layout_width="0dp"
android:layout_height="0dp" <View
android:layout_weight="1" /> android:layout_width="match_parent"
android:layout_height="1px"
<View android:background="@color/phone_divider" />
android:layout_width="0dp"
android:layout_height="0dp" <!-- ==================== 列表 ==================== -->
android:layout_weight="1" /> <com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/srl"
</LinearLayout> android:layout_width="match_parent"
<androidx.appcompat.widget.LinearLayoutCompat android:layout_height="0dp"
android:layout_width="match_parent" android:layout_weight="1">
android:layout_height="wrap_content"
android:gravity="center_vertical" <androidx.recyclerview.widget.RecyclerView
android:paddingTop="10dp"> android:id="@+id/rv"
android:layout_width="match_parent"
<TextView android:layout_height="match_parent"
android:layout_width="wrap_content" android:clipToPadding="false"
android:layout_height="wrap_content" android:overScrollMode="never"
android:layout_marginLeft="15dp" android:paddingBottom="12dp"
android:onClick="@{()->viewModel.checkAllClick()}" itemLayoutId="@{viewModel.itemLayoutId}"
android:text="全选" /> viewHolder="@{viewModel.itemViewHolder}"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
<ImageView tools:itemCount="3"
android:id="@+id/checkIcon" tools:listitem="@layout/item_gnj_move_stash_list" />
android:layout_width="30dp"
android:layout_height="30dp" </com.scwang.smart.refresh.layout.SmartRefreshLayout>
android:layout_marginLeft="5dp"
android:onClick="@{()->viewModel.checkAllClick()}" <!-- ==================== 底部操作条(已移库 Tab 下隐藏) ==================== -->
android:src="@drawable/img_check_all" /> <com.lukouguoji.module_base.ui.weight.phone.PhoneBottomBar
android:layout_width="match_parent"
</androidx.appcompat.widget.LinearLayoutCompat> android:layout_height="wrap_content"
actionText='@{"移库"}'
<com.scwang.smart.refresh.layout.SmartRefreshLayout allChecked="@{viewModel.isAllChecked}"
android:id="@+id/srl" countText='@{"已选 " + viewModel.selectedCount + " 项"}'
android:layout_width="match_parent" setOnActionClick="@{(v)-> viewModel.moveStashClick()}"
android:layout_height="0dp" setOnAllCheckClick="@{(v)-> viewModel.toggleSelectAll()}"
android:layout_weight="1"> android:visibility="@{`1`.equals(viewModel.moveState) ? View.GONE : View.VISIBLE}" />
<androidx.recyclerview.widget.RecyclerView </LinearLayout>
android:id="@+id/rv"
itemLayoutId="@{viewModel.itemLayoutId}" <!-- ==================== 筛选弹层 ==================== -->
viewHolder="@{viewModel.itemViewHolder}" <com.lukouguoji.module_base.ui.weight.phone.PhoneFilterPanel
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" panelVisible="@{activity.filterPanelVisible}"
tools:listitem="@layout/item_gnj_move_stash_list" /> setOnConfirmClick="@{(v)-> activity.confirmFilter()}"
setOnDismissClick="@{(v)-> activity.toggleFilterPanel()}"
</com.scwang.smart.refresh.layout.SmartRefreshLayout> setOnResetClick="@{(v)-> activity.resetFilter()}"
title='@{"筛选条件"}'>
<LinearLayout
android:layout_width="match_parent" <!-- 航班日期(入参 fdate -->
android:layout_height="50dp" <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:background="@color/color_bottom_layout" android:layout_width="match_parent"
android:gravity="center_vertical" android:layout_height="wrap_content"
android:paddingHorizontal="15dp"> hint='@{"请选择航班日期"}'
title='@{"航班日期"}'
<TextView type="@{PhoneDataLayoutType.DATE}"
android:layout_width="0dp" value="@={viewModel.flightDate}" />
android:layout_height="wrap_content"
android:layout_weight="1" <!-- 航班号(入参 fno -->
android:text='@{"合计:"+viewModel.count+"条,总件数:"+viewModel.number+",总重量:"+viewModel.weight+"KG"}' <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:textColor="@color/white" android:layout_width="match_parent"
android:textSize="18sp" android:layout_height="wrap_content"
android:textStyle="bold" hint='@{"请输入航班号"}'
tools:text="合计3条总件数212总重量342KG" /> title='@{"航班号"}'
type="@{PhoneDataLayoutType.INPUT}"
<TextView value="@={viewModel.flightNo}" />
style="@style/tv_bottom_btn"
android:onClick="@{()-> viewModel.moveStashClick()}" <!-- 特码(入参 spCode -->
android:text="移库" /> <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_width="match_parent"
</LinearLayout> android:layout_height="wrap_content"
hint='@{"请选择特码"}'
</LinearLayout> list="@{viewModel.spCodeList}"
</layout> title='@{"特码"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.spCode}" />
<!-- 运单类型(入参 awbType复用平板既有 businessType 字段与字典) -->
<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.PhoneFilterPanel>
</FrameLayout>
</layout>

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
国内进港移库「拍照上传」—— 5.5 寸手持端专属页面(无平板变体)
对应设计稿 11_进港移库/photo.html
· 白卡「运单照片上传」+ 图片预览网格(复用公共 ImageSelectNewViewHolder末位加号槽位
· 底部两个按钮:拍照/上传(蓝) + 确认提交(绿)
提交走 DomImpMove/modifypic/originalPic/picNumber 三字段规范)。
-->
<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>
<variable
name="viewModel"
type="com.lukouguoji.aerologic.page.gnj.move.stash.photo.GnjMoveStashPhotoViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/phone_page_bg"
android:orientation="vertical">
<include layout="@layout/title_tool_bar" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_phone_card"
android:orientation="vertical"
android:padding="16dp">
<!-- 标题:运单照片上传(副行展示运单号) -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单照片上传"
android:textColor="@color/phone_text_strong"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@{viewModel.wbNo}"
android:textColor="@color/phone_text_body"
android:textSize="13sp"
tools:text="78133363573" />
<!-- 图片预览网格(末位加号槽位,长按出删除角标) -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:overScrollMode="never"
itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="3"
tools:itemCount="3" />
<!-- 底部按钮:拍照/上传(蓝) + 确认提交(绿) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="44dp"
android:layout_weight="1"
android:background="@drawable/bg_phone_btn_primary"
android:gravity="center"
android:onClick="@{()-> viewModel.pickClick()}"
android:text="拍照/上传"
android:textColor="@color/white"
android:textSize="15sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="44dp"
android:layout_marginStart="12dp"
android:layout_weight="1"
android:background="@drawable/bg_phone_btn_green"
android:gravity="center"
android:onClick="@{()-> viewModel.submitClick()}"
android:text="确认提交"
android:textColor="@color/white"
android:textSize="15sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
</layout>

View File

@@ -160,17 +160,6 @@
type="@{viewModel.pageType == DetailsPageType.Details ? PhoneFormRowType.TEXT : PhoneFormRowType.SELECT}" type="@{viewModel.pageType == DetailsPageType.Details ? PhoneFormRowType.TEXT : PhoneFormRowType.SELECT}"
value="@={viewModel.uldBean.carrier}" /> value="@={viewModel.uldBean.carrier}" />
<!-- 来源(后端字段暂不支持,已登记清单;提交后端忽略) -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneFormRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
enable="@{viewModel.pageType != DetailsPageType.Details}"
hint='@{"请选择来源"}'
list="@{viewModel.sourceEditList}"
title='@{"来源"}'
type="@{viewModel.pageType == DetailsPageType.Details ? PhoneFormRowType.TEXT : PhoneFormRowType.SELECT}"
value="@={viewModel.uldBean.source}" />
<!-- 自重(kg) --> <!-- 自重(kg) -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneFormRow <com.lukouguoji.module_base.ui.weight.phone.PhoneFormRow
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -221,6 +210,17 @@
type="@{viewModel.pageType == DetailsPageType.Details ? PhoneFormRowType.TEXT : PhoneFormRowType.INPUT}" type="@{viewModel.pageType == DetailsPageType.Details ? PhoneFormRowType.TEXT : PhoneFormRowType.INPUT}"
value="@={viewModel.uldBean.airport}" /> value="@={viewModel.uldBean.airport}" />
<!-- 来源(设计稿顺序位于所在港之后;后端字段暂不支持,已登记清单,提交后端忽略) -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneFormRow
android:layout_width="match_parent"
android:layout_height="wrap_content"
enable="@{viewModel.pageType != DetailsPageType.Details}"
hint='@{"请选择来源"}'
list="@{viewModel.sourceEditList}"
title='@{"来源"}'
type="@{viewModel.pageType == DetailsPageType.Details ? PhoneFormRowType.TEXT : PhoneFormRowType.SELECT}"
value="@={viewModel.uldBean.source}" />
<!-- 入库时间(绑 checkInDate筛选/格式语义待后端确认,已登记清单) --> <!-- 入库时间(绑 checkInDate筛选/格式语义待后端确认,已登记清单) -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneFormRow <com.lukouguoji.module_base.ui.weight.phone.PhoneFormRow
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@@ -1,287 +1,227 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
国内进港移库 —— 列表项 5.5 寸手持端布局(平板变体见 layout-sw600dp/ 同名文件)
一套布局覆盖设计稿两种卡片形态,按 bean.isMoved 切换(载入时按端点打标):
· 待移库:圆形勾选框 + 蓝色运单号 + 橙色「待移库」标签
· 已移库:无勾选框 + 深色运单号 + 绿色对勾「已移库」
长按卡片出「拍照」浮层(跳拍照上传页),点浮层空白处收起。
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android" <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"> xmlns:tools="http://schemas.android.com/tools">
<data> <data>
<import type="android.view.View" />
<variable <variable
name="bean" name="bean"
type="com.lukouguoji.module_base.bean.MoveStashBean" /> type="com.lukouguoji.module_base.bean.MoveStashBean" />
<variable
name="position"
type="Integer" />
<variable
name="activity"
type="com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListActivity" />
</data> </data>
<!-- 外层容器承载间距 --> <FrameLayout
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp" android:layout_marginHorizontal="12dp"
android:layout_marginVertical="5dp" android:layout_marginTop="12dp">
android:orientation="vertical">
<!-- 侧滑布局 --> <LinearLayout
<com.mcxtzhang.swipemenulib.SwipeMenuLayout
android:id="@+id/swipe_menu"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:background="@drawable/bg_phone_card"
android:onLongClick="@{()-> activity.showCardActionPhone(bean)}"
android:orientation="vertical"
android:padding="16dp">
<!-- 主列表项容器 --> <!-- ==================== 卡片头部:勾选框 + 运单号 + 状态 ==================== -->
<androidx.appcompat.widget.LinearLayoutCompat <LinearLayout
android:id="@+id/ll"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/bg_item" android:gravity="center_vertical"
android:orientation="horizontal" android:orientation="horizontal">
android:padding="10dp">
<!-- 圆形勾选框(已移库的记录不可勾选,隐藏) -->
<ImageView <ImageView
android:id="@+id/iv_icon" android:id="@+id/iv_icon"
loadImage="@{bean.checked ? @drawable/img_plane_s : @drawable/img_plane}" android:layout_width="20dp"
android:layout_width="40dp" android:layout_height="20dp"
android:layout_height="40dp" android:layout_marginEnd="8dp"
android:layout_gravity="center" android:src="@drawable/ic_phone_check_round_unchecked"
android:src="@drawable/img_plane" /> android:visibility="@{bean.isMoved ? View.GONE : View.VISIBLE}"
loadImage="@{bean.checked.get() ? @drawable/ic_phone_check_round_checked : @drawable/ic_phone_check_round_unchecked}" />
<LinearLayout <!-- 运单号 -->
<TextView
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1" android:layout_weight="1"
android:orientation="vertical"> android:text="@{bean.wbNo}"
android:textColor="@{bean.isMoved ? @color/phone_text_title : @color/phone_primary}"
android:textSize="15sp"
android:textStyle="bold" />
<androidx.appcompat.widget.LinearLayoutCompat <!-- 待移库:橙色状态标签 -->
android:layout_width="match_parent" <TextView
android:layout_height="wrap_content"> 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.isMoved ? View.GONE : View.VISIBLE}" />
<androidx.appcompat.widget.LinearLayoutCompat <!-- 已移库:对勾 + 状态文字 -->
android:layout_width="0dp" <LinearLayout
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:layout_weight="1.1" android:layout_height="wrap_content"
android:gravity="center_vertical"> android:layout_marginStart="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="@{bean.isMoved ? View.VISIBLE : View.GONE}">
<TextView <ImageView
completeSpace="@{4}" android:layout_width="16dp"
android:layout_width="wrap_content" android:layout_height="16dp"
android:layout_height="wrap_content" android:src="@drawable/ic_phone_check_circle" />
android:text="运单号:" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.wbNo}"
android:textColor="@color/colorPrimary"
tools:text="789165431" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="件数:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.pc}' />
</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
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="重量:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.weight}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="代理人:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.agentCode}' />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单类型:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.awbType}' />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp"> android:layout_marginStart="4dp"
android:text="已移库"
<androidx.appcompat.widget.LinearLayoutCompat android:textColor="@color/phone_text_title"
android:layout_width="0dp" android:textSize="13sp" />
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="航班:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.flight}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="始发港:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.origin}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="起始站:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.dep}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="目的港:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.dest}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="品名:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.goods}" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</LinearLayout> </LinearLayout>
<!-- 右侧箭头 --> </LinearLayout>
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:src="@drawable/img_pda_right" />
</androidx.appcompat.widget.LinearLayoutCompat> <!-- ==================== 航班信息行 ==================== -->
<LinearLayout
<!-- 侧滑菜单区域 --> android:layout_width="match_parent"
<androidx.appcompat.widget.LinearLayoutCompat android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_marginTop="12dp"
android:layout_height="match_parent" android:layout_marginBottom="12dp"
android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
<!-- 编辑按钮 --> <ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:src="@drawable/ic_phone_airplane" />
<TextView <TextView
android:id="@+id/btn_edit" android:layout_width="0dp"
style="@style/tv_item_action" android:layout_height="wrap_content"
android:background="@color/colorPrimary" android:layout_marginStart="4dp"
android:text="编辑" /> android:layout_weight="1"
android:text='@{"航班信息:" + bean.orDash(bean.flight)}'
android:textColor="@color/phone_text_body"
android:textSize="13sp"
tools:text="航班信息20260709/MU2311" />
</androidx.appcompat.widget.LinearLayoutCompat> </LinearLayout>
</com.mcxtzhang.swipemenulib.SwipeMenuLayout> <!-- ==================== 统计框:特码 / 件数 / 重量 ==================== -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneStatBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
label1='@{"特码"}'
label2='@{"件数"}'
label3='@{"重量"}'
value1="@{bean.orDash(bean.spCode)}"
value2='@{bean.orDash(bean.pc) + "件"}'
value3='@{bean.orDash(bean.weight) + "kg"}' />
</LinearLayout> <!-- ==================== 出运路径 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:src="@drawable/ic_phone_location" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_weight="1"
android:text='@{"出运路径:" + bean.orDash(bean.range)}'
android:textColor="@color/phone_text_body"
android:textSize="13sp" />
</LinearLayout>
<!-- ==================== 查看详情 ==================== -->
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginTop="16dp"
android:background="@color/phone_stat_bg" />
<LinearLayout
android:id="@+id/ll_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|end"
android:orientation="horizontal"
android:paddingTop="12dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查看详情"
android:textColor="@color/phone_primary"
android:textSize="14sp" />
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_phone_chevron_right" />
</LinearLayout>
</LinearLayout>
<!-- ==================== 长按操作浮层:拍照 ==================== -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#66000000"
android:clickable="true"
android:onClick="@{()-> activity.hideCardActionPhone(bean)}"
android:visibility="@{bean.actionMenuVisible ? View.VISIBLE : View.GONE}">
<TextView
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_gravity="center"
android:background="@drawable/bg_phone_fab_purple"
android:gravity="center"
android:onClick="@{()-> activity.openPhoto(bean)}"
android:text="拍照"
android:textColor="@color/white"
android:textSize="12sp"
android:textStyle="bold" />
</FrameLayout>
</FrameLayout>
</layout> </layout>

View File

@@ -162,6 +162,20 @@ data class GjcMaWb(
/** 5.5寸手机版:空值统一占位 "--"(空串与 null 都兜底,布局绑定用) */ /** 5.5寸手机版:空值统一占位 "--"(空串与 null 都兜底,布局绑定用) */
fun orDash(value: String?): String = if (value.isNullOrEmpty()) "--" else value fun orDash(value: String?): String = if (value.isNullOrEmpty()) "--" else value
/**
* 5.5寸手机版:代理人展示值(名称优先,空则回退代码)。
* 不能在 XML 里用 `??` 兜底——转换器会把 JSON null 归一成空串,`??` 只判 null 不判空串。
*/
val agentDisplay: String?
get() = if (agentName.isNullOrEmpty()) agentCode else agentName
/**
* 5.5寸手机版-出港仓库:卡片状态标签(已清仓=绿 / 未清仓=橙clearNormal 为空视作未清仓)。
* 已清仓时卡片「清仓」按钮置灰不可点。
*/
val isCleared: Boolean
get() = clearNormal == "1"
// ==================== 状态转换扩展属性 ==================== // ==================== 状态转换扩展属性 ====================
/** /**
* 计重状态中文 * 计重状态中文

View File

@@ -74,4 +74,11 @@ class IntImpPickUpDLVBean : Serializable {
var isSelected: Boolean var isSelected: Boolean
get() = checked.get() get() = checked.get()
set(value) = checked.set(value) set(value) = checked.set(value)
/**
* 5.5寸手机版:是否已出库(出库时间非空)。
* 卡片按此切两种形态:待出库(勾选框+橙标签+库位行)/已出库(绿标签+出库人行)。
*/
val isPickedUp: Boolean
get() = dlvTime.isNotEmpty()
} }

View File

@@ -54,4 +54,26 @@ data class IntImpQueryBean(
// ==================== 其他 ==================== // ==================== 其他 ====================
var remark: String? = null, // 备注 var remark: String? = null, // 备注
var activeId: Long? = null // 有效值 var activeId: Long? = null // 有效值
) ) {
/**
* 5.5寸手机版-进港查询:卡片状态标签。
* 已出库 = 出库时间dlvTime非空已入库 = 入库时间inDate非空都为空 = 未入库(灰)。
* 接口无独立状态出参,此判定为前端推断(与平板列表「入库时间/出库时间」两列同源)。
*/
val isQueryOutbound: Boolean
get() = !dlvTime.isNullOrEmpty()
val isQueryStored: Boolean
get() = !inDate.isNullOrEmpty()
/** 5.5寸手机版:空值统一占位 "--"(空串与 null 都兜底,布局绑定用) */
fun orDash(value: String?): String = if (value.isNullOrEmpty()) "--" else value
/**
* 5.5寸手机版:代理人展示值(名称优先,空则回退代码)。
* 不能在 XML 里用 `??` 兜底——转换器会把 JSON null 归一成空串,`??` 只判 null 不判空串。
*/
val agentDisplay: String?
get() = if (agentName.isNullOrEmpty()) agentCode else agentName
}

View File

@@ -6,6 +6,7 @@ import com.lukouguoji.module_base.interfaces.ICheck
class MoveStashBean : ICheck { class MoveStashBean : ICheck {
var activeId: String = "" // null var activeId: String = "" // null
var agentCode: String = "" // HFEXB var agentCode: String = "" // HFEXB
var agentName: String = "" // 代理人名称search 出参有定义)
var awbType: String = "" // 国际进港(国内中转) var awbType: String = "" // 国际进港(国内中转)
var businessType: String = "" // null var businessType: String = "" // null
var by1: String = "" // null var by1: String = "" // null
@@ -49,4 +50,19 @@ class MoveStashBean : ICheck {
override fun getCheckObservable(): ObservableBoolean { override fun getCheckObservable(): ObservableBoolean {
return checked return checked
} }
// ========== 5.5 寸手持端展示辅助字段(仅前端使用,不参与提交) ==========
/** 是否已移库由列表加载端点决定search=待移库 / searchMoved=已移库),载入时打标 */
var isMoved: Boolean = false
/** 卡片长按「拍照」操作浮层显隐(仅 UI 状态) */
val actionMenuVisible = ObservableBoolean(false)
/** 代理显示:网络层会把 null 归一成空串,须 isNullOrEmpty 双兜底(沿用进港/出港查询口径) */
val agentDisplay: String
get() = if (agentName.isNotEmpty()) agentName else agentCode
/** 详情页/卡片字段统一空值占位 */
fun orDash(value: String?): String = if (value.isNullOrEmpty()) "-" else value
} }

View File

@@ -272,6 +272,8 @@ interface Constant {
const val IntImpTally = "AppIntImpTally" //理货报告 const val IntImpTally = "AppIntImpTally" //理货报告
const val IntImpPickUpRecord = "AppIntImpPickUpRecord" //提取记录 const val IntImpPickUpRecord = "AppIntImpPickUpRecord" //提取记录
const val IntImpPickUpDLV = "AppIntImpPickUpDLV" //提取出库 const val IntImpPickUpDLV = "AppIntImpPickUpDLV" //提取出库
// 进港移库后端暂无该模块与权限串2026-07-31 api-doc 核对),按 AppIntImp* 命名约定预定义,
// 权限串下发前手机首页菜单不会显示该入口(已登记后端接口对接问题清单)
const val IntImpAccidentVisa = "AppIntImpAccidentVisa" //事故签证 const val IntImpAccidentVisa = "AppIntImpAccidentVisa" //事故签证
const val GjjManifestListActivity = "AppIntExpManifest" //舱单 const val GjjManifestListActivity = "AppIntExpManifest" //舱单
const val GjjTallyListActivity = "AppIntExpTally" //理货 const val GjjTallyListActivity = "AppIntExpTally" //理货

View File

@@ -1766,6 +1766,12 @@ interface Api {
@POST("DomImpMove/search") @POST("DomImpMove/search")
suspend fun getGnjMoveStashList(@Body data: RequestBody): BaseListBean<MoveStashBean> suspend fun getGnjMoveStashList(@Body data: RequestBody): BaseListBean<MoveStashBean>
/**
* 获取-国内进港移库-已移库列表移库完成分页搜索5.5 寸手机端「已移库」Tab
*/
@POST("DomImpMove/searchMoved")
suspend fun getGnjMoveStashMovedList(@Body data: RequestBody): BaseListBean<MoveStashBean>
/** /**
* 获取-国内进港移库-列表--运单列表 * 获取-国内进港移库-列表--运单列表
*/ */

View File

@@ -104,6 +104,7 @@ object ARouterConstants {
// 国内进港移库(新版本) // 国内进港移库(新版本)
const val ACTIVITY_URL_GNJ_YIKU_LIST = "/gnj/GnjYiKuListActivity" //国内进港 移库列表 const val ACTIVITY_URL_GNJ_YIKU_LIST = "/gnj/GnjYiKuListActivity" //国内进港 移库列表
const val ACTIVITY_URL_GNJ_MOVE_STASH_LIST = "/app/GnjMoveStashListActivity" //国内进港 移库(首页菜单实际跳转页,双形态)
const val ACTIVITY_URL_GNJ_YIKU_DETAILS = "/gnj/GnjYiKuDetailsActivity" //国内进港 移库详情 const val ACTIVITY_URL_GNJ_YIKU_DETAILS = "/gnj/GnjYiKuDetailsActivity" //国内进港 移库详情
const val ACTIVITY_URL_GNJ_YIKU_EDIT = "/gnj/GnjYiKuEditActivity" //国内进港 移库编辑 const val ACTIVITY_URL_GNJ_YIKU_EDIT = "/gnj/GnjYiKuEditActivity" //国内进港 移库编辑
const val ACTIVITY_URL_GNJ_YIKU_HANDOVER = "/gnj/GnjYiKuHandoverActivity" //国内进港 移交编辑/详情 const val ACTIVITY_URL_GNJ_YIKU_HANDOVER = "/gnj/GnjYiKuHandoverActivity" //国内进港 移交编辑/详情

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 手机版禁用态操作按钮:灰底 + 10dp 圆角(出港仓库卡片「清仓」已清仓时置灰) -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/phone_tag_gray_bg" />
<corners android:radius="10dp" />
</shape>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 手机版绿色操作按钮:完成态绿实底 + 10dp 圆角(进港移库-拍照上传「确认提交」) -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="#0E9F6E" />
<corners android:radius="10dp" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="@color/phone_green" />
<corners android:radius="10dp" />
</shape>
</item>
</selector>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 手机版详情卡片表头:橙色底 + 顶部 12dp 圆角(进港移库-异常照片卡片) -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/phone_amber" />
<corners
android:topLeftRadius="12dp"
android:topRightRadius="12dp" />
</shape>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 手机版照片加号槽位:灰色虚线边框 + 8dp 圆角(进港移库-异常照片) -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/transparent" />
<corners android:radius="8dp" />
<stroke
android:width="1dp"
android:color="@color/phone_divider"
android:dashGap="4dp"
android:dashWidth="4dp" />
</shape>

View File

@@ -79,5 +79,6 @@
<color name="phone_tag_indigo_text">#6366F1</color> <color name="phone_tag_indigo_text">#6366F1</color>
<color name="phone_tag_amber_bg">#FEF3C7</color> <!-- 状态标签-琥珀底(出港运抵申报状态 E --> <color name="phone_tag_amber_bg">#FEF3C7</color> <!-- 状态标签-琥珀底(出港运抵申报状态 E -->
<color name="phone_tag_amber_text">#D97706</color> <color name="phone_tag_amber_text">#D97706</color>
<color name="phone_amber">#F59E0B</color> <!-- 橙色信息卡表头(进港移库-异常照片) -->
</resources> </resources>

View File

@@ -32,7 +32,7 @@ class GjcQueryActivity :
override fun viewModelClass() = GjcQueryViewModel::class.java override fun viewModelClass() = GjcQueryViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) { override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国际出港查询") setBackArrow(if (DeviceUtil.isPhone()) "出港查询" else "国际出港查询")
binding.viewModel = viewModel binding.viewModel = viewModel

View File

@@ -1,90 +1,91 @@
package com.lukouguoji.gjc.activity package com.lukouguoji.gjc.activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.Gravity import android.view.Gravity
import android.widget.ImageView import android.widget.ImageView
import android.widget.LinearLayout import android.widget.LinearLayout
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import com.alibaba.android.arouter.facade.annotation.Route import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter import com.alibaba.android.arouter.launcher.ARouter
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.ActivityGjcQueryDetailsBinding import com.lukouguoji.gjc.databinding.ActivityGjcQueryDetailsBinding
import com.lukouguoji.gjc.viewModel.GjcQueryDetailsViewModel import com.lukouguoji.gjc.viewModel.GjcQueryDetailsViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.base.CustomVP2Adapter import com.lukouguoji.module_base.base.CustomVP2Adapter
import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.router.ARouterConstants import com.lukouguoji.module_base.router.ARouterConstants
import com.lukouguoji.module_base.util.DeviceUtil
/**
* 国际出港查询详情页面 /**
*/ * 国际出港查询详情页面
@Route(path = ARouterConstants.ACTIVITY_URL_GJC_QUERY_DETAILS) */
class GjcQueryDetailsActivity : @Route(path = ARouterConstants.ACTIVITY_URL_GJC_QUERY_DETAILS)
BaseBindingActivity<ActivityGjcQueryDetailsBinding, GjcQueryDetailsViewModel>() { class GjcQueryDetailsActivity :
BaseBindingActivity<ActivityGjcQueryDetailsBinding, GjcQueryDetailsViewModel>() {
override fun layoutId() = R.layout.activity_gjc_query_details
override fun viewModelClass() = GjcQueryDetailsViewModel::class.java override fun layoutId() = R.layout.activity_gjc_query_details
override fun viewModelClass() = GjcQueryDetailsViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国际出港查询详情") override fun initOnCreate(savedInstanceState: Bundle?) {
binding.viewModel = viewModel setBackArrow(if (DeviceUtil.isPhone()) "出港货物" else "国际出港查询详情")
binding.viewModel = viewModel
// 初始化ViewModel(传入maWbId)
viewModel.initOnCreated(intent) // 初始化ViewModel(传入maWbId)
viewModel.initOnCreated(intent)
// 配置ViewPager2
binding.vp.adapter = CustomVP2Adapter( // 配置ViewPager2
viewModel.fragmentList, binding.vp.adapter = CustomVP2Adapter(
supportFragmentManager, viewModel.fragmentList,
lifecycle supportFragmentManager,
) lifecycle
binding.vp.isUserInputEnabled = false // 禁用滑动 )
binding.vp.offscreenPageLimit = 3 // 预加载3个Fragment binding.vp.isUserInputEnabled = false // 禁用滑动
binding.vp.offscreenPageLimit = 3 // 预加载3个Fragment
// 监听Tab索引变化,切换Fragment
viewModel.currentTab.observe(this) { // 监听Tab索引变化,切换Fragment
binding.vp.setCurrentItem(it, false) // false:无动画 viewModel.currentTab.observe(this) {
} binding.vp.setCurrentItem(it, false) // false:无动画
}
// 标题栏右侧添加日志查询图标
val toolbar = findViewById<Toolbar>(com.lukouguoji.module_base.R.id.toolbar) // 标题栏右侧添加日志查询图标
val logIcon = ImageView(this).apply { val toolbar = findViewById<Toolbar>(com.lukouguoji.module_base.R.id.toolbar)
setImageResource(com.lukouguoji.module_base.R.drawable.img_log) val logIcon = ImageView(this).apply {
layoutParams = Toolbar.LayoutParams( setImageResource(com.lukouguoji.module_base.R.drawable.img_log)
LinearLayout.LayoutParams.WRAP_CONTENT, layoutParams = Toolbar.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT LinearLayout.LayoutParams.WRAP_CONTENT,
).apply { LinearLayout.LayoutParams.WRAP_CONTENT
gravity = Gravity.END or Gravity.CENTER_VERTICAL ).apply {
marginEnd = 15 gravity = Gravity.END or Gravity.CENTER_VERTICAL
width = 30.dp marginEnd = 15
height = 30.dp width = 30.dp
} height = 30.dp
setOnClickListener { }
val wbNo = viewModel.maWbData.value?.get("wbNo") as? String ?: "" setOnClickListener {
ARouter.getInstance() val wbNo = viewModel.maWbData.value?.get("wbNo") as? String ?: ""
.build(ARouterConstants.ACTIVITY_URL_LOG_DETAIL) ARouter.getInstance()
.withString(Constant.Key.KEY, wbNo) .build(ARouterConstants.ACTIVITY_URL_LOG_DETAIL)
.withString(Constant.Key.AWB_TYPE, "IO") .withString(Constant.Key.KEY, wbNo)
.navigation() .withString(Constant.Key.AWB_TYPE, "IO")
} .navigation()
} }
toolbar.addView(logIcon) }
toolbar.addView(logIcon)
// 加载详情数据
viewModel.loadDetails() // 加载详情数据
} viewModel.loadDetails()
}
private val Int.dp: Int
get() = (this * resources!!.displayMetrics.density).toInt() private val Int.dp: Int
get() = (this * resources!!.displayMetrics.density).toInt()
companion object {
@JvmStatic companion object {
fun start(context: Context, maWbId: Long?) { @JvmStatic
val starter = Intent(context, GjcQueryDetailsActivity::class.java) fun start(context: Context, maWbId: Long?) {
.putExtra(Constant.Key.ID, maWbId?.toString() ?: "") val starter = Intent(context, GjcQueryDetailsActivity::class.java)
context.startActivity(starter) .putExtra(Constant.Key.ID, maWbId?.toString() ?: "")
} context.startActivity(starter)
} }
} }
}

View File

@@ -1,105 +1,105 @@
package com.lukouguoji.gjc.activity package com.lukouguoji.gjc.activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.databinding.ObservableBoolean import androidx.databinding.ObservableBoolean
import com.alibaba.android.arouter.facade.annotation.Route import com.alibaba.android.arouter.facade.annotation.Route
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.ActivityGjcWeighingListBinding import com.lukouguoji.gjc.databinding.ActivityGjcWeighingListBinding
import com.lukouguoji.gjc.viewModel.GjcWeighingViewModel import com.lukouguoji.gjc.viewModel.GjcWeighingViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.bean.GjcWeighingBean import com.lukouguoji.module_base.bean.GjcWeighingBean
import com.lukouguoji.module_base.common.ConstantEvent import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.impl.FlowBus import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.impl.observe import com.lukouguoji.module_base.impl.observe
import com.lukouguoji.module_base.ktx.getLifecycleOwner import com.lukouguoji.module_base.ktx.getLifecycleOwner
import com.lukouguoji.module_base.router.ARouterConstants import com.lukouguoji.module_base.router.ARouterConstants
import com.lukouguoji.module_base.util.DeviceUtil import com.lukouguoji.module_base.util.DeviceUtil
/** /**
* 国际出港计重列表页 * 国际出港计重列表页
* *
* 布局 id 不区分设备,平板/手机由资源限定符自动选择: * 布局 id 不区分设备,平板/手机由资源限定符自动选择:
* layout-sw600dp/activity_gjc_weighing_list.xml平板 * layout-sw600dp/activity_gjc_weighing_list.xml平板
* layout/activity_gjc_weighing_list.xml手机 * layout/activity_gjc_weighing_list.xml手机
*/ */
@Route(path = ARouterConstants.ACTIVITY_URL_GJC_WEIGHING_LIST) @Route(path = ARouterConstants.ACTIVITY_URL_GJC_WEIGHING_LIST)
class GjcWeighingListActivity : class GjcWeighingListActivity :
BaseBindingActivity<ActivityGjcWeighingListBinding, GjcWeighingViewModel>() { BaseBindingActivity<ActivityGjcWeighingListBinding, GjcWeighingViewModel>() {
override fun layoutId() = R.layout.activity_gjc_weighing_list override fun layoutId() = R.layout.activity_gjc_weighing_list
override fun viewModelClass() = GjcWeighingViewModel::class.java override fun viewModelClass() = GjcWeighingViewModel::class.java
/** 手机版筛选弹层显隐(仅 UI 状态,不涉及业务逻辑) */ /** 手机版筛选弹层显隐(仅 UI 状态,不涉及业务逻辑) */
val filterPanelVisible = ObservableBoolean(false) val filterPanelVisible = ObservableBoolean(false)
override fun initOnCreate(savedInstanceState: Bundle?) { override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国际出港待计重") setBackArrow(if (DeviceUtil.isPhone()) "出港待计重" else "国际出港待计重")
binding.viewModel = viewModel binding.viewModel = viewModel
binding.activity = this binding.activity = this
// 手机版专属数据:放开默认日期、加载筛选弹层字典、启用三格统计 // 手机版专属数据:放开默认日期、加载筛选弹层字典、启用三格统计
// 平板端不调用,查询链路与请求次数与改造前完全一致 // 平板端不调用,查询链路与请求次数与改造前完全一致
if (DeviceUtil.isPhone()) { if (DeviceUtil.isPhone()) {
viewModel.initPhoneExtras() viewModel.initPhoneExtras()
} }
// 初始化代理人列表从API获取 // 初始化代理人列表从API获取
viewModel.initAgentList() viewModel.initAgentList()
// 初始化特码列表从API获取 // 初始化特码列表从API获取
viewModel.initSpecialCodeList() viewModel.initSpecialCodeList()
// 绑定分页逻辑 // 绑定分页逻辑
viewModel.pageModel viewModel.pageModel
.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, getLifecycleOwner()) .bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, getLifecycleOwner())
// 监听刷新事件 // 监听刷新事件
FlowBus.with<String>(ConstantEvent.EVENT_CHECK_CHANGED).observe(this) { viewModel.onItemCheckChanged() } FlowBus.with<String>(ConstantEvent.EVENT_CHECK_CHANGED).observe(this) { viewModel.onItemCheckChanged() }
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH) FlowBus.with<String>(ConstantEvent.EVENT_REFRESH)
.observe(this) { .observe(this) {
viewModel.refresh() viewModel.refresh()
} }
// 初始加载 // 初始加载
viewModel.refresh() viewModel.refresh()
} }
// ==================== 手机版专用交互(纯 UI复用既有 ViewModel 字段) ==================== // ==================== 手机版专用交互(纯 UI复用既有 ViewModel 字段) ====================
/** 手机版筛选弹层显隐切换 */ /** 手机版筛选弹层显隐切换 */
fun toggleFilterPanel() { fun toggleFilterPanel() {
filterPanelVisible.set(!filterPanelVisible.get()) filterPanelVisible.set(!filterPanelVisible.get())
} }
/** 手机版筛选:重置(只清弹层内条件,不影响顶部搜索框) */ /** 手机版筛选:重置(只清弹层内条件,不影响顶部搜索框) */
fun resetFilter() { fun resetFilter() {
viewModel.channelFilter.value = "" viewModel.channelFilter.value = ""
viewModel.carrierFilter.value = "" viewModel.carrierFilter.value = ""
viewModel.awbTypeFilter.value = "" viewModel.awbTypeFilter.value = ""
viewModel.agentCode.value = "" viewModel.agentCode.value = ""
} }
/** 手机版筛选:确认 */ /** 手机版筛选:确认 */
fun confirmFilter() { fun confirmFilter() {
filterPanelVisible.set(false) filterPanelVisible.set(false)
viewModel.searchClick() viewModel.searchClick()
} }
/** 手机版卡片内「提前运抵」(单票,由 ViewHolder 调用) */ /** 手机版卡片内「提前运抵」(单票,由 ViewHolder 调用) */
fun preArriveClick(bean: GjcWeighingBean) { fun preArriveClick(bean: GjcWeighingBean) {
viewModel.arrivedAheadSingle(bean) viewModel.arrivedAheadSingle(bean)
} }
companion object { companion object {
@JvmStatic @JvmStatic
fun start(context: Context) { fun start(context: Context) {
val starter = Intent(context, GjcWeighingListActivity::class.java) val starter = Intent(context, GjcWeighingListActivity::class.java)
context.startActivity(starter) context.startActivity(starter)
} }
} }
} }

View File

@@ -1,103 +1,104 @@
package com.lukouguoji.gjc.activity package com.lukouguoji.gjc.activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.alibaba.android.arouter.facade.annotation.Route import com.alibaba.android.arouter.facade.annotation.Route
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.ActivityGjcWeighingRecordDetailsBinding import com.lukouguoji.gjc.databinding.ActivityGjcWeighingRecordDetailsBinding
import com.lukouguoji.gjc.holder.GjcCheckInRecordViewHolder import com.lukouguoji.gjc.holder.GjcCheckInRecordViewHolder
import com.lukouguoji.gjc.viewModel.GjcWeighingRecordDetailsViewModel import com.lukouguoji.gjc.viewModel.GjcWeighingRecordDetailsViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.base.CommonAdapter import com.lukouguoji.module_base.base.CommonAdapter
import com.lukouguoji.module_base.bean.GjcCheckInRecord import com.lukouguoji.module_base.bean.GjcCheckInRecord
import com.lukouguoji.module_base.bean.GjcWeighingRecordBean import com.lukouguoji.module_base.bean.GjcWeighingRecordBean
import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.router.ARouterConstants import com.lukouguoji.module_base.router.ARouterConstants
import com.lukouguoji.module_base.util.DeviceUtil
/**
* 国际出港计重明细页 /**
* * 国际出港计重明细页
* 布局 id 不区分设备,平板/手机由资源限定符自动选择: *
* layout-sw600dp/activity_gjc_weighing_record_details.xml平板列表内联编辑 * 布局 id 不区分设备,平板/手机由资源限定符自动选择:
* layout/activity_gjc_weighing_record_details.xml手机,单条记录经全屏「修改记录」覆层编辑) * layout-sw600dp/activity_gjc_weighing_record_details.xml平板,列表内联编辑)
*/ * layout/activity_gjc_weighing_record_details.xml手机单条记录经全屏「修改记录」覆层编辑
@Route(path = ARouterConstants.ACTIVITY_URL_GJC_WEIGHING_RECORD_DETAILS) */
class GjcWeighingRecordDetailsActivity : @Route(path = ARouterConstants.ACTIVITY_URL_GJC_WEIGHING_RECORD_DETAILS)
BaseBindingActivity<ActivityGjcWeighingRecordDetailsBinding, GjcWeighingRecordDetailsViewModel>() { class GjcWeighingRecordDetailsActivity :
BaseBindingActivity<ActivityGjcWeighingRecordDetailsBinding, GjcWeighingRecordDetailsViewModel>() {
private lateinit var adapter: CommonAdapter
private lateinit var adapter: CommonAdapter
// 当前编辑模式供ViewHolder获取
var currentEditMode = false // 当前编辑模式供ViewHolder获取
var currentEditMode = false
override fun layoutId() = R.layout.activity_gjc_weighing_record_details
override fun layoutId() = R.layout.activity_gjc_weighing_record_details
override fun viewModelClass() = GjcWeighingRecordDetailsViewModel::class.java
override fun viewModelClass() = GjcWeighingRecordDetailsViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国际出港计重明细") override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow(if (DeviceUtil.isPhone()) "计重明细" else "国际出港计重明细")
binding.viewModel = viewModel
binding.viewModel = viewModel
// 初始化RecyclerView
val layoutManager = LinearLayoutManager(this) // 初始化RecyclerView
binding.recyclerView.layoutManager = layoutManager val layoutManager = LinearLayoutManager(this)
binding.recyclerView.layoutManager = layoutManager
// 添加分割线
val divider = DividerItemDecoration(this, DividerItemDecoration.VERTICAL) // 添加分割线
binding.recyclerView.addItemDecoration(divider) val divider = DividerItemDecoration(this, DividerItemDecoration.VERTICAL)
binding.recyclerView.addItemDecoration(divider)
adapter = CommonAdapter(
this, adapter = CommonAdapter(
R.layout.item_gjc_check_in_record, this,
GjcCheckInRecordViewHolder::class.java R.layout.item_gjc_check_in_record,
) GjcCheckInRecordViewHolder::class.java
binding.recyclerView.adapter = adapter )
binding.recyclerView.adapter = adapter
// 监听数据变化更新RecyclerView
viewModel.recordList.observe(this) { records -> // 监听数据变化更新RecyclerView
adapter.refresh(records) viewModel.recordList.observe(this) { records ->
} adapter.refresh(records)
}
// 监听编辑模式变化,更新当前编辑模式并刷新列表
viewModel.isEditMode.observe(this) { isEditMode -> // 监听编辑模式变化,更新当前编辑模式并刷新列表
// 更新当前编辑模式状态 viewModel.isEditMode.observe(this) { isEditMode ->
currentEditMode = isEditMode // 更新当前编辑模式状态
currentEditMode = isEditMode
// 刷新所有可见的 ViewHolder
adapter.notifyDataSetChanged() // 刷新所有可见的 ViewHolder
} adapter.notifyDataSetChanged()
}
// 初始化数据
viewModel.initOnCreated(intent) // 初始化数据
} viewModel.initOnCreated(intent)
}
// ==================== 手机版专用交互(纯 UI复用既有 ViewModel 编辑链路) ====================
// ==================== 手机版专用交互(纯 UI复用既有 ViewModel 编辑链路) ====================
/**
* 手机版:打开「修改记录」覆层编辑指定记录。 /**
* 复用 [GjcWeighingRecordDetailsViewModel.onModifyClick] 的备份/编辑态逻辑, * 手机版:打开「修改记录」覆层编辑指定记录。
* 覆层显隐由 isEditMode 驱动(平板端该状态驱动列表内联编辑,互不影响)。 * 复用 [GjcWeighingRecordDetailsViewModel.onModifyClick] 的备份/编辑态逻辑,
*/ * 覆层显隐由 isEditMode 驱动(平板端该状态驱动列表内联编辑,互不影响)。
fun openPhoneEdit(record: GjcCheckInRecord) { */
viewModel.onModifyClick() fun openPhoneEdit(record: GjcCheckInRecord) {
binding.editRecord = record viewModel.onModifyClick()
} binding.editRecord = record
}
/** 手机版:取消编辑(恢复备份并收起覆层) */
fun closePhoneEdit() { /** 手机版:取消编辑(恢复备份并收起覆层) */
viewModel.onCancelClick() fun closePhoneEdit() {
} viewModel.onCancelClick()
}
companion object {
@JvmStatic companion object {
fun start(context: Context, bean: GjcWeighingRecordBean) { @JvmStatic
val starter = Intent(context, GjcWeighingRecordDetailsActivity::class.java) fun start(context: Context, bean: GjcWeighingRecordBean) {
.putExtra(Constant.Key.BEAN, bean) val starter = Intent(context, GjcWeighingRecordDetailsActivity::class.java)
context.startActivity(starter) .putExtra(Constant.Key.BEAN, bean)
} context.startActivity(starter)
} }
} }
}

View File

@@ -1,99 +1,99 @@
package com.lukouguoji.gjc.activity package com.lukouguoji.gjc.activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.databinding.ObservableBoolean import androidx.databinding.ObservableBoolean
import com.alibaba.android.arouter.facade.annotation.Route import com.alibaba.android.arouter.facade.annotation.Route
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.ActivityGjcWeighingRecordListBinding import com.lukouguoji.gjc.databinding.ActivityGjcWeighingRecordListBinding
import com.lukouguoji.gjc.viewModel.GjcWeighingRecordViewModel import com.lukouguoji.gjc.viewModel.GjcWeighingRecordViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.common.ConstantEvent import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.impl.FlowBus import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.impl.observe import com.lukouguoji.module_base.impl.observe
import com.lukouguoji.module_base.ktx.getLifecycleOwner import com.lukouguoji.module_base.ktx.getLifecycleOwner
import com.lukouguoji.module_base.router.ARouterConstants import com.lukouguoji.module_base.router.ARouterConstants
import com.lukouguoji.module_base.util.DeviceUtil import com.lukouguoji.module_base.util.DeviceUtil
/** /**
* 国际出港计重记录列表页 * 国际出港计重记录列表页
* *
* 布局 id 不区分设备,平板/手机由资源限定符自动选择: * 布局 id 不区分设备,平板/手机由资源限定符自动选择:
* layout-sw600dp/activity_gjc_weighing_record_list.xml平板 * layout-sw600dp/activity_gjc_weighing_record_list.xml平板
* layout/activity_gjc_weighing_record_list.xml手机 * layout/activity_gjc_weighing_record_list.xml手机
*/ */
@Route(path = ARouterConstants.ACTIVITY_URL_GJC_WEIGHING_RECORD_LIST) @Route(path = ARouterConstants.ACTIVITY_URL_GJC_WEIGHING_RECORD_LIST)
class GjcWeighingRecordListActivity : class GjcWeighingRecordListActivity :
BaseBindingActivity<ActivityGjcWeighingRecordListBinding, GjcWeighingRecordViewModel>() { BaseBindingActivity<ActivityGjcWeighingRecordListBinding, GjcWeighingRecordViewModel>() {
override fun layoutId() = R.layout.activity_gjc_weighing_record_list override fun layoutId() = R.layout.activity_gjc_weighing_record_list
override fun viewModelClass() = GjcWeighingRecordViewModel::class.java override fun viewModelClass() = GjcWeighingRecordViewModel::class.java
/** 手机版筛选弹层显隐(仅 UI 状态,不涉及业务逻辑) */ /** 手机版筛选弹层显隐(仅 UI 状态,不涉及业务逻辑) */
val filterPanelVisible = ObservableBoolean(false) val filterPanelVisible = ObservableBoolean(false)
override fun initOnCreate(savedInstanceState: Bundle?) { override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国际出港计重记录") setBackArrow(if (DeviceUtil.isPhone()) "计重记录" else "国际出港计重记录")
binding.viewModel = viewModel binding.viewModel = viewModel
binding.activity = this binding.activity = this
// 手机版专属数据:放开默认日期、加载计重人下拉 // 手机版专属数据:放开默认日期、加载计重人下拉
// 平板端不调用,查询链路与请求次数与改造前完全一致 // 平板端不调用,查询链路与请求次数与改造前完全一致
if (DeviceUtil.isPhone()) { if (DeviceUtil.isPhone()) {
viewModel.initPhoneExtras() viewModel.initPhoneExtras()
} }
// 初始化代理人列表 // 初始化代理人列表
viewModel.initAgentList() viewModel.initAgentList()
// 初始化特码列表 // 初始化特码列表
viewModel.initSpecialCodeList() viewModel.initSpecialCodeList()
// 绑定分页逻辑 // 绑定分页逻辑
viewModel.pageModel viewModel.pageModel
.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, getLifecycleOwner()) .bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, getLifecycleOwner())
// 监听刷新事件 // 监听刷新事件
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH) FlowBus.with<String>(ConstantEvent.EVENT_REFRESH)
.observe(this) { .observe(this) {
viewModel.refresh() viewModel.refresh()
} }
// 初始加载 // 初始加载
viewModel.refresh() viewModel.refresh()
} }
// ==================== 手机版专用交互(纯 UI复用既有 ViewModel 字段) ==================== // ==================== 手机版专用交互(纯 UI复用既有 ViewModel 字段) ====================
/** 手机版筛选弹层显隐切换 */ /** 手机版筛选弹层显隐切换 */
fun toggleFilterPanel() { fun toggleFilterPanel() {
filterPanelVisible.set(!filterPanelVisible.get()) filterPanelVisible.set(!filterPanelVisible.get())
} }
/** 手机版筛选:重置(只清弹层内条件,不影响顶部搜索框) */ /** 手机版筛选:重置(只清弹层内条件,不影响顶部搜索框) */
fun resetFilter() { fun resetFilter() {
viewModel.checkInDateStart.value = "" viewModel.checkInDateStart.value = ""
viewModel.checkInDateEnd.value = "" viewModel.checkInDateEnd.value = ""
viewModel.agentCode.value = "" viewModel.agentCode.value = ""
viewModel.spCode.value = "" viewModel.spCode.value = ""
viewModel.destFilter.value = "" viewModel.destFilter.value = ""
viewModel.opUserFilter.value = "" viewModel.opUserFilter.value = ""
} }
/** 手机版筛选:确认 */ /** 手机版筛选:确认 */
fun confirmFilter() { fun confirmFilter() {
filterPanelVisible.set(false) filterPanelVisible.set(false)
viewModel.searchClick() viewModel.searchClick()
} }
companion object { companion object {
@JvmStatic @JvmStatic
fun start(context: Context) { fun start(context: Context) {
val starter = Intent(context, GjcWeighingRecordListActivity::class.java) val starter = Intent(context, GjcWeighingRecordListActivity::class.java)
context.startActivity(starter) context.startActivity(starter)
} }
} }
} }

View File

@@ -1,221 +1,221 @@
package com.lukouguoji.gjc.activity package com.lukouguoji.gjc.activity
import android.animation.Animator import android.animation.Animator
import android.animation.AnimatorListenerAdapter import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet import android.animation.AnimatorSet
import android.animation.ObjectAnimator import android.animation.ObjectAnimator
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import com.alibaba.android.arouter.facade.annotation.Route import com.alibaba.android.arouter.facade.annotation.Route
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.ActivityGjcWeighingStartBinding import com.lukouguoji.gjc.databinding.ActivityGjcWeighingStartBinding
import com.lukouguoji.gjc.viewModel.GjcWeighingStartViewModel import com.lukouguoji.gjc.viewModel.GjcWeighingStartViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.router.ARouterConstants import com.lukouguoji.module_base.router.ARouterConstants
import com.lukouguoji.module_base.util.DeviceUtil import com.lukouguoji.module_base.util.DeviceUtil
/** /**
* 国际出港计重-开始计重页面 * 国际出港计重-开始计重页面
*/ */
@Route(path = ARouterConstants.ACTIVITY_URL_GJC_WEIGHING_START) @Route(path = ARouterConstants.ACTIVITY_URL_GJC_WEIGHING_START)
class GjcWeighingStartActivity : class GjcWeighingStartActivity :
BaseBindingActivity<ActivityGjcWeighingStartBinding, GjcWeighingStartViewModel>() { BaseBindingActivity<ActivityGjcWeighingStartBinding, GjcWeighingStartViewModel>() {
private var isExpanded = false private var isExpanded = false
override fun layoutId() = R.layout.activity_gjc_weighing_start override fun layoutId() = R.layout.activity_gjc_weighing_start
override fun viewModelClass() = GjcWeighingStartViewModel::class.java override fun viewModelClass() = GjcWeighingStartViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) { override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国际出港开始计重") setBackArrow(if (DeviceUtil.isPhone()) "开始计重" else "国际出港开始计重")
binding.viewModel = viewModel binding.viewModel = viewModel
// 手机版专属:提交体携带托盘数量/托盘自重(平板不调用,请求体与改造前完全一致) // 手机版专属:提交体携带托盘数量/托盘自重(平板不调用,请求体与改造前完全一致)
if (DeviceUtil.isPhone()) { if (DeviceUtil.isPhone()) {
viewModel.initPhoneExtras() viewModel.initPhoneExtras()
} }
viewModel.initOnCreated(this, intent) viewModel.initOnCreated(this, intent)
setupFloatButtons() setupFloatButtons()
} }
private fun setupFloatButtons() { private fun setupFloatButtons() {
// 浮动按钮组仅平板布局存在layout-sw600dp手机布局无这些 id直接跳过 // 浮动按钮组仅平板布局存在layout-sw600dp手机布局无这些 id直接跳过
val mainFloatButton = binding.mainFloatButton ?: return val mainFloatButton = binding.mainFloatButton ?: return
val maskView = binding.maskView ?: return val maskView = binding.maskView ?: return
val subButton1 = binding.subButton1 ?: return val subButton1 = binding.subButton1 ?: return
val subButton2 = binding.subButton2 ?: return val subButton2 = binding.subButton2 ?: return
// 主按钮点击事件 // 主按钮点击事件
mainFloatButton.setOnClickListener { mainFloatButton.setOnClickListener {
if (!isExpanded) { if (!isExpanded) {
expandButtons() expandButtons()
} }
} }
// 遮罩层点击事件 // 遮罩层点击事件
maskView.setOnClickListener { maskView.setOnClickListener {
collapseButtons() collapseButtons()
} }
// 子按钮1点击事件 - 跳转到出港运抵页面 // 子按钮1点击事件 - 跳转到出港运抵页面
subButton1.setOnClickListener { subButton1.setOnClickListener {
com.alibaba.android.arouter.launcher.ARouter.getInstance() com.alibaba.android.arouter.launcher.ARouter.getInstance()
.build(ARouterConstants.ACTIVITY_URL_INT_EXP_ARRIVE) .build(ARouterConstants.ACTIVITY_URL_INT_EXP_ARRIVE)
.navigation() .navigation()
collapseButtons() collapseButtons()
} }
// 子按钮2点击事件 - 跳转到计重记录 // 子按钮2点击事件 - 跳转到计重记录
subButton2.setOnClickListener { subButton2.setOnClickListener {
com.alibaba.android.arouter.launcher.ARouter.getInstance() com.alibaba.android.arouter.launcher.ARouter.getInstance()
.build(ARouterConstants.ACTIVITY_URL_GJC_WEIGHING_RECORD_LIST) .build(ARouterConstants.ACTIVITY_URL_GJC_WEIGHING_RECORD_LIST)
.navigation() .navigation()
collapseButtons() collapseButtons()
} }
} }
/** /**
* 展开子按钮(仅平板,手机布局无浮动按钮组) * 展开子按钮(仅平板,手机布局无浮动按钮组)
*/ */
private fun expandButtons() { private fun expandButtons() {
val mainFloatButton = binding.mainFloatButton ?: return val mainFloatButton = binding.mainFloatButton ?: return
val maskView = binding.maskView ?: return val maskView = binding.maskView ?: return
val subButton1 = binding.subButton1 ?: return val subButton1 = binding.subButton1 ?: return
val subButton2 = binding.subButton2 ?: return val subButton2 = binding.subButton2 ?: return
isExpanded = true isExpanded = true
// 显示遮罩层 // 显示遮罩层
maskView.visibility = View.VISIBLE maskView.visibility = View.VISIBLE
maskView.alpha = 0f maskView.alpha = 0f
maskView.animate().alpha(0.3f).setDuration(200).start() maskView.animate().alpha(0.3f).setDuration(200).start()
// 显示子按钮 // 显示子按钮
subButton1.visibility = View.VISIBLE subButton1.visibility = View.VISIBLE
subButton2.visibility = View.VISIBLE subButton2.visibility = View.VISIBLE
// 子按钮1动画向左上方移动: 左移15dp, 上移55dp // 子按钮1动画向左上方移动: 左移15dp, 上移55dp
val sub1TransX = ObjectAnimator.ofFloat(subButton1, "translationX", 0f, -5f) val sub1TransX = ObjectAnimator.ofFloat(subButton1, "translationX", 0f, -5f)
val sub1TransY = ObjectAnimator.ofFloat(subButton1, "translationY", 0f, -25f) val sub1TransY = ObjectAnimator.ofFloat(subButton1, "translationY", 0f, -25f)
val sub1Alpha = ObjectAnimator.ofFloat(subButton1, "alpha", 0f, 1f) val sub1Alpha = ObjectAnimator.ofFloat(subButton1, "alpha", 0f, 1f)
val sub1Scale = ObjectAnimator.ofFloat(subButton1, "scaleX", 0f, 1f) val sub1Scale = ObjectAnimator.ofFloat(subButton1, "scaleX", 0f, 1f)
val sub1ScaleY = ObjectAnimator.ofFloat(subButton1, "scaleY", 0f, 1f) val sub1ScaleY = ObjectAnimator.ofFloat(subButton1, "scaleY", 0f, 1f)
val animSet1 = AnimatorSet() val animSet1 = AnimatorSet()
animSet1.playTogether(sub1TransX, sub1TransY, sub1Alpha, sub1Scale, sub1ScaleY) animSet1.playTogether(sub1TransX, sub1TransY, sub1Alpha, sub1Scale, sub1ScaleY)
animSet1.duration = 200 animSet1.duration = 200
// 子按钮2动画向左下方移动: 左移55dp, 下移15dp // 子按钮2动画向左下方移动: 左移55dp, 下移15dp
val sub2TransX = ObjectAnimator.ofFloat(subButton2, "translationX", 0f, -25f) val sub2TransX = ObjectAnimator.ofFloat(subButton2, "translationX", 0f, -25f)
val sub2TransY = ObjectAnimator.ofFloat(subButton2, "translationY", 0f, -5f) val sub2TransY = ObjectAnimator.ofFloat(subButton2, "translationY", 0f, -5f)
val sub2Alpha = ObjectAnimator.ofFloat(subButton2, "alpha", 0f, 1f) val sub2Alpha = ObjectAnimator.ofFloat(subButton2, "alpha", 0f, 1f)
val sub2Scale = ObjectAnimator.ofFloat(subButton2, "scaleX", 0f, 1f) val sub2Scale = ObjectAnimator.ofFloat(subButton2, "scaleX", 0f, 1f)
val sub2ScaleY = ObjectAnimator.ofFloat(subButton2, "scaleY", 0f, 1f) val sub2ScaleY = ObjectAnimator.ofFloat(subButton2, "scaleY", 0f, 1f)
val animSet2 = AnimatorSet() val animSet2 = AnimatorSet()
animSet2.playTogether(sub2TransX, sub2TransY, sub2Alpha, sub2Scale, sub2ScaleY) animSet2.playTogether(sub2TransX, sub2TransY, sub2Alpha, sub2Scale, sub2ScaleY)
animSet2.duration = 200 animSet2.duration = 200
animSet2.startDelay = 50 animSet2.startDelay = 50
// 主按钮隐藏动画 // 主按钮隐藏动画
mainFloatButton.animate() mainFloatButton.animate()
.scaleX(0f) .scaleX(0f)
.scaleY(0f) .scaleY(0f)
.alpha(0f) .alpha(0f)
.setDuration(150) .setDuration(150)
.setListener(object : AnimatorListenerAdapter() { .setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) { override fun onAnimationEnd(animation: Animator) {
mainFloatButton.visibility = View.GONE mainFloatButton.visibility = View.GONE
} }
}) })
.start() .start()
animSet1.start() animSet1.start()
animSet2.start() animSet2.start()
} }
/** /**
* 收起子按钮(仅平板,手机布局无浮动按钮组) * 收起子按钮(仅平板,手机布局无浮动按钮组)
*/ */
private fun collapseButtons() { private fun collapseButtons() {
val mainFloatButton = binding.mainFloatButton ?: return val mainFloatButton = binding.mainFloatButton ?: return
val maskView = binding.maskView ?: return val maskView = binding.maskView ?: return
val subButton1 = binding.subButton1 ?: return val subButton1 = binding.subButton1 ?: return
val subButton2 = binding.subButton2 ?: return val subButton2 = binding.subButton2 ?: return
isExpanded = false isExpanded = false
// 隐藏遮罩层 // 隐藏遮罩层
maskView.animate().alpha(0f).setDuration(200).withEndAction { maskView.animate().alpha(0f).setDuration(200).withEndAction {
maskView.visibility = View.GONE maskView.visibility = View.GONE
}.start() }.start()
// 子按钮1动画回到原位 // 子按钮1动画回到原位
val sub1TransX = ObjectAnimator.ofFloat(subButton1, "translationX", subButton1.translationX, 0f) val sub1TransX = ObjectAnimator.ofFloat(subButton1, "translationX", subButton1.translationX, 0f)
val sub1TransY = ObjectAnimator.ofFloat(subButton1, "translationY", subButton1.translationY, 0f) val sub1TransY = ObjectAnimator.ofFloat(subButton1, "translationY", subButton1.translationY, 0f)
val sub1Alpha = ObjectAnimator.ofFloat(subButton1, "alpha", 1f, 0f) val sub1Alpha = ObjectAnimator.ofFloat(subButton1, "alpha", 1f, 0f)
val sub1Scale = ObjectAnimator.ofFloat(subButton1, "scaleX", 1f, 0f) val sub1Scale = ObjectAnimator.ofFloat(subButton1, "scaleX", 1f, 0f)
val sub1ScaleY = ObjectAnimator.ofFloat(subButton1, "scaleY", 1f, 0f) val sub1ScaleY = ObjectAnimator.ofFloat(subButton1, "scaleY", 1f, 0f)
val animSet1 = AnimatorSet() val animSet1 = AnimatorSet()
animSet1.playTogether(sub1TransX, sub1TransY, sub1Alpha, sub1Scale, sub1ScaleY) animSet1.playTogether(sub1TransX, sub1TransY, sub1Alpha, sub1Scale, sub1ScaleY)
animSet1.duration = 200 animSet1.duration = 200
// 子按钮2动画回到原位 // 子按钮2动画回到原位
val sub2TransX = ObjectAnimator.ofFloat(subButton2, "translationX", subButton2.translationX, 0f) val sub2TransX = ObjectAnimator.ofFloat(subButton2, "translationX", subButton2.translationX, 0f)
val sub2TransY = ObjectAnimator.ofFloat(subButton2, "translationY", subButton2.translationY, 0f) val sub2TransY = ObjectAnimator.ofFloat(subButton2, "translationY", subButton2.translationY, 0f)
val sub2Alpha = ObjectAnimator.ofFloat(subButton2, "alpha", 1f, 0f) val sub2Alpha = ObjectAnimator.ofFloat(subButton2, "alpha", 1f, 0f)
val sub2Scale = ObjectAnimator.ofFloat(subButton2, "scaleX", 1f, 0f) val sub2Scale = ObjectAnimator.ofFloat(subButton2, "scaleX", 1f, 0f)
val sub2ScaleY = ObjectAnimator.ofFloat(subButton2, "scaleY", 1f, 0f) val sub2ScaleY = ObjectAnimator.ofFloat(subButton2, "scaleY", 1f, 0f)
val animSet2 = AnimatorSet() val animSet2 = AnimatorSet()
animSet2.playTogether(sub2TransX, sub2TransY, sub2Alpha, sub2Scale, sub2ScaleY) animSet2.playTogether(sub2TransX, sub2TransY, sub2Alpha, sub2Scale, sub2ScaleY)
animSet2.duration = 200 animSet2.duration = 200
animSet1.addListener(object : AnimatorListenerAdapter() { animSet1.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) { override fun onAnimationEnd(animation: Animator) {
subButton1.visibility = View.GONE subButton1.visibility = View.GONE
} }
}) })
animSet2.addListener(object : AnimatorListenerAdapter() { animSet2.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) { override fun onAnimationEnd(animation: Animator) {
subButton2.visibility = View.GONE subButton2.visibility = View.GONE
} }
}) })
// 主按钮显示动画 // 主按钮显示动画
mainFloatButton.visibility = View.VISIBLE mainFloatButton.visibility = View.VISIBLE
mainFloatButton.animate() mainFloatButton.animate()
.scaleX(1f) .scaleX(1f)
.scaleY(1f) .scaleY(1f)
.alpha(1f) .alpha(1f)
.setDuration(200) .setDuration(200)
.setStartDelay(100) .setStartDelay(100)
.setListener(null) .setListener(null)
.start() .start()
animSet1.start() animSet1.start()
animSet2.start() animSet2.start()
} }
companion object { companion object {
/** /**
* 启动开始计重页面 * 启动开始计重页面
* @param context 上下文 * @param context 上下文
* @param maWbId 运单ID默认为0新增模式 * @param maWbId 运单ID默认为0新增模式
*/ */
@JvmStatic @JvmStatic
fun startForAdd(context: Context, maWbId: Long = 0) { fun startForAdd(context: Context, maWbId: Long = 0) {
val starter = Intent(context, GjcWeighingStartActivity::class.java) val starter = Intent(context, GjcWeighingStartActivity::class.java)
.putExtra(Constant.Key.MAWB_ID, maWbId) .putExtra(Constant.Key.MAWB_ID, maWbId)
context.startActivity(starter) context.startActivity(starter)
} }
} }
} }

View File

@@ -1,177 +1,177 @@
package com.lukouguoji.gjc.activity package com.lukouguoji.gjc.activity
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.databinding.ObservableBoolean import androidx.databinding.ObservableBoolean
import com.alibaba.android.arouter.facade.annotation.Autowired import com.alibaba.android.arouter.facade.annotation.Autowired
import com.alibaba.android.arouter.facade.annotation.Route import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter import com.alibaba.android.arouter.launcher.ARouter
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.ActivityIntExpArriveBinding import com.lukouguoji.gjc.databinding.ActivityIntExpArriveBinding
import com.lukouguoji.gjc.viewModel.IntExpArriveViewModel import com.lukouguoji.gjc.viewModel.IntExpArriveViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.bean.GjcHaWb import com.lukouguoji.module_base.bean.GjcHaWb
import com.lukouguoji.module_base.bean.GjcMaWb import com.lukouguoji.module_base.bean.GjcMaWb
import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.impl.FlowBus import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.impl.observe import com.lukouguoji.module_base.impl.observe
import com.lukouguoji.module_base.ktx.addOnItemClickListener import com.lukouguoji.module_base.ktx.addOnItemClickListener
import com.lukouguoji.module_base.ktx.commonAdapter import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.router.ARouterConstants import com.lukouguoji.module_base.router.ARouterConstants
import com.lukouguoji.module_base.util.DeviceUtil import com.lukouguoji.module_base.util.DeviceUtil
import java.util.ArrayList import java.util.ArrayList
/** /**
* 国际出港-出港运抵页面 * 国际出港-出港运抵页面
* *
* 布局 id 不区分设备,平板/手机由资源限定符自动选择: * 布局 id 不区分设备,平板/手机由资源限定符自动选择:
* layout-sw600dp/activity_int_exp_arrive.xml平板 * layout-sw600dp/activity_int_exp_arrive.xml平板
* layout/activity_int_exp_arrive.xml手机 * layout/activity_int_exp_arrive.xml手机
*/ */
@Route(path = ARouterConstants.ACTIVITY_URL_INT_EXP_ARRIVE) @Route(path = ARouterConstants.ACTIVITY_URL_INT_EXP_ARRIVE)
class IntExpArriveActivity : class IntExpArriveActivity :
BaseBindingActivity<ActivityIntExpArriveBinding, IntExpArriveViewModel>() { BaseBindingActivity<ActivityIntExpArriveBinding, IntExpArriveViewModel>() {
@JvmField @JvmField
@Autowired @Autowired
var wbNoParam: String? = null var wbNoParam: String? = null
override fun layoutId() = R.layout.activity_int_exp_arrive override fun layoutId() = R.layout.activity_int_exp_arrive
override fun viewModelClass() = IntExpArriveViewModel::class.java override fun viewModelClass() = IntExpArriveViewModel::class.java
/** 手机版筛选弹层显隐(仅 UI 状态,不涉及业务逻辑) */ /** 手机版筛选弹层显隐(仅 UI 状态,不涉及业务逻辑) */
val filterPanelVisible = ObservableBoolean(false) val filterPanelVisible = ObservableBoolean(false)
/** 供 [com.lukouguoji.gjc.holder.IntExpArriveViewHolder] 绑定 item 布局的 viewModel 变量(父类 viewModel 为 protected */ /** 供 [com.lukouguoji.gjc.holder.IntExpArriveViewHolder] 绑定 item 布局的 viewModel 变量(父类 viewModel 为 protected */
val itemViewModel: IntExpArriveViewModel get() = viewModel val itemViewModel: IntExpArriveViewModel get() = viewModel
override fun initOnCreate(savedInstanceState: Bundle?) { override fun initOnCreate(savedInstanceState: Bundle?) {
// 注入 ARouter 参数 // 注入 ARouter 参数
ARouter.getInstance().inject(this) ARouter.getInstance().inject(this)
setBackArrow("国际出港运抵") setBackArrow(if (DeviceUtil.isPhone()) "出港运抵" else "国际出港运抵")
binding.viewModel = viewModel binding.viewModel = viewModel
binding.activity = this binding.activity = this
// 手机版专属数据:加载「代理」筛选下拉 // 手机版专属数据:加载「代理」筛选下拉
// 平板端不调用,查询链路与请求次数与改造前完全一致 // 平板端不调用,查询链路与请求次数与改造前完全一致
if (DeviceUtil.isPhone()) { if (DeviceUtil.isPhone()) {
viewModel.initPhoneExtras() viewModel.initPhoneExtras()
} }
// 如果有传入运单号,自动填充并触发搜索 // 如果有传入运单号,自动填充并触发搜索
if (!wbNoParam.isNullOrEmpty()) { if (!wbNoParam.isNullOrEmpty()) {
viewModel.waybillNo.value = wbNoParam viewModel.waybillNo.value = wbNoParam
viewModel.searchClick() viewModel.searchClick()
} }
// 绑定分页 // 绑定分页
viewModel.pageModel.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, this) viewModel.pageModel.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, this)
// 设置item点击监听 // 设置item点击监听
binding.rv.addOnItemClickListener(viewModel) binding.rv.addOnItemClickListener(viewModel)
// 监听刷新事件 // 监听刷新事件
FlowBus.with<String>(ConstantEvent.EVENT_CHECK_CHANGED).observe(this) { viewModel.onItemCheckChanged() } FlowBus.with<String>(ConstantEvent.EVENT_CHECK_CHANGED).observe(this) { viewModel.onItemCheckChanged() }
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).observe(this) { FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).observe(this) {
viewModel.refresh() viewModel.refresh()
} }
// 初始加载数据(如果没有传入运单号,才执行初始加载) // 初始加载数据(如果没有传入运单号,才执行初始加载)
if (wbNoParam.isNullOrEmpty()) { if (wbNoParam.isNullOrEmpty()) {
viewModel.refresh() viewModel.refresh()
} }
} }
// ==================== 手机版专用交互(纯 UI复用既有 ViewModel 字段与数据) ==================== // ==================== 手机版专用交互(纯 UI复用既有 ViewModel 字段与数据) ====================
/** /**
* 手机版 Tab 切换回调PhoneStatusTab 已通过双向绑定写入 viewModel.currentTab * 手机版 Tab 切换回调PhoneStatusTab 已通过双向绑定写入 viewModel.currentTab
* 这里触发 ViewModel 把适配器数据集替换为过滤后的子集(不发起新请求)。 * 这里触发 ViewModel 把适配器数据集替换为过滤后的子集(不发起新请求)。
*/ */
fun onArriveTabChanged() { fun onArriveTabChanged() {
viewModel.onTabChangedPhone() viewModel.onTabChangedPhone()
} }
/** 卡片长按展开操作浮层View.OnLongClickListener 要求返回 Boolean */ /** 卡片长按展开操作浮层View.OnLongClickListener 要求返回 Boolean */
fun showCardActionPhone(bean: GjcMaWb): Boolean { fun showCardActionPhone(bean: GjcMaWb): Boolean {
bean.actionMenuVisible.set(true) bean.actionMenuVisible.set(true)
return true return true
} }
/** 点击浮层遮罩/空白处:收起操作浮层 */ /** 点击浮层遮罩/空白处:收起操作浮层 */
fun hideCardActionPhone(bean: GjcMaWb) { fun hideCardActionPhone(bean: GjcMaWb) {
bean.actionMenuVisible.set(false) bean.actionMenuVisible.set(false)
} }
/** 选择圈勾选状态变化后回调(由 ViewHolder 调用) */ /** 选择圈勾选状态变化后回调(由 ViewHolder 调用) */
fun onItemCheckChanged() { fun onItemCheckChanged() {
viewModel.onItemCheckChanged() viewModel.onItemCheckChanged()
} }
/** 手机版筛选弹层显隐切换 */ /** 手机版筛选弹层显隐切换 */
fun toggleFilterPanel() { fun toggleFilterPanel() {
filterPanelVisible.set(!filterPanelVisible.get()) filterPanelVisible.set(!filterPanelVisible.get())
} }
/** 手机版筛选:重置 */ /** 手机版筛选:重置 */
fun resetFilter() { fun resetFilter() {
viewModel.flightDate.value = "" viewModel.flightDate.value = ""
viewModel.flightNo.value = "" viewModel.flightNo.value = ""
viewModel.agentCodePhone.value = "" viewModel.agentCodePhone.value = ""
} }
/** 手机版筛选:确认 */ /** 手机版筛选:确认 */
fun confirmFilter() { fun confirmFilter() {
filterPanelVisible.set(false) filterPanelVisible.set(false)
viewModel.searchClick() viewModel.searchClick()
} }
/** /**
* 进入「分单明细」页:直接传递该运单已加载的 haWbList零新增请求。 * 进入「分单明细」页:直接传递该运单已加载的 haWbList零新增请求。
*/ */
fun openSubOrder(bean: GjcMaWb) { fun openSubOrder(bean: GjcMaWb) {
val list = ArrayList<GjcHaWb>(bean.haWbList.orEmpty()) val list = ArrayList<GjcHaWb>(bean.haWbList.orEmpty())
IntExpArriveSubOrderActivity.start(this, bean.wbNo.orEmpty(), list) IntExpArriveSubOrderActivity.start(this, bean.wbNo.orEmpty(), list)
} }
/** /**
* 进入「回执」页(手机专属只读页):复用 haWbList[].response + arrivalOpDate零新增请求。 * 进入「回执」页(手机专属只读页):复用 haWbList[].response + arrivalOpDate零新增请求。
*/ */
fun openReceipt(bean: GjcMaWb) { fun openReceipt(bean: GjcMaWb) {
bean.actionMenuVisible.set(false) bean.actionMenuVisible.set(false)
val list = ArrayList<GjcHaWb>(bean.haWbList.orEmpty()) val list = ArrayList<GjcHaWb>(bean.haWbList.orEmpty())
IntExpArriveReceiptActivity.start(this, bean.wbNo.orEmpty(), list) IntExpArriveReceiptActivity.start(this, bean.wbNo.orEmpty(), list)
} }
/** /**
* 进入「补充信息」页(手机专属新页):对该运单整个 haWbList 批量应用(参照 Pad 端国际进港 * 进入「补充信息」页(手机专属新页):对该运单整个 haWbList 批量应用(参照 Pad 端国际进港
* IntArrSupplementInfoViewModel 的批量复制模式)。后端暂无保存接口,见接口问题清单。 * IntArrSupplementInfoViewModel 的批量复制模式)。后端暂无保存接口,见接口问题清单。
*/ */
fun openSupplement(bean: GjcMaWb) { fun openSupplement(bean: GjcMaWb) {
bean.actionMenuVisible.set(false) bean.actionMenuVisible.set(false)
val list = ArrayList<GjcHaWb>(bean.haWbList.orEmpty()) val list = ArrayList<GjcHaWb>(bean.haWbList.orEmpty())
IntExpArriveSupplementActivity.start(this, bean.wbNo.orEmpty(), list) IntExpArriveSupplementActivity.start(this, bean.wbNo.orEmpty(), list)
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
when (requestCode) { when (requestCode) {
Constant.RequestCode.WAYBILL -> { Constant.RequestCode.WAYBILL -> {
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
viewModel.waybillNo.value = data?.getStringExtra(Constant.Result.CODED_CONTENT) viewModel.waybillNo.value = data?.getStringExtra(Constant.Result.CODED_CONTENT)
viewModel.searchClick() viewModel.searchClick()
} }
} }
Constant.RequestCode.CODE -> { Constant.RequestCode.CODE -> {
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
viewModel.hno.value = data?.getStringExtra(Constant.Result.CODED_CONTENT) viewModel.hno.value = data?.getStringExtra(Constant.Result.CODED_CONTENT)
viewModel.searchClick() viewModel.searchClick()
} }
} }
} }
} }
} }

View File

@@ -35,7 +35,7 @@ class IntExpOutHandoverActivity :
val filterPanelVisible = ObservableBoolean(false) val filterPanelVisible = ObservableBoolean(false)
override fun initOnCreate(savedInstanceState: Bundle?) { override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国际出港出库交接") setBackArrow(if (DeviceUtil.isPhone()) "出库交接" else "国际出港出库交接")
binding.viewModel = viewModel binding.viewModel = viewModel
binding.activity = this binding.activity = this

View File

@@ -3,7 +3,6 @@ package com.lukouguoji.gjc.activity
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import com.alibaba.android.arouter.facade.annotation.Route import com.alibaba.android.arouter.facade.annotation.Route
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.ActivityIntExpStorageUseBinding import com.lukouguoji.gjc.databinding.ActivityIntExpStorageUseBinding
@@ -18,7 +17,9 @@ import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.impl.observe import com.lukouguoji.module_base.impl.observe
import com.lukouguoji.module_base.ktx.commonAdapter import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.showToast import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.model.ConfirmDialogModel
import com.lukouguoji.module_base.router.ARouterConstants import com.lukouguoji.module_base.router.ARouterConstants
import com.lukouguoji.module_base.util.DeviceUtil
/** /**
* 国际出港-仓库 * 国际出港-仓库
@@ -31,10 +32,13 @@ class IntExpStorageUseActivity :
override fun viewModelClass() = IntExpStorageUseViewModel::class.java override fun viewModelClass() = IntExpStorageUseViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) { override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国际出港仓库") setBackArrow(if (DeviceUtil.isPhone()) "出港仓库" else "国际出港仓库")
binding.viewModel = viewModel binding.viewModel = viewModel
binding.activity = this binding.activity = this
// 手机形态专属:筛选字典 + 未清仓/已清仓分项统计(平板不调用,行为零变化)
if (DeviceUtil.isPhone()) viewModel.initPhoneExtras()
// 绑定分页 // 绑定分页
viewModel.pageModel.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, this) viewModel.pageModel.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, this)
@@ -139,15 +143,60 @@ class IntExpStorageUseActivity :
} }
// 显示二次确认对话框 // 显示二次确认对话框
AlertDialog.Builder(this) ConfirmDialogModel(
.setTitle("出库确认") message = "确定要将选中的 ${selectedStorageUseList.size} 个库位执行出库操作吗?",
.setMessage("确定要将选中的 ${selectedStorageUseList.size} 个库位执行出库操作吗?") title = "出库确认"
.setPositiveButton("确定") { _, _ -> ) {
// 用户确认后,执行出库操作 // 用户确认后,执行出库操作
viewModel.performOutStorage(selectedStorageUseList) viewModel.performOutStorage(selectedStorageUseList)
} }.show(this)
.setNegativeButton("取消", null) }
.show()
// ==================== 5.5寸手机版:卡片级操作 ====================
// 语义等价于「勾选该主单 + 其全部库位」再执行平板的批量操作,复用 performXxx 请求链路。
/** 卡片「清仓」已清仓的卡片按钮置灰ViewHolder 已拦截) */
fun cardClear(bean: com.lukouguoji.module_base.bean.GjcMaWb) {
val maWbListForClear = listOf(bean.copy(storageUseList = bean.storageUseList ?: emptyList()))
IntExpMoveClearDialogModel { dialog ->
viewModel.performClear(dialog.clearNormal.value ?: "", maWbListForClear)
}.show(this)
}
/** 卡片「修改库位」:弹层内先单选原库位(单库位时默认选中)再选新库位 */
fun cardModifyStorage(bean: com.lukouguoji.module_base.bean.GjcMaWb) {
val storageList = bean.storageUseList ?: emptyList()
if (storageList.isEmpty()) {
showToast("该运单暂无库位")
return
}
IntExpModifyStorageDialogModel(sourceStorageList = storageList) { dialog ->
val sourceStorage = dialog.selectedSourceStorage ?: return@IntExpModifyStorageDialogModel
viewModel.performModifyStorage(dialog.locationName, dialog.locationId, sourceStorage)
}.show(this)
}
/** 卡片「出库」:该运单全部库位出库(与平板勾选主单后出库同语义) */
fun cardOutStorage(bean: com.lukouguoji.module_base.bean.GjcMaWb) {
val storageList = bean.storageUseList ?: emptyList()
if (storageList.isEmpty()) {
showToast("该运单暂无库位")
return
}
ConfirmDialogModel(
message = "确定要将运单 ${bean.wbNo}${storageList.size} 个库位执行出库操作吗?",
title = "出库确认"
) {
viewModel.performOutStorage(storageList)
}.show(this)
}
/** 卡片「入库」:弹层选库位后整票入库 */
fun cardInStorage(bean: com.lukouguoji.module_base.bean.GjcMaWb) {
val maWbListForInStorage = listOf(bean.copy(storageUseList = bean.storageUseList ?: emptyList()))
IntExpInStorageDialogModel { dialog ->
viewModel.performInStorage(dialog.locationName, dialog.locationId, maWbListForInStorage)
}.show(this)
} }
/** /**

View File

@@ -9,14 +9,18 @@ import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.ktx.launchCollect import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.showToast import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import com.lukouguoji.module_base.util.DeviceUtil
import dev.utils.app.info.KeyValue import dev.utils.app.info.KeyValue
/** /**
* 国际出港仓库 - 入库操作对话框 * 国际出港仓库 - 入库操作对话框
* 手机为底部弹层layout/ 变体平板为居中弹框layout-sw600dp/ 变体)
*/ */
class IntExpInStorageDialogModel( class IntExpInStorageDialogModel(
private val callback: (IntExpInStorageDialogModel) -> Unit private val callback: (IntExpInStorageDialogModel) -> Unit
) : BaseDialogModel<DialogIntExpInStorageBinding>(DIALOG_TYPE_CENTER) { ) : BaseDialogModel<DialogIntExpInStorageBinding>(
if (DeviceUtil.isPhone()) DIALOG_TYPE_BOTTOM else DIALOG_TYPE_CENTER
) {
// 库位列表 // 库位列表
val locationList = MutableLiveData<List<KeyValue>>() val locationList = MutableLiveData<List<KeyValue>>()

View File

@@ -8,15 +8,24 @@ import com.lukouguoji.module_base.base.BaseDialogModel
import com.lukouguoji.module_base.http.net.NetApply import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.ktx.launchCollect import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.showToast import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.bean.GjcStorageUse
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import com.lukouguoji.module_base.util.DeviceUtil
import dev.utils.app.info.KeyValue import dev.utils.app.info.KeyValue
/** /**
* 国际出港 - 修改库位对话框 * 国际出港 - 修改库位对话框
* 手机为底部弹层layout/ 变体平板为居中弹框layout-sw600dp/ 变体)。
*
* 平板列表勾选唯一库位后打开弹框内只选新库位sourceStorageList 传 null原库位项不存在于平板布局
* 手机:卡片级操作,运单可能有多个库位——传入该运单库位列表,弹层内先单选「原库位」再选新库位。
*/ */
class IntExpModifyStorageDialogModel( class IntExpModifyStorageDialogModel(
private val sourceStorageList: List<GjcStorageUse>? = null,
private val callback: (IntExpModifyStorageDialogModel) -> Unit private val callback: (IntExpModifyStorageDialogModel) -> Unit
) : BaseDialogModel<DialogIntExpModifyStorageBinding>(DIALOG_TYPE_CENTER) { ) : BaseDialogModel<DialogIntExpModifyStorageBinding>(
if (DeviceUtil.isPhone()) DIALOG_TYPE_BOTTOM else DIALOG_TYPE_CENTER
) {
// 库位列表 // 库位列表
val locationList = MutableLiveData<List<KeyValue>>() val locationList = MutableLiveData<List<KeyValue>>()
@@ -30,6 +39,13 @@ class IntExpModifyStorageDialogModel(
// 库位名称 (后端需要的name) // 库位名称 (后端需要的name)
var locationName: String = "" var locationName: String = ""
// ========== 手机卡片级操作专属:原库位单选 ==========
val sourceList = MutableLiveData<List<KeyValue>>(emptyList())
val selectedSourceId = MutableLiveData("")
// 选中的原库位对象(保存后由调用方取用)
var selectedSourceStorage: GjcStorageUse? = null
override fun layoutId(): Int { override fun layoutId(): Int {
return R.layout.dialog_int_exp_modify_storage return R.layout.dialog_int_exp_modify_storage
} }
@@ -44,6 +60,19 @@ class IntExpModifyStorageDialogModel(
locationId = selectedItem?.value ?: "" locationId = selectedItem?.value ?: ""
locationName = selectedItem?.key ?: "" locationName = selectedItem?.key ?: ""
} }
// 手机版:初始化原库位列表,单库位时默认选中
if (sourceStorageList != null) {
sourceList.value = sourceStorageList.map {
KeyValue(it.location ?: "", it.id?.toString() ?: "")
}
selectedSourceId.observeForever { id ->
selectedSourceStorage = sourceStorageList.find { it.id?.toString() == id }
}
if (sourceStorageList.size == 1) {
selectedSourceId.value = sourceStorageList[0].id?.toString() ?: ""
}
}
} }
/** /**
@@ -65,6 +94,10 @@ class IntExpModifyStorageDialogModel(
* 保存按钮点击 * 保存按钮点击
*/ */
fun onSaveClick() { fun onSaveClick() {
if (sourceStorageList != null && selectedSourceStorage == null) {
showToast("请选择原库位")
return
}
if (selectedLocationCode.value.verifyNullOrEmpty("请选择库位")) { if (selectedLocationCode.value.verifyNullOrEmpty("请选择库位")) {
return return
} }

View File

@@ -6,14 +6,18 @@ import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.DialogIntExpMoveClearBinding import com.lukouguoji.gjc.databinding.DialogIntExpMoveClearBinding
import com.lukouguoji.module_base.base.BaseDialogModel import com.lukouguoji.module_base.base.BaseDialogModel
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import com.lukouguoji.module_base.util.DeviceUtil
import dev.utils.app.info.KeyValue import dev.utils.app.info.KeyValue
/** /**
* 国际出港移库 - 清仓操作对话框 * 国际出港移库 - 清仓操作对话框
* 手机为底部弹层layout/ 变体平板为居中弹框layout-sw600dp/ 变体)
*/ */
class IntExpMoveClearDialogModel( class IntExpMoveClearDialogModel(
private val callback: (IntExpMoveClearDialogModel) -> Unit private val callback: (IntExpMoveClearDialogModel) -> Unit
) : BaseDialogModel<DialogIntExpMoveClearBinding>(DIALOG_TYPE_CENTER) { ) : BaseDialogModel<DialogIntExpMoveClearBinding>(
if (DeviceUtil.isPhone()) DIALOG_TYPE_BOTTOM else DIALOG_TYPE_CENTER
) {
// 清仓正常(存储的是 code"0" 或 "1" // 清仓正常(存储的是 code"0" 或 "1"
val clearNormal = MutableLiveData("") val clearNormal = MutableLiveData("")

View File

@@ -2,6 +2,8 @@ package com.lukouguoji.gjc.holder
import android.view.View import android.view.View
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.activity.GjcQueryDetailsActivity
import com.lukouguoji.gjc.activity.IntExpStorageUseActivity
import com.lukouguoji.gjc.databinding.ItemIntExpStorageUseBinding import com.lukouguoji.gjc.databinding.ItemIntExpStorageUseBinding
import com.lukouguoji.module_base.adapter.setCommonAdapter import com.lukouguoji.module_base.adapter.setCommonAdapter
import com.lukouguoji.module_base.base.BaseViewHolder import com.lukouguoji.module_base.base.BaseViewHolder
@@ -12,6 +14,10 @@ import com.lukouguoji.module_base.ktx.refresh
/** /**
* 国际出港-仓库 ViewHolder * 国际出港-仓库 ViewHolder
*
* 双形态布局:平板变体含 iv_icon/iv_show/rv_sub多选 + 库位子列表),手机变体含
* ll/btn_clear/btn_modify/btn_out/btn_in整卡进详情 + 卡片级四操作按钮)。
* 单侧独有的 id 在 Binding 基类中为 @Nullable必须判空访问。
*/ */
class IntExpStorageUseViewHolder(view: View) : class IntExpStorageUseViewHolder(view: View) :
BaseViewHolder<GjcMaWb, ItemIntExpStorageUseBinding>(view) { BaseViewHolder<GjcMaWb, ItemIntExpStorageUseBinding>(view) {
@@ -22,8 +28,10 @@ class IntExpStorageUseViewHolder(view: View) :
binding.position = position binding.position = position
binding.executePendingBindings() binding.executePendingBindings()
// ==================== 平板:多选 + 子列表 ====================
// 图标点击切换选择状态(联动子列表) // 图标点击切换选择状态(联动子列表)
binding.ivIcon.setOnClickListener { binding.ivIcon?.setOnClickListener {
// 切换主列表项的选择状态 // 切换主列表项的选择状态
val newCheckedState = !bean.checked.get() val newCheckedState = !bean.checked.get()
bean.checked.set(newCheckedState) bean.checked.set(newCheckedState)
@@ -37,25 +45,45 @@ class IntExpStorageUseViewHolder(view: View) :
// 刷新UI // 刷新UI
binding.executePendingBindings() binding.executePendingBindings()
binding.rvSub.adapter?.notifyDataSetChanged() binding.rvSub?.adapter?.notifyDataSetChanged()
} }
// 展开按钮点击事件 // 展开按钮点击事件
binding.ivShow.setOnClickListener { binding.ivShow?.setOnClickListener {
bean.showMore.set(!bean.showMore.get()) bean.showMore.set(!bean.showMore.get())
} }
// 初始化库位明细子列表 RecyclerView // 初始化库位明细子列表 RecyclerView
setCommonAdapter( binding.rvSub?.let { rvSub ->
binding.rvSub, setCommonAdapter(
IntExpStorageUseSubViewHolder::class.java, rvSub,
R.layout.item_int_exp_storage_use_sub IntExpStorageUseSubViewHolder::class.java,
) R.layout.item_int_exp_storage_use_sub
)
// 刷新库位明细数据传递父Bean引用 // 刷新库位明细数据传递父Bean引用
val storageUseList = bean.storageUseList ?: emptyList() val storageUseList = bean.storageUseList ?: emptyList()
// 为每个子列表项设置父Bean引用通过tag传递 // 为每个子列表项设置父Bean引用通过tag传递
binding.rvSub.tag = bean rvSub.tag = bean
binding.rvSub.refresh(storageUseList) rvSub.refresh(storageUseList)
}
// ==================== 手机:整卡进详情 + 卡片级操作 ====================
val activity = itemView.context as? IntExpStorageUseActivity
// 整卡点击进详情复用出港查询详情页3 Tab 运单/仓库/库位信息)
binding.ll?.setOnClickListener {
GjcQueryDetailsActivity.start(itemView.context, bean.maWbId)
}
// 清仓(已清仓时置灰不可点,样式由 XML 按 bean.isCleared 切换)
binding.btnClear?.setOnClickListener {
if (!bean.isCleared) activity?.cardClear(bean)
}
binding.btnModify?.setOnClickListener { activity?.cardModifyStorage(bean) }
binding.btnOut?.setOnClickListener { activity?.cardOutStorage(bean) }
binding.btnIn?.setOnClickListener { activity?.cardInStorage(bean) }
} }
} }

View File

@@ -1,171 +1,171 @@
package com.lukouguoji.gjc.page.move package com.lukouguoji.gjc.page.move
import android.app.Activity import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.databinding.ObservableBoolean import androidx.databinding.ObservableBoolean
import com.alibaba.android.arouter.facade.annotation.Route import com.alibaba.android.arouter.facade.annotation.Route
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.ActivityIntExpMoveBinding import com.lukouguoji.gjc.databinding.ActivityIntExpMoveBinding
import com.lukouguoji.gjc.viewModel.IntExpMoveViewModel import com.lukouguoji.gjc.viewModel.IntExpMoveViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.impl.FlowBus import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.impl.observe import com.lukouguoji.module_base.impl.observe
import com.lukouguoji.module_base.ktx.addOnItemClickListener import com.lukouguoji.module_base.ktx.addOnItemClickListener
import com.lukouguoji.module_base.ktx.showToast import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.model.ConfirmDialogModel import com.lukouguoji.module_base.model.ConfirmDialogModel
import com.lukouguoji.module_base.model.ScanModel import com.lukouguoji.module_base.model.ScanModel
import com.lukouguoji.module_base.router.ARouterConstants import com.lukouguoji.module_base.router.ARouterConstants
import com.lukouguoji.module_base.util.DeviceUtil import com.lukouguoji.module_base.util.DeviceUtil
/** /**
* 国际出港-出港移库 * 国际出港-出港移库
*/ */
@Route(path = ARouterConstants.ACTIVITY_URL_INT_EXP_MOVE) @Route(path = ARouterConstants.ACTIVITY_URL_INT_EXP_MOVE)
class IntExpMoveActivity : BaseBindingActivity<ActivityIntExpMoveBinding, IntExpMoveViewModel>() { class IntExpMoveActivity : BaseBindingActivity<ActivityIntExpMoveBinding, IntExpMoveViewModel>() {
// 布局 id 不区分设备,平板/手机由资源限定符自动选择: // 布局 id 不区分设备,平板/手机由资源限定符自动选择:
// layout-sw600dp/activity_int_exp_move.xml平板 / layout/activity_int_exp_move.xml手机 // layout-sw600dp/activity_int_exp_move.xml平板 / layout/activity_int_exp_move.xml手机
override fun layoutId() = R.layout.activity_int_exp_move override fun layoutId() = R.layout.activity_int_exp_move
override fun viewModelClass() = IntExpMoveViewModel::class.java override fun viewModelClass() = IntExpMoveViewModel::class.java
/** 手机版筛选弹层显隐(仅 UI 状态,不涉及业务逻辑) */ /** 手机版筛选弹层显隐(仅 UI 状态,不涉及业务逻辑) */
val filterPanelVisible = ObservableBoolean(false) val filterPanelVisible = ObservableBoolean(false)
override fun initOnCreate(savedInstanceState: Bundle?) { override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国际出港移库") setBackArrow(if (DeviceUtil.isPhone()) "出港移库" else "国际出港移库")
binding.viewModel = viewModel binding.viewModel = viewModel
binding.activity = this binding.activity = this
// 手机版专属数据默认「待移库」Tab、Tab 角标计数、特码下拉 // 手机版专属数据默认「待移库」Tab、Tab 角标计数、特码下拉
// 平板端不调用,查询链路与请求次数与改造前完全一致 // 平板端不调用,查询链路与请求次数与改造前完全一致
if (DeviceUtil.isPhone()) { if (DeviceUtil.isPhone()) {
viewModel.initPhoneExtras() viewModel.initPhoneExtras()
} }
initRecyclerView() initRecyclerView()
initListeners() initListeners()
observeData() observeData()
} }
/** /**
* 初始化RecyclerView * 初始化RecyclerView
*/ */
private fun initRecyclerView() { private fun initRecyclerView() {
viewModel.pageModel.bindSmartRefreshLayout( viewModel.pageModel.bindSmartRefreshLayout(
binding.srl, binding.srl,
binding.rv, binding.rv,
viewModel, viewModel,
this this
) )
binding.rv.addOnItemClickListener(viewModel) binding.rv.addOnItemClickListener(viewModel)
} }
/** /**
* 初始化监听器 * 初始化监听器
*/ */
private fun initListeners() { private fun initListeners() {
// 移库按钮btnMove 只存在于平板变体(手机版底部条走 setOnActionClick故判空 // 移库按钮btnMove 只存在于平板变体(手机版底部条走 setOnActionClick故判空
binding.btnMove?.setOnClickListener { binding.btnMove?.setOnClickListener {
showMoveConfirmDialog() showMoveConfirmDialog()
} }
} }
/** /**
* 观察数据变化 * 观察数据变化
*/ */
private fun observeData() { private fun observeData() {
// 监听item选择变化事件,更新全选状态 // 监听item选择变化事件,更新全选状态
FlowBus.with<String>(ConstantEvent.EVENT_CHECK_CHANGED).observe(this) { FlowBus.with<String>(ConstantEvent.EVENT_CHECK_CHANGED).observe(this) {
viewModel.onItemCheckChanged() viewModel.onItemCheckChanged()
} }
// 监听刷新事件 // 监听刷新事件
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).observe(this) { FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).observe(this) {
viewModel.refresh() viewModel.refresh()
} }
// 初始加载数据 // 初始加载数据
viewModel.refresh() viewModel.refresh()
} }
/** /**
* 扫码运单号 * 扫码运单号
*/ */
fun scanWaybill() { fun scanWaybill() {
ScanModel.startScan(this, Constant.RequestCode.WAYBILL) ScanModel.startScan(this, Constant.RequestCode.WAYBILL)
} }
// ==================== 手机版专用交互(复用既有 ViewModel 字段,无新增业务逻辑) ==================== // ==================== 手机版专用交互(复用既有 ViewModel 字段,无新增业务逻辑) ====================
/** /**
* 手机版筛选弹层显隐切换 * 手机版筛选弹层显隐切换
*/ */
fun toggleFilterPanel() { fun toggleFilterPanel() {
filterPanelVisible.set(!filterPanelVisible.get()) filterPanelVisible.set(!filterPanelVisible.get())
} }
/** /**
* 手机版筛选:重置 * 手机版筛选:重置
* *
* 只清空弹层内的三个条件(承运人 / 运单类型 / 特码),不影响 Tab 与顶部搜索框。 * 只清空弹层内的三个条件(承运人 / 运单类型 / 特码),不影响 Tab 与顶部搜索框。
*/ */
fun resetFilter() { fun resetFilter() {
viewModel.by1.value = "" viewModel.by1.value = ""
viewModel.awbType.value = "" viewModel.awbType.value = ""
viewModel.spCode.value = "" viewModel.spCode.value = ""
} }
/** /**
* 手机版筛选:确定 * 手机版筛选:确定
*/ */
fun confirmFilter() { fun confirmFilter() {
filterPanelVisible.set(false) filterPanelVisible.set(false)
viewModel.searchClick() viewModel.searchClick()
} }
/** /**
* 显示移库确认对话框 * 显示移库确认对话框
* *
* 手机版底部操作条通过 XML 的 setOnActionClick 调用,故为 public。 * 手机版底部操作条通过 XML 的 setOnActionClick 调用,故为 public。
*/ */
fun showMoveConfirmDialog() { fun showMoveConfirmDialog() {
val selectedItems = viewModel.getSelectedItems() val selectedItems = viewModel.getSelectedItems()
if (selectedItems.isEmpty()) { if (selectedItems.isEmpty()) {
showToast("请至少选择一条运单") showToast("请至少选择一条运单")
return return
} }
ConfirmDialogModel( ConfirmDialogModel(
message = "确定要移库选中的 ${selectedItems.size} 条运单吗?", message = "确定要移库选中的 ${selectedItems.size} 条运单吗?",
title = "移库确认" title = "移库确认"
) { ) {
viewModel.submitMove() viewModel.submitMove()
}.show() }.show()
} }
/** /**
* 扫码回调 * 扫码回调
*/ */
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
if (requestCode == Constant.RequestCode.WAYBILL && resultCode == Activity.RESULT_OK) { if (requestCode == Constant.RequestCode.WAYBILL && resultCode == Activity.RESULT_OK) {
val code = data?.getStringExtra(Constant.Result.CODED_CONTENT) val code = data?.getStringExtra(Constant.Result.CODED_CONTENT)
viewModel.waybillNo.value = code viewModel.waybillNo.value = code
viewModel.searchClick() viewModel.searchClick()
} }
} }
companion object { companion object {
@JvmStatic @JvmStatic
fun start(context: Context) { fun start(context: Context) {
val starter = Intent(context, IntExpMoveActivity::class.java) val starter = Intent(context, IntExpMoveActivity::class.java)
context.startActivity(starter) context.startActivity(starter)
} }
} }
} }

View File

@@ -17,6 +17,7 @@ import com.lukouguoji.module_base.ktx.noNull
import com.lukouguoji.module_base.ktx.showToast import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.model.ScanModel import com.lukouguoji.module_base.model.ScanModel
import com.lukouguoji.module_base.util.DictUtils
import dev.utils.app.info.KeyValue import dev.utils.app.info.KeyValue
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -38,6 +39,89 @@ class IntExpStorageUseViewModel : BasePageViewModel() {
val totalPc = MutableLiveData("0") // 总件数 val totalPc = MutableLiveData("0") // 总件数
val totalWeight = MutableLiveData("0") // 总重量 val totalWeight = MutableLiveData("0") // 总重量
// ========== 5.5寸手机版专属 ==========
// 筛选弹层显隐
val filterVisible = MutableLiveData(false)
// 筛选条件(设计稿弹层 8 项中平板没有的 6 项;平板布局无对应控件 → 恒为空 → 不进请求)
val agentId = MutableLiveData("") // 代理agentCode
val spCode = MutableLiveData("") // 特码
val dest = MutableLiveData("") // 目的站
val awbType = MutableLiveData("") // 运单类型pageQuery 无此入参,预留,见接口问题清单)
val businessType = MutableLiveData("") // 业务类型(同上预留)
val goodsCn = MutableLiveData("") // 品名(中)(同上预留)
// 筛选下拉字典initPhoneExtras 加载,平板不请求)
val agentList = MutableLiveData(listOf(KeyValue("全部", "")))
val specialCodeList = MutableLiveData<List<KeyValue>>(emptyList())
val awbTypeList = MutableLiveData<List<KeyValue>>(emptyList())
val businessTypeList = MutableLiveData(
listOf(
KeyValue("全部", ""),
KeyValue("普货", "1"),
KeyValue("特货", "2")
)
)
// 三格统计:未清仓 / 已清仓(总票数复用 totalWbNumber服务端全量口径
// 复用 pageQueryTotal 按 clearNormal=0/1 各查一次(入参 schema 含 clearNormal
val unclearedCount = MutableLiveData("0")
val clearedCount = MutableLiveData("0")
private var phoneExtrasEnabled = false
/**
* 手机形态专属初始化Activity 在 DeviceUtil.isPhone() 时调用)。
* 平板端不调用,请求次数与行为零变化。
*/
fun initPhoneExtras() {
phoneExtrasEnabled = true
// 代理(与 06 出港查询同源接口)
launchCollect({ NetApply.api.getIntExpAgentList() }) {
onSuccess = { result ->
val list = mutableListOf(KeyValue("全部", ""))
result.data?.forEach { list.add(KeyValue(it.name ?: "", it.code ?: "")) }
agentList.value = list
}
}
// 特码flag=1 国际ieFlag 必须留空——传 "E" 后端返回空数组
DictUtils.getSpecialCodeList(addAll = false, flag = 1, ieFlag = "") { list ->
specialCodeList.postValue(listOf(KeyValue("全部", "")) + list)
}
// 运单类型type=IO 国际出港)
DictUtils.getWaybillTypeList(type = Constant.businessType.IO, addAll = true) {
awbTypeList.postValue(it)
}
}
/** 筛选按钮点击 - 打开筛选面板 */
fun filterClick() {
filterVisible.value = true
}
/** 关闭筛选面板 */
fun closeFilter() {
filterVisible.value = false
}
/** 重置筛选条件 */
fun resetFilter() {
flightDate.value = ""
flightNo.value = ""
agentId.value = ""
spCode.value = ""
dest.value = ""
awbType.value = ""
businessType.value = ""
goodsCn.value = ""
}
/** 确认筛选 - 关闭面板并刷新 */
fun confirmFilter() {
filterVisible.value = false
refresh()
}
// ========== 全选状态 ========== // ========== 全选状态 ==========
val isAllChecked = MutableLiveData(false) val isAllChecked = MutableLiveData(false)
@@ -301,13 +385,20 @@ class IntExpStorageUseViewModel : BasePageViewModel() {
* 获取数据 (重写BasePageViewModel) * 获取数据 (重写BasePageViewModel)
*/ */
override fun getData() { override fun getData() {
// 构建搜索条件 // 构建搜索条件(手机专属 6 项平板恒为空不进请求awbType/businessType/goodsCn
// 为 pageQuery 未定义入参,后端静默忽略,补齐后自动生效,见接口问题清单)
val filterParams = mapOf( val filterParams = mapOf(
"fdate" to flightDate.value?.ifEmpty { null }, "fdate" to flightDate.value?.ifEmpty { null },
"fno" to flightNo.value?.ifEmpty { null }, "fno" to flightNo.value?.ifEmpty { null },
"wbNo" to wbNo.value?.ifEmpty { null }, "wbNo" to wbNo.value?.ifEmpty { null },
"location" to location.value?.ifEmpty { null }, "location" to location.value?.ifEmpty { null },
"clearNormal" to clearResult.value?.ifEmpty { null } "clearNormal" to clearResult.value?.ifEmpty { null },
"agentCode" to agentId.value?.ifEmpty { null },
"spCode" to spCode.value?.ifEmpty { null },
"dest" to dest.value?.ifEmpty { null },
"awbType" to awbType.value?.ifEmpty { null },
"businessType" to businessType.value?.ifEmpty { null },
"goodsCn" to goodsCn.value?.ifEmpty { null }
) )
// 列表参数 (含分页) // 列表参数 (含分页)
@@ -339,5 +430,17 @@ class IntExpStorageUseViewModel : BasePageViewModel() {
totalWeight.value = (data?.totalWeight ?: 0.0).toString() totalWeight.value = (data?.totalWeight ?: 0.0).toString()
} }
} }
// 手机专属:未清仓/已清仓分项统计(同条件 + clearNormal=0/1 各查一次,平板不发)
if (phoneExtrasEnabled) {
val unclearedParams = (filterParams + mapOf("clearNormal" to "0")).toRequestBody()
launchCollect({ NetApply.api.getIntExpStorageUseTotal(unclearedParams) }) {
onSuccess = { unclearedCount.value = (it.data?.wbNumber ?: 0).toString() }
}
val clearedParams = (filterParams + mapOf("clearNormal" to "1")).toRequestBody()
launchCollect({ NetApply.api.getIntExpStorageUseTotal(clearedParams) }) {
onSuccess = { clearedCount.value = (it.data?.wbNumber ?: 0).toString() }
}
}
} }
} }

View File

@@ -0,0 +1,253 @@
<?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="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType" />
<import type="com.lukouguoji.gjc.R" />
<variable
name="viewModel"
type="com.lukouguoji.gjc.viewModel.IntExpStorageUseViewModel" />
<variable
name="activity"
type="com.lukouguoji.gjc.activity.IntExpStorageUseActivity" />
</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" />
<!-- 搜索区域 -->
<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
hint='@{"请选择航班日期"}'
icon="@{@drawable/img_date}"
type="@{SearchLayoutType.DATE}"
value="@={viewModel.flightDate}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 航班号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请输入航班号"}'
setUpperCaseAlphanumeric="@{true}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.flightNo}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 清仓综合结果 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请选择清仓结果"}'
list="@{viewModel.clearResultList}"
type="@{SearchLayoutType.SPINNER}"
value="@={viewModel.clearResult}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 运单号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
autoQueryEnabled="@{true}"
autoQueryMaxLength="@{8}"
autoQueryMinLength="@{4}"
autoQueryParamKey="@{`wbNo`}"
autoQueryTitle="@{`选择运单号`}"
autoQueryUrl="@{`/IntExpStorageUse/queryWbNoList`}"
hint='@{"请输入运单号"}'
icon="@{@drawable/img_scan}"
setOnIconClickListener="@{(v)-> viewModel.scanWbNo()}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.wbNo}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 库位号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请输入库位号"}'
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.location}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 搜索按钮 -->
<LinearLayout
android:layout_width="200dp"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="10dp">
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:onClick="@{()-> viewModel.searchClick()}"
android:padding="2dp"
android:src="@drawable/img_search" />
<!-- 全局展开/收起按钮 -->
<ImageView
loadImage="@{viewModel.isAllExpanded ? R.drawable.ic_new_expand_1 : R.drawable.ic_new_expand_1}"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="16dp"
android:contentDescription="展开/收起全部子列表"
android:onClick="@{()-> viewModel.toggleAllExpand()}"
android:padding="2dp"
android:scaleType="fitCenter" />
</LinearLayout>
</LinearLayout>
<!-- 列表 -->
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/srl"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="3"
tools:listitem="@layout/item_int_exp_storage_use" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<!-- 底部统计和操作按钮 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@android:color/white"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<!-- 全选按钮 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:gravity="center_vertical"
android:onClick="@{()-> viewModel.checkAllClick()}"
android:orientation="horizontal">
<ImageView
android:id="@+id/checkIcon"
setIVCheckAllImage="@{viewModel.isAllChecked}"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="5dp"
android:src="@drawable/img_check_all_unchecked" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="全选"
android:textColor="@color/color_66"
android:textSize="18sp" />
</LinearLayout>
<!-- 统计信息 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{"合计:"+viewModel.totalWbNumber+"票"}'
android:textColor="@color/bottom_tool_tips_text_color"
android:textSize="18sp"
android:textStyle="bold" />
<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="18sp"
android:textStyle="bold" />
<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="18sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 操作按钮组 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- 清仓按钮 -->
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()-> activity.showClearDialog()}"
android:text="清 仓" />
<!-- 修改库位按钮 -->
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()-> activity.showModifyStorageDialog()}"
android:text="修改库位" />
<!-- 出库按钮 -->
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()-> activity.showOutStorageDialog()}"
android:text="出 库" />
<!-- 入库按钮 -->
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()-> activity.showInStorageDialog()}"
android:text="入 库" />
</LinearLayout>
</LinearLayout>
</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.IntExpInStorageDialogModel" />
</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.locationList}"
value="@={model.selectedLocationCode}" />
</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,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.IntExpModifyStorageDialogModel" />
</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.locationList}"
value="@={model.selectedLocationCode}" />
</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,86 @@
<?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.IntExpMoveClearDialogModel" />
</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}"
list="@{model.clearNormalList}"
value="@={model.clearNormal}" />
</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,419 @@
<?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:loadImage="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable
name="bean"
type="com.lukouguoji.module_base.bean.GjcMaWb" />
<variable
name="position"
type="Integer" />
</data>
<!-- 主列表项容器 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:orientation="vertical">
<!-- 白色卡片主要内容区域 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_8"
android:orientation="vertical">
<!-- 主要内容区域 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingVertical="20dp"
android:paddingHorizontal="10dp">
<!-- 选中图标 -->
<ImageView
android:id="@+id/iv_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginTop="0.5px"
android:layout_marginEnd="10dp"
loadImage="@{bean.checked.get() ? @drawable/img_plane_s : @drawable/img_plane}"
android:src="@drawable/img_plane" />
<!-- 数据展示区域 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<!-- 第一行:运单号、航班信息、航程、品名、重量 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- 运单号 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.9"
android:orientation="horizontal">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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" />
</LinearLayout>
<!-- 航班信息 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:orientation="horizontal">
<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.flightInfo}"
android:textSize="15sp" />
</LinearLayout>
<!-- 航程 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:orientation="horizontal">
<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.range}"
android:textSize="15sp" />
</LinearLayout>
<!-- 品名(英) -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:orientation="horizontal">
<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:ellipsize="end"
android:maxLines="1"
android:text="@{bean.goods}"
android:textSize="15sp" />
</LinearLayout>
<!-- 重量 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:orientation="horizontal">
<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((int)bean.weight)}"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
<!-- 第二行:代理人、件数、清仓正常否、入库时间、库位数 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<!-- 代理人 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.9"
android:orientation="horizontal">
<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.agentCode}"
android:textSize="15sp" />
</LinearLayout>
<!-- 件数 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:orientation="horizontal">
<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="@{String.valueOf(bean.pc)}"
android:textSize="15sp" />
</LinearLayout>
<!-- 清仓正常否 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:orientation="horizontal">
<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:background="@{`1`.equals(bean.clearNormal) ? @drawable/tag_status_green : (`0`.equals(bean.clearNormal) ? @drawable/tag_status_orange : @drawable/tag_status_gray)}"
android:paddingHorizontal="8dp"
android:paddingVertical="2dp"
android:text="@{bean.clearNormalText}"
android:textColor="@{`1`.equals(bean.clearNormal) ? @color/text_green : (`0`.equals(bean.clearNormal) ? @color/text_orange : @color/text_gray)}"
android:textSize="14sp"
android:visibility="@{bean.clearNormalText != null &amp;&amp; !bean.clearNormalText.isEmpty() ? View.VISIBLE : View.GONE}" />
</LinearLayout>
<!-- 入库时间 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:orientation="horizontal">
<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" />
</LinearLayout>
<!-- 库位数 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:orientation="horizontal">
<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.storageUseNumber)}"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- 展开/折叠按钮 -->
<ImageView
android:id="@+id/iv_show"
visible="@{bean.storageUseList != null &amp;&amp; !bean.storageUseList.empty}"
android:layout_width="match_parent"
android:layout_height="20dp"
android:paddingVertical="2.5dp"
android:layout_marginTop="-20dp"
android:scaleType="center"
android:src="@mipmap/img_down" />
</LinearLayout>
<!-- 库位明细列表容器(在白色卡片外面) -->
<LinearLayout
visible="@{bean.showMore}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@drawable/bg_white_radius_8"
android:orientation="vertical"
android:visibility="gone">
<!-- 表头(浅蓝色背景,顶部圆角同卡片) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_arrive_sub_header"
android:orientation="horizontal"
android:paddingHorizontal="10dp"
android:paddingVertical="10dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center"
android:text="选项"
android:textColor="@color/text_normal"
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/text_normal"
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/text_normal"
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/text_normal"
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/text_normal"
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/text_normal"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1px"
app:dividerColor="@color/sub_list_divider" />
<!-- 子列表 RecyclerView -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_sub"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
</LinearLayout>
</layout>

View File

@@ -1,253 +1,327 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
国际出港仓库 —— 手机版布局5.5 寸手持端,最小宽度 < 600dp 时生效)
平板版为同名文件 layout-sw600dp/activity_int_exp_storage_use.xml两者是同一布局的资源变体
DataBinding 因此生成同一个 ActivityIntExpStorageUseBinding 类。
变体之间必须满足:
· DataBinding 变量完全一致viewModel / activity
· 保留 Activity 中引用的控件 idsrl / rv
· 平板独有的 checkIcon底部全选手机版不提供Binding 基类中自动变 @Nullable
交互差异(均复用既有 IntExpStorageUseViewModel 字段与接口):
· 平板 5 个横排搜索条 → 手机顶部搜索框(运单号)+ 底部筛选弹层 8 项
(设计稿弹层无「库位号/清仓结果」两项,对应平板字段保持空值不参与请求)
· 三格统计(总票数/未清仓/已清仓后两格为手机专属统计请求initPhoneExtras 开启,
复用 pageQueryTotal 按 clearNormal=0/1 各查一次)
· 平板底部批量操作条 → 手机卡片级操作按钮(见 item 布局),无全选/批量
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android" <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"> xmlns:tools="http://schemas.android.com/tools">
<data> <data>
<import type="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType" /> <import type="android.view.View" />
<import type="com.lukouguoji.gjc.R" /> <import type="com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayoutType" />
<variable <variable
name="viewModel" name="viewModel"
type="com.lukouguoji.gjc.viewModel.IntExpStorageUseViewModel" /> type="com.lukouguoji.gjc.viewModel.IntExpStorageUseViewModel" />
<!-- 与平板变体保持一致(手机版卡片操作经 ViewHolder 调 ActivityXML 中不直接引用) -->
<variable <variable
name="activity" name="activity"
type="com.lukouguoji.gjc.activity.IntExpStorageUseActivity" /> type="com.lukouguoji.gjc.activity.IntExpStorageUseActivity" />
</data> </data>
<LinearLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="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" />
<!-- 搜索区域 -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginHorizontal="10dp" android:orientation="vertical">
android:layout_marginTop="10dp"
android:gravity="center_vertical" <include layout="@layout/title_tool_bar" />
android:orientation="horizontal">
<!-- ==================== 搜索行 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
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.scanWbNo()}"
setRefreshCallBack="@{viewModel::searchClick}"
value="@={viewModel.wbNo}" />
</LinearLayout>
<!-- ==================== 三格统计:总票数 / 未清仓 / 已清仓 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<!-- 总票数(蓝) -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
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_primary" />
<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.totalWbNumber}"
android:textColor="@color/phone_primary"
android:textSize="20sp"
android:textStyle="bold"
tools:text="8" />
</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.unclearedCount}"
android:textColor="@color/phone_tag_orange_text"
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_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.clearedCount}"
android:textColor="@color/phone_tag_green_text"
android:textSize="20sp"
android:textStyle="bold"
tools:text="4" />
</LinearLayout>
</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"
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_int_exp_storage_use" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
</LinearLayout>
<!-- ==================== 筛选弹层8 项,对应设计稿 filterSheet ==================== -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneFilterPanel
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="8dp"
panelVisible="@{viewModel.filterVisible}"
setOnConfirmClick="@{(v)-> viewModel.confirmFilter()}"
setOnDismissClick="@{(v)-> viewModel.closeFilter()}"
setOnResetClick="@{(v)-> viewModel.resetFilter()}"
title='@{"筛选条件"}'>
<!-- 航班日期 --> <!-- 航班日期 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
hint='@{"请选择航班日期"}' android:layout_width="match_parent"
icon="@{@drawable/img_date}"
type="@{SearchLayoutType.DATE}"
value="@={viewModel.flightDate}"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" /> hint='@{"请选择航班日期"}'
title='@{"航班日期"}'
type="@{PhoneDataLayoutType.DATE}"
value="@={viewModel.flightDate}" />
<!-- 航班号 --> <!-- 航班号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
hint='@{"请输入航班号"}'
setUpperCaseAlphanumeric="@{true}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.flightNo}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 清仓综合结果 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请选择清仓结果"}'
list="@{viewModel.clearResultList}"
type="@{SearchLayoutType.SPINNER}"
value="@={viewModel.clearResult}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 运单号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
autoQueryEnabled="@{true}"
autoQueryMaxLength="@{8}"
autoQueryMinLength="@{4}"
autoQueryParamKey="@{`wbNo`}"
autoQueryTitle="@{`选择运单号`}"
autoQueryUrl="@{`/IntExpStorageUse/queryWbNoList`}"
hint='@{"请输入运单号"}'
icon="@{@drawable/img_scan}"
setOnIconClickListener="@{(v)-> viewModel.scanWbNo()}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.wbNo}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 库位号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请输入库位号"}'
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.location}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 搜索按钮 -->
<LinearLayout
android:layout_width="200dp"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="10dp">
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:onClick="@{()-> viewModel.searchClick()}"
android:padding="2dp"
android:src="@drawable/img_search" />
<!-- 全局展开/收起按钮 -->
<ImageView
loadImage="@{viewModel.isAllExpanded ? R.drawable.ic_new_expand_1 : R.drawable.ic_new_expand_1}"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="16dp"
android:contentDescription="展开/收起全部子列表"
android:onClick="@{()-> viewModel.toggleAllExpand()}"
android:padding="2dp"
android:scaleType="fitCenter" />
</LinearLayout>
</LinearLayout>
<!-- 列表 -->
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/srl"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="3"
tools:listitem="@layout/item_int_exp_storage_use" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<!-- 底部统计和操作按钮 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@android:color/white"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<!-- 全选按钮 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="5dp" hint='@{"请输入航班号"}'
android:gravity="center_vertical" title='@{"航班号"}'
android:onClick="@{()-> viewModel.checkAllClick()}" type="@{PhoneDataLayoutType.INPUT}"
android:orientation="horizontal"> value="@={viewModel.flightNo}" />
<ImageView <!-- 代理(手机专属筛选,字典由 initPhoneExtras 加载) -->
android:id="@+id/checkIcon" <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
setIVCheckAllImage="@{viewModel.isAllChecked}" android:layout_width="match_parent"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="5dp"
android:src="@drawable/img_check_all_unchecked" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="全选"
android:textColor="@color/color_66"
android:textSize="18sp" />
</LinearLayout>
<!-- 统计信息 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="20dp" hint='@{"请选择代理"}'
android:layout_weight="1" list="@{viewModel.agentList}"
android:gravity="center_vertical" title='@{"代理"}'
android:orientation="horizontal"> type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.agentId}" />
<TextView <!-- 特码 -->
android:layout_width="wrap_content" <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text='@{"合计:"+viewModel.totalWbNumber+"票"}'
android:textColor="@color/bottom_tool_tips_text_color"
android:textSize="18sp"
android:textStyle="bold" />
<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="18sp"
android:textStyle="bold" />
<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="18sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 操作按钮组 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> hint='@{"请选择特码"}'
list="@{viewModel.specialCodeList}"
title='@{"特码"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.spCode}" />
<!-- 清仓按钮 --> <!-- 目的站 -->
<TextView <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
style="@style/tv_bottom_btn" android:layout_width="match_parent"
android:onClick="@{()-> activity.showClearDialog()}" android:layout_height="wrap_content"
android:text="清 仓" /> hint='@{"请输入目的站"}'
title='@{"目的站"}'
type="@{PhoneDataLayoutType.INPUT}"
value="@={viewModel.dest}" />
<!-- 修改库位按钮 --> <!-- 运单类型pageQuery 无此入参,后端补齐后自动生效,见接口问题清单) -->
<TextView <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
style="@style/tv_bottom_btn" android:layout_width="match_parent"
android:onClick="@{()-> activity.showModifyStorageDialog()}" android:layout_height="wrap_content"
android:text="修改库位" /> hint='@{"请选择运单类型"}'
list="@{viewModel.awbTypeList}"
title='@{"运单类型"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.awbType}" />
<!-- 出库按钮 --> <!-- 业务类型pageQuery 无此入参,同上) -->
<TextView <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
style="@style/tv_bottom_btn" android:layout_width="match_parent"
android:onClick="@{()-> activity.showOutStorageDialog()}" android:layout_height="wrap_content"
android:text="出 库" /> hint='@{"请选择业务类型"}'
list="@{viewModel.businessTypeList}"
title='@{"业务类型"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.businessType}" />
<!-- 入库按钮 --> <!-- 品名(中)pageQuery 无此入参,同上) -->
<TextView <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
style="@style/tv_bottom_btn" android:layout_width="match_parent"
android:onClick="@{()-> activity.showInStorageDialog()}" android:layout_height="wrap_content"
android:text="入 库" /> hint='@{"请输入中文品名"}'
title='@{"品名(中)"}'
type="@{PhoneDataLayoutType.INPUT}"
value="@={viewModel.goodsCn}" />
</LinearLayout> </com.lukouguoji.module_base.ui.weight.phone.PhoneFilterPanel>
</LinearLayout> </FrameLayout>
</LinearLayout>
</layout> </layout>

View File

@@ -1,8 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
入库操作弹框手机版5.5 寸手持端):底部弹层样式。
平板变体layout-sw600dp/dialog_int_exp_in_storage.xml居中弹框
弹出位置由 IntExpInStorageDialogModel 按设备形态选择 BOTTOM/CENTER。
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <layout xmlns:android="http://schemas.android.com/apk/res/android">
<data> <data>
<import type="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType"/> <import type="com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayoutType" />
<variable <variable
name="model" name="model"
@@ -11,77 +16,60 @@
</data> </data>
<LinearLayout <LinearLayout
android:layout_width="480dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/bg_dialog_f2_radius_10" android:background="@drawable/bg_phone_panel_top"
android:gravity="center_horizontal" android:orientation="vertical"
android:orientation="vertical"> android:paddingHorizontal="20dp"
android:paddingTop="24dp"
android:paddingBottom="32dp">
<!-- 标题 --> <!-- 标题行:标题居中 + 右上关闭 -->
<TextView <FrameLayout
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_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="30dp" android:layout_marginBottom="24dp">
android:layout_marginTop="30dp"
android:orientation="vertical">
<!-- 库位号 --> <TextView
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical" android:gravity="center"
android:orientation="horizontal"> android:text="入库操作"
android:textColor="@color/phone_text_strong"
android:textSize="18sp"
android:textStyle="bold" />
<TextView <ImageView
android:layout_width="wrap_content" android:layout_width="24dp"
android:layout_height="wrap_content" android:layout_height="24dp"
completeSpace="@{5}" android:layout_gravity="end|center_vertical"
android:text="库位号:" android:onClick="@{()-> model.dismiss()}"
android:textColor="@color/text_normal" android:src="@drawable/ic_phone_close" />
android:textSize="16sp" />
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout </FrameLayout>
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
type="@{SearchLayoutType.SPINNER}"
hint='@{"请选择库位"}'
list="@{model.locationList}"
value="@={model.selectedLocationCode}" />
</LinearLayout> <!-- 库位号下拉 -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
</LinearLayout> android:layout_width="match_parent"
<!-- 底部按钮 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="40dp" hint='@{"请选择库位"}'
android:layout_marginBottom="20dp"> list="@{model.locationList}"
title='@{"库位号"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={model.selectedLocationCode}" />
<TextView <!-- 确定按钮 -->
style="@style/tv_bottom_btn" <TextView
android:onClick="@{()->model.dismiss()}" android:layout_width="match_parent"
android:text="取消" /> android:layout_height="48dp"
android:layout_marginTop="32dp"
<TextView android:background="@drawable/bg_phone_btn_primary"
style="@style/tv_bottom_btn" android:gravity="center"
android:onClick="@{()->model.onSaveClick()}" android:onClick="@{()-> model.onSaveClick()}"
android:text="确定" /> android:text="确定"
android:textColor="@color/white"
</LinearLayout> android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout> </LinearLayout>
</layout> </layout>

View File

@@ -1,8 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
修改库位弹框手机版5.5 寸手持端):底部弹层样式。
平板变体layout-sw600dp/dialog_int_exp_modify_storage.xml居中弹框由列表勾选唯一库位后打开
无「原库位」项);手机为卡片级操作,运单可能有多个库位,弹层内先单选「原库位」再选新库位。
弹出位置由 IntExpModifyStorageDialogModel 按设备形态选择 BOTTOM/CENTER。
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <layout xmlns:android="http://schemas.android.com/apk/res/android">
<data> <data>
<import type="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType"/> <import type="com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayoutType" />
<variable <variable
name="model" name="model"
@@ -11,77 +17,71 @@
</data> </data>
<LinearLayout <LinearLayout
android:layout_width="480dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/bg_dialog_f2_radius_10" android:background="@drawable/bg_phone_panel_top"
android:gravity="center_horizontal" android:orientation="vertical"
android:orientation="vertical"> android:paddingHorizontal="20dp"
android:paddingTop="24dp"
android:paddingBottom="32dp">
<!-- 标题 --> <!-- 标题行:标题居中 + 右上关闭 -->
<TextView <FrameLayout
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_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="30dp" android:layout_marginBottom="24dp">
android:layout_marginTop="30dp"
android:orientation="vertical">
<!-- 库位号 --> <TextView
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical" android:gravity="center"
android:orientation="horizontal"> android:text="修改库位"
android:textColor="@color/phone_text_strong"
android:textSize="18sp"
android:textStyle="bold" />
<TextView <ImageView
android:layout_width="wrap_content" android:layout_width="24dp"
android:layout_height="wrap_content" android:layout_height="24dp"
completeSpace="@{5}" android:layout_gravity="end|center_vertical"
android:text="库位号:" android:onClick="@{()-> model.dismiss()}"
android:textColor="@color/text_normal" android:src="@drawable/ic_phone_close" />
android:textSize="16sp" />
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout </FrameLayout>
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
type="@{SearchLayoutType.SPINNER}"
hint='@{"请选择库位"}'
list="@{model.locationList}"
value="@={model.selectedLocationCode}" />
</LinearLayout> <!-- 原库位(手机卡片级操作专属:该运单的库位列表,单库位时默认选中) -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
</LinearLayout> android:layout_width="match_parent"
<!-- 底部按钮 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="40dp" hint='@{"请选择原库位"}'
android:layout_marginBottom="20dp"> list="@{model.sourceList}"
title='@{"原库位"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={model.selectedSourceId}" />
<TextView <!-- 新库位下拉 -->
style="@style/tv_bottom_btn" <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:onClick="@{()->model.dismiss()}" android:layout_width="match_parent"
android:text="取消" /> android:layout_height="wrap_content"
android:layout_marginTop="20dp"
hint='@{"请选择库位"}'
list="@{model.locationList}"
title='@{"新库位"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={model.selectedLocationCode}" />
<TextView <!-- 确定按钮 -->
style="@style/tv_bottom_btn" <TextView
android:onClick="@{()->model.onSaveClick()}" android:layout_width="match_parent"
android:text="确定" /> android:layout_height="48dp"
android:layout_marginTop="32dp"
</LinearLayout> 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> </LinearLayout>
</layout> </layout>

View File

@@ -1,8 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
清仓操作弹框手机版5.5 寸手持端):底部弹层样式。
平板变体layout-sw600dp/dialog_int_exp_move_clear.xml居中弹框
弹出位置由 IntExpMoveClearDialogModel 按设备形态选择 BOTTOM/CENTER。
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <layout xmlns:android="http://schemas.android.com/apk/res/android">
<data> <data>
<import type="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType"/> <import type="com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayoutType" />
<variable <variable
name="model" name="model"
@@ -11,76 +16,60 @@
</data> </data>
<LinearLayout <LinearLayout
android:layout_width="480dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/bg_dialog_f2_radius_10" android:background="@drawable/bg_phone_panel_top"
android:gravity="center_horizontal" android:orientation="vertical"
android:orientation="vertical"> android:paddingHorizontal="20dp"
android:paddingTop="24dp"
android:paddingBottom="32dp">
<!-- 标题 --> <!-- 标题行:标题居中 + 右上关闭 -->
<TextView <FrameLayout
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_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="30dp" android:layout_marginBottom="24dp">
android:layout_marginTop="30dp"
android:orientation="vertical">
<!-- 清仓正常 --> <TextView
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical" android:gravity="center"
android:orientation="horizontal"> android:text="清仓操作"
android:textColor="@color/phone_text_strong"
android:textSize="18sp"
android:textStyle="bold" />
<TextView <ImageView
android:layout_width="wrap_content" android:layout_width="24dp"
android:layout_height="wrap_content" android:layout_height="24dp"
completeSpace="@{5}" android:layout_gravity="end|center_vertical"
android:text="清仓正常:" android:onClick="@{()-> model.dismiss()}"
android:textColor="@color/text_normal" android:src="@drawable/ic_phone_close" />
android:textSize="16sp" />
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout </FrameLayout>
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
type="@{SearchLayoutType.SPINNER}"
list="@{model.clearNormalList}"
value="@={model.clearNormal}" />
</LinearLayout> <!-- 清仓正常下拉 -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
</LinearLayout> android:layout_width="match_parent"
<!-- 底部按钮 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="40dp" hint='@{"请选择清仓正常"}'
android:layout_marginBottom="20dp"> list="@{model.clearNormalList}"
title='@{"清仓正常"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={model.clearNormal}" />
<TextView <!-- 确定按钮 -->
style="@style/tv_bottom_btn" <TextView
android:onClick="@{()->model.dismiss()}" android:layout_width="match_parent"
android:text="取消" /> android:layout_height="48dp"
android:layout_marginTop="32dp"
<TextView android:background="@drawable/bg_phone_btn_primary"
style="@style/tv_bottom_btn" android:gravity="center"
android:onClick="@{()->model.onSaveClick()}" android:onClick="@{()-> model.onSaveClick()}"
android:text="确定" /> android:text="确定"
android:textColor="@color/white"
</LinearLayout> android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout> </LinearLayout>
</layout> </layout>

View File

@@ -189,7 +189,7 @@
android:layout_weight="1" android:layout_weight="1"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:text='@{"代理人:" + bean.orDash(bean.agentName ?? bean.agentCode)}' android:text='@{"代理人:" + bean.orDash(bean.agentDisplay)}'
android:textColor="@color/phone_text_body" android:textColor="@color/phone_text_body"
android:textSize="13sp" android:textSize="13sp"
tools:text="代理人:中外运" /> tools:text="代理人:中外运" />

View File

@@ -75,23 +75,51 @@
android:layout_marginTop="12dp" android:layout_marginTop="12dp"
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:text='@{"日期: " + bean.fdate}' android:gravity="center_vertical"
android:textColor="@color/phone_text_body" android:orientation="horizontal">
android:textSize="13sp"
tools:text="日期: 20260721" />
<TextView <ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:src="@drawable/ic_phone_airplane" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:text='@{"日期: " + bean.fdate}'
android:textColor="@color/phone_text_body"
android:textSize="13sp"
tools:text="日期: 20260721" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:text='@{"航程: " + bean.range}' android:gravity="center_vertical"
android:textColor="@color/phone_text_body" android:orientation="horizontal">
android:textSize="13sp"
tools:text="航程: HFE-LAX" /> <ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:src="@drawable/ic_phone_location" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:text='@{"航程: " + bean.range}'
android:textColor="@color/phone_text_body"
android:textSize="13sp"
tools:text="航程: HFE-LAX" />
</LinearLayout>
</LinearLayout> </LinearLayout>
@@ -102,23 +130,54 @@
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:text='@{"代理: " + bean.agentName}' android:gravity="center_vertical"
android:textColor="@color/phone_text_body" android:orientation="horizontal">
android:textSize="13sp"
tools:text="代理: 中外运" />
<TextView <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.agentName}'
android:textColor="@color/phone_text_body"
android:textSize="13sp"
tools:text="代理: 中外运" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:text='@{"特码: " + bean.spCode}' android:gravity="center_vertical"
android:textColor="@color/phone_text_body" android:orientation="horizontal">
android:textSize="13sp"
tools:text="特码: DGR" /> <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.spCode}'
android:textColor="@color/phone_text_body"
android:textSize="13sp"
tools:text="特码: DGR" />
</LinearLayout>
</LinearLayout> </LinearLayout>

View File

@@ -56,14 +56,28 @@
</LinearLayout> </LinearLayout>
<!-- 代理 --> <!-- 代理 -->
<TextView <LinearLayout
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:text='@{"代理: " + bean.agentName}' android:gravity="center_vertical"
android:textColor="@color/phone_text_body" android:orientation="horizontal">
android:textSize="13sp"
tools:text="代理: 马道" /> <ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:src="@drawable/ic_phone_person" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:text='@{"代理: " + bean.agentName}'
android:textColor="@color/phone_text_body"
android:textSize="13sp"
tools:text="代理: 马道" />
</LinearLayout>
<!-- 运抵统计框 --> <!-- 运抵统计框 -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneStatBox <com.lukouguoji.module_base.ui.weight.phone.PhoneStatBox

View File

@@ -1,7 +1,23 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
国际出港仓库 —— 列表项手机版布局5.5 寸手持端,最小宽度 < 600dp 时生效)
平板版为同名文件 layout-sw600dp/item_int_exp_storage_use.xml两者是同一布局的资源变体
DataBinding 因此生成同一个 ItemIntExpStorageUseBinding 类。
变体之间必须满足:
· DataBinding 变量完全一致bean / position
· 平板独有的 iv_icon多选图标/ iv_show展开/ rv_sub库位子列表手机版不提供
Binding 基类中自动变 @NullableIntExpStorageUseViewHolder 已判空
· 手机独有的 ll整卡点击进详情/ btn_clear / btn_modify / btn_out / btn_in
平板变体同样为 @Nullable仅手机路径使用
交互差异:平板勾选主/子列表后底部批量操作 → 手机卡片级四按钮(清仓/修改库位/出库/入库),
语义等价于「勾选该主单 + 其全部库位」再执行既有批量操作(复用 performXxx 请求链路)。
状态标签clearNormal=1 → 已清仓(绿,清仓按钮置灰不可点);其余 → 未清仓(橙)。
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android" <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">
xmlns:loadImage="http://schemas.android.com/tools">
<data> <data>
@@ -16,404 +32,243 @@
type="Integer" /> type="Integer" />
</data> </data>
<!-- 主列表项容器 --> <androidx.appcompat.widget.LinearLayoutCompat
<LinearLayout android:id="@+id/ll"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp" android:layout_marginHorizontal="16dp"
android:layout_marginTop="10dp" android:layout_marginTop="12dp"
android:orientation="vertical"> android:background="@drawable/bg_phone_card"
android:orientation="vertical"
android:padding="14dp">
<!-- 白色卡片主要内容区域 --> <!-- ==================== 头行:蓝点 + 运单号 + 状态标签 + 箭头 ==================== -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_8" android:gravity="center_vertical"
android:orientation="vertical"> android:orientation="horizontal">
<!-- 主要内容区域 --> <View
<LinearLayout android:layout_width="8dp"
android:layout_width="match_parent" 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_height="wrap_content"
android:gravity="center_vertical" android:layout_weight="1"
android:orientation="horizontal" android:text="@{bean.wbNo}"
android:paddingVertical="20dp" android:textColor="@color/phone_text_title"
android:paddingHorizontal="10dp"> android:textSize="16sp"
android:textStyle="bold"
tools:text="78133363396" />
<!-- 选中图标 --> <!-- 已清仓(绿) -->
<ImageView <TextView
android:id="@+id/iv_icon" android:layout_width="wrap_content"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginTop="0.5px"
android:layout_marginEnd="10dp"
loadImage="@{bean.checked.get() ? @drawable/img_plane_s : @drawable/img_plane}"
android:src="@drawable/img_plane" />
<!-- 数据展示区域 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<!-- 第一行:运单号、航班信息、航程、品名、重量 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- 运单号 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.9"
android:orientation="horizontal">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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" />
</LinearLayout>
<!-- 航班信息 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:orientation="horizontal">
<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.flightInfo}"
android:textSize="15sp" />
</LinearLayout>
<!-- 航程 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:orientation="horizontal">
<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.range}"
android:textSize="15sp" />
</LinearLayout>
<!-- 品名(英) -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:orientation="horizontal">
<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:ellipsize="end"
android:maxLines="1"
android:text="@{bean.goods}"
android:textSize="15sp" />
</LinearLayout>
<!-- 重量 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:orientation="horizontal">
<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((int)bean.weight)}"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
<!-- 第二行:代理人、件数、清仓正常否、入库时间、库位数 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<!-- 代理人 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.9"
android:orientation="horizontal">
<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.agentCode}"
android:textSize="15sp" />
</LinearLayout>
<!-- 件数 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:orientation="horizontal">
<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="@{String.valueOf(bean.pc)}"
android:textSize="15sp" />
</LinearLayout>
<!-- 清仓正常否 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:orientation="horizontal">
<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:background="@{`1`.equals(bean.clearNormal) ? @drawable/tag_status_green : (`0`.equals(bean.clearNormal) ? @drawable/tag_status_orange : @drawable/tag_status_gray)}"
android:paddingHorizontal="8dp"
android:paddingVertical="2dp"
android:text="@{bean.clearNormalText}"
android:textColor="@{`1`.equals(bean.clearNormal) ? @color/text_green : (`0`.equals(bean.clearNormal) ? @color/text_orange : @color/text_gray)}"
android:textSize="14sp"
android:visibility="@{bean.clearNormalText != null &amp;&amp; !bean.clearNormalText.isEmpty() ? View.VISIBLE : View.GONE}" />
</LinearLayout>
<!-- 入库时间 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:orientation="horizontal">
<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" />
</LinearLayout>
<!-- 库位数 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:orientation="horizontal">
<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.storageUseNumber)}"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- 展开/折叠按钮 -->
<ImageView
android:id="@+id/iv_show"
visible="@{bean.storageUseList != null &amp;&amp; !bean.storageUseList.empty}"
android:layout_width="match_parent"
android:layout_height="20dp" android:layout_height="20dp"
android:paddingVertical="2.5dp" android:layout_marginStart="8dp"
android:layout_marginTop="-20dp" android:background="@drawable/bg_phone_tag_green"
android:scaleType="center" android:gravity="center"
android:src="@mipmap/img_down" /> android:paddingHorizontal="8dp"
android:text="已清仓"
android:textColor="@color/phone_tag_green_text"
android:textSize="11sp"
android:visibility="@{bean.isCleared ? 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.isCleared ? View.GONE : View.VISIBLE}" />
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginStart="6dp"
android:src="@drawable/ic_phone_chevron_right" />
</LinearLayout> </LinearLayout>
<!-- 库位明细列表容器(在白色卡片外面) --> <!-- ==================== 字段网格:件数 / 重量 ==================== -->
<LinearLayout <LinearLayout
visible="@{bean.showMore}"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp" android:layout_marginTop="12dp"
android:background="@drawable/bg_white_radius_8" android:orientation="horizontal">
android:orientation="vertical"
android:visibility="gone">
<!-- 表头(浅蓝色背景,顶部圆角同卡片) -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/bg_arrive_sub_header" android:layout_weight="1"
android:orientation="horizontal" android:gravity="center_vertical"
android:paddingHorizontal="10dp" android:orientation="horizontal">
android:paddingVertical="10dp">
<ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:src="@drawable/ic_phone_package" />
<TextView <TextView
android:layout_width="0dp" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0.5" android:layout_marginStart="6dp"
android:gravity="center" android:text='@{"件数:" + (bean.pc != null ? String.valueOf(bean.pc) : "--")}'
android:text="选项" android:textColor="@color/phone_text_body"
android:textColor="@color/text_normal" android:textSize="13sp"
android:textSize="14sp" tools:text="件数111" />
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/text_normal"
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/text_normal"
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/text_normal"
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/text_normal"
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/text_normal"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout> </LinearLayout>
<com.google.android.material.divider.MaterialDivider <LinearLayout
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="1px"
app:dividerColor="@color/sub_list_divider" />
<!-- 子列表 RecyclerView -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_sub"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" /> 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="重量2300" />
</LinearLayout>
</LinearLayout> </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_airplane" />
<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.fno)}'
android:textColor="@color/phone_text_body"
android:textSize="13sp"
tools:text="航班号MU1111" />
</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_location" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:text='@{"目的站:" + bean.orDash(bean.dest)}'
android:textColor="@color/phone_text_body"
android:textSize="13sp"
tools:text="目的站HFE" />
</LinearLayout>
</LinearLayout>
<!-- ==================== 操作按钮行:清仓 / 修改库位 / 出库 / 入库 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<!-- 清仓(已清仓时置灰,点击在 ViewHolder 中按 isCleared 拦截) -->
<TextView
android:id="@+id/btn_clear"
android:layout_width="0dp"
android:layout_height="36dp"
android:layout_weight="1"
android:background="@{bean.isCleared ? @drawable/bg_phone_btn_disabled : @drawable/bg_phone_btn_weak}"
android:gravity="center"
android:text="清仓"
android:textColor="@{bean.isCleared ? @color/phone_tag_gray_text : @color/phone_primary}"
android:textSize="13sp" />
<TextView
android:id="@+id/btn_modify"
android:layout_width="0dp"
android:layout_height="36dp"
android:layout_marginStart="8dp"
android:layout_weight="1.3"
android:background="@drawable/bg_phone_btn_weak"
android:gravity="center"
android:text="修改库位"
android:textColor="@color/phone_primary"
android:textSize="13sp" />
<TextView
android:id="@+id/btn_out"
android:layout_width="0dp"
android:layout_height="36dp"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:background="@drawable/bg_phone_btn_weak"
android:gravity="center"
android:text="出库"
android:textColor="@color/phone_primary"
android:textSize="13sp" />
<TextView
android:id="@+id/btn_in"
android:layout_width="0dp"
android:layout_height="36dp"
android:layout_marginStart="8dp"
android:layout_weight="1"
android:background="@drawable/bg_phone_btn_weak"
android:gravity="center"
android:text="入库"
android:textColor="@color/phone_primary"
android:textSize="13sp" />
</LinearLayout>
</androidx.appcompat.widget.LinearLayoutCompat>
</layout> </layout>

View File

@@ -13,6 +13,7 @@ import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.impl.FlowBus import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.impl.observe import com.lukouguoji.module_base.impl.observe
import com.lukouguoji.module_base.router.ARouterConstants import com.lukouguoji.module_base.router.ARouterConstants
import com.lukouguoji.module_base.util.DeviceUtil
/** /**
* 国际进港-提取出库 * 国际进港-提取出库
@@ -25,9 +26,12 @@ class IntImpPickUpDLVActivity :
override fun viewModelClass() = IntImpPickUpDLVViewModel::class.java override fun viewModelClass() = IntImpPickUpDLVViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) { override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国际进港出库") setBackArrow(if (DeviceUtil.isPhone()) "提取出库" else "国际进港出库")
binding.viewModel = viewModel binding.viewModel = viewModel
// 手机形态专属:待出库 Tab 默认态 + 角标计数 + 特码字典(平板不调用,行为零变化)
if (DeviceUtil.isPhone()) viewModel.initPhoneExtras()
// 绑定分页 // 绑定分页
viewModel.pageModel.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, this) viewModel.pageModel.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, this)

View File

@@ -0,0 +1,45 @@
package com.lukouguoji.gjj.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.ActivityIntImpPickUpDetailBinding
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.IntImpPickUpDLVBean
import com.lukouguoji.module_base.common.Constant
/**
* 国际进港提取出库-运单详情5.5 寸手机版专属页面)
*
* 设计稿 09_提取出库「查看详情」内嵌页蓝头运单卡品名/件重/特码/代理/港站/航班/库位/提货单号)
* + 绿头提货信息卡(柜台办理人/时间,已出库追加出库人/出库时间)。
* 数据直接复用列表已加载的 beanIntent 传 Serializable零新增请求平板端无入口不可达。
*/
class IntImpPickUpDetailActivity :
BaseBindingActivity<ActivityIntImpPickUpDetailBinding, BaseViewModel>() {
override fun layoutId() = R.layout.activity_int_imp_pick_up_detail
override fun viewModelClass() = BaseViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("运单详情")
val bean = intent.getSerializableExtra(Constant.Key.DATA) as? IntImpPickUpDLVBean
if (bean == null) {
finish()
return
}
binding.bean = bean
}
companion object {
@JvmStatic
fun start(context: Context, bean: IntImpPickUpDLVBean) {
context.startActivity(
Intent(context, IntImpPickUpDetailActivity::class.java)
.putExtra(Constant.Key.DATA, bean)
)
}
}
}

View File

@@ -19,6 +19,7 @@ import com.lukouguoji.module_base.ktx.getLifecycleOwner
import com.lukouguoji.module_base.ktx.setUpperCaseAlphanumericFilter import com.lukouguoji.module_base.ktx.setUpperCaseAlphanumericFilter
import com.lukouguoji.module_base.ktx.setUpperCaseLetterFilter import com.lukouguoji.module_base.ktx.setUpperCaseLetterFilter
import com.lukouguoji.module_base.router.ARouterConstants import com.lukouguoji.module_base.router.ARouterConstants
import com.lukouguoji.module_base.util.DeviceUtil
/** /**
* 国际进港查询列表页 * 国际进港查询列表页
@@ -32,7 +33,7 @@ class IntImpQueryActivity :
override fun viewModelClass() = IntImpQueryViewModel::class.java override fun viewModelClass() = IntImpQueryViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) { override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国际进港查询") setBackArrow(if (DeviceUtil.isPhone()) "进港查询" else "国际进港查询")
binding.viewModel = viewModel binding.viewModel = viewModel
@@ -50,22 +51,35 @@ class IntImpQueryActivity :
viewModel.initSpecialCodeList() viewModel.initSpecialCodeList()
viewModel.initFilterLists() viewModel.initFilterLists()
// 观察筛选面板显示状态 // 平板变体才有侧滑筛选面板filter_panel/filter_overlay 手机变体不存在Binding 字段为 null
viewModel.filterVisible.observe(this) { visible -> val padFilterPanel = binding.filterPanel
if (visible) showFilterPanel() else hideFilterPanel() if (padFilterPanel != null) {
// 观察筛选面板显示状态(滑入/滑出动画)
viewModel.filterVisible.observe(this) { visible ->
if (visible) showFilterPanel() else hideFilterPanel()
}
// 航班号:大写字母+数字
padFilterPanel.filterFlightNo.et.setUpperCaseAlphanumericFilter()
// 始发港:仅大写字母
padFilterPanel.filterOrigin.et.setUpperCaseLetterFilter()
} else {
// 手机变体PhoneFilterPanel 的显隐由 XML 直接绑定 viewModel.filterVisible无需动画代码
binding.phoneFilterFlightNo?.et?.setUpperCaseAlphanumericFilter()
binding.phoneFilterOrigin?.et?.setUpperCaseLetterFilter()
} }
// 航班号:大写字母+数字 // 手机形态专属:已入库/已出库统计计数
binding.filterPanel.filterFlightNo.et.setUpperCaseAlphanumericFilter() if (DeviceUtil.isPhone()) {
// 始发港:仅大写字母 viewModel.initPhoneExtras()
binding.filterPanel.filterOrigin.et.setUpperCaseLetterFilter() }
viewModel.refresh() viewModel.refresh()
} }
private fun showFilterPanel() { private fun showFilterPanel() {
val panel = binding.filterPanel.root val panel = binding.filterPanel?.root ?: return
val overlay = binding.filterOverlay val overlay = binding.filterOverlay ?: return
val panelWidth = window.decorView.width / 3 val panelWidth = window.decorView.width / 3
panel.layoutParams = (panel.layoutParams as FrameLayout.LayoutParams).apply { panel.layoutParams = (panel.layoutParams as FrameLayout.LayoutParams).apply {
@@ -87,8 +101,8 @@ class IntImpQueryActivity :
} }
private fun hideFilterPanel() { private fun hideFilterPanel() {
val panel = binding.filterPanel.root val panel = binding.filterPanel?.root ?: return
val overlay = binding.filterOverlay val overlay = binding.filterOverlay ?: return
if (panel.visibility != View.VISIBLE) return if (panel.visibility != View.VISIBLE) return

View File

@@ -16,6 +16,7 @@ import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.base.CustomVP2Adapter import com.lukouguoji.module_base.base.CustomVP2Adapter
import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.router.ARouterConstants import com.lukouguoji.module_base.router.ARouterConstants
import com.lukouguoji.module_base.util.DeviceUtil
/** /**
* 国际进港查询详情页面 * 国际进港查询详情页面
@@ -28,7 +29,7 @@ class IntImpQueryDetailsActivity :
override fun viewModelClass() = IntImpQueryDetailsViewModel::class.java override fun viewModelClass() = IntImpQueryDetailsViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) { override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国际进港查询详情") setBackArrow(if (DeviceUtil.isPhone()) "进港货物" else "国际进港查询详情")
binding.viewModel = viewModel binding.viewModel = viewModel
// 初始化ViewModel(传入maWbId) // 初始化ViewModel(传入maWbId)

View File

@@ -19,6 +19,7 @@ import com.lukouguoji.module_base.impl.observe
import com.lukouguoji.module_base.ktx.commonAdapter import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.showToast import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.router.ARouterConstants import com.lukouguoji.module_base.router.ARouterConstants
import com.lukouguoji.module_base.util.DeviceUtil
/** /**
* 国际进港-仓库 * 国际进港-仓库
@@ -31,10 +32,13 @@ class IntImpStorageUseActivity :
override fun viewModelClass() = IntImpStorageUseViewModel::class.java override fun viewModelClass() = IntImpStorageUseViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) { override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国际进港仓库") setBackArrow(if (DeviceUtil.isPhone()) "进港仓库" else "国际进港仓库")
binding.viewModel = viewModel binding.viewModel = viewModel
binding.activity = this binding.activity = this
// 手机形态专属:筛选字典 + 未清仓/已清仓分项统计(平板不调用,行为零变化)
if (DeviceUtil.isPhone()) viewModel.initPhoneExtras()
// 绑定分页 // 绑定分页
viewModel.pageModel.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, this) viewModel.pageModel.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, this)
@@ -182,6 +186,55 @@ class IntImpStorageUseActivity :
}.show(this) }.show(this)
} }
// ==================== 5.5寸手机版:卡片级操作 ====================
// 语义等价于「勾选该主单 + 其全部库位」再执行平板的批量操作,复用 performXxx 请求链路。
/** 卡片「清仓」已清仓的卡片按钮置灰ViewHolder 已拦截) */
fun cardClear(bean: com.lukouguoji.module_base.bean.GjcMaWb) {
val maWbListForClear = listOf(bean.copy(storageUseList = bean.storageUseList ?: emptyList()))
IntImpMoveClearDialogModel { dialog ->
viewModel.performClear(dialog.clearNormal.value ?: "", maWbListForClear)
}.show(this)
}
/** 卡片「修改库位」:弹层内先单选原库位(未出库的才可选,单库位时默认选中)再选新库位 */
fun cardModifyStorage(bean: com.lukouguoji.module_base.bean.GjcMaWb) {
// 已出库的分单不允许修改库位(与平板校验同口径)
val modifiableList = (bean.storageUseList ?: emptyList())
.filter { it.outOpId.isNullOrEmpty() && it.outDate.isNullOrEmpty() }
if (modifiableList.isEmpty()) {
showToast(if (bean.storageUseList.isNullOrEmpty()) "该运单暂无库位" else "该运单库位均已出库,不允许修改库位")
return
}
IntImpModifyStorageDialogModel(sourceStorageList = modifiableList) { dialog ->
val sourceStorage = dialog.selectedSourceStorage ?: return@IntImpModifyStorageDialogModel
viewModel.performModifyStorage(dialog.locationName, dialog.locationId, sourceStorage)
}.show(this)
}
/** 卡片「出库」:该运单全部库位出库(与平板勾选主单后出库同语义) */
fun cardOutStorage(bean: com.lukouguoji.module_base.bean.GjcMaWb) {
val storageList = bean.storageUseList ?: emptyList()
if (storageList.isEmpty()) {
showToast("该运单暂无库位")
return
}
ConfirmDialogModel(
message = "确定要将运单 ${bean.wbNo}${storageList.size} 个库位执行出库操作吗?",
title = "出库确认"
) {
viewModel.performOutStorage(storageList)
}.show(this)
}
/** 卡片「入库」:弹层选库位后整票入库 */
fun cardInStorage(bean: com.lukouguoji.module_base.bean.GjcMaWb) {
val maWbListForInStorage = listOf(bean.copy(storageUseList = bean.storageUseList ?: emptyList()))
IntImpInStorageDialogModel { dialog ->
viewModel.performInStorage(dialog.locationName, dialog.locationId, maWbListForInStorage)
}.show(this)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
if (requestCode == Constant.RequestCode.WAYBILL && resultCode == Activity.RESULT_OK) { if (requestCode == Constant.RequestCode.WAYBILL && resultCode == Activity.RESULT_OK) {

View File

@@ -5,6 +5,7 @@ import androidx.lifecycle.MutableLiveData
import com.lukouguoji.gjj.R import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.DialogIntImpInStorageBinding import com.lukouguoji.gjj.databinding.DialogIntImpInStorageBinding
import com.lukouguoji.module_base.base.BaseDialogModel import com.lukouguoji.module_base.base.BaseDialogModel
import com.lukouguoji.module_base.util.DeviceUtil
import com.lukouguoji.module_base.http.net.NetApply import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.ktx.launchCollect import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.showToast import com.lukouguoji.module_base.ktx.showToast
@@ -16,7 +17,9 @@ import dev.utils.app.info.KeyValue
*/ */
class IntImpInStorageDialogModel( class IntImpInStorageDialogModel(
private val callback: (IntImpInStorageDialogModel) -> Unit private val callback: (IntImpInStorageDialogModel) -> Unit
) : BaseDialogModel<DialogIntImpInStorageBinding>(DIALOG_TYPE_CENTER) { ) : BaseDialogModel<DialogIntImpInStorageBinding>(
if (DeviceUtil.isPhone()) DIALOG_TYPE_BOTTOM else DIALOG_TYPE_CENTER
) {
// 库位列表 // 库位列表
val locationList = MutableLiveData<List<KeyValue>>() val locationList = MutableLiveData<List<KeyValue>>()

View File

@@ -8,17 +8,26 @@ import com.lukouguoji.module_base.base.BaseDialogModel
import com.lukouguoji.module_base.http.net.NetApply import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.ktx.launchCollect import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.showToast import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.bean.GjcStorageUse
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import com.lukouguoji.module_base.util.DeviceUtil
import dev.utils.app.info.KeyValue import dev.utils.app.info.KeyValue
/** /**
* 国际进港 - 修改库位对话框 * 国际进港 - 修改库位对话框
* 手机为底部弹层layout/ 变体平板为居中弹框layout-sw600dp/ 变体)。
*
* 平板列表勾选唯一库位后打开弹框内只选新库位sourceStorageList 传 null原库位项不存在于平板布局
* 手机:卡片级操作,运单可能有多个库位——传入该运单未出库的库位列表,弹层内先单选「原库位」再选新库位。
*/ */
class IntImpModifyStorageDialogModel( class IntImpModifyStorageDialogModel(
private val currentLocationId: String = "", private val currentLocationId: String = "",
private val currentLocationName: String = "", private val currentLocationName: String = "",
private val sourceStorageList: List<GjcStorageUse>? = null,
private val callback: (IntImpModifyStorageDialogModel) -> Unit private val callback: (IntImpModifyStorageDialogModel) -> Unit
) : BaseDialogModel<DialogIntImpModifyStorageBinding>(DIALOG_TYPE_CENTER) { ) : BaseDialogModel<DialogIntImpModifyStorageBinding>(
if (DeviceUtil.isPhone()) DIALOG_TYPE_BOTTOM else DIALOG_TYPE_CENTER
) {
// 库位列表 // 库位列表
val locationList = MutableLiveData<List<KeyValue>>() val locationList = MutableLiveData<List<KeyValue>>()
@@ -32,6 +41,13 @@ class IntImpModifyStorageDialogModel(
// 库位名称 (后端需要的name) // 库位名称 (后端需要的name)
var locationName: String = "" var locationName: String = ""
// ========== 手机卡片级操作专属:原库位单选 ==========
val sourceList = MutableLiveData<List<KeyValue>>(emptyList())
val selectedSourceId = MutableLiveData("")
// 选中的原库位对象(保存后由调用方取用)
var selectedSourceStorage: GjcStorageUse? = null
override fun layoutId(): Int { override fun layoutId(): Int {
return R.layout.dialog_int_imp_modify_storage return R.layout.dialog_int_imp_modify_storage
} }
@@ -46,6 +62,19 @@ class IntImpModifyStorageDialogModel(
locationId = selectedItem?.value ?: "" locationId = selectedItem?.value ?: ""
locationName = selectedItem?.key ?: "" locationName = selectedItem?.key ?: ""
} }
// 手机版:初始化原库位列表,单库位时默认选中
if (sourceStorageList != null) {
sourceList.value = sourceStorageList.map {
KeyValue(it.location ?: "", it.id?.toString() ?: "")
}
selectedSourceId.observeForever { id ->
selectedSourceStorage = sourceStorageList.find { it.id?.toString() == id }
}
if (sourceStorageList.size == 1) {
selectedSourceId.value = sourceStorageList[0].id?.toString() ?: ""
}
}
} }
/** /**
@@ -76,6 +105,10 @@ class IntImpModifyStorageDialogModel(
* 保存按钮点击 * 保存按钮点击
*/ */
fun onSaveClick() { fun onSaveClick() {
if (sourceStorageList != null && selectedSourceStorage == null) {
showToast("请选择原库位")
return
}
if (selectedLocationCode.value.verifyNullOrEmpty("请选择库位")) { if (selectedLocationCode.value.verifyNullOrEmpty("请选择库位")) {
return return
} }

View File

@@ -5,6 +5,7 @@ import androidx.lifecycle.MutableLiveData
import com.lukouguoji.gjj.R import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.DialogIntImpMoveClearBinding import com.lukouguoji.gjj.databinding.DialogIntImpMoveClearBinding
import com.lukouguoji.module_base.base.BaseDialogModel import com.lukouguoji.module_base.base.BaseDialogModel
import com.lukouguoji.module_base.util.DeviceUtil
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import dev.utils.app.info.KeyValue import dev.utils.app.info.KeyValue
@@ -13,7 +14,9 @@ import dev.utils.app.info.KeyValue
*/ */
class IntImpMoveClearDialogModel( class IntImpMoveClearDialogModel(
private val callback: (IntImpMoveClearDialogModel) -> Unit private val callback: (IntImpMoveClearDialogModel) -> Unit
) : BaseDialogModel<DialogIntImpMoveClearBinding>(DIALOG_TYPE_CENTER) { ) : BaseDialogModel<DialogIntImpMoveClearBinding>(
if (DeviceUtil.isPhone()) DIALOG_TYPE_BOTTOM else DIALOG_TYPE_CENTER
) {
// 清仓正常(存储的是 code"0" 或 "1" // 清仓正常(存储的是 code"0" 或 "1"
val clearNormal = MutableLiveData("") val clearNormal = MutableLiveData("")

View File

@@ -1,6 +1,7 @@
package com.lukouguoji.gjj.holder package com.lukouguoji.gjj.holder
import android.view.View import android.view.View
import com.lukouguoji.gjj.activity.IntImpPickUpDetailActivity
import com.lukouguoji.gjj.databinding.ItemIntImpPickUpDlvBinding import com.lukouguoji.gjj.databinding.ItemIntImpPickUpDlvBinding
import com.lukouguoji.module_base.base.BaseViewHolder import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.common.ConstantEvent import com.lukouguoji.module_base.common.ConstantEvent
@@ -9,6 +10,9 @@ import com.lukouguoji.module_base.bean.IntImpPickUpDLVBean
/** /**
* 国际进港-提取出库 列表项ViewHolder * 国际进港-提取出库 列表项ViewHolder
*
* 双形态布局:平板变体含 iv_icon多选图标手机变体含 iv_check圆形勾选框仅待出库形态显示
* 与 tv_detail查看详情。单侧独有的 id 在 Binding 基类中为 @Nullable必须判空访问。
*/ */
class IntImpPickUpDLVViewHolder(view: View) : class IntImpPickUpDLVViewHolder(view: View) :
BaseViewHolder<IntImpPickUpDLVBean, ItemIntImpPickUpDlvBinding>(view) { BaseViewHolder<IntImpPickUpDLVBean, ItemIntImpPickUpDlvBinding>(view) {
@@ -19,11 +23,25 @@ class IntImpPickUpDLVViewHolder(view: View) :
binding.position = position binding.position = position
binding.executePendingBindings() binding.executePendingBindings()
// 点击图标切换选中状态 // 平板:点击图标切换选中状态
binding.ivIcon.setOnClickListener { binding.ivIcon?.setOnClickListener {
bean.checked.set(!bean.checked.get()) bean.checked.set(!bean.checked.get())
FlowBus.with<String>(ConstantEvent.EVENT_CHECK_CHANGED).tryEmit("check_changed") FlowBus.with<String>(ConstantEvent.EVENT_CHECK_CHANGED).tryEmit("check_changed")
binding.executePendingBindings() binding.executePendingBindings()
} }
// 手机:圆形勾选框(已出库形态隐藏,无勾选语义)
binding.ivCheck?.setOnClickListener {
if (!bean.isPickedUp) {
bean.checked.set(!bean.checked.get())
FlowBus.with<String>(ConstantEvent.EVENT_CHECK_CHANGED).tryEmit("check_changed")
binding.executePendingBindings()
}
}
// 手机:查看详情(手机专属新页,数据直接传当前 bean零新增请求
binding.tvDetail?.setOnClickListener {
IntImpPickUpDetailActivity.start(itemView.context, bean)
}
} }
} }

View File

@@ -19,9 +19,9 @@ class IntImpQueryViewHolder(view: View) :
// 注册整行点击事件 // 注册整行点击事件
notifyItemClick(position, binding.ll) notifyItemClick(position, binding.ll)
// 侧滑菜单 - 修改按钮 // 侧滑菜单 - 修改按钮(平板变体独有;手机变体无侧滑编辑入口,字段为 null
binding.btnEdit.setOnClickListener { binding.btnEdit?.setOnClickListener {
binding.swipeMenu.quickClose() binding.swipeMenu?.quickClose()
clickListener?.onItemClick(position, 2000) // type=2000表示修改操作 clickListener?.onItemClick(position, 2000) // type=2000表示修改操作
} }
} }

View File

@@ -2,6 +2,8 @@ package com.lukouguoji.gjj.holder
import android.view.View import android.view.View
import com.lukouguoji.gjj.R import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.activity.IntImpQueryDetailsActivity
import com.lukouguoji.gjj.activity.IntImpStorageUseActivity
import com.lukouguoji.gjj.databinding.ItemIntImpStorageUseBinding import com.lukouguoji.gjj.databinding.ItemIntImpStorageUseBinding
import com.lukouguoji.module_base.adapter.setCommonAdapter import com.lukouguoji.module_base.adapter.setCommonAdapter
import com.lukouguoji.module_base.base.BaseViewHolder import com.lukouguoji.module_base.base.BaseViewHolder
@@ -12,6 +14,10 @@ import com.lukouguoji.module_base.ktx.refresh
/** /**
* 国际进港-仓库 ViewHolder * 国际进港-仓库 ViewHolder
*
* 双形态布局:平板变体含 iv_icon/iv_show/rv_sub/ll_header/divider_header/tv_empty
* (多选 + 库位子列表),手机变体含 ll/btn_clear/btn_modify/btn_out/btn_in
* (整卡进详情 + 卡片级四操作按钮)。单侧独有的 id 在 Binding 基类中为 @Nullable必须判空访问。
*/ */
class IntImpStorageUseViewHolder(view: View) : class IntImpStorageUseViewHolder(view: View) :
BaseViewHolder<GjcMaWb, ItemIntImpStorageUseBinding>(view) { BaseViewHolder<GjcMaWb, ItemIntImpStorageUseBinding>(view) {
@@ -22,43 +28,58 @@ class IntImpStorageUseViewHolder(view: View) :
binding.position = position binding.position = position
binding.executePendingBindings() binding.executePendingBindings()
// ==================== 平板:多选 + 子列表 ====================
// 图标点击切换选择状态 // 图标点击切换选择状态
binding.ivIcon.setOnClickListener { binding.ivIcon?.setOnClickListener {
bean.checked.set(!bean.checked.get()) bean.checked.set(!bean.checked.get())
FlowBus.with<String>(ConstantEvent.EVENT_CHECK_CHANGED).tryEmit("check_changed") FlowBus.with<String>(ConstantEvent.EVENT_CHECK_CHANGED).tryEmit("check_changed")
binding.executePendingBindings() binding.executePendingBindings()
} }
// 展开按钮点击事件 // 展开按钮点击事件
binding.ivShow.setOnClickListener { binding.ivShow?.setOnClickListener {
bean.showMore.set(!bean.showMore.get()) bean.showMore.set(!bean.showMore.get())
} }
// 初始化库位明细子列表 RecyclerView // 初始化库位明细子列表 RecyclerView
setCommonAdapter( binding.rvSub?.let { rvSub ->
binding.rvSub, setCommonAdapter(
IntImpStorageUseSubViewHolder::class.java, rvSub,
R.layout.item_int_imp_storage_use_sub IntImpStorageUseSubViewHolder::class.java,
) R.layout.item_int_imp_storage_use_sub
)
// 刷新库位明细数据传递父Bean引用 // 刷新库位明细数据传递父Bean引用
val storageUseList = bean.storageUseList ?: emptyList() val storageUseList = bean.storageUseList ?: emptyList()
binding.rvSub.tag = bean rvSub.tag = bean
binding.rvSub.refresh(storageUseList) rvSub.refresh(storageUseList)
updateSubListVisibility(storageUseList.isNotEmpty()) updateSubListVisibility(storageUseList.isNotEmpty())
}
// ==================== 手机:整卡进详情 + 卡片级操作 ====================
val activity = itemView.context as? IntImpStorageUseActivity
// 整卡点击进详情复用进港查询详情页3 Tab 运单/仓库/库位信息)
binding.ll?.setOnClickListener {
IntImpQueryDetailsActivity.start(itemView.context, bean.prefix, bean.no)
}
// 清仓(已清仓时置灰不可点,样式由 XML 按 bean.isCleared 切换)
binding.btnClear?.setOnClickListener {
if (!bean.isCleared) activity?.cardClear(bean)
}
binding.btnModify?.setOnClickListener { activity?.cardModifyStorage(bean) }
binding.btnOut?.setOnClickListener { activity?.cardOutStorage(bean) }
binding.btnIn?.setOnClickListener { activity?.cardInStorage(bean) }
} }
private fun updateSubListVisibility(hasData: Boolean) { private fun updateSubListVisibility(hasData: Boolean) {
if (hasData) { binding.llHeader?.visibility = if (hasData) View.VISIBLE else View.GONE
binding.llHeader.visibility = View.VISIBLE binding.dividerHeader?.visibility = if (hasData) View.VISIBLE else View.GONE
binding.dividerHeader.visibility = View.VISIBLE binding.rvSub?.visibility = if (hasData) View.VISIBLE else View.GONE
binding.rvSub.visibility = View.VISIBLE binding.tvEmpty?.visibility = if (hasData) View.GONE else View.VISIBLE
binding.tvEmpty.visibility = View.GONE
} else {
binding.llHeader.visibility = View.GONE
binding.dividerHeader.visibility = View.GONE
binding.rvSub.visibility = View.GONE
binding.tvEmpty.visibility = View.VISIBLE
}
} }
} }

View File

@@ -20,6 +20,7 @@ import com.lukouguoji.module_base.ktx.formatDate
import com.lukouguoji.module_base.ktx.toRequestBody import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.model.ConfirmDialogModel import com.lukouguoji.module_base.model.ConfirmDialogModel
import com.lukouguoji.module_base.model.ScanModel import com.lukouguoji.module_base.model.ScanModel
import com.lukouguoji.module_base.util.DictUtils
import dev.utils.app.info.KeyValue import dev.utils.app.info.KeyValue
import dev.utils.common.DateUtils import dev.utils.common.DateUtils
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -54,6 +55,68 @@ class IntImpPickUpDLVViewModel : BasePageViewModel() {
fun updateCheckAllStatus() { fun updateCheckAllStatus() {
val list = pageModel.rv?.commonAdapter()?.items as? List<IntImpPickUpDLVBean> ?: return val list = pageModel.rv?.commonAdapter()?.items as? List<IntImpPickUpDLVBean> ?: return
isAllChecked.value = list.isNotEmpty() && list.all { it.checked.get() } isAllChecked.value = list.isNotEmpty() && list.all { it.checked.get() }
selectedCountText.value = "已选 ${list.count { it.checked.get() }} 项"
}
// ========== 5.5寸手机版专属 ==========
// 状态 Tab待出库/已出库outState 为 pageQuery 真实入参0未出库1已出库平板恒空不进请求
val outState = MutableLiveData("")
val tabList = MutableLiveData(listOf(KeyValue("待出库", "0"), KeyValue("已出库", "1")))
val tabCounts = MutableLiveData(listOf("0", "0"))
// 底部操作条「已选 N 项」
val selectedCountText = MutableLiveData("已选 0 项")
// 筛选弹层显隐
val filterVisible = MutableLiveData(false)
// 筛选条件flightDate 为 pageQuery 未定义入参 fdate预留传参见接口问题清单
val flightDate = MutableLiveData("")
val flightNo = MutableLiveData("")
// 特码下拉字典initPhoneExtras 加载,平板为扫码输入不加载)
val specialCodeList = MutableLiveData<List<KeyValue>>(emptyList())
private var phoneExtrasEnabled = false
/**
* 手机形态专属初始化Activity 在 DeviceUtil.isPhone() 时调用)。
* 平板端不调用,请求次数与行为零变化。
*/
fun initPhoneExtras() {
phoneExtrasEnabled = true
// 默认进「待出库」Tab
outState.value = "0"
// 平板默认按当天缴费日期过滤,设计稿无此默认——手机端清空查全量
paymentDateStart.value = ""
// 特码字典flag=1 国际ieFlag 必须留空
DictUtils.getSpecialCodeList(addAll = false, flag = 1, ieFlag = "") { list ->
specialCodeList.postValue(listOf(KeyValue("全部", "")) + list)
}
}
/** 筛选按钮点击 - 打开筛选面板 */
fun filterClick() {
filterVisible.value = true
}
/** 关闭筛选面板 */
fun closeFilter() {
filterVisible.value = false
}
/** 重置筛选条件 */
fun resetFilter() {
flightDate.value = ""
flightNo.value = ""
agentCode.value = ""
spCode.value = ""
}
/** 确认筛选 - 关闭面板并刷新 */
fun confirmFilter() {
filterVisible.value = false
refresh()
} }
// ========== 适配器配置 ========== // ========== 适配器配置 ==========
@@ -105,6 +168,8 @@ class IntImpPickUpDLVViewModel : BasePageViewModel() {
list.forEach { it.checked.set(shouldCheckAll) } list.forEach { it.checked.set(shouldCheckAll) }
isAllChecked.value = shouldCheckAll isAllChecked.value = shouldCheckAll
pageModel.rv?.commonAdapter()?.notifyDataSetChanged() pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
// 同步手机版底部条「已选 N 项」(平板布局不绑定该字段,无影响)
selectedCountText.value = "已选 ${list.count { it.checked.get() }} 项"
} }
/** /**
@@ -139,12 +204,17 @@ class IntImpPickUpDLVViewModel : BasePageViewModel() {
* 获取列表数据 * 获取列表数据
*/ */
override fun getData() { override fun getData() {
// 手机专属 3 项平板恒为空不进请求fdate 为 pageQuery 未定义入参
//(后端静默忽略,补齐后自动生效,见接口问题清单)
val filterParams = mapOf( val filterParams = mapOf(
"beginDate" to paymentDateStart.value?.ifEmpty { null }, "beginDate" to paymentDateStart.value?.ifEmpty { null },
"endDate" to paymentDateEnd.value?.ifEmpty { null }, "endDate" to paymentDateEnd.value?.ifEmpty { null },
"agentCode" to agentCode.value?.ifEmpty { null }, "agentCode" to agentCode.value?.ifEmpty { null },
"no" to wbNo.value?.ifEmpty { null }, "no" to wbNo.value?.ifEmpty { null },
"spCode" to spCode.value?.ifEmpty { null } "spCode" to spCode.value?.ifEmpty { null },
"outState" to outState.value?.ifEmpty { null },
"fno" to flightNo.value?.ifEmpty { null },
"fdate" to flightDate.value?.ifEmpty { null }
) )
val listParams = (filterParams + mapOf( val listParams = (filterParams + mapOf(
@@ -169,6 +239,28 @@ class IntImpPickUpDLVViewModel : BasePageViewModel() {
totalWeight.value = (data?.totalWeight ?: 0.0).toString() totalWeight.value = (data?.totalWeight ?: 0.0).toString()
} }
} }
// 手机专属Tab 角标计数(同条件 + outState=0/1 各查一次,平板不发)
if (phoneExtrasEnabled) {
val pendingParams = (filterParams + mapOf("outState" to "0")).toRequestBody()
launchCollect({ NetApply.api.getIntImpPickUpDLVTotal(pendingParams) }) {
onSuccess = { result ->
tabCounts.value = listOf(
(result.data?.wbNumber ?: 0).toString(),
tabCounts.value?.getOrNull(1) ?: "0"
)
}
}
val shippedParams = (filterParams + mapOf("outState" to "1")).toRequestBody()
launchCollect({ NetApply.api.getIntImpPickUpDLVTotal(shippedParams) }) {
onSuccess = { result ->
tabCounts.value = listOf(
tabCounts.value?.getOrNull(0) ?: "0",
(result.data?.wbNumber ?: 0).toString()
)
}
}
}
} }
/** /**

View File

@@ -61,6 +61,39 @@ class IntImpQueryDetailsViewModel : BaseViewModel() {
currentTab.value = index currentTab.value = index
} }
// ==================== 5.5寸手机版取值帮助(与出港 GjcQueryDetailsViewModel 同口径) ====================
/**
* 从详情 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 的展示值(如 by1 优先于 by0
*/
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 { "--" }
}
}
/** /**
* 加载详情数据 * 加载详情数据
*/ */

View File

@@ -64,6 +64,24 @@ class IntImpQueryViewModel : BasePageViewModel(), IOnItemClickListener {
val awbTypeList = MutableLiveData<List<KeyValue>>(emptyList()) val awbTypeList = MutableLiveData<List<KeyValue>>(emptyList())
val businessTypeList = MutableLiveData<List<KeyValue>>(emptyList()) val businessTypeList = MutableLiveData<List<KeyValue>>(emptyList())
// ==================== 5.5寸手机版专属 ====================
// 三格统计:已入库 / 已出库(总票数复用 totalCount为服务端全量口径
// pageQueryTotal 无分项统计出参——已入库/已出库为「已加载数据」客户端计数口径,
// 与卡片状态标签同一判定dlvTime / inDate见 IntImpQueryBean
val storedCount = MutableLiveData("0")
val outboundCount = MutableLiveData("0")
private var phoneExtrasEnabled = false
private var phoneLoadedList: List<IntImpQueryBean> = emptyList()
/**
* 手机形态专属初始化Activity 在 DeviceUtil.isPhone() 时调用)。
* 平板端不调用,请求次数与行为零变化。
*/
fun initPhoneExtras() {
phoneExtrasEnabled = true
}
// ==================== 筛选条件 ==================== // ==================== 筛选条件 ====================
val spCode = MutableLiveData("") val spCode = MutableLiveData("")
val flightNo = MutableLiveData("") val flightNo = MutableLiveData("")
@@ -165,6 +183,14 @@ class IntImpQueryViewModel : BasePageViewModel(), IOnItemClickListener {
}) { }) {
onSuccess = { pageInfo -> onSuccess = { pageInfo ->
pageModel.handleListBean(pageInfo.toBaseListBean()) pageModel.handleListBean(pageInfo.toBaseListBean())
// 手机三格统计:对已加载数据做客户端计数(平板不触发)
if (phoneExtrasEnabled) {
val pageItems = pageInfo.list ?: emptyList()
phoneLoadedList =
if (pageModel.page <= 1) pageItems else phoneLoadedList + pageItems
updatePhoneCounts()
}
} }
} }
@@ -180,6 +206,16 @@ class IntImpQueryViewModel : BasePageViewModel(), IOnItemClickListener {
} }
} }
/**
* 手机三格统计(已入库/已出库与卡片状态标签同一判定口径dlvTime / inDate
* 统计范围为已加载的列表数据。
*/
private fun updatePhoneCounts() {
outboundCount.value = phoneLoadedList.count { it.isQueryOutbound }.toString()
storedCount.value =
phoneLoadedList.count { !it.isQueryOutbound && it.isQueryStored }.toString()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK && data != null) { if (resultCode == Activity.RESULT_OK && data != null) {
when (requestCode) { when (requestCode) {

View File

@@ -18,6 +18,7 @@ import com.lukouguoji.module_base.ktx.noNull
import com.lukouguoji.module_base.ktx.showToast import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.model.ScanModel import com.lukouguoji.module_base.model.ScanModel
import com.lukouguoji.module_base.util.DictUtils
import dev.utils.app.info.KeyValue import dev.utils.app.info.KeyValue
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -39,6 +40,109 @@ class IntImpStorageUseViewModel : BasePageViewModel() {
val totalPc = MutableLiveData("0") // 总件数 val totalPc = MutableLiveData("0") // 总件数
val totalWeight = MutableLiveData("0") // 总重量 val totalWeight = MutableLiveData("0") // 总重量
// ========== 5.5寸手机版专属 ==========
// 搜索框统一入口placeholder「搜索运单号/航班号」phoneSearchClick 分流)
val phoneSearchKey = MutableLiveData("")
// 筛选弹层显隐
val filterVisible = MutableLiveData(false)
// 筛选条件fdep 为接口入参;其余 5 项为后端未定义入参,预留传参,见接口问题清单 #25
val fdep = MutableLiveData("") // 始发站
val agentId = MutableLiveData("") // 代理agentCode预留
val spCode = MutableLiveData("") // 特码(预留)
val awbType = MutableLiveData("") // 运单类型(预留)
val businessType = MutableLiveData("") // 业务类型(预留)
val goodsCn = MutableLiveData("") // 品名(中)(预留)
// 筛选下拉字典initPhoneExtras 加载,平板不请求)
val agentList = MutableLiveData(listOf(KeyValue("全部", "")))
val specialCodeList = MutableLiveData<List<KeyValue>>(emptyList())
val awbTypeList = MutableLiveData<List<KeyValue>>(emptyList())
val businessTypeList = MutableLiveData(
listOf(
KeyValue("全部", ""),
KeyValue("普货", "1"),
KeyValue("特货", "2")
)
)
// 三格统计:未清仓 / 已清仓(复用 pageQueryTotal 按 clearNormal=0/1 各查一次)
val unclearedCount = MutableLiveData("0")
val clearedCount = MutableLiveData("0")
private var phoneExtrasEnabled = false
/**
* 手机形态专属初始化Activity 在 DeviceUtil.isPhone() 时调用)。
* 平板端不调用,请求次数与行为零变化。
*/
fun initPhoneExtras() {
phoneExtrasEnabled = true
// 代理(国际进港口径)
DictUtils.getIntImpAgentList(addAll = false) { list ->
agentList.postValue(listOf(KeyValue("全部", "")) + list)
}
// 特码flag=1 国际ieFlag 必须留空
DictUtils.getSpecialCodeList(addAll = false, flag = 1, ieFlag = "") { list ->
specialCodeList.postValue(listOf(KeyValue("全部", "")) + list)
}
// 运单类型type=II 国际进港)
DictUtils.getWaybillTypeList(type = Constant.businessType.II, addAll = true) {
awbTypeList.postValue(it)
}
}
/**
* 手机搜索框查询:按出港计重实测规则分流——含字母→航班号,其余→运单号
*/
fun phoneSearchClick() {
val key = phoneSearchKey.value?.trim() ?: ""
when {
key.isEmpty() -> {
wbNo.value = ""
flightNo.value = ""
}
key.any { it.isLetter() } -> {
flightNo.value = key
wbNo.value = ""
}
else -> {
wbNo.value = key
flightNo.value = ""
}
}
refresh()
}
/** 筛选按钮点击 - 打开筛选面板 */
fun filterClick() {
filterVisible.value = true
}
/** 关闭筛选面板 */
fun closeFilter() {
filterVisible.value = false
}
/** 重置筛选条件 */
fun resetFilter() {
flightDate.value = ""
flightNo.value = ""
fdep.value = ""
agentId.value = ""
spCode.value = ""
awbType.value = ""
businessType.value = ""
goodsCn.value = ""
}
/** 确认筛选 - 关闭面板并刷新 */
fun confirmFilter() {
filterVisible.value = false
refresh()
}
// ========== 全选状态 ========== // ========== 全选状态 ==========
val isAllChecked = MutableLiveData(false) val isAllChecked = MutableLiveData(false)
@@ -250,12 +354,20 @@ class IntImpStorageUseViewModel : BasePageViewModel() {
} }
override fun getData() { override fun getData() {
// 手机专属 6 项平板恒为空不进请求agentCode/spCode/awbType/businessType/goodsCn
// 为 pageQuery 未定义入参(后端静默忽略,补齐后自动生效,见接口问题清单 #25
val filterParams = mapOf( val filterParams = mapOf(
"fdate" to flightDate.value?.ifEmpty { null }, "fdate" to flightDate.value?.ifEmpty { null },
"fno" to flightNo.value?.ifEmpty { null }, "fno" to flightNo.value?.ifEmpty { null },
"wbNo" to wbNo.value?.ifEmpty { null }, "wbNo" to wbNo.value?.ifEmpty { null },
"location" to location.value?.ifEmpty { null }, "location" to location.value?.ifEmpty { null },
"clearNormal" to clearResult.value?.ifEmpty { null } "clearNormal" to clearResult.value?.ifEmpty { null },
"fdep" to fdep.value?.ifEmpty { null },
"agentCode" to agentId.value?.ifEmpty { null },
"spCode" to spCode.value?.ifEmpty { null },
"awbType" to awbType.value?.ifEmpty { null },
"businessType" to businessType.value?.ifEmpty { null },
"goodsCn" to goodsCn.value?.ifEmpty { null }
) )
val listParams = (filterParams + mapOf( val listParams = (filterParams + mapOf(
@@ -281,5 +393,17 @@ class IntImpStorageUseViewModel : BasePageViewModel() {
totalWeight.value = (data?.totalWeight ?: 0.0).toString() totalWeight.value = (data?.totalWeight ?: 0.0).toString()
} }
} }
// 手机专属:未清仓/已清仓分项统计(同条件 + clearNormal=0/1 各查一次,平板不发)
if (phoneExtrasEnabled) {
val unclearedParams = (filterParams + mapOf("clearNormal" to "0")).toRequestBody()
launchCollect({ NetApply.api.getIntImpStorageUseTotal(unclearedParams) }) {
onSuccess = { unclearedCount.value = (it.data?.wbNumber ?: 0).toString() }
}
val clearedParams = (filterParams + mapOf("clearNormal" to "1")).toRequestBody()
launchCollect({ NetApply.api.getIntImpStorageUseTotal(clearedParams) }) {
onSuccess = { clearedCount.value = (it.data?.wbNumber ?: 0).toString() }
}
}
} }
} }

View File

@@ -0,0 +1,204 @@
<?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="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType" />
<variable
name="viewModel"
type="com.lukouguoji.gjj.viewModel.IntImpPickUpDLVViewModel" />
</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" />
<!-- 搜索区域 -->
<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
hint='@{"选择缴费日期起"}'
icon="@{@drawable/img_date}"
type="@{SearchLayoutType.DATE}"
value="@={viewModel.paymentDateStart}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 缴费日期止 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请选择结束缴费日期"}'
icon="@{@drawable/img_date}"
type="@{SearchLayoutType.DATE}"
value="@={viewModel.paymentDateEnd}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 代理人 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请选择代理人"}'
list="@{viewModel.agentList}"
type="@{SearchLayoutType.SPINNER}"
value="@={viewModel.agentCode}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 运单号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
autoQueryEnabled="@{true}"
autoQueryMaxLength="@{8}"
autoQueryMinLength="@{4}"
autoQueryParamKey="@{`wbNo`}"
autoQueryTitle="@{`选择运单号`}"
autoQueryUrl="@{`/IntImpPickUpDlv/queryWbNoList`}"
hint='@{"请输入运单号"}'
icon="@{@drawable/img_scan}"
setOnIconClickListener="@{(v)-> viewModel.scanWbNo()}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.wbNo}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 特码 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请输入特码"}'
icon="@{@drawable/img_scan}"
setOnIconClickListener="@{(v)-> viewModel.scanSpCode()}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.spCode}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 搜索按钮 -->
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginHorizontal="10dp"
android:onClick="@{()-> viewModel.searchClick()}"
android:padding="2dp"
android:src="@drawable/img_search" />
</LinearLayout>
<!-- 列表 -->
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/srl"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="3"
tools:listitem="@layout/item_int_imp_pick_up_dlv" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<!-- 底部统计和操作按钮 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@android:color/white"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<!-- 全选按钮 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:gravity="center_vertical"
android:onClick="@{()-> viewModel.checkAllClick()}"
android:orientation="horizontal">
<ImageView
android:id="@+id/checkIcon"
setIVCheckAllImage="@{viewModel.isAllChecked}"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="5dp"
android:src="@drawable/img_check_all_unchecked" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="全选"
android:textColor="@color/color_66"
android:textSize="18sp" />
</LinearLayout>
<!-- 统计信息 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_weight="1"
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="18sp"
android:textStyle="bold" />
<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="18sp"
android:textStyle="bold" />
<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="18sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 确认出库按钮 -->
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()-> viewModel.confirmOutbound()}"
android:text="确认出库" />
</LinearLayout>
</LinearLayout>
</layout>

View File

@@ -0,0 +1,234 @@
<?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.gjj.viewModel.IntImpQueryViewModel" />
</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="@{`/IntImpSearch/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_int_imp_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_int_imp_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,124 @@
<?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.gjj.viewModel.IntImpQueryDetailsViewModel" />
</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:text="仓库信息"
android:textStyle="bold"
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:text="库位信息"
android:textStyle="bold"
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,253 @@
<?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="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType" />
<import type="com.lukouguoji.gjj.R" />
<variable
name="viewModel"
type="com.lukouguoji.gjj.viewModel.IntImpStorageUseViewModel" />
<variable
name="activity"
type="com.lukouguoji.gjj.activity.IntImpStorageUseActivity" />
</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" />
<!-- 搜索区域 -->
<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
hint='@{"请选择航班日期"}'
icon="@{@drawable/img_date}"
type="@{SearchLayoutType.DATE}"
value="@={viewModel.flightDate}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 航班号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请输入航班号"}'
setUpperCaseAlphanumeric="@{true}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.flightNo}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 清仓综合结果 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请选择清仓结果"}'
list="@{viewModel.clearResultList}"
type="@{SearchLayoutType.SPINNER}"
value="@={viewModel.clearResult}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 运单号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
autoQueryEnabled="@{true}"
autoQueryMaxLength="@{8}"
autoQueryMinLength="@{4}"
autoQueryParamKey="@{`wbNo`}"
autoQueryTitle="@{`选择运单号`}"
autoQueryUrl="@{`/IntImpStorage/queryWbNoList`}"
hint='@{"请输入运单号"}'
icon="@{@drawable/img_scan}"
setOnIconClickListener="@{(v)-> viewModel.scanWbNo()}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.wbNo}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 库位号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请输入库位号"}'
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.location}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 搜索按钮 -->
<LinearLayout
android:layout_width="200dp"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="10dp">
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:onClick="@{()-> viewModel.searchClick()}"
android:padding="2dp"
android:src="@drawable/img_search" />
<!-- 全局展开/收起按钮 -->
<ImageView
loadImage="@{viewModel.isAllExpanded ? R.drawable.ic_new_expand_1 : R.drawable.ic_new_expand_1}"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="16dp"
android:contentDescription="展开/收起全部子列表"
android:onClick="@{()-> viewModel.toggleAllExpand()}"
android:padding="2dp"
android:scaleType="fitCenter" />
</LinearLayout>
</LinearLayout>
<!-- 列表 -->
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/srl"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="3"
tools:listitem="@layout/item_int_imp_storage_use" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<!-- 底部统计和操作按钮 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@android:color/white"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<!-- 全选按钮 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:gravity="center_vertical"
android:onClick="@{()-> viewModel.checkAllClick()}"
android:orientation="horizontal">
<ImageView
android:id="@+id/checkIcon"
setIVCheckAllImage="@{viewModel.isAllChecked}"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="5dp"
android:src="@drawable/img_check_all_unchecked" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="全选"
android:textColor="@color/color_66"
android:textSize="18sp" />
</LinearLayout>
<!-- 统计信息 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{"合计:"+viewModel.totalWbNumber+"票"}'
android:textColor="@color/bottom_tool_tips_text_color"
android:textSize="18sp"
android:textStyle="bold" />
<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="18sp"
android:textStyle="bold" />
<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="18sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 操作按钮组 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- 清仓按钮 -->
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()-> activity.showClearDialog()}"
android:text="清 仓" />
<!-- 修改库位按钮 -->
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()-> activity.showModifyStorageDialog()}"
android:text="修改库位" />
<!-- 出库按钮 -->
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()-> activity.showOutStorageDialog()}"
android:text="出 库" />
<!-- 入库按钮 -->
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()-> activity.showInStorageDialog()}"
android:text="入 库" />
</LinearLayout>
</LinearLayout>
</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.gjj.dialog.IntImpInStorageDialogModel" />
</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.locationList}"
value="@={model.selectedLocationCode}" />
</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,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.gjj.dialog.IntImpModifyStorageDialogModel" />
</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.locationList}"
value="@={model.selectedLocationCode}" />
</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,86 @@
<?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.gjj.dialog.IntImpMoveClearDialogModel" />
</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}"
list="@{model.clearNormalList}"
value="@={model.clearNormal}" />
</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,136 @@
<?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,146 @@
<?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="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" />
<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.6"
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.3"
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,336 @@
<?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.gjj.viewModel.IntImpQueryDetailsViewModel" />
</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("awbPc") != null ? String.valueOf((int)Math.round(((Double)viewModel.maWbData.get("awbPc")))) : ``}' />
<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("awbWeight") != null ? String.valueOf(viewModel.maWbData.get("awbWeight")) : ``}' />
<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>
<!-- 第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='@{viewModel.maWbData.get("inPc") != null ? String.valueOf((int)Math.round(((Double)viewModel.maWbData.get("inPc")))) : ``}' />
<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("inWeight") != null ? String.valueOf(viewModel.maWbData.get("inWeight")) : ``}' />
<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("cashWeight") != null ? String.valueOf(viewModel.maWbData.get("cashWeight")) : ``}' />
</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="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"承运人"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("by1")}' />
<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("range")}' />
<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")}' />
</LinearLayout>
<!-- 第5行: 运单类型、UN编号 -->
<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("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='@{"UN编号"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("unNumber")}' />
<Space
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
<!-- 第6行: 品名(中)占2列、锁定状态占1列 -->
<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="2"
enable="@{false}"
title='@{"品名(中)"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("goodsCn")}' />
<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("lockStateText")}' />
</LinearLayout>
<!-- 第7行: 品名(英)占2列、出库时间占1列 -->
<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="2"
enable="@{false}"
title='@{"品名(英)"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{(String)viewModel.maWbData.get("goods")}' />
<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("dlvTime")}' />
</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("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("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("command")}' />
</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,266 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:loadImage="http://schemas.android.com/tools">
<data>
<variable
name="bean"
type="com.lukouguoji.module_base.bean.IntImpPickUpDLVBean" />
<variable
name="position"
type="Integer" />
</data>
<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:gravity="center_vertical"
android:orientation="horizontal"
android:paddingVertical="20dp"
android:paddingHorizontal="10dp">
<!-- 选中图标 -->
<ImageView
android:id="@+id/iv_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
loadImage="@{bean.checked.get() ? @drawable/img_plane_s : @drawable/img_plane}"
android:src="@drawable/img_plane" />
<!-- 数据展示区域 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
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="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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"
android:textStyle="bold" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 代理人 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="代理人:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.agentCode}"
android:textSize="15sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 航班信息 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:gravity="center_vertical">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="航班信息:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.flightInfo}"
android:textSize="15sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 件数 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 重量 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:gravity="center_vertical">
<TextView
completeSpace="@{3}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="重量:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf((int)bean.weight)}"
android:textSize="15sp" />
</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="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="特码:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.spCode}"
android:textSize="15sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 库位 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="库位:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.locationInStore}"
android:textSize="15sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 办理时间 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:gravity="center_vertical">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="办理时间:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.chargeTime}"
android:textSize="15sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 品名(中):占据件数+重量两列宽度 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.4"
android:gravity="center_vertical">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="品名(中)"
android:textSize="15sp" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:text="@{bean.goods}"
android:textSize="15sp" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</LinearLayout>
</androidx.appcompat.widget.LinearLayoutCompat>
</layout>

View File

@@ -0,0 +1,325 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="bean"
type="com.lukouguoji.module_base.bean.IntImpQueryBean" />
</data>
<!-- 外层容器承载间距 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="5dp"
android:orientation="vertical">
<!-- 侧滑布局 -->
<com.mcxtzhang.swipemenulib.SwipeMenuLayout
android:id="@+id/swipe_menu"
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: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_marginLeft="10dp"
android:layout_weight="1"
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="0.8"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
completeSpace="@{4}"
android:text="运单号:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text="@{bean.wbNo}"
android:textColor="@color/colorPrimary"
tools:text="78109081212" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 件数 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
completeSpace="@{3}"
android:text="件数:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text='@{String.valueOf(bean.inPc)}'
tools:text="10" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 重量 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
completeSpace="@{5}"
android:text="重量:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text='@{String.valueOf(bean.inWeight)}'
tools:text="200" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 代理人 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
completeSpace="@{5}"
android:text="代理人:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text='@{bean.agentName}'
tools:text="SF" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 航班信息 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
completeSpace="@{5}"
android:text="航班信息:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text='@{bean.flight}'
tools:text="20240216/MU2026" />
</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="0.8"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
completeSpace="@{4}"
android:text="航程:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text="@{bean.range}"
tools:text="LAX-HFE" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 特码 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
completeSpace="@{3}"
android:text="特码:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text="@{bean.spCode}"
tools:text="NOR" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 运单类型 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
completeSpace="@{5}"
android:text="运单类型:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text='@{bean.awbName}'
tools:text="国际进港" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 入库时间 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
completeSpace="@{5}"
android:text="入库时间:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text='@{bean.inDate}'
tools:text="2024-05-13 17:10:22" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 出库时间 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:gravity="center_vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
completeSpace="@{5}"
android:text="出库时间:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text='@{bean.dlvTime}'
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:layout_marginLeft="10dp"
android:src="@drawable/img_pda_right" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 侧滑菜单按钮区 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- 修改按钮 -->
<TextView
android:id="@+id/btn_edit"
style="@style/tv_item_action"
android:background="@color/colorPrimary"
android:text="修改" />
</androidx.appcompat.widget.LinearLayoutCompat>
</com.mcxtzhang.swipemenulib.SwipeMenuLayout>
</LinearLayout>
</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.GjjStorageUse" />
<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.inOpName != null ? bean.inOpName : (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; bean.inDate.length() >= 16 ? bean.inDate.substring(0, 16) : (bean.inDate != null &amp;&amp; bean.inDate.length() > 0 ? 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.outOpName != null ? bean.outOpName : (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; bean.outDate.length() >= 16 ? bean.outDate.substring(0, 16) : (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,109 @@
<?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.GjjWarehouse" />
<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="0.8"
android:gravity="center"
android:text="@{bean.pc != null ? 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="@{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.6"
android:gravity="center"
android:text="@{bean.splitFlag != null &amp;&amp; bean.splitFlag.length() > 0 ? bean.splitFlag : `1`}"
android:textColor="@android:color/black"
android:textSize="14sp" />
<!-- 入库时间(取 opDate -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.3"
android:gravity="center"
android:text="@{bean.opDate != null &amp;&amp; bean.opDate.length() >= 16 ? bean.opDate.substring(0, 16) : (bean.opDate ?? ``)}"
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,433 @@
<?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:loadImage="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable
name="bean"
type="com.lukouguoji.module_base.bean.GjcMaWb" />
<variable
name="position"
type="Integer" />
</data>
<!-- 主列表项容器 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:orientation="vertical">
<!-- 白色卡片主要内容区域 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_8"
android:orientation="vertical">
<!-- 主要内容区域 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingVertical="20dp"
android:paddingHorizontal="10dp">
<!-- 选中图标 -->
<ImageView
android:id="@+id/iv_icon"
loadImage="@{bean.checked.get() ? @drawable/img_plane_s : @drawable/img_plane}"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginTop="0.5px"
android:layout_marginEnd="10dp"
android:src="@drawable/img_plane" />
<!-- 数据展示区域 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<!-- 第一行:运单号、航班信息、航程、品名、重量 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- 运单号 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.9"
android:orientation="horizontal">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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" />
</LinearLayout>
<!-- 航班信息 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:orientation="horizontal">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="航班信息:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.flightInfo}"
android:textSize="15sp" />
</LinearLayout>
<!-- 航程 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:orientation="horizontal">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="航程:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.range}"
android:textSize="15sp" />
</LinearLayout>
<!-- 件数 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:orientation="horizontal">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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" />
</LinearLayout>
<!-- 重量 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:orientation="horizontal">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="重量:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf((int)bean.weight)}"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
<!-- 第二行:代理人、件数、清仓正常否、入库时间、库位数 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<!-- 代理人 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.9"
android:orientation="horizontal">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="代理人:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.agentCode}"
android:textSize="15sp" />
</LinearLayout>
<!-- 品名(英) -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:orientation="horizontal">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="品名(英)"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
android:text="@{bean.goods}"
android:textSize="15sp" />
</LinearLayout>
<!-- 清仓正常否 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:orientation="horizontal">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="清仓正常:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@{`1`.equals(bean.clearNormal) ? @drawable/tag_status_green : (`0`.equals(bean.clearNormal) ? @drawable/tag_status_orange : @drawable/tag_status_gray)}"
android:paddingHorizontal="8dp"
android:paddingVertical="2dp"
android:text="@{bean.clearNormalText}"
android:textColor="@{`1`.equals(bean.clearNormal) ? @color/text_green : (`0`.equals(bean.clearNormal) ? @color/text_orange : @color/text_gray)}"
android:textSize="14sp"
android:visibility="@{bean.clearNormalText != null &amp;&amp; !bean.clearNormalText.isEmpty() ? View.VISIBLE : View.GONE}" />
</LinearLayout>
<!-- 入库时间 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:orientation="horizontal">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="入库时间:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.inDate}"
android:textSize="15sp" />
</LinearLayout>
<!-- 库位数 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.6"
android:orientation="horizontal">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="库位数:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf(bean.storageUseNumber)}"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- 展开/折叠按钮 -->
<ImageView
android:id="@+id/iv_show"
android:layout_width="match_parent"
android:layout_height="20dp"
android:paddingVertical="2.5dp"
android:layout_marginTop="-20dp"
android:scaleType="center"
android:src="@mipmap/img_down" />
</LinearLayout>
<!-- 库位明细列表容器(在白色卡片外面) -->
<LinearLayout
visible="@{bean.showMore}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@drawable/bg_white_radius_8"
android:orientation="vertical"
android:visibility="gone">
<!-- 暂无数据提示 -->
<TextView
android:id="@+id/tv_empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingVertical="15dp"
android:text="暂无库位数据"
android:textColor="@color/text_gray"
android:textSize="14sp"
android:visibility="gone" />
<!-- 表头(浅蓝色背景,顶部圆角同卡片) -->
<LinearLayout
android:id="@+id/ll_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_arrive_sub_header"
android:orientation="horizontal"
android:paddingHorizontal="10dp"
android:paddingVertical="10dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center"
android:text="选项"
android:textColor="@color/text_normal"
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/text_normal"
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/text_normal"
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/text_normal"
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/text_normal"
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/text_normal"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:id="@+id/divider_header"
android:layout_width="match_parent"
android:layout_height="1px"
app:dividerColor="@color/sub_list_divider" />
<!-- 子列表 RecyclerView -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_sub"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
</LinearLayout>
</layout>

View File

@@ -0,0 +1,340 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
国际进港提取出库-运单详情5.5 寸手机版专属页面,无平板变体——平板端无入口)
对应设计稿 09_提取出库 的 page-detail
蓝头卡(运单号 + 绿点提取时间)+ 红标签「国际进港」|业务类型 + 品名大标题 +
两列 KV件数/重量/特码/代理/始发港/目的港/航班日期/航班号/库位橙标签/提货单号)
+ 绿头「提货信息」卡(柜台办理人/时间;已出库追加出库人/出库时间行)。
「目的港/业务类型」为 pageQuery 出参缺失字段(见问题清单),空值兜底为双横线占位。
-->
<layout xmlns:android="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.IntImpPickUpDLVBean" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/phone_page_bg"
android:orientation="vertical">
<include layout="@layout/title_tool_bar" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="12dp">
<!-- ==================== 卡片1运单信息蓝头 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_phone_card"
android:orientation="vertical">
<!-- 蓝色头部:运单号 + 绿点提取时间 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_phone_card_header_blue"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="16dp"
android:paddingVertical="14dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{bean.wbNo}"
android:textColor="@color/white"
android:textSize="17sp"
android:textStyle="bold"
tools:text="78133363573" />
<View
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginEnd="6dp"
android:background="@drawable/bg_phone_dot_green" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.chargeTime.empty ? "--" : bean.chargeTime}'
android:textColor="@color/white"
android:textSize="13sp"
tools:text="2026-07-05 10:30" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- 红标签「国际进港」 | 业务类型 -->
<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="20dp"
android:background="@drawable/bg_phone_tag_red"
android:gravity="center"
android:paddingHorizontal="8dp"
android:text="国际进港"
android:textColor="@color/white"
android:textSize="11sp" />
<View
android:layout_width="1px"
android:layout_height="14dp"
android:layout_marginHorizontal="10dp"
android:background="@color/phone_divider" />
<!-- 业务类型pageQuery 出参无此字段,见问题清单,兜底双横线) -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="--"
android:textColor="@color/phone_text_body"
android:textSize="13sp"
tools:text="普通货物运输" />
</LinearLayout>
<!-- 品名大标题 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text='@{bean.goods.empty ? "--" : bean.goods}'
android:textColor="@color/phone_text_strong"
android:textSize="22sp"
android:textStyle="bold"
tools:text="电子元器件" />
<!-- 件数 | 重量 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
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='@{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.spCode.empty ? "--" : bean.spCode}' />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"代理"}'
value='@{bean.agentCode.empty ? "--" : bean.agentCode}' />
</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.origin.empty ? "--" : bean.origin}' />
<!-- 目的港pageQuery 出参无此字段,见问题清单,兜底双横线) -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"目的港"}'
value='@{"--"}' />
</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.empty ? "--" : 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.empty ? "--" : 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"
tag="@{true}"
title='@{"库位"}'
value='@{bean.location.empty ? "--" : bean.location}' />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"提货单号"}'
value='@{bean.pkId.empty ? "--" : bean.pkId}' />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- ==================== 卡片2提货信息绿头 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:background="@drawable/bg_phone_card"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_phone_card_header_green"
android:paddingHorizontal="16dp"
android:paddingVertical="12dp"
android:text="提货信息"
android:textColor="@color/white"
android:textSize="15sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- 柜台办理人 | 柜台办理时间 -->
<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.chargeName.empty ? "--" : bean.chargeName}' />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"柜台办理时间"}'
value='@{bean.chargeTime.empty ? "--" : bean.chargeTime}' />
</LinearLayout>
<!-- 出库人 | 出库时间(仅已出库) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal"
android:visibility="@{bean.isPickedUp ? View.VISIBLE : View.GONE}">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"出库人"}'
value='@{bean.dlvName.empty ? "--" : bean.dlvName}' />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"出库时间"}'
value='@{bean.dlvTime.empty ? "--" : bean.dlvTime}' />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
</layout>

View File

@@ -1,204 +1,166 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
国际进港提取出库 —— 手机版布局5.5 寸手持端,最小宽度 < 600dp 时生效)
平板版为同名文件 layout-sw600dp/activity_int_imp_pick_up_dlv.xml两者是同一布局的资源变体
DataBinding 因此生成同一个 ActivityIntImpPickUpDlvBinding 类。
变体之间必须满足:
· DataBinding 变量完全一致viewModel
· 保留 Activity 中引用的控件 idsrl / rv
· 平板独有的 checkIcon底部全选手机版不提供Binding 基类中自动变 @Nullable
交互差异(均复用既有 IntImpPickUpDLVViewModel 字段与接口):
· 状态 Tab 待出库/已出库 → outState 入参真实过滤api-doc 确认 0/1
角标 = 双 pageQueryTotalinitPhoneExtras 开启,平板不发)
· 平板「缴费日期起止」筛选设计稿无对应项手机端进入时清空默认当天initPhoneExtras
· 底部操作条仅待出库 Tab 显示PhoneBottomBar全选 + 已选统计 + 出库)
· 筛选弹层 4 项航班日期pageQuery 无 fdate 入参,预留,见问题清单)/航班号(fno)/代理人/特码
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android" <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"> xmlns:tools="http://schemas.android.com/tools">
<data> <data>
<import type="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType" /> <import type="android.view.View" />
<import type="com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayoutType" />
<variable <variable
name="viewModel" name="viewModel"
type="com.lukouguoji.gjj.viewModel.IntImpPickUpDLVViewModel" /> type="com.lukouguoji.gjj.viewModel.IntImpPickUpDLVViewModel" />
</data> </data>
<LinearLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="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" />
<!-- 搜索区域 -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginHorizontal="10dp" android:orientation="vertical">
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<!-- 缴费日期起 --> <include layout="@layout/title_tool_bar" />
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"选择缴费日期起"}' <!-- ==================== 搜索行 ==================== -->
icon="@{@drawable/img_date}" <LinearLayout
type="@{SearchLayoutType.DATE}" android:layout_width="match_parent"
value="@={viewModel.paymentDateStart}"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" /> android:background="@color/white"
android:orientation="vertical"
android:paddingHorizontal="16dp"
android:paddingTop="16dp"
android:paddingBottom="12dp">
<!-- 缴费日期止 --> <com.lukouguoji.module_base.ui.weight.phone.PhoneSearchBar
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout android:layout_width="match_parent"
hint='@{"请选择结束缴费日期"}' android:layout_height="wrap_content"
icon="@{@drawable/img_date}" hint='@{"搜索运单号"}'
type="@{SearchLayoutType.DATE}" setOnFilterClickListener="@{(v)-> viewModel.filterClick()}"
value="@={viewModel.paymentDateEnd}" setOnScanClickListener="@{(v)-> viewModel.scanWbNo()}"
android:layout_width="0dp" setRefreshCallBack="@{viewModel::searchClick}"
value="@={viewModel.wbNo}" />
</LinearLayout>
<!-- ==================== 状态 Tab待出库 / 已出库(角标为服务端全量计数) ==================== -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneStatusTab
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" /> counts="@{viewModel.tabCounts}"
setOnTabChanged="@{()-> viewModel.searchClick()}"
tabs="@{viewModel.tabList}"
value="@={viewModel.outState}" />
<!-- 代理人 --> <!-- ==================== 列表 ==================== -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout <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"
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_int_imp_pick_up_dlv" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<!-- ==================== 底部操作条(仅待出库 Tab ==================== -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneBottomBar
actionText='@{"出库"}'
allChecked="@{viewModel.isAllChecked}"
countText="@{viewModel.selectedCountText}"
setOnActionClick="@{(v)-> viewModel.confirmOutbound()}"
setOnAllCheckClick="@{(v)-> viewModel.checkAllClick()}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility='@{"1".equals(viewModel.outState) ? View.GONE : View.VISIBLE}' />
</LinearLayout>
<!-- ==================== 筛选弹层4 项,对应设计稿 filter-panel ==================== -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneFilterPanel
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="8dp"
panelVisible="@{viewModel.filterVisible}"
setOnConfirmClick="@{(v)-> viewModel.confirmFilter()}"
setOnDismissClick="@{(v)-> viewModel.closeFilter()}"
setOnResetClick="@{(v)-> viewModel.resetFilter()}"
title='@{"筛选条件"}'>
<!-- 航班日期pageQuery 无 fdate 入参,预留传参,见问题清单) -->
<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.flightDate}" />
<!-- 航班号 -->
<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.flightNo}" />
<!-- 代理人(复用平板既有 agentList -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"请选择代理人"}' hint='@{"请选择代理人"}'
list="@{viewModel.agentList}" list="@{viewModel.agentList}"
type="@{SearchLayoutType.SPINNER}" title='@{"代理人"}'
value="@={viewModel.agentCode}" type="@{PhoneDataLayoutType.SPINNER}"
android:layout_width="0dp" value="@={viewModel.agentCode}" />
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 运单号 --> <!-- 特码(字典由 initPhoneExtras 加载) -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
autoQueryEnabled="@{true}"
autoQueryMaxLength="@{8}"
autoQueryMinLength="@{4}"
autoQueryParamKey="@{`wbNo`}"
autoQueryTitle="@{`选择运单号`}"
autoQueryUrl="@{`/IntImpPickUpDlv/queryWbNoList`}"
hint='@{"请输入运单号"}'
icon="@{@drawable/img_scan}"
setOnIconClickListener="@{(v)-> viewModel.scanWbNo()}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.wbNo}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 特码 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请输入特码"}'
icon="@{@drawable/img_scan}"
setOnIconClickListener="@{(v)-> viewModel.scanSpCode()}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.spCode}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 搜索按钮 -->
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginHorizontal="10dp"
android:onClick="@{()-> viewModel.searchClick()}"
android:padding="2dp"
android:src="@drawable/img_search" />
</LinearLayout>
<!-- 列表 -->
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/srl"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="3"
tools:listitem="@layout/item_int_imp_pick_up_dlv" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<!-- 底部统计和操作按钮 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@android:color/white"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<!-- 全选按钮 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="5dp" hint='@{"请选择特码"}'
android:gravity="center_vertical" list="@{viewModel.specialCodeList}"
android:onClick="@{()-> viewModel.checkAllClick()}" title='@{"特码"}'
android:orientation="horizontal"> type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.spCode}" />
<ImageView </com.lukouguoji.module_base.ui.weight.phone.PhoneFilterPanel>
android:id="@+id/checkIcon"
setIVCheckAllImage="@{viewModel.isAllChecked}"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="5dp"
android:src="@drawable/img_check_all_unchecked" />
<TextView </FrameLayout>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="全选"
android:textColor="@color/color_66"
android:textSize="18sp" />
</LinearLayout>
<!-- 统计信息 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_weight="1"
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="18sp"
android:textStyle="bold" />
<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="18sp"
android:textStyle="bold" />
<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="18sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 确认出库按钮 -->
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()-> viewModel.confirmOutbound()}"
android:text="确认出库" />
</LinearLayout>
</LinearLayout>
</layout> </layout>

View File

@@ -1,205 +1,201 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
国际进港查询 —— 手机版布局5.5 寸手持端,最小宽度 < 600dp 时生效)
平板版为同名文件 layout-sw600dp/activity_int_imp_query.xml两者是同一布局的资源变体
DataBinding 因此生成同一个 ActivityIntImpQueryBinding 类。
变体之间必须满足:
· DataBinding 变量完全一致viewModel
· 保留 Activity 中引用的控件 idsrl / rv
· 平板独有的 filter_overlay / filter_panel侧滑筛选手机版不提供
Binding 基类中自动变 @NullableIntImpQueryActivity 已判空处理
交互差异(均复用既有 IntImpQueryViewModel 字段与接口):
· 平板 5 个横排搜索条 → 手机顶部搜索框(运单号)+ 底部筛选弹层
(航班日期起/止、代理从搜索行移入弹层;设计稿无「出库状态」项,未提供)
· 三格统计(总票数/已入库/已出库后两格为手机专属客户端计数initPhoneExtras 开启)
· 筛选弹层显隐直接绑既有 viewModel.filterVisible无需平板的滑入动画代码
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android" <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"> xmlns:tools="http://schemas.android.com/tools">
<data> <data>
<import type="android.view.View" /> <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 <variable
name="viewModel" name="viewModel"
type="com.lukouguoji.gjj.viewModel.IntImpQueryViewModel" /> type="com.lukouguoji.gjj.viewModel.IntImpQueryViewModel" />
</data> </data>
<LinearLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/color_f2" android:background="@color/phone_page_bg">
android:orientation="vertical">
<!-- 标题栏(始终在最上层,不被遮挡) --> <LinearLayout
<include layout="@layout/title_tool_bar" />
<!-- 内容区域FrameLayout 包裹,筛选面板和遮罩只在此区域内) -->
<FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="match_parent"
android:layout_weight="1"> android:orientation="vertical">
<!-- 原有内容 --> <include layout="@layout/title_tool_bar" />
<!-- ==================== 搜索行 ==================== -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:orientation="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
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp" hint='@{"搜索运单号"}'
android:layout_marginTop="10dp" setOnFilterClickListener="@{(v)-> viewModel.filterClick()}"
android:gravity="center_vertical" 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">
<!-- 总票数(蓝) -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/bg_phone_card"
android:orientation="horizontal"> android:orientation="horizontal">
<!-- 航班日期起 --> <View
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout android:layout_width="4dp"
android:layout_width="0dp" android:layout_height="match_parent"
android:layout_height="wrap_content" android:layout_marginVertical="12dp"
android:layout_weight="1" android:background="@color/phone_primary" />
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="@{`/IntImpSearch/queryWbNoList`}"
autoQueryParamKey="@{`wbNo`}"
autoQueryMinLength="@{4}"
autoQueryMaxLength="@{8}"
autoQueryTitle="@{`选择运单号`}" />
<!-- 搜索和筛选按钮 -->
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:orientation="vertical"
android:gravity="center_vertical|start" android:paddingHorizontal="12dp"
android:orientation="horizontal" android:paddingVertical="10dp">
android:paddingHorizontal="24dp">
<ImageView <TextView
android:layout_width="36dp" android:layout_width="wrap_content"
android:layout_height="36dp" android:layout_height="wrap_content"
android:onClick="@{()-> viewModel.searchClick()}" android:text="总票数"
android:padding="2dp" android:textColor="@color/phone_text_body"
android:src="@drawable/img_search" /> android:textSize="12sp" />
<FrameLayout <TextView
android:layout_width="36dp" android:layout_width="wrap_content"
android:layout_height="36dp" android:layout_height="wrap_content"
android:layout_marginLeft="16dp"> android:layout_marginTop="2dp"
android:text="@{viewModel.totalCount}"
<ImageView android:textColor="@color/phone_primary"
android:layout_width="match_parent" android:textSize="20sp"
android:layout_height="match_parent" android:textStyle="bold"
android:onClick="@{()-> viewModel.filterClick()}" tools:text="4" />
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>
</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_int_imp_query" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<!-- 底部统计信息 -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="50dp" android:layout_height="wrap_content"
android:background="@color/white" android:layout_marginStart="10dp"
android:gravity="center_vertical" android:layout_weight="1"
android:paddingHorizontal="15dp"> 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 <LinearLayout
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical" android:orientation="vertical"
android:orientation="horizontal"> android:paddingHorizontal="12dp"
android:paddingVertical="10dp">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text='@{`合计:` + viewModel.totalCount + `票`}' android:text="已入库"
android:textColor="@color/bottom_tool_tips_text_color" android:textColor="@color/phone_text_body"
android:textSize="16sp" android:textSize="12sp" />
android:textStyle="bold"
tools:text="合计3票" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="20dp" android:layout_marginTop="2dp"
android:text='@{`总件数:` + viewModel.totalPc}' android:text="@{viewModel.storedCount}"
android:textColor="@color/bottom_tool_tips_text_color" android:textColor="@color/phone_tag_orange_text"
android:textSize="16sp" android:textSize="20sp"
android:textStyle="bold" android:textStyle="bold"
tools:text="总件数100" /> 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 <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="20dp" android:text="已出库"
android:text='@{`总重量:` + viewModel.totalWeight}' android:textColor="@color/phone_text_body"
android:textColor="@color/bottom_tool_tips_text_color" android:textSize="12sp" />
android:textSize="16sp"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:text="@{viewModel.outboundCount}"
android:textColor="@color/phone_tag_green_text"
android:textSize="20sp"
android:textStyle="bold" android:textStyle="bold"
tools:text="总重量100" /> tools:text="2" />
</LinearLayout> </LinearLayout>
@@ -207,28 +203,131 @@
</LinearLayout> </LinearLayout>
<!-- 遮罩层(只覆盖内容区域) --> <!-- ==================== 列表 ==================== -->
<View <com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/filter_overlay" android:id="@+id/srl"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="0dp"
android:background="#80000000" android:layout_weight="1">
android:clickable="true"
android:focusable="true"
android:onClick="@{()-> viewModel.closeFilter()}"
android:visibility="gone" />
<!-- 筛选面板(从右侧滑入,只在内容区域内) --> <androidx.recyclerview.widget.RecyclerView
<include android:id="@+id/rv"
android:id="@+id/filter_panel" android:layout_width="match_parent"
layout="@layout/layout_int_imp_query_filter" android:layout_height="match_parent"
android:layout_width="wrap_content" android:clipToPadding="false"
android:layout_height="match_parent" android:overScrollMode="never"
android:layout_gravity="end" android:paddingTop="4dp"
android:visibility="gone" android:paddingBottom="24dp"
app:viewModel="@{viewModel}" /> itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="3"
tools:listitem="@layout/item_int_imp_query" />
</FrameLayout> </com.scwang.smart.refresh.layout.SmartRefreshLayout>
</LinearLayout>
<!-- ==================== 筛选弹层(绑既有 filterVisible ==================== -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneFilterPanel
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="8dp"
panelVisible="@{viewModel.filterVisible}"
setOnConfirmClick="@{(v)-> viewModel.confirmFilter()}"
setOnDismissClick="@{(v)-> viewModel.closeFilter()}"
setOnResetClick="@{(v)-> viewModel.resetFilter()}"
title='@{"筛选条件"}'>
<!-- 航班日期起(平板搜索行字段,手机移入弹层) -->
<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}" />
<!-- 特码(复用平板筛选面板同一字典 spCodeList -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"请选择特码"}'
list="@{viewModel.spCodeList}"
title='@{"特码"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.spCode}" />
<!-- 始发站 -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:id="@+id/phone_filter_origin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"请输入始发站"}'
title='@{"始发站"}'
type="@{PhoneDataLayoutType.INPUT}"
value="@={viewModel.origin}" />
<!-- 运单类型 -->
<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> </layout>

View File

@@ -1,6 +1,18 @@
<?xml version="1.0" encoding="utf-8"?> <?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_int_imp_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> <data>
@@ -14,27 +26,25 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/color_f2" android:background="@color/phone_page_bg"
android:orientation="vertical"> android:orientation="vertical">
<!-- 标题栏 -->
<include layout="@layout/title_tool_bar" /> <include layout="@layout/title_tool_bar" />
<!-- Tab栏 (自定义,文字Tab + 底线) --> <!-- ==================== Tab 栏:运单信息 / 仓库信息 / 库位信息 ==================== -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="40dp" android:layout_height="42dp"
android:layout_marginHorizontal="15dp" android:background="@color/white"
android:layout_marginTop="15dp"
android:background="@drawable/bg_white_radius_top_8"
android:orientation="horizontal"> android:orientation="horizontal">
<!-- Tab1: 运单信息 --> <!-- Tab1: 运单信息 -->
<LinearLayout <LinearLayout
android:layout_width="100dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center" android:gravity="center"
android:onClick="@{()->viewModel.onTabClick(0)}" android:onClick="@{()-> viewModel.onTabClick(0)}"
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
@@ -43,23 +53,25 @@
android:layout_weight="1" android:layout_weight="1"
android:gravity="center" android:gravity="center"
android:text="运单信息" android:text="运单信息"
android:textStyle="bold" android:textColor="@{viewModel.currentTab == 0 ? @color/phone_primary : @color/phone_text_body}"
android:textColor="@{viewModel.currentTab == 0 ? @color/colorPrimary : @color/text_gray}" android:textSize="14sp"
android:textSize="16sp" /> android:textStyle="bold" />
<View <View
android:layout_width="60dp" android:layout_width="28dp"
android:layout_height="3dp" 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}" /> android:visibility="@{viewModel.currentTab == 0 ? View.VISIBLE : View.INVISIBLE}" />
</LinearLayout> </LinearLayout>
<!-- Tab2: 仓库信息 --> <!-- Tab2: 仓库信息 -->
<LinearLayout <LinearLayout
android:layout_width="100dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center" android:gravity="center"
android:onClick="@{()->viewModel.onTabClick(1)}" android:onClick="@{()-> viewModel.onTabClick(1)}"
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
@@ -68,23 +80,25 @@
android:layout_weight="1" android:layout_weight="1"
android:gravity="center" android:gravity="center"
android:text="仓库信息" android:text="仓库信息"
android:textStyle="bold" android:textColor="@{viewModel.currentTab == 1 ? @color/phone_primary : @color/phone_text_body}"
android:textColor="@{viewModel.currentTab == 1 ? @color/colorPrimary : @color/text_gray}" android:textSize="14sp"
android:textSize="16sp" /> android:textStyle="bold" />
<View <View
android:layout_width="60dp" android:layout_width="28dp"
android:layout_height="3dp" 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}" /> android:visibility="@{viewModel.currentTab == 1 ? View.VISIBLE : View.INVISIBLE}" />
</LinearLayout> </LinearLayout>
<!-- Tab3: 库位信息 --> <!-- Tab3: 库位信息 -->
<LinearLayout <LinearLayout
android:layout_width="100dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center" android:gravity="center"
android:onClick="@{()->viewModel.onTabClick(2)}" android:onClick="@{()-> viewModel.onTabClick(2)}"
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
@@ -93,25 +107,24 @@
android:layout_weight="1" android:layout_weight="1"
android:gravity="center" android:gravity="center"
android:text="库位信息" android:text="库位信息"
android:textStyle="bold" android:textColor="@{viewModel.currentTab == 2 ? @color/phone_primary : @color/phone_text_body}"
android:textColor="@{viewModel.currentTab == 2 ? @color/colorPrimary : @color/text_gray}" android:textSize="14sp"
android:textSize="16sp" /> android:textStyle="bold" />
<View <View
android:layout_width="60dp" android:layout_width="28dp"
android:layout_height="3dp" 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}" /> android:visibility="@{viewModel.currentTab == 2 ? View.VISIBLE : View.INVISIBLE}" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<com.google.android.material.divider.MaterialDivider <com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1px"
android:layout_marginStart="15dp" android:background="@color/phone_divider" />
android:layout_marginEnd="23dp"
android:background="@color/color_f2" />
<!-- ViewPager2 --> <!-- ViewPager2 -->
<androidx.viewpager2.widget.ViewPager2 <androidx.viewpager2.widget.ViewPager2

View File

@@ -1,253 +1,329 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
国际进港仓库 —— 手机版布局5.5 寸手持端,最小宽度 < 600dp 时生效)
平板版为同名文件 layout-sw600dp/activity_int_exp_storage_use.xml两者是同一布局的资源变体
DataBinding 因此生成同一个 ActivityIntExpStorageUseBinding 类。
变体之间必须满足:
· DataBinding 变量完全一致viewModel / activity
· 保留 Activity 中引用的控件 idsrl / rv
· 平板独有的 checkIcon底部全选手机版不提供Binding 基类中自动变 @Nullable
交互差异(均复用既有 IntExpStorageUseViewModel 字段与接口):
· 平板 5 个横排搜索条 → 手机顶部搜索框(运单号)+ 底部筛选弹层 8 项
(设计稿弹层无「库位号/清仓结果」两项,对应平板字段保持空值不参与请求)
· 三格统计(总票数/未清仓/已清仓后两格为手机专属统计请求initPhoneExtras 开启,
复用 pageQueryTotal 按 clearNormal=0/1 各查一次)
· 平板底部批量操作条 → 手机卡片级操作按钮(见 item 布局),无全选/批量
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android" <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"> xmlns:tools="http://schemas.android.com/tools">
<data> <data>
<import type="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType" /> <import type="android.view.View" />
<import type="com.lukouguoji.gjj.R" /> <import type="com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayoutType" />
<variable <variable
name="viewModel" name="viewModel"
type="com.lukouguoji.gjj.viewModel.IntImpStorageUseViewModel" /> type="com.lukouguoji.gjj.viewModel.IntImpStorageUseViewModel" />
<!-- 与平板变体保持一致(手机版卡片操作经 ViewHolder 调 ActivityXML 中不直接引用) -->
<variable <variable
name="activity" name="activity"
type="com.lukouguoji.gjj.activity.IntImpStorageUseActivity" /> type="com.lukouguoji.gjj.activity.IntImpStorageUseActivity" />
</data> </data>
<LinearLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="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" />
<!-- 搜索区域 -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginHorizontal="10dp" android:orientation="vertical">
android:layout_marginTop="10dp"
android:gravity="center_vertical" <include layout="@layout/title_tool_bar" />
android:orientation="horizontal">
<!-- ==================== 搜索行 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical"
android:paddingHorizontal="16dp"
android:paddingTop="16dp"
android:paddingBottom="12dp">
<!-- 搜索分流同出港计重实测规则含字母→fno其余→wbNo见 phoneSearchClick -->
<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.scanWbNo()}"
setRefreshCallBack="@{viewModel::phoneSearchClick}"
upperCase="@{true}"
value="@={viewModel.phoneSearchKey}" />
</LinearLayout>
<!-- ==================== 三格统计:总票数 / 未清仓 / 已清仓 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<!-- 总票数(蓝) -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
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_primary" />
<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.totalWbNumber}"
android:textColor="@color/phone_primary"
android:textSize="20sp"
android:textStyle="bold"
tools:text="8" />
</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.unclearedCount}"
android:textColor="@color/phone_tag_orange_text"
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_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.clearedCount}"
android:textColor="@color/phone_tag_green_text"
android:textSize="20sp"
android:textStyle="bold"
tools:text="4" />
</LinearLayout>
</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"
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_int_imp_storage_use" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
</LinearLayout>
<!-- ==================== 筛选弹层8 项,对应设计稿 filterSheet ==================== -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneFilterPanel
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="8dp"
panelVisible="@{viewModel.filterVisible}"
setOnConfirmClick="@{(v)-> viewModel.confirmFilter()}"
setOnDismissClick="@{(v)-> viewModel.closeFilter()}"
setOnResetClick="@{(v)-> viewModel.resetFilter()}"
title='@{"筛选条件"}'>
<!-- 航班日期 --> <!-- 航班日期 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
hint='@{"请选择航班日期"}' android:layout_width="match_parent"
icon="@{@drawable/img_date}"
type="@{SearchLayoutType.DATE}"
value="@={viewModel.flightDate}"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" /> hint='@{"请选择航班日期"}'
title='@{"航班日期"}'
type="@{PhoneDataLayoutType.DATE}"
value="@={viewModel.flightDate}" />
<!-- 航班号 --> <!-- 航班号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
hint='@{"请输入航班号"}'
setUpperCaseAlphanumeric="@{true}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.flightNo}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 清仓综合结果 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请选择清仓结果"}'
list="@{viewModel.clearResultList}"
type="@{SearchLayoutType.SPINNER}"
value="@={viewModel.clearResult}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 运单号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
autoQueryEnabled="@{true}"
autoQueryMaxLength="@{8}"
autoQueryMinLength="@{4}"
autoQueryParamKey="@{`wbNo`}"
autoQueryTitle="@{`选择运单号`}"
autoQueryUrl="@{`/IntImpStorage/queryWbNoList`}"
hint='@{"请输入运单号"}'
icon="@{@drawable/img_scan}"
setOnIconClickListener="@{(v)-> viewModel.scanWbNo()}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.wbNo}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 库位号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请输入库位号"}'
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.location}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 搜索按钮 -->
<LinearLayout
android:layout_width="200dp"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="10dp">
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:onClick="@{()-> viewModel.searchClick()}"
android:padding="2dp"
android:src="@drawable/img_search" />
<!-- 全局展开/收起按钮 -->
<ImageView
loadImage="@{viewModel.isAllExpanded ? R.drawable.ic_new_expand_1 : R.drawable.ic_new_expand_1}"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="16dp"
android:contentDescription="展开/收起全部子列表"
android:onClick="@{()-> viewModel.toggleAllExpand()}"
android:padding="2dp"
android:scaleType="fitCenter" />
</LinearLayout>
</LinearLayout>
<!-- 列表 -->
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/srl"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="3"
tools:listitem="@layout/item_int_imp_storage_use" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<!-- 底部统计和操作按钮 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@android:color/white"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<!-- 全选按钮 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="5dp" hint='@{"请输入航班号"}'
android:gravity="center_vertical" title='@{"航班号"}'
android:onClick="@{()-> viewModel.checkAllClick()}" type="@{PhoneDataLayoutType.INPUT}"
android:orientation="horizontal"> value="@={viewModel.flightNo}" />
<ImageView <!-- 代理(手机专属筛选,字典由 initPhoneExtras 加载) -->
android:id="@+id/checkIcon" <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
setIVCheckAllImage="@{viewModel.isAllChecked}" android:layout_width="match_parent"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="5dp"
android:src="@drawable/img_check_all_unchecked" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="全选"
android:textColor="@color/color_66"
android:textSize="18sp" />
</LinearLayout>
<!-- 统计信息 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="20dp" hint='@{"请选择代理"}'
android:layout_weight="1" list="@{viewModel.agentList}"
android:gravity="center_vertical" title='@{"代理"}'
android:orientation="horizontal"> type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.agentId}" />
<TextView <!-- 特码 -->
android:layout_width="wrap_content" <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_height="wrap_content" android:layout_width="match_parent"
android:text='@{"合计:"+viewModel.totalWbNumber+"票"}'
android:textColor="@color/bottom_tool_tips_text_color"
android:textSize="18sp"
android:textStyle="bold" />
<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="18sp"
android:textStyle="bold" />
<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="18sp"
android:textStyle="bold" />
</LinearLayout>
<!-- 操作按钮组 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> hint='@{"请选择特码"}'
list="@{viewModel.specialCodeList}"
title='@{"特码"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.spCode}" />
<!-- 清仓按钮 --> <!-- 始发站(进港按始发站筛,入参 fdep -->
<TextView <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
style="@style/tv_bottom_btn" android:layout_width="match_parent"
android:onClick="@{()-> activity.showClearDialog()}" android:layout_height="wrap_content"
android:text="清 仓" /> hint='@{"请输入始发站"}'
title='@{"始发站"}'
type="@{PhoneDataLayoutType.INPUT}"
value="@={viewModel.fdep}" />
<!-- 修改库位按钮 --> <!-- 运单类型pageQuery 无此入参,后端补齐后自动生效,见接口问题清单) -->
<TextView <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
style="@style/tv_bottom_btn" android:layout_width="match_parent"
android:onClick="@{()-> activity.showModifyStorageDialog()}" android:layout_height="wrap_content"
android:text="修改库位" /> hint='@{"请选择运单类型"}'
list="@{viewModel.awbTypeList}"
title='@{"运单类型"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.awbType}" />
<!-- 出库按钮 --> <!-- 业务类型pageQuery 无此入参,同上) -->
<TextView <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
style="@style/tv_bottom_btn" android:layout_width="match_parent"
android:onClick="@{()-> activity.showOutStorageDialog()}" android:layout_height="wrap_content"
android:text="出 库" /> hint='@{"请选择业务类型"}'
list="@{viewModel.businessTypeList}"
title='@{"业务类型"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.businessType}" />
<!-- 入库按钮 --> <!-- 品名(中)pageQuery 无此入参,同上) -->
<TextView <com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
style="@style/tv_bottom_btn" android:layout_width="match_parent"
android:onClick="@{()-> activity.showInStorageDialog()}" android:layout_height="wrap_content"
android:text="入 库" /> hint='@{"请输入中文品名"}'
title='@{"品名(中)"}'
type="@{PhoneDataLayoutType.INPUT}"
value="@={viewModel.goodsCn}" />
</LinearLayout> </com.lukouguoji.module_base.ui.weight.phone.PhoneFilterPanel>
</LinearLayout> </FrameLayout>
</LinearLayout>
</layout> </layout>

View File

@@ -1,8 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
入库操作弹框手机版5.5 寸手持端):底部弹层样式。
平板变体layout-sw600dp/dialog_int_imp_in_storage.xml居中弹框
弹出位置由 IntImpInStorageDialogModel 按设备形态选择 BOTTOM/CENTER。
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <layout xmlns:android="http://schemas.android.com/apk/res/android">
<data> <data>
<import type="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType"/> <import type="com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayoutType" />
<variable <variable
name="model" name="model"
@@ -11,77 +16,60 @@
</data> </data>
<LinearLayout <LinearLayout
android:layout_width="480dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/bg_dialog_f2_radius_10" android:background="@drawable/bg_phone_panel_top"
android:gravity="center_horizontal" android:orientation="vertical"
android:orientation="vertical"> android:paddingHorizontal="20dp"
android:paddingTop="24dp"
android:paddingBottom="32dp">
<!-- 标题 --> <!-- 标题行:标题居中 + 右上关闭 -->
<TextView <FrameLayout
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_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="30dp" android:layout_marginBottom="24dp">
android:layout_marginTop="30dp"
android:orientation="vertical">
<!-- 库位号 --> <TextView
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center_vertical" android:gravity="center"
android:orientation="horizontal"> android:text="入库操作"
android:textColor="@color/phone_text_strong"
android:textSize="18sp"
android:textStyle="bold" />
<TextView <ImageView
android:layout_width="wrap_content" android:layout_width="24dp"
android:layout_height="wrap_content" android:layout_height="24dp"
completeSpace="@{5}" android:layout_gravity="end|center_vertical"
android:text="库位号:" android:onClick="@{()-> model.dismiss()}"
android:textColor="@color/text_normal" android:src="@drawable/ic_phone_close" />
android:textSize="16sp" />
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout </FrameLayout>
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
type="@{SearchLayoutType.SPINNER}"
hint='@{"请选择库位"}'
list="@{model.locationList}"
value="@={model.selectedLocationCode}" />
</LinearLayout> <!-- 库位号下拉 -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
</LinearLayout> android:layout_width="match_parent"
<!-- 底部按钮 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="40dp" hint='@{"请选择库位"}'
android:layout_marginBottom="20dp"> list="@{model.locationList}"
title='@{"库位号"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={model.selectedLocationCode}" />
<TextView <!-- 确定按钮 -->
style="@style/tv_bottom_btn" <TextView
android:onClick="@{()->model.dismiss()}" android:layout_width="match_parent"
android:text="取消" /> android:layout_height="48dp"
android:layout_marginTop="32dp"
<TextView android:background="@drawable/bg_phone_btn_primary"
style="@style/tv_bottom_btn" android:gravity="center"
android:onClick="@{()->model.onSaveClick()}" android:onClick="@{()-> model.onSaveClick()}"
android:text="确定" /> android:text="确定"
android:textColor="@color/white"
</LinearLayout> android:textSize="16sp"
android:textStyle="bold" />
</LinearLayout> </LinearLayout>
</layout> </layout>

Some files were not shown because too many files have changed in this diff Show More