From 1eb288a70355f4db047133fadb8b9cd075446de4 Mon Sep 17 00:00:00 2001 From: YANG JIANKUAN Date: Wed, 29 Jul 2026 20:09:55 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90=E5=87=BA=E6=B8=AF?= =?UTF-8?q?=E8=AE=A1=E9=87=8D=E9=A1=B5=E9=9D=A25.5=E5=AF=B8=E6=89=8B?= =?UTF-8?q?=E6=9C=BA=E7=AB=AF=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 待计重列表:三格统计、卡片单票提前运抵、筛选弹层(通道号/承运人/运单类型/代理人) - 开始计重:预配统计卡 + PhoneFormRow 表单 - 计重记录:三格统计、筛选弹层(入库日期/代理人/特码/目的站/计重人) - 计重明细:新增手机端全屏「修改记录」覆层,复用平板编辑链路 - 新增手机专属「运单详情」页 - 手机首页「国际」Tab 增加「出港计重」入口 - 登记后端接口缺口 7 项(#12~#18)至问题清单 Co-Authored-By: Claude Opus 4.6 --- .../skills/phone-adapt/references/api-doc.md | 8 + .../phone-adapt/references/components.md | 6 +- CHANGELOG.md | 22 + CLAUDE.md | 8 + app/src/debug/AndroidManifest.xml | 30 + app/src/main/AndroidManifest.xml | 6 + documents/后端接口对接问题清单.xlsx | Bin 14095 -> 16942 bytes .../module_base/bean/GjcCheckInRecord.kt | 12 + .../lukouguoji/module_base/bean/GjcMaWb.kt | 2 + .../main/res/drawable/bg_phone_btn_weak.xml | 7 + .../res/drawable/bg_phone_card_top_accent.xml | 9 + .../main/res/drawable/ic_phone_clipboard.xml | 11 + .../src/main/res/drawable/ic_phone_weight.xml | 11 + .../gjc/activity/GjcWeighingListActivity.kt | 43 + .../GjcWeighingRecordDetailsActivity.kt | 22 + .../activity/GjcWeighingRecordListActivity.kt | 39 + .../gjc/activity/GjcWeighingStartActivity.kt | 101 ++- .../activity/GjcWeighingWbDetailActivity.kt | 40 + .../gjc/holder/GjcCheckInRecordViewHolder.kt | 5 + .../gjc/holder/GjcWeighingRecordViewHolder.kt | 19 +- .../gjc/holder/GjcWeighingViewHolder.kt | 18 +- .../GjcWeighingRecordDetailsViewModel.kt | 38 + .../viewModel/GjcWeighingRecordViewModel.kt | 67 +- .../viewModel/GjcWeighingStartViewModel.kt | 28 +- .../gjc/viewModel/GjcWeighingViewModel.kt | 147 +++- .../viewModel/GjcWeighingWbDetailViewModel.kt | 30 + .../activity_gjc_weighing_list.xml | 227 +++++ .../activity_gjc_weighing_record_details.xml | 279 +++++++ .../activity_gjc_weighing_record_list.xml | 188 +++++ .../activity_gjc_weighing_start.xml | 496 +++++++++++ .../item_gjc_check_in_record.xml | 95 +++ .../res/layout-sw600dp/item_gjc_weighing.xml | 316 +++++++ .../item_gjc_weighing_record.xml | 272 ++++++ .../res/layout/activity_gjc_weighing_list.xml | 523 +++++++----- .../activity_gjc_weighing_record_details.xml | 527 ++++++------ .../activity_gjc_weighing_record_list.xml | 484 +++++++---- .../layout/activity_gjc_weighing_start.xml | 782 +++++++----------- .../activity_gjc_weighing_wb_detail.xml | 254 ++++++ .../res/layout/item_gjc_check_in_record.xml | 291 ++++--- .../src/main/res/layout/item_gjc_weighing.xml | 457 ++++------ .../res/layout/item_gjc_weighing_record.xml | 395 +++------ .../sixin/module_p/ui/enter/gj/GjViewModel.kt | 6 + .../img_gjc_chugangjizhong.png | Bin 0 -> 31892 bytes 43 files changed, 4380 insertions(+), 1941 deletions(-) create mode 100644 module_base/src/main/res/drawable/bg_phone_btn_weak.xml create mode 100644 module_base/src/main/res/drawable/bg_phone_card_top_accent.xml create mode 100644 module_base/src/main/res/drawable/ic_phone_clipboard.xml create mode 100644 module_base/src/main/res/drawable/ic_phone_weight.xml create mode 100644 module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingWbDetailActivity.kt create mode 100644 module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingWbDetailViewModel.kt create mode 100644 module_gjc/src/main/res/layout-sw600dp/activity_gjc_weighing_list.xml create mode 100644 module_gjc/src/main/res/layout-sw600dp/activity_gjc_weighing_record_details.xml create mode 100644 module_gjc/src/main/res/layout-sw600dp/activity_gjc_weighing_record_list.xml create mode 100644 module_gjc/src/main/res/layout-sw600dp/activity_gjc_weighing_start.xml create mode 100644 module_gjc/src/main/res/layout-sw600dp/item_gjc_check_in_record.xml create mode 100644 module_gjc/src/main/res/layout-sw600dp/item_gjc_weighing.xml create mode 100644 module_gjc/src/main/res/layout-sw600dp/item_gjc_weighing_record.xml create mode 100644 module_gjc/src/main/res/layout/activity_gjc_weighing_wb_detail.xml create mode 100644 module_p/src/main/res/drawable-xxhdpi/img_gjc_chugangjizhong.png diff --git a/.claude/skills/phone-adapt/references/api-doc.md b/.claude/skills/phone-adapt/references/api-doc.md index b7358d6..8634cee 100644 --- a/.claude/skills/phone-adapt/references/api-doc.md +++ b/.claude/skills/phone-adapt/references/api-doc.md @@ -70,6 +70,14 @@ curl -s -X POST "$URL" -H "$AUTH" -H "Content-Type: application/json" \ 0 正常/1 故障(三态需求=缺口 #7);无「来源」字段(#8)、无 `checkInDate`/`ifNo` 筛选入参(#9)、 无批量删除(#10,`deleteUld` 是 `@Query` 单条);出参 `ifNo`/`efNo`/`checkInDate`/`checkOutDate` 文档无描述,按命名推断进/出港航班号与出入库时间(#11 待确认) +- `IntExpCheckIn`(出港计重,2026-07-29 内网实测):`likeNo` **并非任意模糊**——按 8 位 `no` + 匹配(11 位 wbNo 或部分号均 0 条),11 位全号必须走 `wbNo`;`checkIn`/`checkInList` + 文档有定义但 `pageQuery`/`pageQueryTotal` **均静默忽略**(缺口 #12,待计重/计重中计数依赖); + 查询入参无通道号/承运人/运单类型(#13)、`checked/*` 无收运时间范围(#14);`checked/pageQuery` + 出参无通道号(#15)但有 `userName`(计重人中文名);`listRecordByWh` 出参计重人仅 `opId`(#16); + `preArrive` 成功后 `pageQuery` 的 `arriveFlag` 不回填(#17);`splitCheckIn`/`completeCheckIn` + 无 `palletNumber`/`carWeight` 入参(#18,手机版托盘数量/自重按设计稿传预留参数); + 运单类型字典:`DictUtils.getWaybillTypeList2(ieFlag="E", type="IO")` ## 内网直调验证技巧(比驱动 UI 快得多) diff --git a/.claude/skills/phone-adapt/references/components.md b/.claude/skills/phone-adapt/references/components.md index 5d9bc39..bc747d4 100644 --- a/.claude/skills/phone-adapt/references/components.md +++ b/.claude/skills/phone-adapt/references/components.md @@ -122,11 +122,13 @@ android.util.Log.d("DBG", "value '$field' -> '$v'", Throwable("trace")) `phone_divider` `phone_badge_bg` `phone_green` `phone_check_border` `phone_tag_gray_*` `phone_tag_green_*` `phone_tag_red_*` `phone_orange_bg/text` - 背景:`bg_phone_card` `bg_phone_search` `bg_phone_input` `bg_phone_stat_box` `bg_phone_panel_top` - `bg_phone_icon_round` `bg_phone_btn_primary` `bg_phone_btn_outline` `bg_phone_badge` - `bg_phone_tag_green/gray/red/orange` `bg_phone_card_header_blue/green` + `bg_phone_icon_round` `bg_phone_btn_primary` `bg_phone_btn_outline` `bg_phone_btn_weak`(浅蓝弱按钮) + `bg_phone_badge` `bg_phone_tag_green/gray/red/orange` `bg_phone_card_header_blue/green` + `bg_phone_card_top_accent`(卡片顶部主色描边条,出港计重头部卡片) - 图标:`ic_phone_airplane` `ic_phone_location` `ic_phone_person` `ic_phone_check_circle` `ic_phone_chevron_right/down` `ic_phone_calendar` `ic_phone_close` `ic_phone_check_round_checked/unchecked`(圆形复选框) + `ic_phone_clipboard`(剪贴板,白色 FAB 用)`ic_phone_weight`(砝码,可 tint) - 复用 Pad 的矢量图:`img_search` `img_scan` `img_filter`(可 `app:tint` 染色) 设计稿里的 MDI 图标若缺失,直接写 24×24 的 vector(用 MDI 官方 path),比找位图靠谱且能染色。 diff --git a/CHANGELOG.md b/CHANGELOG.md index d23c007..c2753ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,28 @@ ## [Unreleased] ### 新增 (Added) +- 「出港计重」5.5 寸手机端适配(首个全链路 4+1 页模块,设计稿 03_出港计重): + 待计重列表(三格统计 总票数/待计重/计重中 + 卡片状态标签 未计重/计重中 + 卡片内单票「提前运抵」+ + FAB 进计重记录 + 筛选弹层 通道号/承运人/运单类型/代理人)、开始计重(头部预配统计卡 + PhoneFormRow 表单, + 托盘数量/托盘自重按设计稿手输)、计重记录(三格统计 + 卡片地磅图标进明细/「查看详情」进运单详情 + + 筛选弹层 入库日期起止/代理人/特码/目的站/计重人)、计重明细(汇总卡含托盘总重 + 记录卡「修改」→ + 全屏「修改记录」覆层,复用平板 isEditMode 编辑链路,保存后留在本页)、手机专属新页「运单详情」 + `GjcWeighingWbDetailActivity`(12 字段只读网格);手机首页「国际」Tab 增「出港计重」入口 +- 新增手机版公共资源:`bg_phone_btn_weak`(浅蓝弱按钮)、`bg_phone_card_top_accent`(卡片顶部主色描边条)、 + `ic_phone_clipboard`、`ic_phone_weight` +- `GjcMaWb` 预留 `palletNumber`/`carWeight` 字段、`GjcCheckInRecord` 增 `carWeightStr` 双向绑定属性 + (均为手机版专属,平板请求体零变化);后端缺口 7 项登记问题清单 #12~#18 + (checkIn 过滤不生效、主列表筛选三入参、入库日期范围、通道号出参、计重人姓名、arriveFlag 不回填、 + 托盘数量/自重入参) + +### 修复 (Fixed) +- 出港计重手机版搜索分流按实测修正:`likeNo` 并非任意模糊(按 8 位 no 匹配), + 11 位全号改走 `wbNo` 精确查询,含字母走 `fno` + +### 验证 (Verified) +- 出港计重双端实机验证通过:手机端 待计重列表/筛选/开始计重(必填校验)/计重记录/记录筛选/运单详情/ + 计重明细/修改覆层保存/单票提前运抵 全链路 crash=0、方向无闪屏、请求体新参数全部正确携带; + 平板端 待计重/计重记录/开始计重 三页回归无变化(横屏、5 搜索条、日期默认今天、地磅区/托盘车号/浮动按钮组均在) - 「ULD管理」5.5 寸手机端适配(app 模块首个适配页):列表卡片(三色状态标签)+ 筛选弹层(入库时间/进港航班号/所属航司/来源)+ 右下角浮动新增 + 底部全选/批量删除(循环调用单条删除接口)+ 一套 `activity_uld_edit` 手机布局覆盖 新增/修改/详情 三态 (详情态右上铅笔进入修改、状态底部选择面板、所在港默认 HFE、必填校验仅手机生效) diff --git a/CLAUDE.md b/CLAUDE.md index fa2bfc2..9be348d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1054,6 +1054,8 @@ DataBinding 适配器统一放在 `PhoneWidgetKtx.kt`(同名属性按控件类 `PhoneBottomBar` 追加 `actionDanger` 属性:true 时主按钮转浅红底红字 + 垃圾桶图标(ULD 管理批量删除)。 新增资源:`bg_phone_btn_danger`、`bg_phone_fab`(圆形浮动 + 按钮)、`bg_phone_tag_red_light`(浅红标签)、 `ic_phone_trash`、`ic_phone_edit`、色值 `phone_danger_bg/text`。 +出港计重追加:`bg_phone_btn_weak`(浅蓝弱按钮,卡片内提前运抵)、`bg_phone_card_top_accent` +(卡片顶部主色描边条)、`ic_phone_clipboard`(FAB 剪贴板)、`ic_phone_weight`(砝码图标,可 tint)。 ⚠️ **弹层与浮动按钮的层级**:`PhoneFilterPanel` 默认无 elevation,页面里有带 elevation 的浮动按钮(FAB)时 会穿透到弹层之上——给弹层实例加 `android:elevation="8dp"`(大于 FAB 的 6dp)。 @@ -1102,6 +1104,12 @@ override fun dispatchRestoreInstanceState(container: SparseArray) = (公共组件首个完整落地页,双端实机验证通过) - 「ULD管理」`UldListActivity` + `UldEditActivity`(app 模块首个适配页;一套编辑布局覆盖 新增/修改/详情三态;批量删除为前端循环调用单条接口;状态三态/来源等 5 项后端缺口见问题清单 #7~#11) + - 「出港计重」全链路 4+1 页:`GjcWeighingListActivity`(待计重列表,三格统计 + 卡片单票提前运抵 + + FAB 进记录)、`GjcWeighingStartActivity`(开始计重,托盘数量/自重按设计稿手输)、 + `GjcWeighingRecordListActivity`(计重记录)、`GjcWeighingRecordDetailsActivity`(计重明细, + isEditMode 复用为手机全屏「修改记录」覆层)+ 手机专属新页 `GjcWeighingWbDetailActivity`(运单详情)。 + 搜索分流规则(实测):含字母→fno、11 位数字→wbNo、其余→likeNo(likeNo 按 8 位 no 匹配并非模糊); + checkIn 过滤等 7 项后端缺口见问题清单 #12~#18 - ⏳ **待办**: - `PhoneSearchBar` 接入 AutoQuery 联想(`AutoQueryManager` 目前只对接了 Pad 系组件) - 出库交接 Tab 角标恒 0:`IntExpOutHandover/pageQueryTotal` 出参恒 0(后端缺陷,问题清单 #6), diff --git a/app/src/debug/AndroidManifest.xml b/app/src/debug/AndroidManifest.xml index 0ecb42d..3fabae5 100644 --- a/app/src/debug/AndroidManifest.xml +++ b/app/src/debug/AndroidManifest.xml @@ -50,5 +50,35 @@ android:exported="true" tools:replace="android:exported" /> + + + + + + + + + + + + + + + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e0d5ebd..cc1e1d7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -205,6 +205,12 @@ android:configChanges="orientation|keyboardHidden" android:exported="false" android:screenOrientation="unspecified" /> + + +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 delta 7948 zcmZ8mWl&t*vK^cN!2=BL?ht|xE<#)6x%d1sG&`~+jbn_g6kR>FeMm}YJ{dpOdX17Plc z^x)_<6n;L}N|Qkq3bT=I+~b^sd+}3ZP0nMr-sPFCugy+2%Lp)~G+u%E!LstA?z74b zBFbfoWecyDa^pjjnPYk4avOFi?+??rl{5$yBUJ<_+10cfI5f6>#ZG0#9y$!3+S{G7 z1nxbW^qk@t7aV=>=_g+iFN}{nz-JCx^`lH{bq=%j*~DuhKeLzJ`CwYXPDDbIK>259 z8~D!lqUPo5{bf^Gl_M;JEBpG;p{c7qv!>^1gX%2Lrz^$L#6wY@7DXy0pcPcHykwm=N#SIgtBE&(HCNShy!+n_IWR0}CX_gi?7* zMy1Q4@zl00y4^=_zSha~mF_VduxY?0NKzDlz4>XHb-meIGNvti6*KB}&E zzUqlz>2l0wI>L9z!YMf09AB(rWy{p3j{rv1&V23MbZ$y$j#4mTo4tE$e>U>Fu}eHl zEBUCgJWy*S}uTpaSCBPtq+LRlG0cggh!X81i$Mx>D< zC?z@(La?y%eL$CJ^+5=)am;>zqEJy?!~*YqNena!&BS=dgxNPi(i6kaMs3i99jmx^A1d?mdLvD(KaM z7!Mr@p3I48m%>?N=^6lha;fFUos-ewBgLZxiR6x!5l_|ah24*+kcY-^iTQ2ymn;r2NcEPoz_JJ0|&UGbKadiH^h!-DTI zX~kNWjaM7Sk0h^NQxHNZ8IdN#Ndbxw>cMwTAs+$}jwO!{Hd& zx!=}F5nbTMA-@@$D5;bW;9oa`>|?jKLZV5CUXjLkpsalFoR|7Lt%ei&s^%ej!nFRck1! z4EN7unSoZX!Hgwxwn~kf@InjLR-=6Ux!dgc5DTn-x9h!>Mj08-hTbq;iN`ltj#S7lFlSI&>EPo-PD|dqF@>(UX|O0+ zvFNH-(mQ}q+`LJm03O4!U|t9^@062!YWJ`$9_Dnzkgjvc#>KN%9rp|NxZj=#Igu=) zz8Fz%3J`(WjTO@GGY~$LQJ>GyI`6*n1J3N&PI9UD(nWUlvXLRkbrI1xn`QxjKk5FCYQhLy4RBhW5~WUH5- zUjW3IhRR3;BDf5UeCX;;@mrBb&@4NDk&0CA;*ZJwLP7Dh?9iz<2IV>b;B&M<96)Kg zOM3an?G)9~PJ98y>^Tw#F`4EdLkQwB2I(cSN!(=hm>p+zaNN{H8=32f4SeI?G1)y# z+{MHDxm`*j{Xx?&r;4EwX|9@|26~8C`Ss5==B*tOMh?7Dh$u5S@?^_$8;Ja-Z^gRa zS@wry22Wa~*|n~460N=y0ZEJ6hyte$#iG6XG6do9y#*a_Z;NTsyz>v#Hh@;}MQmSeoB0@ef z0LhiprZT=jPd%)`3L=0p394&V_$!*SW<@`^`$4wW|B}R%hss15NC58zBA?<>->*#b zm|Z$8=Z&SM_m|cbWuzJnfo#;rlxjB2tTK2QLpL+DE!G~+MXBtXdpVNvJEWJA{Gg8h zSS?pd7oee#m*_#t7%v+{qJ!pcSdHu5zAu~4OPv@0W5O^A+_e&69 z-`&rijcno*shQOhs3$mX3y)NJ&Xt(5eV`a?$2=(Qz zsPLw7qLl8U$NPPkHg5K;fX3binnSLpKu0)#r^1n~VDoHm{m6JKT99gRCn{E|Eued7`mH3|7ahk zgiDM(btgJ?=P&9`;HD?=*ETD@Ia58WXYmSOg&7nwHo>R8RzWSIqjuEW6zMI2h_h{# zf4*6vM$%Y`99I~rA6kNxI7^_PJT0xbqehy@&Z_5FfB|kMoR={jk)D5OWW(<-O$_i; zydF8*)_Kq}fy7Ag$f!eB{TKVO-xA^E%()51}s0v!(!ZHnq6F7y#=MBEHG9C2qR>nfgdm zoJ}xvAe=9`{fOZcy^vo*Y4Zu{2IvkClMS&dN;9iX^F}8Wf64Z~EXm*+CC_Qe_v~xli7&3F3@oS}vc2d52KAP-dw0os>by25<>gqH zHGxzG&%ITKMUJ|>_&&I(^*ZFdgbwJ^%RrbhuPM7J;&U0oFzr}qrJ5* zfwY29YymVDit*NHCF=M5X$Va*cwxQWs=PE^^}Ka?`|zP(1NQ#!OXyYuORkQmBb-f9 zyZ!fXuXf6L1N{8`_FgDqQ@#XNw?9azGx_@g9g_Q+lRWBt6-u)+D0MID*9P{{**M9= z48|Hsw z;M?xrj~^+)U0wJ6VcPrtXZ~ZSDvkPYFw1!gm-c28Qdu|EE_q*WsrgD$V=b{Su_itO z-2{xN${g+-vqF%gFJrry2yo#o)P9TA58W(jXo{`b?2WoyEau6Mj9XT^^vc*6>q>%y z7(rgo&rF8A(+@E21*#QKjxDQSy5!6b+#j5|WPGzAUZS=DF&mGOn3fmCn7CEHYciVo zSTJT=%4qZvVC?)wNxB(}o$$N)V;^xJQ21u(lHdH9N^VpM=nZp#H)_>Kk7%`7Ek^fy zSX#~i6>Dv@9VeI&MJ9xL)ZFq z_g?*S4;P}!KStEHz(>#4+^+-8ji__jVI&ykkUd7TPR%waJeLh9A~;?TiBTndCw?*( zCMHC+b@)9So`_Fo*m-z+!&62lG?Oq>z=y~Ju9r1gRR%Q})N0g~EKd>is;kAGW4OtE zLeBOL6~*Zmrg^PJ!bHJugjTP)j znc7cmWrclbs)n9T&=AvB_hB!GZ07YNHPF`cJqm7NeV*-`y;i{PGB6mER?LW=89S43 zKuZv9B!-K|q`KGG2asI+x}A0&(b=TmJgz`ZW~=bgo+;!PlM;LCrv${#SZqT`D${c# zWDnD6eg+>)BnAm}^+dZsOs@+?p8v!`NcEr;EVB zA0uX46rg8o>DO^DM7AZ~AGF+6kh-*e;!9CoJ7Z>OMYG`Cp@4?X^!y&(v()69e1tb> zOBMVJWRa1#IdSqF5KkH*C?#ElXqybG}Fw zuAH&Kvwylov6a$m{E}_uM{l3)4Xx8WG*IQB-?cPr4=XeTPs5@ZrWm4!w>OgpCb>RB zsT`X|D!^NW@IL)Gs(Gj5`-x@eM9b$0!g9wLcV>5w{(g}?tFN3_(F0Sm>pT11K`cF* z@BMk%`)cQWpjvI~T{c7IKBO-pibBrq9W2k3Dm8p>S>l_8y|7G$oj;|wi~_PeB1Khg z;4QZTJOqJ%U8^Tqyf~j*!z?DG;H0Z*kX}+bs?pF0ZxZRW|01BNf^UZQ&q8SAc1-5!WZ| z7lfslSciP!<9J-|wMeAyIcn1{Hu4unKgYXxzb~&)8hG9C{pw3v%muXDsyEudM86G( zSxI3?Fzq=ub|2O$qKzOj-_tR7moFva*zivnQ--(D>ihTBZXJ)ebGbP`nR8Y%Rj#Az z@Z;O11A$blkTrW}D{*h4ee0}|hZE_Y@t^ug>D}-u@vi08k*T*f1K4Y6x3&*sA{Gvh z-ymdr-78-%wl%9zqf*ndJoI7UahG01Ukm6MMMx~;YJI4q!d0SwMw7P zajQ2E`ijhDnCT*N%yiC+dG$$}K4SwEzuvlTT4nho3MVFpyh^CPX0B>Csh8#a@MRFL5pnJYy?#((bV4YFa$VYd5TT z36jVijlbqDsD0t+%B+D*re`}$8$By6_y`pronLS34fk-bGRZ}Awhm3#5or2q!{LnE zV_KtAb4zXNVQ1=lf7J6|y4CYPiVUg~lura11e$*Sk0QhSSCMH+cXVDB_$ylFBlxyO zZ3fG{Yz<<3I}JJ{;y=8~YOpgbr?)56WO}#|p|oC9v1TAkcvX7i0#E{?d83OH-|JR& z-V%$=YR`;s)x0}irr%F9G_E>{wR1-jdu#c2C*S^+;(|eq&KoV=XAJa8_Synx7GaLB zJb3u7fm&8Ff6Jni?%GuU&e_z(@h$!zulzV)8U7?o8miVN^RHS>zZ#a}0RN$}CcBnj z+3M1VvPWsnL=i%X_FMbF*zTbWj&o+Uv8Efau zZz*sX-zu;5)_eQe=J2(gqH*QAO*Oaf!kkb^K%}RP^zJ}B&FVs(wPkp;vg`TdPP$=EpNOGDp^iiQ@hl{N#MlHhTyE^v| zOmSl)#3R(e_aKF7U7z8F!{ILA&C@5qlS;dZcddD76eAO*I42H2Xa2p;%T*DGl6l5gxAUMHavrO?99?e`MpNa(^7~Lq0}lkD9VZlhF~t{XGQIGNTwTKo0;il z&v`E;SSH`)lu*ygt3tt&Fal307#Da4e88guFQOp6bs*+mkAOPGYENY$wZ+Ba5Iw-ah4%FhW#a4Vny$>xR))49(v};%3oX(}2+f$SsPUiDg{_T>{%wX~hQ{AWE`< znY^N;_c4(j1iuDBs-05kDsKU&@pP5tHSL-r`lT$_q#695I!BsvLE-R>oTJ0@n<;#j ze)IHCbka*<#geF-iths$I_+1BXTnC2ySbrhIH7{+S3bsLNDyC?ZhM!7n-#1R5w9b9i(C+rR z^(v~a93fFTtYK?GSW|jH5FZv4cNQNB)r=yRW%MT6#8BCnO_1fJ5$cT%425vA@@@}G z;Ro@vtA1-djo-X>4SCY?*;qnoQ}cG9k9uuF?)KaJ^XPQRcZi2L3ydY3vvU0wgp>M8 zh#o@5d0T*ZO4ykcri&Wjv@u>%Lj`(xYq`?BS@&ar&FPHmziyeJrhMl5f62cpvYAqr zs2~s{;h)Qf5=hlsc3Kw1eR$D_a+elytwe$Lxm3>~Xqq(OZUjyFaITSk6eX;EM zxq$wQ#}TqDRFk$Mlh1Y{=KYz`T>SXAc7gi_&R63OjSkDl;iAsFN^P83aQj06m!I90 z3$mCqcQnqeEo?;QGaX}K8dg){s`2e}S|eBu7guFjD`4cf;+XqV_0V1Y>Gyc*9Na;Q zX*G1RD%|>zYdf8Id9%;o^|93@ss;~%qH4MtYY`h8mZ8gB3s zKf79b9gGxmaB>|S2vt283r;+tmrgR;C-n{Jkj0;;w}!#kzAu<`10&_dHg}H{Wm1|X znJI&Jc)Q=?jW9Beeuk0l$}6S(T6nI#A-b3}%#ySKAQwFhnm{H~20Ku)r z2e&}oH2SD-xqS4UbLL&#dmK|HMY=|1QlJTfZS#vI4RDuDQ8l<|4T5%rxyQmx<*bzgnWmHxUvPFh>U~nThuA@M%M-yHw z&n*^a*}ht6Gp;ld`}8~oP9<#scohD?Oxny4G*ifz@ zeI_I`s1_mv|3=GGP%nT>^UDb7TT<@i*G;>P^Icc%H05q%9WqZH_9(|}X|gT*woDjf zJmtqa;<|{SV@tF6VTl_O7nCr1C#-sKT+D1gJr>mkMGEaFmY4F^4cm!(KtOsM>@}pN z&ayFKOSomgtJdOEgrx6FTVCr=glY5vxiYay1q5{RuE~^bKd8P2s|0r$FkRh2KXick z;uR!I73*k2wj(XDjE!yECO@%HnwSV<<8e~VRY~dwu6*AZEE@Kv{OG3lp+n;nn=$O$ z?9S?Fze;jidUtE{OhG~M5imaFZ)BlD3orLGc;3APz1ggw(IaNbkm@v;IS#qTmO3aUi;<#VrSu(RN*p=0UA{bpgd8y1 zhV1!fc~8lI8E@|cV;H&tVdQrzrMOz&FQ0>WL-CA>vSlw<=S-Ih-2r`#l)eHNVM3v} z(cZDI*!R~33rQ5(3@oe-utgya28x~OJ?qEV+fydpr{4xGvY8ajK~jne9_MKpSpGbz z&M~8N9@z|T_}N1NKO!BgWB0Zn5PyAiw^eUhW@U;J@OXUd8g3r#%o-D1*7j;a&QQsz zyFghWwPoQ%7kc|3jSCF3AiV>dez0-~Z>9_dYu=QkQ!DJd8j@&YYQ#qFPc^@bs{<=! zzu^=`swfe(_%awkmse38?Z0>MJ|A*<>Xe6BCdAztGPUJQ6Ml|g5EC;!+2@PT7-2tM-*H3Dg7&pRN-iK0wnDRZPa10Vc!EfS<}^CR{q^q{y4L~^Yq_6>A|Qj zy(vS$6$ud>l#D6-^N(q|5S~Ez3kOB7{=!Z%y?-DPL=^qs!`);9$g96wk|B`)KhIo; z2vYyu_MZne2t@K{7X0rO7*qpJu4jIctSo`|H-(u5IU*(H9}j7Ah6L6>q5o-*|37q! z{-4mre}x|X3AJNO#*icv`CBnP3P#@hrwqZLsWaxk%l)x|2 + + + + + diff --git a/module_base/src/main/res/drawable/bg_phone_card_top_accent.xml b/module_base/src/main/res/drawable/bg_phone_card_top_accent.xml new file mode 100644 index 0000000..b551906 --- /dev/null +++ b/module_base/src/main/res/drawable/bg_phone_card_top_accent.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/module_base/src/main/res/drawable/ic_phone_clipboard.xml b/module_base/src/main/res/drawable/ic_phone_clipboard.xml new file mode 100644 index 0000000..980d0ed --- /dev/null +++ b/module_base/src/main/res/drawable/ic_phone_clipboard.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/module_base/src/main/res/drawable/ic_phone_weight.xml b/module_base/src/main/res/drawable/ic_phone_weight.xml new file mode 100644 index 0000000..ebec08a --- /dev/null +++ b/module_base/src/main/res/drawable/ic_phone_weight.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingListActivity.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingListActivity.kt index a0e37bb..f657b23 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingListActivity.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingListActivity.kt @@ -3,19 +3,26 @@ package com.lukouguoji.gjc.activity import android.content.Context import android.content.Intent import android.os.Bundle +import androidx.databinding.ObservableBoolean import com.alibaba.android.arouter.facade.annotation.Route import com.lukouguoji.gjc.R import com.lukouguoji.gjc.databinding.ActivityGjcWeighingListBinding import com.lukouguoji.gjc.viewModel.GjcWeighingViewModel import com.lukouguoji.module_base.base.BaseBindingActivity +import com.lukouguoji.module_base.bean.GjcWeighingBean import com.lukouguoji.module_base.common.ConstantEvent import com.lukouguoji.module_base.impl.FlowBus import com.lukouguoji.module_base.impl.observe import com.lukouguoji.module_base.ktx.getLifecycleOwner import com.lukouguoji.module_base.router.ARouterConstants +import com.lukouguoji.module_base.util.DeviceUtil /** * 国际出港计重列表页 + * + * 布局 id 不区分设备,平板/手机由资源限定符自动选择: + * layout-sw600dp/activity_gjc_weighing_list.xml(平板) + * layout/activity_gjc_weighing_list.xml(手机) */ @Route(path = ARouterConstants.ACTIVITY_URL_GJC_WEIGHING_LIST) class GjcWeighingListActivity : @@ -25,10 +32,20 @@ class GjcWeighingListActivity : override fun viewModelClass() = GjcWeighingViewModel::class.java + /** 手机版筛选弹层显隐(仅 UI 状态,不涉及业务逻辑) */ + val filterPanelVisible = ObservableBoolean(false) + override fun initOnCreate(savedInstanceState: Bundle?) { setBackArrow("国际出港待计重") binding.viewModel = viewModel + binding.activity = this + + // 手机版专属数据:放开默认日期、加载筛选弹层字典、启用三格统计 + // 平板端不调用,查询链路与请求次数与改造前完全一致 + if (DeviceUtil.isPhone()) { + viewModel.initPhoneExtras() + } // 初始化代理人列表(从API获取) viewModel.initAgentList() @@ -52,6 +69,32 @@ class GjcWeighingListActivity : viewModel.refresh() } + // ==================== 手机版专用交互(纯 UI,复用既有 ViewModel 字段) ==================== + + /** 手机版筛选弹层显隐切换 */ + fun toggleFilterPanel() { + filterPanelVisible.set(!filterPanelVisible.get()) + } + + /** 手机版筛选:重置(只清弹层内条件,不影响顶部搜索框) */ + fun resetFilter() { + viewModel.channelFilter.value = "" + viewModel.carrierFilter.value = "" + viewModel.awbTypeFilter.value = "" + viewModel.agentCode.value = "" + } + + /** 手机版筛选:确认 */ + fun confirmFilter() { + filterPanelVisible.set(false) + viewModel.searchClick() + } + + /** 手机版卡片内「提前运抵」(单票,由 ViewHolder 调用) */ + fun preArriveClick(bean: GjcWeighingBean) { + viewModel.arrivedAheadSingle(bean) + } + companion object { @JvmStatic fun start(context: Context) { diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingRecordDetailsActivity.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingRecordDetailsActivity.kt index b9ace48..f2c6887 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingRecordDetailsActivity.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingRecordDetailsActivity.kt @@ -12,12 +12,17 @@ import com.lukouguoji.gjc.holder.GjcCheckInRecordViewHolder import com.lukouguoji.gjc.viewModel.GjcWeighingRecordDetailsViewModel import com.lukouguoji.module_base.base.BaseBindingActivity import com.lukouguoji.module_base.base.CommonAdapter +import com.lukouguoji.module_base.bean.GjcCheckInRecord import com.lukouguoji.module_base.bean.GjcWeighingRecordBean import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.router.ARouterConstants /** * 国际出港计重明细页 + * + * 布局 id 不区分设备,平板/手机由资源限定符自动选择: + * 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 : @@ -70,6 +75,23 @@ class GjcWeighingRecordDetailsActivity : viewModel.initOnCreated(intent) } + // ==================== 手机版专用交互(纯 UI,复用既有 ViewModel 编辑链路) ==================== + + /** + * 手机版:打开「修改记录」覆层编辑指定记录。 + * 复用 [GjcWeighingRecordDetailsViewModel.onModifyClick] 的备份/编辑态逻辑, + * 覆层显隐由 isEditMode 驱动(平板端该状态驱动列表内联编辑,互不影响)。 + */ + fun openPhoneEdit(record: GjcCheckInRecord) { + viewModel.onModifyClick() + binding.editRecord = record + } + + /** 手机版:取消编辑(恢复备份并收起覆层) */ + fun closePhoneEdit() { + viewModel.onCancelClick() + } + companion object { @JvmStatic fun start(context: Context, bean: GjcWeighingRecordBean) { diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingRecordListActivity.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingRecordListActivity.kt index 5d6253e..bb83248 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingRecordListActivity.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingRecordListActivity.kt @@ -3,6 +3,7 @@ package com.lukouguoji.gjc.activity import android.content.Context import android.content.Intent import android.os.Bundle +import androidx.databinding.ObservableBoolean import com.alibaba.android.arouter.facade.annotation.Route import com.lukouguoji.gjc.R import com.lukouguoji.gjc.databinding.ActivityGjcWeighingRecordListBinding @@ -13,9 +14,14 @@ import com.lukouguoji.module_base.impl.FlowBus import com.lukouguoji.module_base.impl.observe import com.lukouguoji.module_base.ktx.getLifecycleOwner import com.lukouguoji.module_base.router.ARouterConstants +import com.lukouguoji.module_base.util.DeviceUtil /** * 国际出港计重记录列表页 + * + * 布局 id 不区分设备,平板/手机由资源限定符自动选择: + * layout-sw600dp/activity_gjc_weighing_record_list.xml(平板) + * layout/activity_gjc_weighing_record_list.xml(手机) */ @Route(path = ARouterConstants.ACTIVITY_URL_GJC_WEIGHING_RECORD_LIST) class GjcWeighingRecordListActivity : @@ -25,10 +31,20 @@ class GjcWeighingRecordListActivity : override fun viewModelClass() = GjcWeighingRecordViewModel::class.java + /** 手机版筛选弹层显隐(仅 UI 状态,不涉及业务逻辑) */ + val filterPanelVisible = ObservableBoolean(false) + override fun initOnCreate(savedInstanceState: Bundle?) { setBackArrow("国际出港计重记录") binding.viewModel = viewModel + binding.activity = this + + // 手机版专属数据:放开默认日期、加载计重人下拉 + // 平板端不调用,查询链路与请求次数与改造前完全一致 + if (DeviceUtil.isPhone()) { + viewModel.initPhoneExtras() + } // 初始化代理人列表 viewModel.initAgentList() @@ -50,6 +66,29 @@ class GjcWeighingRecordListActivity : viewModel.refresh() } + // ==================== 手机版专用交互(纯 UI,复用既有 ViewModel 字段) ==================== + + /** 手机版筛选弹层显隐切换 */ + fun toggleFilterPanel() { + filterPanelVisible.set(!filterPanelVisible.get()) + } + + /** 手机版筛选:重置(只清弹层内条件,不影响顶部搜索框) */ + fun resetFilter() { + viewModel.checkInDateStart.value = "" + viewModel.checkInDateEnd.value = "" + viewModel.agentCode.value = "" + viewModel.spCode.value = "" + viewModel.destFilter.value = "" + viewModel.opUserFilter.value = "" + } + + /** 手机版筛选:确认 */ + fun confirmFilter() { + filterPanelVisible.set(false) + viewModel.searchClick() + } + companion object { @JvmStatic fun start(context: Context) { diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingStartActivity.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingStartActivity.kt index 168ed21..937534d 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingStartActivity.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingStartActivity.kt @@ -15,6 +15,7 @@ import com.lukouguoji.gjc.viewModel.GjcWeighingStartViewModel import com.lukouguoji.module_base.base.BaseBindingActivity import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.router.ARouterConstants +import com.lukouguoji.module_base.util.DeviceUtil /** * 国际出港计重-开始计重页面 @@ -32,26 +33,38 @@ class GjcWeighingStartActivity : override fun initOnCreate(savedInstanceState: Bundle?) { setBackArrow("国际出港开始计重") binding.viewModel = viewModel + + // 手机版专属:提交体携带托盘数量/托盘自重(平板不调用,请求体与改造前完全一致) + if (DeviceUtil.isPhone()) { + viewModel.initPhoneExtras() + } + viewModel.initOnCreated(this, intent) setupFloatButtons() } private fun setupFloatButtons() { + // 浮动按钮组仅平板布局存在(layout-sw600dp),手机布局无这些 id,直接跳过 + val mainFloatButton = binding.mainFloatButton ?: return + val maskView = binding.maskView ?: return + val subButton1 = binding.subButton1 ?: return + val subButton2 = binding.subButton2 ?: return + // 主按钮点击事件 - binding.mainFloatButton.setOnClickListener { + mainFloatButton.setOnClickListener { if (!isExpanded) { expandButtons() } } // 遮罩层点击事件 - binding.maskView.setOnClickListener { + maskView.setOnClickListener { collapseButtons() } // 子按钮1点击事件 - 跳转到出港运抵页面 - binding.subButton1.setOnClickListener { + subButton1.setOnClickListener { com.alibaba.android.arouter.launcher.ARouter.getInstance() .build(ARouterConstants.ACTIVITY_URL_INT_EXP_ARRIVE) .navigation() @@ -59,7 +72,7 @@ class GjcWeighingStartActivity : } // 子按钮2点击事件 - 跳转到计重记录 - binding.subButton2.setOnClickListener { + subButton2.setOnClickListener { com.alibaba.android.arouter.launcher.ARouter.getInstance() .build(ARouterConstants.ACTIVITY_URL_GJC_WEIGHING_RECORD_LIST) .navigation() @@ -68,37 +81,42 @@ class GjcWeighingStartActivity : } /** - * 展开子按钮 + * 展开子按钮(仅平板,手机布局无浮动按钮组) */ private fun expandButtons() { + val mainFloatButton = binding.mainFloatButton ?: return + val maskView = binding.maskView ?: return + val subButton1 = binding.subButton1 ?: return + val subButton2 = binding.subButton2 ?: return + isExpanded = true // 显示遮罩层 - binding.maskView.visibility = View.VISIBLE - binding.maskView.alpha = 0f - binding.maskView.animate().alpha(0.3f).setDuration(200).start() + maskView.visibility = View.VISIBLE + maskView.alpha = 0f + maskView.animate().alpha(0.3f).setDuration(200).start() // 显示子按钮 - binding.subButton1.visibility = View.VISIBLE - binding.subButton2.visibility = View.VISIBLE + subButton1.visibility = View.VISIBLE + subButton2.visibility = View.VISIBLE // 子按钮1动画(向左上方移动: 左移15dp, 上移55dp) - val sub1TransX = ObjectAnimator.ofFloat(binding.subButton1, "translationX", 0f, -5f) - val sub1TransY = ObjectAnimator.ofFloat(binding.subButton1, "translationY", 0f, -25f) - val sub1Alpha = ObjectAnimator.ofFloat(binding.subButton1, "alpha", 0f, 1f) - val sub1Scale = ObjectAnimator.ofFloat(binding.subButton1, "scaleX", 0f, 1f) - val sub1ScaleY = ObjectAnimator.ofFloat(binding.subButton1, "scaleY", 0f, 1f) + val sub1TransX = ObjectAnimator.ofFloat(subButton1, "translationX", 0f, -5f) + val sub1TransY = ObjectAnimator.ofFloat(subButton1, "translationY", 0f, -25f) + val sub1Alpha = ObjectAnimator.ofFloat(subButton1, "alpha", 0f, 1f) + val sub1Scale = ObjectAnimator.ofFloat(subButton1, "scaleX", 0f, 1f) + val sub1ScaleY = ObjectAnimator.ofFloat(subButton1, "scaleY", 0f, 1f) val animSet1 = AnimatorSet() animSet1.playTogether(sub1TransX, sub1TransY, sub1Alpha, sub1Scale, sub1ScaleY) animSet1.duration = 200 // 子按钮2动画(向左下方移动: 左移55dp, 下移15dp) - val sub2TransX = ObjectAnimator.ofFloat(binding.subButton2, "translationX", 0f, -25f) - val sub2TransY = ObjectAnimator.ofFloat(binding.subButton2, "translationY", 0f, -5f) - val sub2Alpha = ObjectAnimator.ofFloat(binding.subButton2, "alpha", 0f, 1f) - val sub2Scale = ObjectAnimator.ofFloat(binding.subButton2, "scaleX", 0f, 1f) - val sub2ScaleY = ObjectAnimator.ofFloat(binding.subButton2, "scaleY", 0f, 1f) + val sub2TransX = ObjectAnimator.ofFloat(subButton2, "translationX", 0f, -25f) + val sub2TransY = ObjectAnimator.ofFloat(subButton2, "translationY", 0f, -5f) + val sub2Alpha = ObjectAnimator.ofFloat(subButton2, "alpha", 0f, 1f) + val sub2Scale = ObjectAnimator.ofFloat(subButton2, "scaleX", 0f, 1f) + val sub2ScaleY = ObjectAnimator.ofFloat(subButton2, "scaleY", 0f, 1f) val animSet2 = AnimatorSet() animSet2.playTogether(sub2TransX, sub2TransY, sub2Alpha, sub2Scale, sub2ScaleY) @@ -106,14 +124,14 @@ class GjcWeighingStartActivity : animSet2.startDelay = 50 // 主按钮隐藏动画 - binding.mainFloatButton.animate() + mainFloatButton.animate() .scaleX(0f) .scaleY(0f) .alpha(0f) .setDuration(150) .setListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { - binding.mainFloatButton.visibility = View.GONE + mainFloatButton.visibility = View.GONE } }) .start() @@ -123,33 +141,38 @@ class GjcWeighingStartActivity : } /** - * 收起子按钮 + * 收起子按钮(仅平板,手机布局无浮动按钮组) */ private fun collapseButtons() { + val mainFloatButton = binding.mainFloatButton ?: return + val maskView = binding.maskView ?: return + val subButton1 = binding.subButton1 ?: return + val subButton2 = binding.subButton2 ?: return + isExpanded = false // 隐藏遮罩层 - binding.maskView.animate().alpha(0f).setDuration(200).withEndAction { - binding.maskView.visibility = View.GONE + maskView.animate().alpha(0f).setDuration(200).withEndAction { + maskView.visibility = View.GONE }.start() // 子按钮1动画(回到原位) - val sub1TransX = ObjectAnimator.ofFloat(binding.subButton1, "translationX", binding.subButton1.translationX, 0f) - val sub1TransY = ObjectAnimator.ofFloat(binding.subButton1, "translationY", binding.subButton1.translationY, 0f) - val sub1Alpha = ObjectAnimator.ofFloat(binding.subButton1, "alpha", 1f, 0f) - val sub1Scale = ObjectAnimator.ofFloat(binding.subButton1, "scaleX", 1f, 0f) - val sub1ScaleY = ObjectAnimator.ofFloat(binding.subButton1, "scaleY", 1f, 0f) + val sub1TransX = ObjectAnimator.ofFloat(subButton1, "translationX", subButton1.translationX, 0f) + val sub1TransY = ObjectAnimator.ofFloat(subButton1, "translationY", subButton1.translationY, 0f) + val sub1Alpha = ObjectAnimator.ofFloat(subButton1, "alpha", 1f, 0f) + val sub1Scale = ObjectAnimator.ofFloat(subButton1, "scaleX", 1f, 0f) + val sub1ScaleY = ObjectAnimator.ofFloat(subButton1, "scaleY", 1f, 0f) val animSet1 = AnimatorSet() animSet1.playTogether(sub1TransX, sub1TransY, sub1Alpha, sub1Scale, sub1ScaleY) animSet1.duration = 200 // 子按钮2动画(回到原位) - val sub2TransX = ObjectAnimator.ofFloat(binding.subButton2, "translationX", binding.subButton2.translationX, 0f) - val sub2TransY = ObjectAnimator.ofFloat(binding.subButton2, "translationY", binding.subButton2.translationY, 0f) - val sub2Alpha = ObjectAnimator.ofFloat(binding.subButton2, "alpha", 1f, 0f) - val sub2Scale = ObjectAnimator.ofFloat(binding.subButton2, "scaleX", 1f, 0f) - val sub2ScaleY = ObjectAnimator.ofFloat(binding.subButton2, "scaleY", 1f, 0f) + val sub2TransX = ObjectAnimator.ofFloat(subButton2, "translationX", subButton2.translationX, 0f) + val sub2TransY = ObjectAnimator.ofFloat(subButton2, "translationY", subButton2.translationY, 0f) + val sub2Alpha = ObjectAnimator.ofFloat(subButton2, "alpha", 1f, 0f) + val sub2Scale = ObjectAnimator.ofFloat(subButton2, "scaleX", 1f, 0f) + val sub2ScaleY = ObjectAnimator.ofFloat(subButton2, "scaleY", 1f, 0f) val animSet2 = AnimatorSet() animSet2.playTogether(sub2TransX, sub2TransY, sub2Alpha, sub2Scale, sub2ScaleY) @@ -157,19 +180,19 @@ class GjcWeighingStartActivity : animSet1.addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { - binding.subButton1.visibility = View.GONE + subButton1.visibility = View.GONE } }) animSet2.addListener(object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { - binding.subButton2.visibility = View.GONE + subButton2.visibility = View.GONE } }) // 主按钮显示动画 - binding.mainFloatButton.visibility = View.VISIBLE - binding.mainFloatButton.animate() + mainFloatButton.visibility = View.VISIBLE + mainFloatButton.animate() .scaleX(1f) .scaleY(1f) .alpha(1f) diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingWbDetailActivity.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingWbDetailActivity.kt new file mode 100644 index 0000000..906a9b2 --- /dev/null +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/activity/GjcWeighingWbDetailActivity.kt @@ -0,0 +1,40 @@ +package com.lukouguoji.gjc.activity + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import com.lukouguoji.gjc.R +import com.lukouguoji.gjc.databinding.ActivityGjcWeighingWbDetailBinding +import com.lukouguoji.gjc.viewModel.GjcWeighingWbDetailViewModel +import com.lukouguoji.module_base.base.BaseBindingActivity +import com.lukouguoji.module_base.bean.GjcWeighingRecordBean +import com.lukouguoji.module_base.common.Constant + +/** + * 国际出港计重-运单详情页(5.5寸手机版专属页面,平板端无对应页面) + * + * 由计重记录列表卡片的「查看详情」进入,只读展示运单基本信息, + * 对应设计稿 documents/5.5寸手持端设计文件/03_出港计重/detail.html。 + */ +class GjcWeighingWbDetailActivity : + BaseBindingActivity() { + + override fun layoutId() = R.layout.activity_gjc_weighing_wb_detail + + override fun viewModelClass() = GjcWeighingWbDetailViewModel::class.java + + override fun initOnCreate(savedInstanceState: Bundle?) { + setBackArrow("运单详情") + binding.viewModel = viewModel + viewModel.initOnCreated(intent) + } + + companion object { + @JvmStatic + fun start(context: Context, bean: GjcWeighingRecordBean) { + val starter = Intent(context, GjcWeighingWbDetailActivity::class.java) + .putExtra(Constant.Key.BEAN, bean) + context.startActivity(starter) + } + } +} diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/holder/GjcCheckInRecordViewHolder.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/holder/GjcCheckInRecordViewHolder.kt index 1b2a843..78f0876 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/holder/GjcCheckInRecordViewHolder.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/holder/GjcCheckInRecordViewHolder.kt @@ -23,5 +23,10 @@ class GjcCheckInRecordViewHolder(view: View) : binding.isEditMode = isEditMode binding.position = position // 传入位置用于显示序号 binding.executePendingBindings() + + // 「修改」按钮(手机独有):打开全屏修改覆层编辑本条记录 + binding.btnEdit?.setOnClickListener { + activity?.openPhoneEdit(record) + } } } diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/holder/GjcWeighingRecordViewHolder.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/holder/GjcWeighingRecordViewHolder.kt index 93b41e5..bf3ae3c 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/holder/GjcWeighingRecordViewHolder.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/holder/GjcWeighingRecordViewHolder.kt @@ -2,12 +2,17 @@ package com.lukouguoji.gjc.holder import android.view.View import com.lukouguoji.gjc.activity.GjcWeighingRecordDetailsActivity +import com.lukouguoji.gjc.activity.GjcWeighingWbDetailActivity import com.lukouguoji.gjc.databinding.ItemGjcWeighingRecordBinding import com.lukouguoji.module_base.base.BaseViewHolder import com.lukouguoji.module_base.bean.GjcWeighingRecordBean /** * 国际出港计重记录列表 ViewHolder + * + * item 布局分平板(layout-sw600dp/item_gjc_weighing_record.xml,含选择图标 iv_icon) + * 与手机(layout/item_gjc_weighing_record.xml,卡片式,地磅图标 iv_scale 进计重明细、 + * 「查看详情」tv_detail 进运单详情)两个变体,单侧独有的 id 需判空调用。 */ class GjcWeighingRecordViewHolder(view: View) : BaseViewHolder(view) { @@ -17,8 +22,8 @@ class GjcWeighingRecordViewHolder(view: View) : binding.bean = bean binding.executePendingBindings() - // 图标点击 - 切换选择状态 - binding.ivIcon.setOnClickListener { + // 图标点击 - 切换选择状态(平板独有) + binding.ivIcon?.setOnClickListener { // 反转checked状态 bean.checked.set(!bean.checked.get()) @@ -26,6 +31,16 @@ class GjcWeighingRecordViewHolder(view: View) : binding.executePendingBindings() } + // 地磅图标点击进计重明细(手机独有) + binding.ivScale?.setOnClickListener { + GjcWeighingRecordDetailsActivity.start(it.context, bean) + } + + // 「查看详情」进运单详情(手机独有页面) + binding.tvDetail?.setOnClickListener { + GjcWeighingWbDetailActivity.start(it.context, bean) + } + // 整行点击跳转到计重明细页 binding.ll.setOnClickListener { GjcWeighingRecordDetailsActivity.start(it.context, bean) diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/holder/GjcWeighingViewHolder.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/holder/GjcWeighingViewHolder.kt index 54e8513..9de45ad 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/holder/GjcWeighingViewHolder.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/holder/GjcWeighingViewHolder.kt @@ -1,15 +1,20 @@ package com.lukouguoji.gjc.holder import android.view.View +import com.lukouguoji.gjc.activity.GjcWeighingListActivity import com.lukouguoji.gjc.activity.GjcWeighingStartActivity import com.lukouguoji.gjc.databinding.ItemGjcWeighingBinding import com.lukouguoji.module_base.base.BaseViewHolder -import com.lukouguoji.module_base.common.ConstantEvent -import com.lukouguoji.module_base.impl.FlowBus +import com.lukouguoji.module_base.common.ConstantEvent +import com.lukouguoji.module_base.impl.FlowBus import com.lukouguoji.module_base.bean.GjcWeighingBean /** * 国际出港计重列表 ViewHolder + * + * item 布局分平板(layout-sw600dp/item_gjc_weighing.xml,含选择图标 iv_icon) + * 与手机(layout/item_gjc_weighing.xml,卡片式,含单票提前运抵按钮 btn_pre_arrive)两个变体, + * 单侧独有的 id 在 Binding 基类中为可空字段,需判空调用。 */ class GjcWeighingViewHolder(view: View) : BaseViewHolder(view) { @@ -20,8 +25,8 @@ class GjcWeighingViewHolder(view: View) : binding.position = position binding.executePendingBindings() - // 选择图标点击事件 - 切换选择状态 - binding.ivIcon.setOnClickListener { + // 选择图标点击事件 - 切换选择状态(平板独有) + binding.ivIcon?.setOnClickListener { // 反转checked状态 bean.checked.set(!bean.checked.get()) FlowBus.with(ConstantEvent.EVENT_CHECK_CHANGED).tryEmit("check_changed") @@ -30,6 +35,11 @@ class GjcWeighingViewHolder(view: View) : binding.executePendingBindings() } + // 卡片内「提前运抵」按钮(手机独有,单票操作) + binding.btnPreArrive?.setOnClickListener { + (it.context as? GjcWeighingListActivity)?.preArriveClick(bean) + } + // 整行点击跳转到开始计重页面 binding.ll.setOnClickListener { GjcWeighingStartActivity.startForAdd(it.context, bean.maWbId) diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingRecordDetailsViewModel.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingRecordDetailsViewModel.kt index 7204d4e..7548180 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingRecordDetailsViewModel.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingRecordDetailsViewModel.kt @@ -53,6 +53,7 @@ class GjcWeighingRecordDetailsViewModel : BaseViewModel() { val totalPc = MutableLiveData("0") // 总件数 val totalWeight = MutableLiveData("0.0") // 总重量 val weightError = MutableLiveData("0.0%") // 重量误差百分比 + val totalCarWeight = MutableLiveData("0") // 托盘总重(5.5寸手机版顶部卡片,平板布局不引用) // 传递参数(用于API调用) private var prefix = "" @@ -143,6 +144,10 @@ class GjcWeighingRecordDetailsViewModel : BaseViewModel() { val sumWeight = records.sumOf { it.weight } totalWeight.value = String.format("%.2f", sumWeight) + // 计算托盘总重(手机版顶部卡片) + val sumCarWeight = records.sumOf { it.carWeight.toDoubleOrNull() ?: 0.0 } + totalCarWeight.value = String.format("%.2f", sumCarWeight) + // 计算重量误差百分比 val preWeightValue = preWeight.value?.toDoubleOrNull() ?: 0.0 val error = if (sumWeight > 0 && preWeightValue > 0) { @@ -191,6 +196,39 @@ class GjcWeighingRecordDetailsViewModel : BaseViewModel() { saveRecords(records) } + /** + * 5.5寸手机版「修改记录」覆层保存:与 [onSaveClick] 相同的批量更新接口, + * 但保存成功后留在本页(收起覆层 + 重新加载),不关闭页面。仅手机布局调用。 + */ + fun onPhoneSaveClick() { + val records = recordList.value ?: return + + if (!validateRecords(records)) return + + launchLoadingCollect({ + NetApply.api.updateGjcCheckInRecordList(records) + }) { + onSuccess = { result -> + if (result.data == true) { + showToast("保存成功") + // 收起编辑覆层 + isEditMode.value = false + // 通知列表页刷新 + viewModelScope.launch { + FlowBus.with(ConstantEvent.EVENT_REFRESH).emit("refresh") + } + // 重新加载本页数据 + loadData() + } else { + showToast("保存失败") + } + } + onFailed = { code, msg -> + showToast("保存失败:$msg") + } + } + } + /////////////////////////////////////////////////////////////////////////// // 业务逻辑 /////////////////////////////////////////////////////////////////////////// diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingRecordViewModel.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingRecordViewModel.kt index 43897e9..65a195e 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingRecordViewModel.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingRecordViewModel.kt @@ -46,6 +46,32 @@ class GjcWeighingRecordViewModel : BasePageViewModel() { val totalWeight = MutableLiveData("0") // 总重量 val cargoWeight = MutableLiveData("0") // 总货重 + // ========== 5.5寸手机版专属字段(平板不调用 initPhoneExtras,行为零变化) ========== + + /** 目的站(后端支持入参 dest) */ + val destFilter = MutableLiveData("") + + /** 计重人(后端支持入参 opId,下拉复用仓库用户列表) */ + val opUserFilter = MutableLiveData("") + val whsUserList = MutableLiveData>(emptyList()) + + /** 入库日期起/止(后端暂无对应入参,传 opDateStart/opDateEnd 预留参数,见接口问题清单) */ + val checkInDateStart = MutableLiveData("") + val checkInDateEnd = MutableLiveData("") + + /** 由手机形态的 Activity 置 true,平板保持 false(不产生任何额外请求与参数) */ + private var phoneExtrasEnabled = false + + /** + * 开启手机版专属数据:放开「今天」默认日期(设计稿筛选无航班日期)、加载计重人下拉。 + * 仅由手机形态的 Activity 调用。 + */ + fun initPhoneExtras() { + phoneExtrasEnabled = true + flightDate.value = "" + DictUtils.getWHSUserList { whsUserList.postValue(it) } + } + /////////////////////////////////////////////////////////////////////////// // 方法区 /////////////////////////////////////////////////////////////////////////// @@ -130,25 +156,38 @@ class GjcWeighingRecordViewModel : BasePageViewModel() { * 获取列表数据 */ override fun getData() { + // 公共查询条件(列表与统计共用) + val baseParams = mutableMapOf( + "fdate" to flightDate.value!!.ifEmpty { null }, + "fno" to flightNo.value!!.ifEmpty { null }, + "agentCode" to agentCode.value!!.ifEmpty { null }, + "spCode" to spCode.value!!.ifEmpty { null }, + "wbNo" to waybillNo.value!!.ifEmpty { null }, + ) + + // 手机版专属条件(平板 phoneExtrasEnabled 恒为 false,请求体与改造前完全一致) + if (phoneExtrasEnabled) { + // 搜索分流(实测):11 位数字走 wbNo 精确;其余走 likeNo(后端按 8 位 no 匹配) + val key = waybillNo.value?.trim() ?: "" + if (key.isNotEmpty() && key.length != 11) { + baseParams["wbNo"] = null + baseParams["likeNo"] = key + } + baseParams["dest"] = destFilter.value?.ifEmpty { null } + baseParams["opId"] = opUserFilter.value?.ifEmpty { null } + // 入库日期起/止为后端预留参数(暂无对应入参,静默忽略,见接口问题清单) + baseParams["opDateStart"] = checkInDateStart.value?.ifEmpty { null } + baseParams["opDateEnd"] = checkInDateEnd.value?.ifEmpty { null } + } + // 构建查询参数(列表接口) - val listParams = mapOf( + val listParams = (baseParams + mapOf( "pageNum" to pageModel.page, "pageSize" to pageModel.limit, - "fdate" to flightDate.value!!.ifEmpty { null }, - "fno" to flightNo.value!!.ifEmpty { null }, - "agentCode" to agentCode.value!!.ifEmpty { null }, - "spCode" to spCode.value!!.ifEmpty { null }, - "wbNo" to waybillNo.value!!.ifEmpty { null }, - ).toRequestBody() + )).toRequestBody() // 构建查询参数(统计接口 - 使用相同的搜索条件) - val totalParams = mapOf( - "fdate" to flightDate.value!!.ifEmpty { null }, - "fno" to flightNo.value!!.ifEmpty { null }, - "agentCode" to agentCode.value!!.ifEmpty { null }, - "spCode" to spCode.value!!.ifEmpty { null }, - "wbNo" to waybillNo.value!!.ifEmpty { null }, - ).toRequestBody() + val totalParams = baseParams.toRequestBody() // 获取列表数据(显示loading) launchLoadingCollect({ diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingStartViewModel.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingStartViewModel.kt index fa338d6..fc45172 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingStartViewModel.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingStartViewModel.kt @@ -72,9 +72,22 @@ class GjcWeighingStartViewModel : BaseViewModel() { val spCodeList = MutableLiveData>() // 特码列表 val businessTypeList = MutableLiveData>() // 业务类型列表 - // 托盘车自重(查询获取) + // 托盘车自重(平板:托盘车号查询回填只读;手机:手输,见下方 initPhoneExtras) val carWeight = MutableLiveData("0") + // ========== 5.5寸手机版专属(平板不调用 initPhoneExtras,行为零变化) ========== + + /** 托盘数量(设计稿字段,后端暂无对应入参,提交时传 palletNumber 预留参数,见接口问题清单) */ + val palletNumber = MutableLiveData("") + + /** 手机形态标记:为 true 时提交体额外携带 palletNumber / carWeight(后端静默忽略) */ + private var phoneMode = false + + /** 仅由手机形态的 Activity 调用 */ + fun initPhoneExtras() { + phoneMode = true + } + /** * 初始化 */ @@ -392,6 +405,12 @@ class GjcWeighingStartViewModel : BaseViewModel() { passageWayId = this@GjcWeighingStartViewModel.channel.value remark = pageRemark.value + + // 手机版专属:托盘数量/托盘自重(后端暂无对应入参,静默忽略;平板 phoneMode 恒 false,字段为 null 不进请求体) + if (this@GjcWeighingStartViewModel.phoneMode) { + palletNumber = this@GjcWeighingStartViewModel.palletNumber.value?.ifEmpty { null } + carWeight = this@GjcWeighingStartViewModel.carWeight.value?.ifEmpty { null } + } } // 3. 构建请求数据(GjcMaWb转RequestBody,包含通道号) @@ -423,8 +442,10 @@ class GjcWeighingStartViewModel : BaseViewModel() { maWbBean.value = maWbBean.value?.apply { carId = null remark = null + palletNumber = null } carWeight.value = "0" + this@GjcWeighingStartViewModel.palletNumber.value = "" } else { showToast(result.msg.noNull("分托计重失败")) } @@ -502,7 +523,10 @@ class GjcWeighingStartViewModel : BaseViewModel() { "remark" to pageRemark.value, "checkIn" to "1", // 收运状态设置为已收运 "passageWayId" to channel.value, // 通道号参数 - "passageWay" to (channelList.value?.firstOrNull{ it.value == channel.value }?.key ?: "") + "passageWay" to (channelList.value?.firstOrNull{ it.value == channel.value }?.key ?: ""), + // 手机版专属预留参数(平板 phoneMode 恒 false → null → removeEmptyOrNull 移除,请求体不变) + "palletNumber" to (if (phoneMode) palletNumber.value?.ifEmpty { null } else null), + "carWeight" to (if (phoneMode) carWeight.value?.ifEmpty { null } else null) ).toRequestBody(removeEmptyOrNull = true) launchLoadingCollect({ diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingViewModel.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingViewModel.kt index 0559c43..feabb0f 100644 --- a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingViewModel.kt +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingViewModel.kt @@ -55,15 +55,80 @@ class GjcWeighingViewModel : BasePageViewModel() { // 全选状态 val isAllChecked = MutableLiveData(false) - - fun onItemCheckChanged() { - updateCheckAllStatus() - } - - fun updateCheckAllStatus() { - val list = pageModel.rv?.commonAdapter()?.items as? List ?: return - isAllChecked.value = list.isNotEmpty() && list.all { it.checked.get() } - } + + // ========== 5.5寸手机版专属字段(平板不调用 initPhoneExtras,行为零变化) ========== + + /** 手机版顶部搜索关键字(运单号/航班号混输,getData 内分流:含字母→fno,纯数字→likeNo 模糊) */ + val searchKey = MutableLiveData("") + + /** 主页三格统计:待计重(checkIn=0)/ 计重中(checkIn=2)数量 */ + val pendingCount = MutableLiveData("0") + val weighingCount = MutableLiveData("0") + + /** 手机版筛选弹层字段。通道号/承运人/运单类型后端暂无查询入参(见接口问题清单),传预留参数名 */ + val channelFilter = MutableLiveData("") // 通道号 → passageWayId + val carrierFilter = MutableLiveData("") // 承运人 → by0 + val awbTypeFilter = MutableLiveData("") // 运单类型 → awbType + val channelList = MutableLiveData>(emptyList()) + val awbTypeList = MutableLiveData>(emptyList()) + + /** 由手机形态的 Activity 置 true,平板保持 false(不产生任何额外请求与参数) */ + private var phoneExtrasEnabled = false + + /** + * 开启手机版专属数据:放开「今天」默认日期(设计稿主页无日期筛选)、加载筛选弹层字典。 + * 仅由手机形态的 Activity 调用。 + */ + fun initPhoneExtras() { + phoneExtrasEnabled = true + flightDate.value = "" + DictUtils.getGjcChannelList { list -> + channelList.postValue(listOf(KeyValue("全部", "")) + list) + } + DictUtils.getWaybillTypeList2(ieFlag = "E", type = "IO") { + awbTypeList.postValue(it) + } + } + + /** + * 单票提前运抵(手机版卡片内按钮;平板走底部批量 [arrivedAhead]) + */ + fun arrivedAheadSingle(bean: GjcWeighingBean) { + if (bean.arriveFlag == "1") { + showToast("该运单已提前运抵") + return + } + val maWbList = listOf( + GjcMaWb( + maWbId = bean.maWbId, + no = bean.no, + prefix = bean.prefix, + wbNo = bean.wbNo, + arriveFlag = "1" + ) + ) + launchLoadingCollect({ NetApply.api.preArrive(maWbList) }) { + onSuccess = { + showToast("提前运抵成功") + viewModelScope.launch { + FlowBus.with(ConstantEvent.EVENT_REFRESH).emit("refresh") + } + refresh() + } + onFailed = { code, msg -> + showToast(msg.noNull("提前运抵失败")) + } + } + } + + fun onItemCheckChanged() { + updateCheckAllStatus() + } + + fun updateCheckAllStatus() { + val list = pageModel.rv?.commonAdapter()?.items as? List ?: return + isAllChecked.value = list.isNotEmpty() && list.all { it.checked.get() } + } /////////////////////////////////////////////////////////////////////////// // 方法区 @@ -185,25 +250,41 @@ class GjcWeighingViewModel : BasePageViewModel() { * 获取列表数据 */ override fun getData() { + // 公共查询条件(列表与统计共用) + val baseParams = mutableMapOf( + "fdate" to flightDate.value!!.ifEmpty { null }, + "fno" to flightNo.value!!.ifEmpty { null }, + "agentCode" to agentCode.value!!.ifEmpty { null }, + "spCode" to spCode.value!!.ifEmpty { null }, + "wbNo" to waybillNo.value!!.ifEmpty { null }, + ) + + // 手机版专属条件(平板 phoneExtrasEnabled 恒为 false,请求体与改造前完全一致) + if (phoneExtrasEnabled) { + val key = searchKey.value?.trim() ?: "" + if (key.isNotEmpty()) { + // 分流规则(实测):含字母 → 航班号;11 位数字 → wbNo 精确; + // 其余数字 → likeNo(后端按 8 位 no 匹配,并非任意模糊) + when { + key.any { it.isLetter() } -> baseParams["fno"] = key + key.length == 11 -> baseParams["wbNo"] = key + else -> baseParams["likeNo"] = key + } + } + // 以下三个为后端预留参数(暂无对应入参,后端静默忽略,见接口问题清单) + baseParams["passageWayId"] = channelFilter.value?.ifEmpty { null } + baseParams["by0"] = carrierFilter.value?.ifEmpty { null } + baseParams["awbType"] = awbTypeFilter.value?.ifEmpty { null } + } + // 构建查询参数(列表接口) - val listParams = mapOf( + val listParams = (baseParams + mapOf( "pageNum" to pageModel.page, "pageSize" to pageModel.limit, - "fdate" to flightDate.value!!.ifEmpty { null }, - "fno" to flightNo.value!!.ifEmpty { null }, - "agentCode" to agentCode.value!!.ifEmpty { null }, - "spCode" to spCode.value!!.ifEmpty { null }, - "wbNo" to waybillNo.value!!.ifEmpty { null }, - ).toRequestBody() + )).toRequestBody() // 构建查询参数(统计接口 - 使用相同的搜索条件) - val totalParams = mapOf( - "fdate" to flightDate.value!!.ifEmpty { null }, - "fno" to flightNo.value!!.ifEmpty { null }, - "agentCode" to agentCode.value!!.ifEmpty { null }, - "spCode" to spCode.value!!.ifEmpty { null }, - "wbNo" to waybillNo.value!!.ifEmpty { null }, - ).toRequestBody() + val totalParams = baseParams.toRequestBody() // 获取列表数据(显示loading) launchLoadingCollect({ @@ -225,6 +306,21 @@ class GjcWeighingViewModel : BasePageViewModel() { totalWeight.value = (data?.totalWeight ?: 0.0).toString() } } + + // 手机版三格统计:待计重 / 计重中(各带一次 checkIn 条件的统计请求,仅手机调用) + if (phoneExtrasEnabled) { + listOf("0" to pendingCount, "2" to weighingCount).forEach { (state, liveData) -> + launchCollect({ + NetApply.api.getGjcWeighingStatistics( + (baseParams + mapOf("checkIn" to state)).toRequestBody() + ) + }) { + onSuccess = { result -> + liveData.value = (result.data?.wbNumber ?: 0).toString() + } + } + } + } } /** @@ -234,7 +330,10 @@ class GjcWeighingViewModel : BasePageViewModel() { if (resultCode == Activity.RESULT_OK && data != null) { when (requestCode) { Constant.RequestCode.WAYBILL -> { - waybillNo.value = data.getStringExtra(Constant.Result.CODED_CONTENT) + val content = data.getStringExtra(Constant.Result.CODED_CONTENT) + // 手机版扫码写入顶部搜索框,平板写入原运单号搜索条 + if (phoneExtrasEnabled) searchKey.value = content + else waybillNo.value = content refresh() } } diff --git a/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingWbDetailViewModel.kt b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingWbDetailViewModel.kt new file mode 100644 index 0000000..0de37cf --- /dev/null +++ b/module_gjc/src/main/java/com/lukouguoji/gjc/viewModel/GjcWeighingWbDetailViewModel.kt @@ -0,0 +1,30 @@ +package com.lukouguoji.gjc.viewModel + +import android.content.Intent +import androidx.lifecycle.MutableLiveData +import com.lukouguoji.module_base.base.BaseViewModel +import com.lukouguoji.module_base.bean.GjcWeighingRecordBean +import com.lukouguoji.module_base.common.Constant +import com.lukouguoji.module_base.ktx.showToast + +/** + * 国际出港计重-运单详情 ViewModel(5.5寸手机版专属页面) + * + * 只读展示计重记录列表传入的运单信息,无接口请求。 + * 注:设计稿中的「通道号」字段在 /IntExpCheckIn/checked/pageQuery 出参中不存在(后端缺口, + * 见接口问题清单),布局侧空值兜底显示 "-"。 + */ +class GjcWeighingWbDetailViewModel : BaseViewModel() { + + // 运单信息(从计重记录列表页传入) + val bean = MutableLiveData(GjcWeighingRecordBean()) + + fun initOnCreated(intent: Intent) { + val data = intent.getSerializableExtra(Constant.Key.BEAN) as? GjcWeighingRecordBean + if (data != null) { + bean.value = data + } else { + showToast("参数错误") + } + } +} diff --git a/module_gjc/src/main/res/layout-sw600dp/activity_gjc_weighing_list.xml b/module_gjc/src/main/res/layout-sw600dp/activity_gjc_weighing_list.xml new file mode 100644 index 0000000..353f09f --- /dev/null +++ b/module_gjc/src/main/res/layout-sw600dp/activity_gjc_weighing_list.xml @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout-sw600dp/activity_gjc_weighing_record_details.xml b/module_gjc/src/main/res/layout-sw600dp/activity_gjc_weighing_record_details.xml new file mode 100644 index 0000000..f3fca7f --- /dev/null +++ b/module_gjc/src/main/res/layout-sw600dp/activity_gjc_weighing_record_details.xml @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout-sw600dp/activity_gjc_weighing_record_list.xml b/module_gjc/src/main/res/layout-sw600dp/activity_gjc_weighing_record_list.xml new file mode 100644 index 0000000..0f8db9d --- /dev/null +++ b/module_gjc/src/main/res/layout-sw600dp/activity_gjc_weighing_record_list.xml @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout-sw600dp/activity_gjc_weighing_start.xml b/module_gjc/src/main/res/layout-sw600dp/activity_gjc_weighing_start.xml new file mode 100644 index 0000000..3e036fe --- /dev/null +++ b/module_gjc/src/main/res/layout-sw600dp/activity_gjc_weighing_start.xml @@ -0,0 +1,496 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout-sw600dp/item_gjc_check_in_record.xml b/module_gjc/src/main/res/layout-sw600dp/item_gjc_check_in_record.xml new file mode 100644 index 0000000..e1fcc60 --- /dev/null +++ b/module_gjc/src/main/res/layout-sw600dp/item_gjc_check_in_record.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout-sw600dp/item_gjc_weighing.xml b/module_gjc/src/main/res/layout-sw600dp/item_gjc_weighing.xml new file mode 100644 index 0000000..3723c6a --- /dev/null +++ b/module_gjc/src/main/res/layout-sw600dp/item_gjc_weighing.xml @@ -0,0 +1,316 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout-sw600dp/item_gjc_weighing_record.xml b/module_gjc/src/main/res/layout-sw600dp/item_gjc_weighing_record.xml new file mode 100644 index 0000000..e1e8d7c --- /dev/null +++ b/module_gjc/src/main/res/layout-sw600dp/item_gjc_weighing_record.xml @@ -0,0 +1,272 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout/activity_gjc_weighing_list.xml b/module_gjc/src/main/res/layout/activity_gjc_weighing_list.xml index 165cefc..f397371 100644 --- a/module_gjc/src/main/res/layout/activity_gjc_weighing_list.xml +++ b/module_gjc/src/main/res/layout/activity_gjc_weighing_list.xml @@ -1,222 +1,301 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout/activity_gjc_weighing_record_details.xml b/module_gjc/src/main/res/layout/activity_gjc_weighing_record_details.xml index 0c5d9f8..b6405b0 100644 --- a/module_gjc/src/main/res/layout/activity_gjc_weighing_record_details.xml +++ b/module_gjc/src/main/res/layout/activity_gjc_weighing_record_details.xml @@ -1,270 +1,257 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout/activity_gjc_weighing_record_list.xml b/module_gjc/src/main/res/layout/activity_gjc_weighing_record_list.xml index 381001f..20c4e3c 100644 --- a/module_gjc/src/main/res/layout/activity_gjc_weighing_record_list.xml +++ b/module_gjc/src/main/res/layout/activity_gjc_weighing_record_list.xml @@ -1,183 +1,301 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout/activity_gjc_weighing_start.xml b/module_gjc/src/main/res/layout/activity_gjc_weighing_start.xml index 3e036fe..c798f17 100644 --- a/module_gjc/src/main/res/layout/activity_gjc_weighing_start.xml +++ b/module_gjc/src/main/res/layout/activity_gjc_weighing_start.xml @@ -1,496 +1,286 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout/activity_gjc_weighing_wb_detail.xml b/module_gjc/src/main/res/layout/activity_gjc_weighing_wb_detail.xml new file mode 100644 index 0000000..54f9593 --- /dev/null +++ b/module_gjc/src/main/res/layout/activity_gjc_weighing_wb_detail.xml @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout/item_gjc_check_in_record.xml b/module_gjc/src/main/res/layout/item_gjc_check_in_record.xml index e1fcc60..79ff69a 100644 --- a/module_gjc/src/main/res/layout/item_gjc_check_in_record.xml +++ b/module_gjc/src/main/res/layout/item_gjc_check_in_record.xml @@ -1,95 +1,196 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout/item_gjc_weighing.xml b/module_gjc/src/main/res/layout/item_gjc_weighing.xml index 3723c6a..12b55aa 100644 --- a/module_gjc/src/main/res/layout/item_gjc_weighing.xml +++ b/module_gjc/src/main/res/layout/item_gjc_weighing.xml @@ -1,316 +1,141 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjc/src/main/res/layout/item_gjc_weighing_record.xml b/module_gjc/src/main/res/layout/item_gjc_weighing_record.xml index e1e8d7c..8f23284 100644 --- a/module_gjc/src/main/res/layout/item_gjc_weighing_record.xml +++ b/module_gjc/src/main/res/layout/item_gjc_weighing_record.xml @@ -1,272 +1,123 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_p/src/main/java/com/sixin/module_p/ui/enter/gj/GjViewModel.kt b/module_p/src/main/java/com/sixin/module_p/ui/enter/gj/GjViewModel.kt index 6bcb6af..15e7b15 100644 --- a/module_p/src/main/java/com/sixin/module_p/ui/enter/gj/GjViewModel.kt +++ b/module_p/src/main/java/com/sixin/module_p/ui/enter/gj/GjViewModel.kt @@ -48,6 +48,12 @@ class GjViewModel : BaseViewModel() { Constant.AuthName.GjcIntExpOutHandover, ARouterConstants.ACTIVITY_URL_INT_EXP_OUT_HANDOVER ), + ActionBean( + "出港计重", + R.drawable.img_gjc_chugangjizhong, + Constant.AuthName.GjcCheckWeighing, + ARouterConstants.ACTIVITY_URL_GJC_WEIGHING_LIST + ), // ULD管理属综合管理业务(Pad 端在「综合管理」菜单组),手机端首页暂无综合 Tab,挂在国际 Tab 下 ActionBean( "ULD管理", diff --git a/module_p/src/main/res/drawable-xxhdpi/img_gjc_chugangjizhong.png b/module_p/src/main/res/drawable-xxhdpi/img_gjc_chugangjizhong.png new file mode 100644 index 0000000000000000000000000000000000000000..57ab8e4a4bffbba83b753f02a2db55193cb6a944 GIT binary patch literal 31892 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 iC>SvivYPZ^DeT7E-oshk;ypuKw+6b#I+