Compare commits

...

38 Commits

Author SHA1 Message Date
6c4e97945b feat: fix form 2026-03-20 15:30:12 +08:00
a663609eeb feat: input required check 2026-03-20 15:18:56 +08:00
74e9f5a827 feat: reset status dialog 2026-03-20 15:09:27 +08:00
d6f72186a3 feat: opt views 2026-03-20 12:46:52 +08:00
b2ea79512c feat: fix issues 2026-03-19 18:31:40 +08:00
8b666364ae feat: opt form 2026-03-18 22:36:05 +08:00
aac2c860c6 feat: opt ui 2026-03-18 20:54:13 +08:00
c2b5e74156 feat: opt uld mgr 2026-03-18 16:18:57 +08:00
093314d601 feat: ii visa add/edit 2026-03-17 11:38:15 +08:00
9b089d51b1 feat: 国际事故签证新增/编辑页面及列表侧滑菜单
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 11:37:26 +08:00
8ced5be7a9 feat: fix issues 2026-03-16 18:29:02 +08:00
da50aa9794 fix: 事故签证列表页新增/删除按钮间距和padding修正
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 12:53:16 +08:00
47cef6ee59 feat: 国际进港查询运单修改页面及列表侧滑菜单
- 新增运单修改页面(编辑表单:代理人/特码/包装类型/运单类型/锁定状态/备注)
- 查询列表添加侧滑"修改"按钮入口
- 详情和修改页接口传参改用 prefix+no
- 详情页和修改页移除"库位"表单项
- 仓库信息入库时间取值改为 opDate

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 12:18:35 +08:00
baaa9c5615 feat: 国际进港查询详情页面(三Tab:运单/仓库/库位信息)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 11:34:20 +08:00
edb1f576b7 fix: 国际进港查询列表运单号自动查询及字段布局修正
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 10:59:53 +08:00
8b0043d2f5 fix: 国际进港出库列表页面优化及交互完善
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 15:52:42 +08:00
5ccb971c61 feat: 国际进港提取记录费用修改页面及列表侧滑菜单
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 15:13:45 +08:00
6278d9738d fix: 提取记录清除提货弹框改用自定义ConfirmDialogModel
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 14:49:30 +08:00
0b25e9c68c fix: 国际进港提取记录接口路径及字段对齐后端优化
- API路径 IntImpPickUpRecord/* 修正为 IntImpPickup/*
- Bean字段名全部对齐后端schema(checkWeight→cashWeight等)
- 请求参数名修正(paymentDateStart→beginDate, pageNum→page等)
- 缴费日期起默认值设为当天
- 详情页改为携带列表数据,不再调用接口
- 运单号搜索框添加autoQuery自动查询
- 列表项布局按规范优化(箭头、列宽、completeSpace对齐)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 14:43:06 +08:00
a4095d6e72 fix: 国际进港仓库接口路径修复及操作逻辑优化
- API路径从 IntImpStorageUse 修正为 IntImpStorage
- 清仓/入库接口参数改为 Query + Body 分离传递
- 清仓/出库/入库支持勾选运单号全选所有库位
- 出库确认弹框改为自定义 ConfirmDialogModel
- 搜索增加清仓综合结果筛选参数

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 14:06:07 +08:00
d31e78ff49 feat: 国际进港理货报告四个操作按钮功能实现
实现人工放行、状态重置、删除理货、理货申报四个按钮的完整业务逻辑,
新增删除申报和状态重置弹框组件,对接后端API接口。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 12:44:19 +08:00
43b1b6f44f feat: opt claude conf 2026-03-13 12:25:22 +08:00
f4d5904003 feat: 国际进港理货报告详情页面
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 12:23:09 +08:00
4b3c31252b feat: 国际进港理货报告展开子单功能及舱单展开优化
- 理货报告列表增加展开分单功能(嵌套子列表、全选联动)
- 运单号搜索框增加自动查询(4位触发)
- 舱单/理货展开查询传递完整主单参数
- 统一空数据展示为"暂无分单数据"UI

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 12:08:29 +08:00
f61302a1f6 feat: 国际进港舱单分单新增与编辑页面
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:32:10 +08:00
a64b963d03 feat: 国际进港舱单详情页面
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:49:42 +08:00
634dd96ac6 feat: 国际进港舱单货物发放改为库位选择弹框
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:19:41 +08:00
93939ed411 feat: 国际进港舱单增删改查接口对齐及交互优化
- 新增/编辑接口切换至新路径,删除统一使用批量删除接口
- 新增模式下航班日期、航班号等字段可编辑,支持航班级联查询自动填充
- 编辑模式下从列表页传入航班日期和航班号进行回显
- 修复编辑模式标题显示错误、航班号大写限制、DATE类型hint不显示等问题

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 16:51:18 +08:00
06d0244e24 fix: 国际进港装机单修改库位及入库接口修正
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 16:06:29 +08:00
f04cf81ff2 feat: 国际进港装机单编辑页面及列表侧滑优化
- 新增装机单编辑页面(Activity/ViewModel/布局)
- 装机单列表项添加侧滑编辑按钮,点击跳转编辑页
- 修复舱单列表项侧滑按钮未覆盖展开按钮的问题
- 修复装机单列表项两行同列completeSpace不一致

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 15:51:22 +08:00
d31a408ddc feat: dev 2026-03-09 19:40:55 +08:00
ce080f04a7 feat: 国际进港舱单货物发放、装机单查询参数对齐及运单号自动查询
- 实现货物发放功能,对接 /IntImpManifest/putUpCargo 接口
- 装机单列表查询参数改为与父页面一致(fid + fdep)
- 修复装机单列表接口返回类型(PageInfo 无需 BaseResultBean 包装)
- 舱单和装机单页面运单号输入框支持4位以上自动查询

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 19:38:01 +08:00
5a9dd6f97a refactor: 国际进港舱单列表项布局优化及分单按需加载
- 主列表项从4行改为2行5列标准KV布局
- 展开按钮移入白色卡片内,始终显示
- 分单数据改为点击展开时按需加载
- 子列表列宽调整,品名支持goodsCn优先显示
- 子列表所有列加单行省略号

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 17:47:43 +08:00
8c774ef3a3 refactor: 国际进港舱单列表改为通过FID查询
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 11:48:57 +08:00
af49cf4fb6 refactor: 国际进港原始舱单主子列表改为独立选择
移除主单↔分单勾选联动,改为独立选择模式;
提取公共方法 getSelectedItems() 分别收集选中的主单和分单;
补充信息操作仅校验主单选中状态;详情页品名字段增加中文品名回退逻辑。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 11:33:20 +08:00
76f55597db chore: 删除.playwright-mcp并加入gitignore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 10:40:25 +08:00
fada4b3231 feat: enable mcp 2026-03-09 10:33:24 +08:00
15e13e8e12 feat: 国际进港原始舱单列表页优化
- 运单号搜索支持输入4位自动查询,带航班日期和航班号额外参数
- 自动查询框架扩展extraParamsProvider,向后兼容旧业务
- 展开按钮移入白色卡片内部,统一为单卡片四圆角
- 子列表品名字段支持goodsCn为空时fallback到goods
- 子列表调整列宽,品名列加大,其余列缩小并支持省略号截断

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 10:32:46 +08:00
130 changed files with 9018 additions and 2207 deletions

View File

@@ -69,7 +69,38 @@
"Bash(python3:*)",
"mcp__apifox__read_project_oas_ukz3j4",
"mcp__apifox__read_project_oas_ref_resources_ukz3j4",
"mcp__apifox__refresh_project_oas_ukz3j4"
"mcp__apifox__refresh_project_oas_ukz3j4",
"mcp__playwright__browser_click",
"mcp__playwright__browser_take_screenshot",
"mcp__playwright__browser_snapshot",
"Bash(/tmp/communicate_type_findings.md:*)",
"Read(//tmp/**)",
"mcp__apifox__read_project_oas_3gn3lx",
"mcp__apifox__read_project_oas_ref_resources_3gn3lx",
"mcp__apifox__refresh_project_oas_3gn3lx",
"Bash(cp \"/var/folders/qz/qk20ny650h1fhmxrx46gdfhr0000gn/T/images/Warp 2026-03-13 09.54.13.tiff\" /tmp/screenshot.png)",
"Read(//private/var/folders/qz/qk20ny650h1fhmxrx46gdfhr0000gn/T/images/**)",
"mcp__apifox__read_project_oas_2s2uhx",
"mcp__apifox__read_project_oas_ref_resources_2s2uhx",
"mcp__apifox__refresh_project_oas_2s2uhx",
"Bash(find /Users/kid/Development/Fusion/Projects/aerologic-app -path \"*/build\" -prune -o -type f \\\\\\( -name \"*manifest*\" -o -name \"*bean*\" \\\\\\) | grep -i \"gjj\\\\|tally\" | grep -E \"\\\\.\\(kt\\)$\" | sort)",
"mcp__apifox__read_project_oas_9otrai",
"mcp__apifox__read_project_oas_ref_resources_9otrai",
"Bash(cd:*)",
"mcp__apifox__read_project_oas_tua249",
"mcp__apifox__read_project_oas_ref_resources_tua249",
"mcp__apifox__read_project_oas_heib77",
"mcp__apifox__read_project_oas_ref_resources_heib77",
"Bash(export JAVA_HOME=\"/Applications/Android Studio.app/Contents/jbr/Contents/Home\")",
"Bash(export PATH=\"$JAVA_HOME/bin:$PATH\")",
"Read(//Library/Java/JavaVirtualMachines/**)",
"Read(//usr/local/**)",
"Read(//opt/homebrew/opt/**)",
"Bash(/Users/kid/.vfox/sdks/java/bin/java -version 2>&1)",
"Bash(export JAVA_HOME=/Users/kid/.vfox/sdks/java)",
"mcp__apifox__read_project_oas_kcl8s7",
"mcp__apifox__refresh_project_oas_kcl8s7",
"mcp__apifox__read_project_oas_ref_resources_kcl8s7"
],
"deny": [],
"ask": []

1
.gitignore vendored
View File

@@ -203,3 +203,4 @@ fabric.properties
.worktrees/
.security-key
logs/security/
.playwright-mcp/

View File

@@ -1,2 +1,2 @@
[tools]
java = "17.0.17+10-amzn"
java = "17+35-amzn"

View File

@@ -1 +1 @@
/Users/kid/.version-fox/cache/java/v-17.0.17+10-amzn/java-17.0.17+10-amzn
/Users/kid/.vfox/cache/java/v-17+35-amzn/java-17+35-amzn

View File

@@ -124,11 +124,12 @@ class XxxViewModel : BasePageViewModel() {
<LinearLayout orientation="vertical">
<include layout="@layout/title_tool_bar" />
<!-- 搜索区PadSearchLayout 横排 -->
<!-- 搜索区PadSearchLayout 横排 + 操作按钮(如有) -->
<LinearLayout orientation="horizontal">
<PadSearchLayout type="@{SearchLayoutType.DATE}" value="@={viewModel.flightDate}" />
<PadSearchLayout type="@{SearchLayoutType.INPUT}" value="@={viewModel.flightNo}" />
<ImageView style="@style/iv_search_action" android:onClick="@{()-> viewModel.searchClick()}" />
<!-- 如需新增/删除按钮,尺寸规范见「开发原则」工具栏图标尺寸规范 -->
</LinearLayout>
<!-- 分页列表 -->
@@ -842,6 +843,7 @@ companion object {
- 标题栏统一用 `title_tool_bar` — 禁止手动编写 Toolbar
- 优先使用 PadDataLayoutNew 和 PadSearchLayout 组件
- 在每个页面布局时,如有截图,务必尽可能还原图片上的页面设计,而不是推测假想。如有困难一律要询问,禁止自己想象
- 工具栏图标尺寸规范: `img_search` 36dp + padding 2dp`img_add` 40dp 无 padding使用 `drawable/img_add.xml` 矢量图,`drawable-xhdpi/img_add.png` 已废弃删除)
- 常用资源: `bg_white_radius_8``colorPrimary``text_normal``text_gray``color_bottom_layout`
### 环境配置

View File

@@ -425,6 +425,20 @@
android:exported="false"
android:screenOrientation="userLandscape" />
<!-- 国际进港-进港舱单分单编辑 -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpManifestSubEditActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="userLandscape" />
<!-- 国际进港-进港舱单详情 -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpManifestDetailsActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="userLandscape" />
<!-- 国际进港-装机单(分拣理货) -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpLoadingListActivity"
@@ -432,6 +446,13 @@
android:exported="false"
android:screenOrientation="userLandscape" />
<!-- 国际进港-装机单编辑 -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpLoadingListEditActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="userLandscape" />
<!-- 国际进港-理货报告 -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpTallyActivity"
@@ -439,6 +460,12 @@
android:exported="false"
android:screenOrientation="userLandscape" />
<activity
android:name="com.lukouguoji.gjj.activity.IntImpTallyDetailsActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="userLandscape" />
<!-- 国际进港-仓库 -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpStorageUseActivity"
@@ -460,6 +487,13 @@
android:exported="false"
android:screenOrientation="userLandscape" />
<!-- 国际进港-费用修改 -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpPickUpChargeEditActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="userLandscape" />
<!-- 国际进港-提取出库 -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpPickUpDLVActivity"
@@ -474,6 +508,20 @@
android:exported="false"
android:screenOrientation="userLandscape" />
<!-- 国际进港-查询详情 -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpQueryDetailsActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="userLandscape" />
<!-- 国际进港-运单修改 -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpQueryEditActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="userLandscape" />
<!-- 国际进港-事故签证 -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpAccidentVisaActivity"
@@ -481,6 +529,12 @@
android:exported="false"
android:screenOrientation="userLandscape" />
<activity
android:name="com.lukouguoji.gjj.activity.IntImpAccidentVisaEditActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="userLandscape" />
<service android:name="com.huitao.printer.service.PrinterService" />
<service android:name="com.lukouguoji.gnc.bluetooth.service.AncillaryService" />
<service android:name="com.lukouguoji.gnc.bluetooth.service.MyService" />

View File

@@ -32,7 +32,7 @@
value="@={viewModel.status}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
android:layout_weight="0.33" />
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"选择所属航司"}'
@@ -41,7 +41,7 @@
value="@={viewModel.uldSuffix}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
android:layout_weight="0.33" />
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请输入ULD编号"}'
@@ -51,7 +51,7 @@
value="@={viewModel.uldNo}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
android:layout_weight="0.33" />
<LinearLayout
android:layout_width="0dp"
@@ -69,11 +69,10 @@
android:src="@drawable/img_search" />
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="16dp"
android:onClick="@{()-> viewModel.onAddClick()}"
android:padding="4dp"
android:src="@drawable/img_add" />
</LinearLayout>

View File

@@ -6,7 +6,17 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 \
--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \
--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \
--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED \
--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED \
--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
kapt.use.worker.api=false
kapt.include.compile.classpath=false
# When configured, Gradle will run in incubating parallel mode.

View File

@@ -0,0 +1,26 @@
package com.lukouguoji.module_base.bean
class GjAccidentVisaEditBean {
var id: Long = 0
var fdate: String = "" // 航班日期
var fno: String = "" // 航班号
var dep: String = "" // 始发站
var dest: String = "" // 目的站
var wbNo: String = "" // 运单号
var dpc: String = "" // 不正常件数
var pc: String = "" // 运单总件数
var weight: String = "" // 运单总重量
var reweight: String = "" // 复称重量
var goods: String = "" // 品名
var opacking: String = "" // 外包装
var damage: String = "" // 包装破损情况
var condition: String = "" // 内容物情况
var problem: String = "" // 不正常类型
var seachDate: String = "" // 发现时间
var photo: String = "" // 图片是否留底
var remarks: String = "" // 备注
var pic: String = "" // 缩略图
var originalPic: String = "" // 原图
var picNumber: String = "" // 图片数量
var idFlag: String = "1" // 国际标志固定为1=国际)
}

View File

@@ -50,7 +50,11 @@ class GjjWarehouse(
var volume: String? = "",
var wbNo: String? = "",
var weight: String? = "",
var whid: String? = ""
var whid: String? = "",
var splitFlag: String? = "",
var inDate: String? = "",
var clearNormal: String? = "",
var range: String? = ""
) {
fun getWaybillCode() = "${prefix}${no}"

View File

@@ -16,6 +16,7 @@ data class GjjHaWb(
var volume: Double = 0.0,
var cashWeight: Double = 0.0,
var goods: String = "",
var goodsCn: String = "",
var spCode: String = "",
var mftStatus: String = "",
var lastMftStatus: String = "",

View File

@@ -47,10 +47,14 @@ data class GjjImportManifest(
var dgrContactMame: String = "",
// 危险品收货人通讯方式
var dgrContactNumber: String = "",
// 航班日期
var fdate: String = "",
// 航班起始站
var fdep: String = "",
// 航班目的站
var fdest: String = "",
// 航班号
var fno: String = "",
// 航班id
var fid: Long = 0,
// 运费支付方式
@@ -114,6 +118,15 @@ data class GjjImportManifest(
// 重量
var weight: Double = 0.0
) : Serializable {
// 获取航班信息(日期去横杠/航班号)
fun getFlightSplit(): String {
if (fdate != "" && fno != "") {
val (year, mon, day) = fdate.split("-")
return "${year}${mon}${day}/${fno}"
}
return ""
}
// ========== UI扩展字段 ==========
// 选中状态
@Transient

View File

@@ -74,7 +74,27 @@ data class GjjImportTally(
// 体积(m³)
var volume: Double = 0.0,
// 重量(kg)
var weight: Double = 0.0
var weight: Double = 0.0,
// 品名(中文)
var goodsCn: String = "",
// 品名(英文)
var goodsEn: String = "",
// 放行模式(代码)
var relMode: String = "",
// 放行模式(名称)
var releaseMode: String = "",
// 放行时间(perDate)
var perDate: String = "",
// 放行时间
var releaseTime: String = "",
// 指令类型(comType)
var comType: String = "",
// 指令类型
var instructionType: String = "",
// 放行备注
var relRemark: String = "",
// 备注
var remark: String = ""
) : Serializable {
// 选中状态(用于多选功能)- 不参与序列化
@Transient
@@ -85,7 +105,24 @@ data class GjjImportTally(
get() = checked.get()
set(value) = checked.set(value)
// 展开/折叠状态 - 不参与序列化
@Transient
val showMore: ObservableBoolean = ObservableBoolean(false)
// 已加载的分单数据 - 不参与序列化
@Transient
var haWbList: MutableList<GjjImportTally>? = null
// 获取完整运单号
fun getWaybillNo() = "$prefix$no"
// 获取航班信息(日期去横杠/航班号)
fun getFlightSplit(): String {
if (fdate != "" && fno != "") {
val (year, mon, day) = fdate.split("-")
return "${year}${mon}${day}/${fno}"
}
return ""
}
}

View File

@@ -0,0 +1,23 @@
package com.lukouguoji.module_base.bean
import java.io.Serializable
/**
* 国际进港-库位使用记录Bean
* 对应接口: /IntImpSearch/detail 返回的 storageUseList 项
*/
data class GjjStorageUse(
var id: Long? = null, // 主键
var maWbId: Long? = null, // 运单id
var prefix: String? = null, // 运单前缀
var no: String? = null, // 运单号
var location: String? = null, // 库位号
var locationId: Long? = null, // 库位id
var inDate: String? = null, // 入库时间
var inOpId: String? = null, // 入库人ID
var inOpName: String? = null, // 入库人姓名
var outDate: String? = null, // 出库时间
var outOpId: String? = null, // 出库人ID
var outOpName: String? = null, // 出库人姓名
var cargoStatus: String? = null // 货物状态
) : Serializable

View File

@@ -38,6 +38,8 @@ class IntImpPickUpDLVBean : Serializable {
var efrCharge: Double = 0.0 // 冷藏费
var svlCharge: Double = 0.0 // 铲车费
var tallyCharge: Double = 0.0 // 理货费
var pipFee: Double = 0.0 // 精密仪器处理费
var lapFee: Double = 0.0 // 活体动物处理费
var chargeId: String = "" // 收费员
var chargeName: String = "" // 收费员名称
var dlvId: String = ""
@@ -54,6 +56,18 @@ class IntImpPickUpDLVBean : Serializable {
var awbPc: Long = 0
// ========== UI扩展字段 ==========
/**
* 航班信息展示:优先使用 flight 字段,否则用 fdate(去杠)/fno 拼接
* 格式示例20240204/MU2023
*/
val flightInfo: String
get() {
if (!flight.isNullOrEmpty()) return flight
val dateStr = fdate?.replace("-", "")?.take(8) ?: ""
val noStr = fno ?: ""
return if (dateStr.isNotEmpty() || noStr.isNotEmpty()) "$dateStr/$noStr" else ""
}
val checked: ObservableBoolean = ObservableBoolean(false)
var isSelected: Boolean

View File

@@ -5,28 +5,35 @@ import java.io.Serializable
/**
* 国际进港提取记录-列表数据Bean
* 对应API: IntImpPickUpRecord/pageQuery
* 对应API: IntImpPickup/pageQuery
*/
class IntImpPickUpRecordBean : Serializable {
var id: Long = 0 // 主键ID
var wbNo: String = "" // 运单号
var no: String = "" // 主单号
var prefix: String = "" // 前缀
var hno: String = "" // 分单号
var serialNo: String = "" // 序号
var pc: Int = 0 // 件数
var weight: Double = 0.0 // 重量
var checkWeight: Double = 0.0 // 计重量
var cashWeight: Double = 0.0 // 计重量
var agentCode: String = "" // 代理人
var spCode: String = "" // 特码
var serviceFee: Double = 0.0 // 服务费
var storageFee: Double = 0.0 // 仓储费
var totalAmount: Double = 0.0 // 总金额
var pickUpTime: String = "" // 提取时间
var pickUpNo: String = "" // 提货编号
var infoFee: Double = 0.0 // 信息费
var drawFee: Double = 0.0 // 抽单费
var coldFee: Double = 0.0 // 冷藏费
var forkliftFee: Double = 0.0 // 铲车费
var tallyFee: Double = 0.0 // 理货费
var operator: String = "" // 办理人
var outTime: String = "" // 出库时间
var optCharge: Double = 0.0 // 服务费
var whsCharge: Double = 0.0 // 仓储费
var amount: Double = 0.0 // 总金额
var chargeTime: String = "" // 缴费时间/提取时间
var pkId: String = "" // 提货编号
var tranCharge: Double = 0.0 // 信息费
var drawBillCharge: Double = 0.0 // 抽单费
var efrCharge: Double = 0.0 // 冷藏费
var svlCharge: Double = 0.0 // 铲车费
var tallyCharge: Double = 0.0 // 理货费
var pipFee: Double = 0.0 // 精密仪器处理费
var lapFee: Double = 0.0 // 活体动物处理费
var chargeName: String = "" // 办理人名称
var chargeId: String = "" // 收费员ID
var dlvTime: String = "" // 出库时间
// ========== UI扩展字段 ==========
val checked: ObservableBoolean = ObservableBoolean(false)

View File

@@ -0,0 +1,53 @@
package com.lukouguoji.module_base.bean
/**
* 国际进港运单修改-数据模型
* 对应接口:/IntImpSearch/modifyMaWb 的请求体 (GjjMaWb)
* 详情数据来源:/IntImpSearch/detail 返回的 maWb + maWbM + warehouseList
*/
data class IntImpQueryEditBean(
// ==================== 主键 ====================
var maWbId: Long? = null, // 主单主键ID
var activeId: Long? = null, // 有效值
// ==================== 运单号(禁用) ====================
var wbNo: String? = null, // 运单号(组合: prefix + no
var prefix: String? = null, // 运单号前缀
var no: String? = null, // 运单号主体
// ==================== 可编辑字段 ====================
var agentCode: String? = null, // 代理人code提交用
var agentName: String? = null, // 代理人名称(显示用)
var spCode: String? = null, // 特码
var packageType: String? = null, // 包装类型
var awbType: String? = null, // 运单类型code
var lockState: String? = null, // 锁定状态("0":未锁, "1":锁定)
var remark: String? = null, // 备注
// ==================== 禁用字段(仅显示) ====================
var awbPc: Long? = null, // 运单件数对应API: pc
var awbWeight: Double? = null, // 运单重量对应API: weight
var businessType: String? = null, // 业务类型code
var businessName: String? = null, // 业务类型名称
var inPc: Long? = null, // 入库件数
var inWeight: Double? = null, // 入库重量
var cashWeight: Double? = null, // 计费重量
var by1: String? = null, // 承运人
var range: String? = null, // 航程
var goodsCn: String? = null, // 品名(中)
var goods: String? = null, // 品名(英)
var unNumber: String? = null, // UN编号
// ==================== 提交时需要的额外字段 ====================
var fno: String? = null, // 航班号
var fdate: String? = null, // 航班日期
var flight: String? = null, // 航班
var pc: Long? = null, // 件数API用
var weight: Double? = null, // 重量API用
var volume: Double? = null, // 体积
var origin: String? = null, // 货源地
var dest: String? = null, // 目的地
var cargoType: String? = null, // 货物类型
var subCode: String? = null, // 子码
var carId: String? = null // 车牌号
)

View File

@@ -51,6 +51,7 @@ import com.lukouguoji.module_base.bean.GjjGoodsDetailsBean
import com.lukouguoji.module_base.bean.GjjGoodsTypeBean
import com.lukouguoji.module_base.bean.GjjHandoverRecordBean
import com.lukouguoji.module_base.bean.GjjImportTally
import com.lukouguoji.module_base.bean.GjAccidentVisaEditBean
import com.lukouguoji.module_base.bean.IntImpAccidentVisaBean
import com.lukouguoji.module_base.bean.IntImpPickUpDLVBean
import com.lukouguoji.module_base.bean.IntImpPickUpRecordBean
@@ -301,6 +302,18 @@ interface Api {
@POST("typeCode/countryType")
suspend fun getAreaTypeList(): DictListBean
/**
* 获取国家代码
*/
@POST("typeCode/countryCode")
suspend fun getCountryCodeList(): DictListBean
/**
* 获取通讯方式类型
*/
@POST("typeCode/communicateType")
suspend fun getCommunicateTypeList(): DictListBean
/**
* 查询平板车信息
*/
@@ -906,73 +919,73 @@ interface Api {
/**
* 国际进港仓库-分页查询
* 接口路径: /IntImpStorageUse/pageQuery
* 接口路径: /IntImpStorage/pageQuery
*/
@POST("IntImpStorageUse/pageQuery")
@POST("IntImpStorage/pageQuery")
suspend fun getIntImpStorageUseList(@Body data: RequestBody): PageInfo<GjcMaWb>
/**
* 国际进港仓库-分页合计
* 接口路径: /IntImpStorageUse/pageQueryTotal
* 接口路径: /IntImpStorage/pageQueryTotal
*/
@POST("IntImpStorageUse/pageQueryTotal")
@POST("IntImpStorage/pageQueryTotal")
suspend fun getIntImpStorageUseTotal(@Body data: RequestBody): BaseResultBean<ManifestTotalDto>
/**
* 国际进港库位操作-清仓
* 接口路径: /IntImpStorageUse/updateClear
* 接口路径: /IntImpStorage/updateClear
*/
@POST("IntImpStorageUse/updateClear")
suspend fun clearIntImpStorage(@Body data: RequestBody): BaseResultBean<Boolean>
@POST("IntImpStorage/updateClear")
suspend fun clearIntImpStorage(@Query("clearNormal") clearNormal: String, @Body data: RequestBody): BaseResultBean<Boolean>
/**
* 国际进港库位操作-修改库位
* 接口路径: /IntImpStorageUse/modifyStorage
* 接口路径: /IntImpStorage/modifyStorage
*/
@POST("IntImpStorageUse/modifyStorage")
@POST("IntImpStorage/modifyStorage")
suspend fun modifyIntImpStorage(@Body data: RequestBody): BaseResultBean<Boolean>
/**
* 国际进港库位操作-出库
* 接口路径: /IntImpStorageUse/outStorage
* 接口路径: /IntImpStorage/outStorage
*/
@POST("IntImpStorageUse/outStorage")
@POST("IntImpStorage/outStorage")
suspend fun outIntImpStorage(@Body data: RequestBody): BaseResultBean<Boolean>
/**
* 国际进港库位操作-入库
* 接口路径: /IntImpStorageUse/inStorage
* 接口路径: /IntImpStorage/inStorage
*/
@POST("IntImpStorageUse/inStorage")
suspend fun inIntImpStorage(@Body data: RequestBody): BaseResultBean<Boolean>
@POST("IntImpStorage/inStorage")
suspend fun inIntImpStorage(@Query("location") location: String, @Body data: RequestBody): BaseResultBean<Boolean>
/**
* 国际进港提取记录-分页查询
* 接口路径: /IntImpPickUpRecord/pageQuery
* 接口路径: /IntImpPickup/pageQuery
*/
@POST("IntImpPickUpRecord/pageQuery")
@POST("IntImpPickup/pageQuery")
suspend fun getIntImpPickUpRecordList(@Body data: RequestBody): PageInfo<IntImpPickUpRecordBean>
/**
* 国际进港提取记录-分页合计
* 接口路径: /IntImpPickUpRecord/pageQueryTotal
* 接口路径: /IntImpPickup/pageQueryTotal
*/
@POST("IntImpPickUpRecord/pageQueryTotal")
@POST("IntImpPickup/pageQueryTotal")
suspend fun getIntImpPickUpRecordTotal(@Body data: RequestBody): BaseResultBean<ManifestTotalDto>
/**
* 国际进港提取记录-清除提货
* 接口路径: /IntImpPickUpRecord/clearPickUp
* 接口路径: /IntImpPickup/clearPickup
*/
@POST("IntImpPickUpRecord/clearPickUp")
suspend fun clearIntImpPickUp(@Body data: RequestBody): BaseResultBean<Boolean>
@POST("IntImpPickup/clearPickup")
suspend fun clearIntImpPickUp(@Body data: RequestBody): BaseResultBean<String>
/**
* 国际进港提取记录-详情
* 接口路径: /IntImpPickUpRecord/getDetails
* 国际进港提取记录-修改费用
* 接口路径: /IntImpPickup/modifyCharge
*/
@POST("IntImpPickUpRecord/getDetails")
suspend fun getIntImpPickUpRecordDetails(@Body data: RequestBody): BaseResultBean<IntImpPickUpRecordBean>
@POST("IntImpPickup/modifyCharge")
suspend fun modifyIntImpPickUpCharge(@Body data: RequestBody): BaseResultBean<String>
/**
* 国际进港提取出库-分页查询
@@ -1009,6 +1022,20 @@ interface Api {
@POST("IntImpSearch/pageQueryTotal")
suspend fun getIntImpQueryTotal(@Body data: RequestBody): BaseResultBean<ManifestTotalDto>
/**
* 国际进港查询-详情
* 接口路径: /IntImpSearch/detail
*/
@POST("IntImpSearch/detail")
suspend fun getIntImpQueryDetails(@Body data: RequestBody): BaseResultBean<Map<String, Any>>
/**
* 国际进港查询-修改运单
* 接口路径: /IntImpSearch/modifyMaWb
*/
@POST("IntImpSearch/modifyMaWb")
suspend fun modifyIntImpMaWb(@Body data: RequestBody): BaseResultBean<String>
/**
* 国际出港待计重-分页搜索
* 接口路径: /IntExpCheckIn/pageQuery
@@ -1248,21 +1275,21 @@ interface Api {
suspend fun getGjjManifestDetail(@Query("id") id: String): BaseResultBean<GjjManifestBean>
/**
* 删除-国际进-舱单-列表
* 批量删除-国际进舱单(请求体为 mfId 数组,如 [1,2,3]
*/
@POST("IntImpManiFest/deleteFestList")
suspend fun gjjManifestDelete(@Body data: RequestBody): BaseResultBean<Any>
suspend fun gjjManifestDeleteBatch(@Body data: RequestBody): BaseResultBean<Any>
/**
* 新增-国际进-舱单
* 新增-国际进舱单
*/
@POST("IntImpManiFest/saveFest")
@POST("IntImpManifest/addManifest")
suspend fun gjjManifestInsert(@Body data: RequestBody): BaseResultBean<Any>
/**
* 更新-国际进-舱单
* 修改-国际进舱单
*/
@POST("IntImpManiFest/updateFest")
@POST("IntImpManifest/modifyManifest")
suspend fun gjjManifestUpdate(@Body data: RequestBody): BaseResultBean<Any>
/**
@@ -1814,7 +1841,7 @@ interface Api {
* 国际进港舱单-分页查询
*/
@POST("IntImpManifest/pageQuery")
suspend fun getIntImpManifestList(@Body data: RequestBody): BaseResultBean<PageInfo<GjjManifest>>
suspend fun getIntImpManifestList(@Body data: RequestBody): PageInfo<GjjManifest>
/**
* 国际进港舱单-分页合计
@@ -1828,11 +1855,29 @@ interface Api {
@POST("IntImpManifest/listHaWbByManifest")
suspend fun getIntImpManifestHaWbList(@Body data: RequestBody): BaseResultBean<List<GjjHaWb>>
/**
* 国际进港舱单-新增分单
*/
@POST("IntImpManifest/addHaWb")
suspend fun intImpManifestAddHaWb(@Body data: RequestBody): BaseResultBean<String>
/**
* 国际进港舱单-修改分单
*/
@POST("IntImpManifest/modifyHaWb")
suspend fun intImpManifestModifyHaWb(@Body data: RequestBody): BaseResultBean<String>
/**
* 国际进港舱单-获取主单减去分单的件数重量
*/
@POST("IntImpManifest/getMaWbMinusHaWb")
suspend fun getMaWbMinusHaWb(@Body data: RequestBody): BaseResultBean<GjjHaWb>
/**
* 国际进港舱单-分拣理货(装机单)-分页查询
*/
@POST("IntImpManifest/pageQueryAir")
suspend fun getIntImpLoadingList(@Body data: RequestBody): BaseResultBean<PageInfo<GjjManifest>>
suspend fun getIntImpLoadingList(@Body data: RequestBody): PageInfo<GjjManifest>
/**
* 国际进港舱单-分拣理货(装机单)-分页合计
@@ -1840,6 +1885,26 @@ interface Api {
@POST("IntImpManifest/pageQueryAirTotal")
suspend fun getIntImpLoadingTotal(@Body data: RequestBody): BaseResultBean<ManifestTotalDto>
/**
* 国际进港舱单-分拣理货(装机单)-修改装机单
*/
@POST("IntImpManifest/modifyManifestAir")
suspend fun modifyIntImpLoadingList(@Body data: RequestBody): BaseResultBean<String>
/**
* 国际进港舱单-分拣理货(装机单)-修改库位
* 接口路径: /IntImpManifest/modifyStorage
*/
@POST("IntImpManifest/modifyStorage")
suspend fun modifyIntImpLoadingStorage(@Body data: RequestBody): BaseResultBean<Boolean>
/**
* 国际进港舱单-分拣理货(装机单)-入库
* 接口路径: /IntImpManifest/inStorage
*/
@POST("IntImpManifest/inStorage")
suspend fun inIntImpLoadingStorage(@Body data: RequestBody): BaseResultBean<Boolean>
/**
* 国际进港理货报告-分页查询
*/
@@ -1852,6 +1917,42 @@ interface Api {
@POST("IntImpTally/pageQueryTotal")
suspend fun getIntImpTallyTotal(@Body data: RequestBody): BaseResultBean<ManifestTotalDto>
/**
* 国际进港理货报告-查询分单列表
*/
@POST("IntImpTally/listHaWb")
suspend fun getIntImpTallySubList(@Body data: RequestBody): BaseResultBean<List<GjjImportTally>>
/**
* 国际进港理货-人工放行
*/
@POST("IntImpTally/customCommand")
suspend fun intImpTallyCustomCommand(@Body data: RequestBody): BaseResultBean<Boolean>
/**
* 国际进港理货-状态重置
*/
@POST("IntImpTally/resetDeclare")
suspend fun intImpTallyResetDeclare(@Body data: RequestBody): BaseResultBean<Boolean>
/**
* 国际进港理货-删除申报
*/
@POST("IntImpTally/deleteDeclare")
suspend fun intImpTallyDeleteDeclare(@Body data: RequestBody): BaseResultBean<Boolean>
/**
* 国际进港理货-理货申报
*/
@POST("IntImpTally/declare")
suspend fun intImpTallyDeclare(@Body data: RequestBody): BaseResultBean<Boolean>
/**
* 国际进港舱单-货物发放
*/
@POST("IntImpManifest/putUpCargo")
suspend fun intImpManifestPutUpCargo(@Body data: RequestBody): BaseResultBean<String>
///////////////////////////////////////////////////////////////////////////
// 国际进港-事故签证
///////////////////////////////////////////////////////////////////////////
@@ -1868,6 +1969,42 @@ interface Api {
@POST("GjAccidentVisa/delete")
suspend fun deleteIntImpAccidentVisa(@Body data: RequestBody): BaseResultBean<String>
/**
* 国际事故签证-新增
*/
@POST("GjAccidentVisa/saveVisa")
suspend fun saveGjAccidentVisa(@Body data: RequestBody): BaseResultBean<String>
/**
* 国际事故签证-修改
*/
@POST("GjAccidentVisa/modifyVisa")
suspend fun modifyGjAccidentVisa(@Body data: RequestBody): BaseResultBean<String>
/**
* 国际事故签证-详情
*/
@POST("GjAccidentVisa/detail")
suspend fun getGjAccidentVisaDetail(@Query("id") id: Long): BaseResultBean<GjAccidentVisaEditBean>
/**
* 字典-破损情况
*/
@POST("typeCode/damageType")
suspend fun getDamageTypeList(): DictListBean
/**
* 字典-内容物情况
*/
@POST("typeCode/contentType")
suspend fun getContentTypeList(): DictListBean
/**
* 字典-不正常类型
*/
@POST("typeCode/unusualType")
suspend fun getUnusualTypeList(): DictListBean
///////////////////////////////////////////////////////////////////////////
// ULD管理
///////////////////////////////////////////////////////////////////////////

View File

@@ -175,6 +175,7 @@ object ARouterConstants {
const val ACTIVITY_URL_INT_ARR_AIR_MANIFEST_DETAILS = "/gjj/IntArrAirManifestDetailsActivity" //国际进港 原始舱单详情
const val ACTIVITY_URL_INT_ARR_SUPPLEMENT_INFO = "/gjj/IntArrSupplementInfoActivity" //国际进港 补充信息
const val ACTIVITY_URL_INT_IMP_MANIFEST = "/gjj/IntImpManifestActivity" //国际进港 进港舱单
const val ACTIVITY_URL_INT_IMP_MANIFEST_DETAILS = "/gjj/IntImpManifestDetailsActivity" //国际进港 进港舱单详情
const val ACTIVITY_URL_INT_IMP_LOADING_LIST = "/gjj/IntImpLoadingListActivity" //国际进港 装机单(分拣理货)
const val ACTIVITY_URL_INT_IMP_TALLY = "/gjj/IntImpTallyActivity" //国际进港 理货报告
const val ACTIVITY_URL_INT_IMP_PICK_UP_DLV = "/gjj/IntImpPickUpDLVActivity" //国际进港 提取出库

View File

@@ -36,7 +36,11 @@ data class AutoQueryConfig(
var title: String = "请选择",
/** 防抖延迟(毫秒,默认 300ms */
var debounceMillis: Long = 300L
var debounceMillis: Long = 300L,
/** 额外参数提供者(查询时动态获取额外参数,如航班日期、航班号等) */
@Transient
var extraParamsProvider: (() -> Map<String, String?>)? = null
) {
/**
* 验证配置是否有效

View File

@@ -113,8 +113,12 @@ class AutoQueryManager(
}
lastQueriedValue = value
// 构建查询参数
val params = mapOf(config.paramKey to value).toRequestBody()
// 构建查询参数(合并额外参数)
val baseParams = mutableMapOf<String, Any?>(config.paramKey to value)
config.extraParamsProvider?.invoke()?.forEach { (key, v) ->
if (!v.isNullOrEmpty()) baseParams[key] = v
}
val params = baseParams.toRequestBody()
// 发起网络请求
scope?.launchCollect({ NetApply.api.getWbNoList(config.url, params) }) {

View File

@@ -96,6 +96,7 @@ class PadDataLayoutNew : FrameLayout {
field = value
et.hint = value
tv.hint = value
bindAdapter(spinner, list, hint)
}

View File

@@ -119,8 +119,12 @@ class SearchAutoQueryManager(
}
lastQueriedValue = value
// 构建查询参数
val params = mapOf(config.paramKey to value).toRequestBody()
// 构建查询参数(合并额外参数)
val baseParams = mutableMapOf<String, Any?>(config.paramKey to value)
config.extraParamsProvider?.invoke()?.forEach { (key, v) ->
if (!v.isNullOrEmpty()) baseParams[key] = v
}
val params = baseParams.toRequestBody()
// 发起网络请求
scope?.launchCollect({ NetApply.api.getWbNoList(config.url, params) }) {

View File

@@ -102,6 +102,24 @@ object DictUtils {
}
}
/**
* 获取国际进港代理列表
*/
fun getIntImpAgentList(
addAll: Boolean = true,
checkedValue: String? = null,
callBack: (List<KeyValue>) -> Unit
) {
launchCollect({
NetApply.api
.getIntImpAgentList()
}) {
onSuccess = {
handleCallBack(it, checkedValue, addAll, callBack)
}
}
}
/**
* 获取仓管列表
*/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 775 B

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:width="200dp"
android:height="200dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path

View File

@@ -100,11 +100,10 @@
<!-- 添加按钮 -->
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="16dp"
android:onClick="@{()-> viewModel.addClick()}"
android:padding="4dp"
android:src="@drawable/img_add" />
</LinearLayout>

View File

@@ -104,11 +104,10 @@
<!-- 添加按钮 -->
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="16dp"
android:onClick="@{()-> viewModel.addClick()}"
android:padding="4dp"
android:src="@drawable/img_add" />
</LinearLayout>

View File

@@ -97,11 +97,10 @@
<!--<><E696B0><EFBFBD>按钮 -->
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="16dp"
android:onClick="@{()-> viewModel.onAddClick()}"
android:padding="4dp"
android:src="@drawable/img_add" />
<!-- 删除按钮 -->

View File

@@ -11,6 +11,7 @@ import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.DetailsPageType
import com.lukouguoji.module_base.ktx.noNull
import com.lukouguoji.module_base.ktx.setUpperCaseAlphanumericFilter
class GjjManifestAddActivity :
BaseBindingActivity<ActivityGjjManifestAddBinding, GjjManifestAddViewModel>() {
@@ -20,15 +21,16 @@ class GjjManifestAddActivity :
override fun viewModelClass() = GjjManifestAddViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
// 动态设置标题
val title = when {
viewModel.pageType.value == DetailsPageType.Modify -> "国际进港舱单编辑"
binding.viewModel = viewModel
binding.flightNoInput.et.setUpperCaseAlphanumericFilter()
viewModel.initOnCreated(intent)
// 动态设置标题(必须在 initOnCreated 之后pageType 已从 Intent 解析)
val title = when (viewModel.pageType.value) {
DetailsPageType.Modify -> "国际进港舱单编辑"
else -> "国际进港舱单新增"
}
setBackArrow(title)
binding.viewModel = viewModel
viewModel.initOnCreated(intent)
}
companion object {
@@ -49,10 +51,17 @@ class GjjManifestAddActivity :
* 编辑舱单通过Bean对象
*/
@JvmStatic
fun startForEdit(context: Context, bean: com.lukouguoji.module_base.bean.GjjManifest) {
fun startForEdit(
context: Context,
bean: com.lukouguoji.module_base.bean.GjjManifest,
flightDate: String = "",
flightNo: String = ""
) {
val starter = Intent(context, GjjManifestAddActivity::class.java)
.putExtra(Constant.Key.PAGE_TYPE, DetailsPageType.Modify.name)
.putExtra(Constant.Key.BEAN, bean)
.putExtra("flightDate", flightDate)
.putExtra("flightNo", flightNo)
context.startActivity(starter)
}

View File

@@ -24,7 +24,7 @@ import com.lukouguoji.module_base.BaseActivity
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.router.ARouterConstants
@Route(path = ARouterConstants.ACTIVITY_URL_GJJ_QUERY_INFO)
// @Route(path = ARouterConstants.ACTIVITY_URL_GJJ_QUERY_INFO) // 已替换为 IntImpQueryDetailsActivity
class GjjQueryInfoActivity : BaseActivity(), View.OnClickListener {
private lateinit var viewModel: GjjQueryInfoViewModel

View File

@@ -45,6 +45,13 @@ class IntArrAirManifestActivity :
viewModel.refresh()
}
// 设置运单号自动查询的额外参数(航班日期、航班号)
binding.pslWaybillNo.autoQueryConfig.extraParamsProvider = {
mapOf(
"fdate" to viewModel.flightDate.value,
"fno" to viewModel.flightNo.value
)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

View File

@@ -8,10 +8,14 @@ import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.ActivityIntImpAccidentVisaBinding
import com.lukouguoji.gjj.viewModel.IntImpAccidentVisaViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.bean.IntImpAccidentVisaBean
import com.lukouguoji.module_base.common.Constant
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.interfaces.IOnItemClickListener
import com.lukouguoji.module_base.ktx.addOnItemClickListener
import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.router.ARouterConstants
/**
@@ -19,7 +23,8 @@ import com.lukouguoji.module_base.router.ARouterConstants
*/
@Route(path = ARouterConstants.ACTIVITY_URL_INT_IMP_ACCIDENT_VISA)
class IntImpAccidentVisaActivity :
BaseBindingActivity<ActivityIntImpAccidentVisaBinding, IntImpAccidentVisaViewModel>() {
BaseBindingActivity<ActivityIntImpAccidentVisaBinding, IntImpAccidentVisaViewModel>(),
IOnItemClickListener {
override fun layoutId() = R.layout.activity_int_imp_accident_visa
override fun viewModelClass() = IntImpAccidentVisaViewModel::class.java
@@ -34,6 +39,8 @@ class IntImpAccidentVisaActivity :
viewModel.pageModel.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, this)
binding.rv.addOnItemClickListener(this)
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).observe(this) {
viewModel.refresh()
}
@@ -48,4 +55,15 @@ class IntImpAccidentVisaActivity :
viewModel.searchClick()
}
}
override fun onItemClick(position: Int, type: Int) {
when (type) {
2000 -> {
// 侧滑菜单 - 修改
val bean = binding.rv.commonAdapter()?.getItem(position) as? IntImpAccidentVisaBean
?: return
IntImpAccidentVisaEditActivity.start(this, bean.id)
}
}
}
}

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.ActivityIntImpAccidentVisaEditBinding
import com.lukouguoji.gjj.viewModel.IntImpAccidentVisaEditViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.DetailsPageType
import com.lukouguoji.module_base.ktx.addOnItemClickListener
/**
* 国际进港-事故签证新增/编辑
*/
class IntImpAccidentVisaEditActivity :
BaseBindingActivity<ActivityIntImpAccidentVisaEditBinding, IntImpAccidentVisaEditViewModel>() {
override fun layoutId() = R.layout.activity_int_imp_accident_visa_edit
override fun viewModelClass() = IntImpAccidentVisaEditViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
binding.viewModel = viewModel
viewModel.rv = binding.rv
binding.rv.addOnItemClickListener(viewModel)
viewModel.initOnCreate(intent)
viewModel.pageType.observe(this) {
val title = if (it == DetailsPageType.Add) "国际事故签证新增" else "国际事故签证修改"
setBackArrow(title)
}
}
companion object {
@JvmStatic
fun start(context: Context, id: Long = 0) {
context.startActivity(
Intent(context, IntImpAccidentVisaEditActivity::class.java)
.putExtra(Constant.Key.ID, id)
)
}
}
}

View File

@@ -51,10 +51,19 @@ class IntImpLoadingListActivity :
viewModel.refresh()
}
// 接收从进港舱单传递的参数
// 设置运单号自动查询的额外参数FID、FDGP
binding.pslWaybillNo.autoQueryConfig.extraParamsProvider = {
mapOf(
"fid" to viewModel.fid,
"fdep" to viewModel.fdep
)
}
// 接收从进港舱单传递的参数FID和FDGP用于查询fdate/fno/fdest用于界面显示
intent.getStringExtra("fid")?.let { if (it.isNotEmpty()) viewModel.fid = it }
intent.getStringExtra("fdep")?.let { if (it.isNotEmpty()) viewModel.fdep = it }
intent.getStringExtra("fdate")?.let { if (it.isNotEmpty()) viewModel.flightDate.value = it }
intent.getStringExtra("fno")?.let { if (it.isNotEmpty()) viewModel.flightNo.value = it }
intent.getStringExtra("sendAddress")?.let { if (it.isNotEmpty()) viewModel.sendAddress.value = it }
intent.getStringExtra("fdest")?.let { if (it.isNotEmpty()) viewModel.fdest.value = it }
// 如果收到了航班号和日期参数,触发航班查询来构建始发站下拉列表

View File

@@ -0,0 +1,37 @@
package com.lukouguoji.gjj.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.google.gson.Gson
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.ActivityIntImpLoadingListEditBinding
import com.lukouguoji.gjj.viewModel.IntImpLoadingListEditViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.bean.GjjManifest
import com.lukouguoji.module_base.common.Constant
/**
* 国际进港-装机单编辑页面
*/
class IntImpLoadingListEditActivity :
BaseBindingActivity<ActivityIntImpLoadingListEditBinding, IntImpLoadingListEditViewModel>() {
override fun layoutId() = R.layout.activity_int_imp_loading_list_edit
override fun viewModelClass() = IntImpLoadingListEditViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("装机单编辑")
binding.viewModel = viewModel
viewModel.initOnCreated(intent)
}
companion object {
@JvmStatic
fun start(context: Context, bean: GjjManifest) {
val starter = Intent(context, IntImpLoadingListEditActivity::class.java)
.putExtra(Constant.Key.DATA, Gson().toJson(bean))
context.startActivity(starter)
}
}
}

View File

@@ -44,6 +44,14 @@ class IntImpManifestActivity :
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).observe(this) {
viewModel.refresh()
}
// 设置运单号自动查询的额外参数FID、FDGP
binding.pslWaybillNo.autoQueryConfig.extraParamsProvider = {
mapOf(
"fid" to viewModel.fid,
"fdep" to viewModel.fdep
)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

View File

@@ -0,0 +1,39 @@
package com.lukouguoji.gjj.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.alibaba.android.arouter.facade.annotation.Route
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.ActivityIntImpManifestDetailsBinding
import com.lukouguoji.gjj.viewModel.IntImpManifestDetailsViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.bean.GjjManifest
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.router.ARouterConstants
/**
* 国际进港舱单详情
*/
@Route(path = ARouterConstants.ACTIVITY_URL_INT_IMP_MANIFEST_DETAILS)
class IntImpManifestDetailsActivity :
BaseBindingActivity<ActivityIntImpManifestDetailsBinding, IntImpManifestDetailsViewModel>() {
override fun layoutId() = R.layout.activity_int_imp_manifest_details
override fun viewModelClass() = IntImpManifestDetailsViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("进港舱单详情")
binding.viewModel = viewModel
viewModel.initOnCreated(intent)
}
companion object {
@JvmStatic
fun start(context: Context, manifest: GjjManifest) {
val starter = Intent(context, IntImpManifestDetailsActivity::class.java)
.putExtra(Constant.Key.DATA, manifest)
context.startActivity(starter)
}
}
}

View File

@@ -0,0 +1,59 @@
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.ActivityIntImpManifestSubEditBinding
import com.lukouguoji.gjj.viewModel.IntImpManifestSubEditViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.bean.GjjHaWb
import com.lukouguoji.module_base.bean.GjjManifest
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.DetailsPageType
class IntImpManifestSubEditActivity :
BaseBindingActivity<ActivityIntImpManifestSubEditBinding, IntImpManifestSubEditViewModel>() {
override fun layoutId() = R.layout.activity_int_imp_manifest_sub_edit
override fun viewModelClass() = IntImpManifestSubEditViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
binding.viewModel = viewModel
viewModel.initOnCreated(intent)
val title = when (viewModel.pageType.value) {
DetailsPageType.Modify -> "分单编辑"
else -> "分单新增"
}
setBackArrow(title)
}
companion object {
/**
* 新增分单
*/
@JvmStatic
fun startForAdd(context: Context, manifest: GjjManifest) {
context.startActivity(
Intent(context, IntImpManifestSubEditActivity::class.java)
.putExtra(Constant.Key.PAGE_TYPE, DetailsPageType.Add.name)
.putExtra(Constant.Key.BEAN, manifest)
)
}
/**
* 修改分单
*/
@JvmStatic
fun startForModify(context: Context, manifest: GjjManifest, haWb: GjjHaWb) {
context.startActivity(
Intent(context, IntImpManifestSubEditActivity::class.java)
.putExtra(Constant.Key.PAGE_TYPE, DetailsPageType.Modify.name)
.putExtra(Constant.Key.BEAN, manifest)
.putExtra("haWb", haWb)
)
}
}
}

View File

@@ -0,0 +1,37 @@
package com.lukouguoji.gjj.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.google.gson.Gson
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.ActivityIntImpPickUpChargeEditBinding
import com.lukouguoji.gjj.viewModel.IntImpPickUpChargeEditViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.bean.IntImpPickUpRecordBean
import com.lukouguoji.module_base.common.Constant
/**
* 国际进港-费用修改
*/
class IntImpPickUpChargeEditActivity :
BaseBindingActivity<ActivityIntImpPickUpChargeEditBinding, IntImpPickUpChargeEditViewModel>() {
override fun layoutId() = R.layout.activity_int_imp_pick_up_charge_edit
override fun viewModelClass() = IntImpPickUpChargeEditViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国际进港费用修改")
binding.viewModel = viewModel
viewModel.initOnCreated(intent)
}
companion object {
@JvmStatic
fun start(context: Context, bean: IntImpPickUpRecordBean) {
val starter = Intent(context, IntImpPickUpChargeEditActivity::class.java)
.putExtra(Constant.Key.DATA, Gson().toJson(bean))
context.startActivity(starter)
}
}
}

View File

@@ -3,7 +3,6 @@ package com.lukouguoji.gjj.activity
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import com.alibaba.android.arouter.facade.annotation.Route
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.ActivityIntImpPickUpRecordBinding
@@ -14,8 +13,11 @@ import com.lukouguoji.module_base.common.Constant
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.interfaces.IOnItemClickListener
import com.lukouguoji.module_base.ktx.addOnItemClickListener
import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.model.ConfirmDialogModel
import com.lukouguoji.module_base.router.ARouterConstants
/**
@@ -41,11 +43,35 @@ class IntImpPickUpRecordActivity :
// 绑定分页
viewModel.pageModel.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, this)
// 设置列表项点击回调(侧滑修改按钮)
binding.rv.addOnItemClickListener(object : IOnItemClickListener {
override fun onItemClick(position: Int, type: Int) {
when (type) {
2000 -> {
// 侧滑修改操作
val list = viewModel.pageModel.rv?.commonAdapter()?.items as? List<*> ?: return
val bean = list.getOrNull(position) as? IntImpPickUpRecordBean ?: return
IntImpPickUpChargeEditActivity.start(this@IntImpPickUpRecordActivity, bean)
}
}
}
})
// 监听刷新事件
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).observe(this) {
viewModel.refresh()
}
// 运单号自动查询额外参数
binding.pslWbNo.autoQueryConfig.extraParamsProvider = {
mapOf(
"beginDate" to viewModel.paymentDateStart.value,
"endDate" to viewModel.paymentDateEnd.value,
"agentCode" to viewModel.agentCode.value,
"spCode" to viewModel.spCode.value
)
}
// 初始化下拉列表
viewModel.initAgentList()
viewModel.initSpecialCodeList()
@@ -68,14 +94,12 @@ class IntImpPickUpRecordActivity :
return
}
AlertDialog.Builder(this)
.setTitle("清除提货确认")
.setMessage("确定要清除选中的 ${selectedItems.size} 条提货记录吗?")
.setPositiveButton("确定") { _, _ ->
ConfirmDialogModel(
message = "确定要清除选中的 ${selectedItems.size} 条提货记录吗?",
title = "清除提货确认"
) {
viewModel.clearPickUp(selectedItems)
}
.setNegativeButton("取消", null)
.show()
}.show(this)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

View File

@@ -3,10 +3,12 @@ package com.lukouguoji.gjj.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.google.gson.Gson
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.ActivityIntImpPickUpRecordDetailsBinding
import com.lukouguoji.gjj.viewModel.IntImpPickUpRecordDetailsViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.bean.IntImpPickUpRecordBean
import com.lukouguoji.module_base.common.Constant
/**
@@ -26,9 +28,9 @@ class IntImpPickUpRecordDetailsActivity :
companion object {
@JvmStatic
fun start(context: Context, id: Long) {
fun start(context: Context, bean: IntImpPickUpRecordBean) {
val starter = Intent(context, IntImpPickUpRecordDetailsActivity::class.java)
.putExtra(Constant.Key.ID, id)
.putExtra(Constant.Key.DATA, Gson().toJson(bean))
context.startActivity(starter)
}
}

View File

@@ -11,6 +11,7 @@ import com.lukouguoji.module_base.base.BaseBindingActivity
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.addOnItemClickListener
import com.lukouguoji.module_base.ktx.getLifecycleOwner
import com.lukouguoji.module_base.router.ARouterConstants
@@ -33,11 +34,15 @@ class IntImpQueryActivity :
viewModel.pageModel
.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, getLifecycleOwner())
// 注册列表项点击事件
binding.rv.addOnItemClickListener(viewModel)
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).observe(this) {
viewModel.refresh()
}
viewModel.initAgentList()
viewModel.initSpecialCodeList()
viewModel.refresh()
}

View File

@@ -0,0 +1,58 @@
package com.lukouguoji.gjj.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.alibaba.android.arouter.facade.annotation.Route
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.ActivityIntImpQueryDetailsBinding
import com.lukouguoji.gjj.viewModel.IntImpQueryDetailsViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.base.CustomVP2Adapter
import com.lukouguoji.module_base.router.ARouterConstants
/**
* 国际进港查询详情页面
*/
@Route(path = ARouterConstants.ACTIVITY_URL_GJJ_QUERY_INFO)
class IntImpQueryDetailsActivity :
BaseBindingActivity<ActivityIntImpQueryDetailsBinding, IntImpQueryDetailsViewModel>() {
override fun layoutId() = R.layout.activity_int_imp_query_details
override fun viewModelClass() = IntImpQueryDetailsViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国际进港查询详情")
binding.viewModel = viewModel
// 初始化ViewModel(传入maWbId)
viewModel.initOnCreated(intent)
// 配置ViewPager2
binding.vp.adapter = CustomVP2Adapter(
viewModel.fragmentList,
supportFragmentManager,
lifecycle
)
binding.vp.isUserInputEnabled = false // 禁用滑动
binding.vp.offscreenPageLimit = 3 // 预加载3个Fragment
// 监听Tab索引变化,切换Fragment
viewModel.currentTab.observe(this) {
binding.vp.setCurrentItem(it, false)
}
// 加载详情数据
viewModel.loadDetails()
}
companion object {
@JvmStatic
fun start(context: Context, prefix: String?, no: String?) {
val starter = Intent(context, IntImpQueryDetailsActivity::class.java)
.putExtra("prefix", prefix ?: "")
.putExtra("no", no ?: "")
context.startActivity(starter)
}
}
}

View File

@@ -0,0 +1,37 @@
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.ActivityIntImpQueryEditBinding
import com.lukouguoji.gjj.viewModel.IntImpQueryEditViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity
/**
* 国际进港运单修改页面
*/
class IntImpQueryEditActivity :
BaseBindingActivity<ActivityIntImpQueryEditBinding, IntImpQueryEditViewModel>() {
override fun layoutId() = R.layout.activity_int_imp_query_edit
override fun viewModelClass() = IntImpQueryEditViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国际进港运单修改")
binding.viewModel = viewModel
viewModel.initOnCreated(intent)
}
companion object {
@JvmStatic
fun start(context: Context, maWbId: Long?, prefix: String?, no: String?) {
val starter = Intent(context, IntImpQueryEditActivity::class.java)
.putExtra("maWbId", maWbId ?: 0L)
.putExtra("prefix", prefix ?: "")
.putExtra("no", no ?: "")
context.startActivity(starter)
}
}
}

View File

@@ -3,7 +3,7 @@ package com.lukouguoji.gjj.activity
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AlertDialog
import com.lukouguoji.module_base.model.ConfirmDialogModel
import com.alibaba.android.arouter.facade.annotation.Route
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.ActivityIntImpStorageUseBinding
@@ -60,14 +60,19 @@ class IntImpStorageUseActivity :
val allItems = list.filterIsInstance<com.lukouguoji.module_base.bean.GjcMaWb>()
val maWbListForClear = allItems.mapNotNull { maWb ->
if (maWb.isSelected) {
// 勾选运单号 → 默认全选该运单号下的所有库位
maWb.copy(storageUseList = maWb.storageUseList ?: emptyList())
} else {
// 勾选库位号 → 只对选择的库位进行操作
val selectedStorageList = maWb.storageUseList?.filter { it.isSelected } ?: emptyList()
if (selectedStorageList.isNotEmpty() || maWb.isSelected) {
if (selectedStorageList.isNotEmpty()) {
maWb.copy(storageUseList = selectedStorageList)
} else {
null
}
}
}
if (maWbListForClear.isEmpty()) {
showToast("请至少选择一个库位")
@@ -105,6 +110,7 @@ class IntImpStorageUseActivity :
val selectedStorage = selectedStorageUseList[0]
// 弹出库位选择弹框,选择后再调用接口
IntImpModifyStorageDialogModel { dialog ->
val locationName = dialog.locationName
val locationId = dialog.locationId
@@ -119,24 +125,32 @@ class IntImpStorageUseActivity :
val list = viewModel.pageModel.rv?.commonAdapter()?.items as? List<*> ?: return
val allItems = list.filterIsInstance<com.lukouguoji.module_base.bean.GjcMaWb>()
val selectedStorageUseList = mutableListOf<com.lukouguoji.module_base.bean.GjcStorageUse>()
allItems.forEach { maWb ->
maWb.storageUseList?.filter { it.isSelected }?.let { selectedStorageUseList.addAll(it) }
val maWbListForOutStorage = allItems.mapNotNull { maWb ->
if (maWb.isSelected) {
// 勾选运单号 → 默认全选该运单号下的所有库位
maWb.copy(storageUseList = maWb.storageUseList ?: emptyList())
} else {
// 勾选库位号 → 只对选择的库位进行操作
val selectedStorageList = maWb.storageUseList?.filter { it.isSelected } ?: emptyList()
if (selectedStorageList.isNotEmpty()) {
maWb.copy(storageUseList = selectedStorageList)
} else {
null
}
}
}
if (selectedStorageUseList.isEmpty()) {
if (maWbListForOutStorage.isEmpty()) {
showToast("请选择要出库的库位")
return
}
AlertDialog.Builder(this)
.setTitle("出库确认")
.setMessage("确定要将选中的 ${selectedStorageUseList.size} 个库位执行出库操作吗?")
.setPositiveButton("确定") { _, _ ->
viewModel.performOutStorage(selectedStorageUseList)
}
.setNegativeButton("取消", null)
.show()
ConfirmDialogModel(
message = "是否确认出库?",
title = "出库确认"
) {
viewModel.performOutStorage(maWbListForOutStorage)
}.show(this)
}
/**
@@ -147,14 +161,19 @@ class IntImpStorageUseActivity :
val allItems = list.filterIsInstance<com.lukouguoji.module_base.bean.GjcMaWb>()
val maWbListForInStorage = allItems.mapNotNull { maWb ->
if (maWb.isSelected) {
// 勾选运单号 → 默认全选该运单号下的所有库位
maWb.copy(storageUseList = maWb.storageUseList ?: emptyList())
} else {
// 勾选库位号 → 只对选择的库位进行操作
val selectedStorageList = maWb.storageUseList?.filter { it.isSelected } ?: emptyList()
if (selectedStorageList.isNotEmpty() || maWb.isSelected) {
if (selectedStorageList.isNotEmpty()) {
maWb.copy(storageUseList = selectedStorageList)
} else {
null
}
}
}
if (maWbListForInStorage.isEmpty()) {
showToast("请至少选择一个单据")

View File

@@ -0,0 +1,36 @@
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.ActivityIntImpTallyDetailsBinding
import com.lukouguoji.gjj.viewModel.IntImpTallyDetailsViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.bean.GjjImportTally
import com.lukouguoji.module_base.common.Constant
/**
* 国际进港理货报告详情
*/
class IntImpTallyDetailsActivity :
BaseBindingActivity<ActivityIntImpTallyDetailsBinding, IntImpTallyDetailsViewModel>() {
override fun layoutId() = R.layout.activity_int_imp_tally_details
override fun viewModelClass() = IntImpTallyDetailsViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("理货报告详情")
binding.viewModel = viewModel
viewModel.initOnCreated(intent)
}
companion object {
@JvmStatic
fun start(context: Context, tally: GjjImportTally) {
val starter = Intent(context, IntImpTallyDetailsActivity::class.java)
.putExtra(Constant.Key.DATA, tally)
context.startActivity(starter)
}
}
}

View File

@@ -50,7 +50,7 @@ class IntImpInStorageDialogModel(
* 加载库位列表
*/
private fun loadLocationList() {
launchCollect({ NetApply.api.getLocationList(flag = 4) }) {
launchCollect({ NetApply.api.getLocationList(flag = 3) }) {
onSuccess = { result ->
val list = result.data?.map { it.toKeyValue() } ?: emptyList()
locationList.value = list

View File

@@ -50,7 +50,7 @@ class IntImpModifyStorageDialogModel(
* 加载库位列表
*/
private fun loadLocationList() {
launchCollect({ NetApply.api.getLocationList(flag = 4) }) {
launchCollect({ NetApply.api.getLocationList(flag = 3) }) {
onSuccess = { result ->
val list = result.data?.map { it.toKeyValue() } ?: emptyList()
locationList.value = list

View File

@@ -20,6 +20,7 @@ import dev.utils.app.info.KeyValue
*/
class IntImpQueryFilterDialogModel(
val spCode: MutableLiveData<String>,
val spCodeList: MutableLiveData<List<KeyValue>>,
val flightNo: MutableLiveData<String>,
val dest: MutableLiveData<String>,
val awbType: MutableLiveData<String>,

View File

@@ -0,0 +1,58 @@
package com.lukouguoji.gjj.dialog
import android.content.Context
import androidx.lifecycle.MutableLiveData
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.DialogIntImpTallyDeleteBinding
import com.lukouguoji.module_base.base.BaseDialogModel
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import dev.utils.app.info.KeyValue
/**
* 国际进港理货 - 删除申报对话框
*/
class IntImpTallyDeleteDialogModel(
val changeReasonList: List<KeyValue>, // 变更原因列表
private val callback: (IntImpTallyDeleteDialogModel) -> Unit
) : BaseDialogModel<DialogIntImpTallyDeleteBinding>(DIALOG_TYPE_CENTER) {
// 变更原因代码(存储的是 code
val changeReason = MutableLiveData("")
// 联系人姓名
val contactName = MutableLiveData("")
// 联系人电话
val contactPhone = MutableLiveData("")
override fun layoutId(): Int {
return R.layout.dialog_int_imp_tally_delete
}
override fun onDialogCreated(context: Context) {
binding.model = this
}
/**
* 确认按钮点击
*/
fun onConfirmClick() {
// 验证变更原因
if (changeReason.value.verifyNullOrEmpty("请选择变更原因")) {
return
}
// 验证联系人姓名
if (contactName.value.verifyNullOrEmpty("请输入联系人姓名")) {
return
}
// 验证联系人电话
if (contactPhone.value.verifyNullOrEmpty("请输入联系人电话")) {
return
}
dismiss()
callback(this)
}
}

View File

@@ -0,0 +1,66 @@
package com.lukouguoji.gjj.dialog
import android.content.Context
import androidx.lifecycle.MutableLiveData
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.DialogIntImpTallyResetBinding
import com.lukouguoji.module_base.base.BaseDialogModel
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import dev.utils.app.info.KeyValue
/**
* 国际进港理货 - 状态重置对话框
*/
class IntImpTallyResetDialogModel(
private val callback: (IntImpTallyResetDialogModel) -> Unit
) : BaseDialogModel<DialogIntImpTallyResetBinding>(DIALOG_TYPE_CENTER) {
// 重置状态列表
val resetStatusList = MutableLiveData<List<KeyValue>>()
// 选中的重置状态存储的是value
val selectedResetStatus = MutableLiveData("")
// 重置状态code (传给后端的restStatus参数)
var resetStatusCode: String? = null
override fun layoutId(): Int {
return R.layout.dialog_int_imp_tally_reset
}
override fun onDialogCreated(context: Context) {
binding.model = this
initResetStatusList()
// 监听选择变化更新resetStatusCode
selectedResetStatus.observeForever { value ->
resetStatusCode = when (value) {
"01" -> "01" // 正常
"02" -> null // 未申报
else -> null
}
}
}
/**
* 初始化重置状态列表
*/
private fun initResetStatusList() {
val list = listOf(
KeyValue("正常", "01"),
KeyValue("未申报", "02")
)
resetStatusList.value = list
}
/**
* 保存按钮点击
*/
fun onSaveClick() {
if (selectedResetStatus.value.verifyNullOrEmpty("请选择重置状态")) {
return
}
dismiss()
callback(this)
}
}

View File

@@ -0,0 +1,89 @@
package com.lukouguoji.gjj.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.FragmentIntImpQueryStorageBinding
import com.lukouguoji.gjj.holder.IntImpQueryStorageViewHolder
import com.lukouguoji.gjj.viewModel.IntImpQueryDetailsViewModel
import com.lukouguoji.module_base.base.CommonAdapter
import com.lukouguoji.module_base.bean.GjjStorageUse
import com.lukouguoji.module_base.http.net.NetApply
/**
* 国际进港查询详情 - 库位信息Fragment
*/
class IntImpQueryStorageFragment : Fragment() {
private lateinit var binding: FragmentIntImpQueryStorageBinding
private lateinit var viewModel: IntImpQueryDetailsViewModel
private lateinit var adapter: CommonAdapter
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = DataBindingUtil.inflate(
inflater,
R.layout.fragment_int_imp_query_storage,
container,
false
)
binding.lifecycleOwner = viewLifecycleOwner
initRecyclerView()
observeData()
return binding.root
}
private fun initRecyclerView() {
adapter = CommonAdapter(
requireContext(),
R.layout.item_int_imp_query_storage,
IntImpQueryStorageViewHolder::class.java
)
binding.rvStorageList.apply {
layoutManager = LinearLayoutManager(requireContext())
adapter = this@IntImpQueryStorageFragment.adapter
}
}
private fun observeData() {
viewModel.storageUseList.observe(viewLifecycleOwner) { mapList ->
if (mapList.isEmpty()) {
binding.rvStorageList.visibility = View.GONE
binding.llEmpty.visibility = View.VISIBLE
} else {
val beanList = mapList.map { map ->
try {
val json = NetApply.gson.toJson(map)
NetApply.gson.fromJson(json, GjjStorageUse::class.java)
} catch (e: Exception) {
e.printStackTrace()
GjjStorageUse()
}
}
binding.rvStorageList.visibility = View.VISIBLE
binding.llEmpty.visibility = View.GONE
adapter.refresh(beanList)
}
}
}
companion object {
@JvmStatic
fun newInstance(vm: IntImpQueryDetailsViewModel) =
IntImpQueryStorageFragment().apply {
viewModel = vm
}
}
}

View File

@@ -0,0 +1,89 @@
package com.lukouguoji.gjj.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.FragmentIntImpQueryWarehouseBinding
import com.lukouguoji.gjj.holder.IntImpQueryWarehouseViewHolder
import com.lukouguoji.gjj.viewModel.IntImpQueryDetailsViewModel
import com.lukouguoji.module_base.base.CommonAdapter
import com.lukouguoji.module_base.bean.GjjWarehouse
import com.lukouguoji.module_base.http.net.NetApply
/**
* 国际进港查询详情 - 仓库信息Fragment
*/
class IntImpQueryWarehouseFragment : Fragment() {
private lateinit var binding: FragmentIntImpQueryWarehouseBinding
private lateinit var viewModel: IntImpQueryDetailsViewModel
private lateinit var adapter: CommonAdapter
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = DataBindingUtil.inflate(
inflater,
R.layout.fragment_int_imp_query_warehouse,
container,
false
)
binding.lifecycleOwner = viewLifecycleOwner
initRecyclerView()
observeData()
return binding.root
}
private fun initRecyclerView() {
adapter = CommonAdapter(
requireContext(),
R.layout.item_int_imp_query_warehouse,
IntImpQueryWarehouseViewHolder::class.java
)
binding.rvWarehouseList.apply {
layoutManager = LinearLayoutManager(requireContext())
adapter = this@IntImpQueryWarehouseFragment.adapter
}
}
private fun observeData() {
viewModel.warehouseList.observe(viewLifecycleOwner) { mapList ->
if (mapList.isEmpty()) {
binding.rvWarehouseList.visibility = View.GONE
binding.llEmpty.visibility = View.VISIBLE
} else {
val beanList = mapList.map { map ->
try {
val json = NetApply.gson.toJson(map)
NetApply.gson.fromJson(json, GjjWarehouse::class.java)
} catch (e: Exception) {
e.printStackTrace()
GjjWarehouse()
}
}
binding.rvWarehouseList.visibility = View.VISIBLE
binding.llEmpty.visibility = View.GONE
adapter.refresh(beanList)
}
}
}
companion object {
@JvmStatic
fun newInstance(vm: IntImpQueryDetailsViewModel) =
IntImpQueryWarehouseFragment().apply {
viewModel = vm
}
}
}

View File

@@ -0,0 +1,44 @@
package com.lukouguoji.gjj.fragment
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.FragmentIntImpQueryWaybillBinding
import com.lukouguoji.gjj.viewModel.IntImpQueryDetailsViewModel
/**
* 国际进港查询详情 - 运单信息Fragment
*/
class IntImpQueryWaybillFragment : Fragment() {
private lateinit var binding: FragmentIntImpQueryWaybillBinding
private lateinit var viewModel: IntImpQueryDetailsViewModel
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = DataBindingUtil.inflate(
inflater,
R.layout.fragment_int_imp_query_waybill,
container,
false
)
binding.lifecycleOwner = viewLifecycleOwner
binding.viewModel = viewModel
return binding.root
}
companion object {
@JvmStatic
fun newInstance(vm: IntImpQueryDetailsViewModel) =
IntImpQueryWaybillFragment().apply {
viewModel = vm
}
}
}

View File

@@ -1,10 +1,8 @@
package com.lukouguoji.gjj.holder
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.lukouguoji.gjj.databinding.ItemIntArrAirManifestSubBinding
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjjAirManifest
import com.lukouguoji.module_base.bean.GjjImportManifest
/**
@@ -19,18 +17,10 @@ class IntArrAirManifestSubViewHolder(view: View) :
binding.position = position
binding.executePendingBindings()
// 单选框点击切换选择状态
// 单选框点击切换选择状态(独立选择,不联动主列表)
binding.ivCheckbox.setOnClickListener {
val newCheckedState = !bean.checked.get()
bean.checked.set(newCheckedState)
bean.checked.set(!bean.checked.get())
binding.executePendingBindings()
// 反向联动主列表项(勾选子项时自动勾选父项)
if (newCheckedState) {
val recyclerView = itemView.parent as? RecyclerView ?: return@setOnClickListener
val parentBean = recyclerView.tag as? GjjAirManifest ?: return@setOnClickListener
parentBean.checked.set(true)
}
}
}
}

View File

@@ -26,14 +26,10 @@ class IntArrAirManifestViewHolder(view: View) :
// 整卡点击 - 跳转详情页
notifyItemClick(position, binding.ll)
// 图标点击 - 切换选择状态(联动子列表)
// 图标点击 - 切换选择状态(独立选择,不联动子列表)
binding.ivIcon.setOnClickListener {
val newCheckedState = !bean.checked.get()
bean.checked.set(newCheckedState)
// 联动子列表选中状态
bean.haWbList?.forEach { sub -> sub.checked.set(newCheckedState) }
bean.checked.set(!bean.checked.get())
binding.executePendingBindings()
binding.rvSub.adapter?.notifyDataSetChanged()
}
// 展开按钮点击事件
@@ -48,7 +44,6 @@ class IntArrAirManifestViewHolder(view: View) :
R.layout.item_int_arr_air_manifest_sub
)
// 设置父Bean引用用于子列表反向联动
binding.rvSub.tag = bean
binding.rvSub.refresh(bean.haWbList ?: emptyList())
}

View File

@@ -21,5 +21,11 @@ class IntImpAccidentVisaViewHolder(view: View) :
bean.checked.set(!bean.checked.get())
binding.executePendingBindings()
}
// 侧滑菜单 - 修改按钮
binding.btnEdit.setOnClickListener {
binding.swipeMenu.quickClose()
clickListener?.onItemClick(position, 2000) // type=2000表示修改操作
}
}
}

View File

@@ -22,5 +22,11 @@ class IntImpLoadingListViewHolder(view: View) :
bean.checked.set(!bean.checked.get())
binding.executePendingBindings()
}
// 侧滑菜单 - 编辑按钮
binding.btnEdit.setOnClickListener {
binding.swipeMenu.quickClose()
clickListener?.onItemClick(position, 2000)
}
}
}

View File

@@ -30,6 +30,9 @@ class IntImpManifestViewHolder(view: View) :
binding.rvSub.adapter?.notifyDataSetChanged()
}
// 整卡点击 - 跳转详情页
notifyItemClick(position, binding.llContent)
// 编辑按钮点击
binding.btnEdit.setOnClickListener {
clickListener?.onItemClick(position, 101) // 101=编辑
@@ -40,10 +43,15 @@ class IntImpManifestViewHolder(view: View) :
clickListener?.onItemClick(position, 102) // 102=删除
}
// 展开按钮点击事件
// 展开按钮点击事件 - 先加载分单数据,再切换展开状态
binding.ivShow.setOnClickListener {
if (!bean.showMore.get() && bean.haWbList.isNullOrEmpty()) {
// 首次展开且无数据,通知 ViewModel 加载分单
clickListener?.onItemClick(position, 103) // 103=加载分单
} else {
bean.showMore.set(!bean.showMore.get())
}
}
// 初始化分单子列表 RecyclerView
setCommonAdapter(
@@ -54,6 +62,29 @@ class IntImpManifestViewHolder(view: View) :
// 设置父Bean引用用于子列表反向联动
binding.rvSub.tag = bean
binding.rvSub.refresh(bean.haWbList ?: emptyList())
val subList = bean.haWbList ?: emptyList()
binding.rvSub.refresh(subList)
updateSubListVisibility(bean.haWbList != null, subList.isNotEmpty())
}
/**
* 根据分单数据状态,切换表头/列表与空数据提示的显隐
* @param loaded 是否已加载过数据haWbList != null
* @param hasData 是否有数据
*/
private fun updateSubListVisibility(loaded: Boolean, hasData: Boolean) {
if (!loaded || hasData) {
// 未加载或有数据:显示表头+列表,隐藏空提示
binding.llHeader.visibility = View.VISIBLE
binding.dividerHeader.visibility = View.VISIBLE
binding.rvSub.visibility = 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

@@ -25,8 +25,14 @@ class IntImpPickUpRecordViewHolder(view: View) :
}
// 列表项点击进入提取详情
itemView.setOnClickListener {
IntImpPickUpRecordDetailsActivity.start(itemView.context, bean.id)
binding.ll.setOnClickListener {
IntImpPickUpRecordDetailsActivity.start(itemView.context, bean)
}
// 侧滑菜单 - 修改按钮
binding.btnEdit.setOnClickListener {
binding.swipeMenu.quickClose()
clickListener?.onItemClick(position, 2000) // type=2000表示修改操作
}
}
}

View File

@@ -0,0 +1,20 @@
package com.lukouguoji.gjj.holder
import android.view.View
import com.lukouguoji.gjj.databinding.ItemIntImpQueryStorageBinding
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjjStorageUse
/**
* 国际进港查询详情-库位信息ViewHolder
*/
class IntImpQueryStorageViewHolder(view: View) :
BaseViewHolder<GjjStorageUse, ItemIntImpQueryStorageBinding>(view) {
override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item) ?: return
binding.bean = bean
binding.position = position
binding.executePendingBindings()
}
}

View File

@@ -15,5 +15,14 @@ class IntImpQueryViewHolder(view: View) :
val bean = getItemBean(item)!!
binding.bean = bean
binding.executePendingBindings()
// 注册整行点击事件
notifyItemClick(position, binding.ll)
// 侧滑菜单 - 修改按钮
binding.btnEdit.setOnClickListener {
binding.swipeMenu.quickClose()
clickListener?.onItemClick(position, 2000) // type=2000表示修改操作
}
}
}

View File

@@ -0,0 +1,20 @@
package com.lukouguoji.gjj.holder
import android.view.View
import com.lukouguoji.gjj.databinding.ItemIntImpQueryWarehouseBinding
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjjWarehouse
/**
* 国际进港查询详情-仓库信息ViewHolder
*/
class IntImpQueryWarehouseViewHolder(view: View) :
BaseViewHolder<GjjWarehouse, ItemIntImpQueryWarehouseBinding>(view) {
override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item) ?: return
binding.bean = bean
binding.position = position
binding.executePendingBindings()
}
}

View File

@@ -0,0 +1,43 @@
package com.lukouguoji.gjj.holder
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.lukouguoji.gjj.databinding.ItemIntImpTallySubBinding
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjjImportTally
/**
* 国际进港理货报告 分单子列表 ViewHolder
*/
class IntImpTallySubViewHolder(view: View) :
BaseViewHolder<GjjImportTally, ItemIntImpTallySubBinding>(view) {
override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item) ?: return
binding.bean = bean
binding.position = position
binding.executePendingBindings()
// 单选框点击切换选择状态(反向联动主列表)
binding.ivCheckbox.setOnClickListener {
val newCheckedState = !bean.checked.get()
bean.checked.set(newCheckedState)
binding.executePendingBindings()
// 反向联动主列表项(勾选时联动主项也勾选)
updateParentCheckState(newCheckedState)
}
}
/**
* 更新父列表项的选择状态
*/
private fun updateParentCheckState(newCheckedState: Boolean) {
val recyclerView = itemView.parent as? RecyclerView ?: return
val parentBean = recyclerView.tag as? GjjImportTally ?: return
if (newCheckedState) {
parentBean.checked.set(true)
}
}
}

View File

@@ -1,9 +1,17 @@
package com.lukouguoji.gjj.holder
import android.view.View
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.ItemIntImpTallyBinding
import com.lukouguoji.gjj.activity.IntImpTallyDetailsActivity
import com.lukouguoji.module_base.adapter.setCommonAdapter
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjjImportTally
import com.google.gson.Gson
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.refresh
import com.lukouguoji.module_base.ktx.toRequestBody
/**
* 国际进港理货报告 ViewHolder
@@ -17,10 +25,84 @@ class IntImpTallyViewHolder(view: View) :
binding.position = position
binding.executePendingBindings()
// 选中图标点击 - 切换选择状态
// 选中图标点击 - 切换选择状态(联动子列表)
binding.ivIcon.setOnClickListener {
bean.checked.set(!bean.checked.get())
val newCheckedState = !bean.checked.get()
bean.checked.set(newCheckedState)
// 联动勾选/取消所有子列表项
bean.haWbList?.forEach { sub ->
sub.checked.set(newCheckedState)
}
binding.executePendingBindings()
binding.rvSub.adapter?.notifyDataSetChanged()
}
// 整个内容区域点击 - 跳转到详情页
binding.llContent.setOnClickListener {
IntImpTallyDetailsActivity.start(it.context, bean)
}
// 展开按钮点击事件
binding.ivShow.setOnClickListener {
if (bean.haWbList != null) {
// 已加载过数据,直接切换显隐
bean.showMore.set(!bean.showMore.get())
} else {
// 首次展开,调用接口加载分单数据
loadSubList(bean)
}
}
// 初始化分单子列表 RecyclerView
setCommonAdapter(
binding.rvSub,
IntImpTallySubViewHolder::class.java,
R.layout.item_int_imp_tally_sub
)
// 刷新分单数据传递父Bean引用用于反向联动
binding.rvSub.tag = bean
val subList = bean.haWbList ?: emptyList()
binding.rvSub.refresh(subList)
updateSubListVisibility(subList.isNotEmpty())
}
/**
* 加载分单列表数据(将主单整体作为请求参数)
*/
private fun loadSubList(bean: GjjImportTally) {
// 将 bean 转为 Map 并补充 wbNo 字段prefix + no
val map = Gson().fromJson(Gson().toJson(bean), HashMap::class.java) as HashMap<String, Any?>
map["wbNo"] = bean.getWaybillNo()
val params = map.toRequestBody()
launchCollect({ NetApply.api.getIntImpTallySubList(params) }) {
onSuccess = { result ->
val list = result.data?.toMutableList() ?: mutableListOf()
bean.haWbList = list
bean.showMore.set(true)
binding.rvSub.refresh(list)
updateSubListVisibility(list.isNotEmpty())
}
}
}
/**
* 根据分单数据是否为空,切换表头/列表与空数据提示的显隐
*/
private fun updateSubListVisibility(hasData: Boolean) {
if (hasData) {
binding.llHeader.visibility = View.VISIBLE
binding.dividerHeader.visibility = View.VISIBLE
binding.rvSub.visibility = 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

@@ -2,6 +2,7 @@ package com.lukouguoji.gjj.viewModel
import android.content.Intent
import android.view.View
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.lukouguoji.module_base.base.BaseViewModel
@@ -38,12 +39,60 @@ class GjjManifestAddViewModel : BaseViewModel() {
// 航班号
val flightNo = MutableLiveData("")
// 航程
val range = MutableLiveData("")
// 运单号
val waybillNo = MutableLiveData("")
// ========== 航班级联查询 ==========
private var lastQueriedFlight = ""
fun onFlightDateInputComplete() {
lastQueriedFlight = ""
queryFlightIfReady()
}
fun onFlightNoInputComplete() {
queryFlightIfReady()
}
private fun queryFlightIfReady() {
val fdate = flightDate.value
val fno = flightNo.value
if (fdate.isNullOrEmpty() || fno.isNullOrEmpty()) return
val key = "$fdate-$fno"
if (key == lastQueriedFlight) return
lastQueriedFlight = key
launchCollect({
NetApply.api.getGjFlightBean(
mapOf(
"fdate" to fdate,
"fno" to fno,
"ieFlag" to "I",
).toRequestBody()
)
}) {
onSuccess = {
if (it.verifySuccess() && it.data != null) {
val flight = it.data!!
fid = flight.fid.noNull()
departure.value = flight.fdep.noNull()
destination.value = flight.fdest.noNull()
} else {
fid = ""
departure.value = ""
destination.value = ""
showToast(it.msg.noNull("获取航班信息失败"))
}
}
onFailed = { _, _ ->
fid = ""
departure.value = ""
destination.value = ""
}
}
}
// UN编号
val unNumber = MutableLiveData("")
@@ -65,6 +114,17 @@ class GjjManifestAddViewModel : BaseViewModel() {
// 目的港
val destination = MutableLiveData("")
// 航程(自动拼接:始发站-目的站)
val range = MediatorLiveData<String>().apply {
val update = {
val dep = departure.value ?: ""
val dest = destination.value ?: ""
value = if (dep.isNotEmpty() || dest.isNotEmpty()) "$dep-$dest" else ""
}
addSource(departure) { update() }
addSource(destination) { update() }
}
// 品名(中)
val goodsNameCn = MutableLiveData("")
@@ -100,10 +160,10 @@ class GjjManifestAddViewModel : BaseViewModel() {
val waybillType = MutableLiveData("")
init {
DictUtils.getAgentList(addAll = false) {
DictUtils.getIntImpAgentList(addAll = false) {
agentList.postValue(listOf(KeyValue("", "")) + it)
}
DictUtils.getSpecialCodeList(addAll = false, flag = 1, ieFlag = "I") {
DictUtils.getSpecialCodeList(addAll = false, flag = 1, ieFlag = "") {
val list = arrayListOf<KeyValue>()
it.find { b -> b.key.contains("普通货物") }?.let { b ->
list.add(b)
@@ -114,7 +174,7 @@ class GjjManifestAddViewModel : BaseViewModel() {
DictUtils.getBusinessTypeList(addAll = false) {
businessTypeList.postValue(it)
}
DictUtils.getGjjPackageTypeList(addAll = false) {
DictUtils.getShouYunPackageTypeList {
packageTypeList.postValue(listOf(KeyValue("", "")) + it)
}
DictUtils.getGjjGoodsTypeList(addAll = false) {
@@ -146,6 +206,10 @@ class GjjManifestAddViewModel : BaseViewModel() {
// 编辑模式从Bean对象加载数据
if (pageType.value == DetailsPageType.Modify) {
// 回填航班日期和航班号Bean中不包含从列表页传入
flightDate.value = intent.getStringExtra("flightDate").noNull()
flightNo.value = intent.getStringExtra("flightNo").noNull()
val bean = intent.getSerializableExtra(Constant.Key.BEAN)
if (bean is com.lukouguoji.module_base.bean.GjjManifest) {
loadManifestFromBean(bean)
@@ -229,15 +293,14 @@ class GjjManifestAddViewModel : BaseViewModel() {
"mfId" to if (pageType.value == DetailsPageType.Modify) mfId else null,
"fid" to fid,
"wbNo" to waybillNo.value,
"agent" to agent.value,
"agentCode" to agent.value,
"spCode" to specialCode.value,
"businessType" to businessType.value,
"awbpc" to waybillNum.value,
"totalPc" to waybillNum.value,
"pc" to actualNum.value,
"weight" to actualWeight.value,
"planweight" to billingWeight.value,
"packagecode" to packageType.value,
"dep" to departure.value,
"cashWeight" to billingWeight.value,
"packageType" to packageType.value,
"origin" to departure.value,
"dest" to destination.value,
"goods" to goodsNameEn.value,

View File

@@ -110,7 +110,7 @@ class GjjManifestDetailsViewModel : BaseViewModel(), IGetData {
DictUtils.getAgentList(addAll = false, checkedValue = data.agent) {
agentList.postValue(it)
}
DictUtils.getSpecialCodeList(addAll = false, flag = 1, ieFlag = "I", checkedValue = data.spCode) {
DictUtils.getSpecialCodeList(addAll = false, flag = 1, ieFlag = "", checkedValue = data.spCode) {
specialCodeList.postValue(it)
}
DictUtils.getBusinessTypeList(

View File

@@ -266,7 +266,7 @@ class GjjManifestListViewModel : BasePageViewModel(), IOnItemClickListener {
private fun onDelete(list: List<GjjManifestBean>) {
showLoading()
launchCollect({
NetApply.api.gjjManifestDelete(
NetApply.api.gjjManifestDeleteBatch(
list.map { it.mfId }.toRequestBody()
)
}) {

View File

@@ -12,6 +12,7 @@ import com.lukouguoji.module_base.bean.GjjDeclareParam
import com.lukouguoji.module_base.bean.GjjImportManifest
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.gjj.dialog.IntImpTallyResetDialogModel
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.ktx.commonAdapter
@@ -113,32 +114,32 @@ class IntArrAirManifestViewModel : BasePageViewModel() {
ScanModel.startScan(getTopActivity(), Constant.RequestCode.HNO)
}
/**
* 收集选中的主单和分单(独立选择,互不影响)
* @return Pair<主单列表, 分单列表>,如果无任何选中返回 null
*/
private fun getSelectedItems(emptyMsg: String): Pair<List<GjjImportManifest>, List<GjjImportManifest>>? {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjAirManifest> ?: return null
val maWbList = list.filter { it.isSelected }.mapNotNull { it.maWb }
val haWbList = list.flatMap { it.haWbList ?: emptyList() }.filter { it.isSelected }
if (maWbList.isEmpty() && haWbList.isEmpty()) {
showToast(emptyMsg)
return null
}
return Pair(maWbList, haWbList)
}
/**
* 状态重置按钮点击
*/
fun resetStatusClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjAirManifest> ?: return
val selectedItems = list.filter { it.isSelected }
if (selectedItems.isEmpty()) {
showToast("请选择要重置的舱单")
return
}
// 提取主单和分单
val maWbList = mutableListOf<GjjImportManifest>()
val haWbList = mutableListOf<GjjImportManifest>()
selectedItems.forEach { airManifest ->
airManifest.maWb?.let { maWbList.add(it) }
airManifest.haWbList?.let { haWbList.addAll(it) }
}
val (maWbList, haWbList) = getSelectedItems("请选择要重置的舱单") ?: return
val dialog = IntImpTallyResetDialogModel { dialogModel ->
val param = GjjDeclareParam(
maWbList = maWbList,
haWbList = haWbList,
restStatus = null, // 未申报状态
resetReason = "状态重置"
restStatus = dialogModel.resetStatusCode
)
launchLoadingCollect({ NetApply.api.resetIntArrManifestStatus(param.toRequestBody()) }) {
@@ -152,26 +153,24 @@ class IntArrAirManifestViewModel : BasePageViewModel() {
}
}
dialog.show()
}
/**
* 补充信息按钮点击
* 补充信息按钮点击(只针对主单)
*/
fun supplementInfoClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjAirManifest> ?: return
val selectedItems = list.filter { it.isSelected }
val selectedMainItems = list.filter { it.isSelected }.mapNotNull { it.maWb }
if (selectedItems.isEmpty()) {
showToast("请选择要补充信息的")
if (selectedMainItems.isEmpty()) {
showToast("请选择要补充信息的")
return
}
// 收集所有选中项的主单数据
val manifestList = ArrayList(selectedItems.mapNotNull { it.maWb })
if (manifestList.isEmpty()) return
// 跳转到补充信息页面(传递完整列表)
com.lukouguoji.gjj.activity.IntArrSupplementInfoActivity.start(
getTopActivity(),
manifestList
ArrayList(selectedMainItems)
)
}
@@ -179,31 +178,14 @@ class IntArrAirManifestViewModel : BasePageViewModel() {
* 删除申报按钮点击
*/
fun deleteDeclarationClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjAirManifest> ?: return
val selectedItems = list.filter { it.isSelected }
if (selectedItems.isEmpty()) {
showToast("请选择要删除申报的舱单")
return
}
val (maWbList, haWbList) = getSelectedItems("请选择要删除申报的舱单") ?: return
// 从接口获取删除原因列表
launchLoadingCollect({ NetApply.api.getDelReasonList() }) {
onSuccess = { result ->
val deleteReasonList = result.data?.map { it.toKeyValue() } ?: emptyList()
// 创建并显示弹框
val dialog = com.lukouguoji.gjj.dialog.IntArrManifestDeleteDialogModel(deleteReasonList) { dialogModel ->
// 弹框确认后的回调
// 提取主单和分单
val maWbList = mutableListOf<GjjImportManifest>()
val haWbList = mutableListOf<GjjImportManifest>()
selectedItems.forEach { airManifest ->
airManifest.maWb?.let { maWbList.add(it) }
airManifest.haWbList?.let { haWbList.addAll(it) }
}
val param = GjjDeclareParam(
dcode = dialogModel.deleteReason.value ?: "",
dcontactsName = dialogModel.contactName.value ?: "",
@@ -212,10 +194,7 @@ class IntArrAirManifestViewModel : BasePageViewModel() {
haWbList = haWbList
)
val requestData = param.toRequestBody()
// 调用删除接口
launchLoadingCollect({ NetApply.api.deleteIntArrManifestDeclare(requestData) }) {
launchLoadingCollect({ NetApply.api.deleteIntArrManifestDeclare(param.toRequestBody()) }) {
onSuccess = {
showToast("删除申报成功")
viewModelScope.launch {
@@ -235,27 +214,9 @@ class IntArrAirManifestViewModel : BasePageViewModel() {
* 舱单申报按钮点击
*/
fun declareClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjAirManifest> ?: return
val selectedItems = list.filter { it.isSelected }
val (maWbList, haWbList) = getSelectedItems("请选择要申报的舱单") ?: return
if (selectedItems.isEmpty()) {
showToast("请选择要申报的舱单")
return
}
// 提取主单和分单
val maWbList = mutableListOf<GjjImportManifest>()
val haWbList = mutableListOf<GjjImportManifest>()
selectedItems.forEach { airManifest ->
airManifest.maWb?.let { maWbList.add(it) }
airManifest.haWbList?.let { haWbList.addAll(it) }
}
val param = GjjDeclareParam(
maWbList = maWbList,
haWbList = haWbList
)
val param = GjjDeclareParam(maWbList = maWbList, haWbList = haWbList)
launchLoadingCollect({ NetApply.api.declareIntArrManifest(param.toRequestBody()) }) {
onSuccess = {
@@ -293,6 +254,19 @@ class IntArrAirManifestViewModel : BasePageViewModel() {
launchLoadingCollect({ NetApply.api.getIntArrAirManifestList(listParams) }) {
onSuccess = { result ->
isAllExpanded.value = false
// 如果接口未返回航班日期/航班号,用筛选条件填充
val fd = flightDate.value ?: ""
val fn = flightNo.value ?: ""
result.list?.forEach { airManifest ->
airManifest.maWb?.let {
if (it.fdate.isEmpty()) it.fdate = fd
if (it.fno.isEmpty()) it.fno = fn
}
airManifest.haWbList?.forEach {
if (it.fdate.isEmpty()) it.fdate = fd
if (it.fno.isEmpty()) it.fno = fn
}
}
pageModel.handleListBean(result.toBaseListBean())
}
}

View File

@@ -13,6 +13,7 @@ import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.launchLoadingCollect
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import dev.utils.app.info.KeyValue
import kotlinx.coroutines.launch
@@ -56,7 +57,7 @@ class IntArrSupplementInfoViewModel : BaseViewModel() {
* 加载国家代码下拉列表
*/
private fun loadCountryCodeList() {
launchCollect({ NetApply.api.getAreaTypeList() }) {
launchCollect({ NetApply.api.getCountryCodeList() }) {
onSuccess = { result ->
val keyValueList = result.data?.mapNotNull { bean ->
if (bean.code != null && bean.name != null) {
@@ -69,13 +70,18 @@ class IntArrSupplementInfoViewModel : BaseViewModel() {
}
/**
* 加载通讯方式下拉列表(本地固定值)
* 加载通讯方式下拉列表
*/
private fun loadComTypeList() {
comTypeList.value = listOf(
KeyValue("电话TE", "TE"),
KeyValue("传真FX", "FX")
)
launchCollect({ NetApply.api.getCommunicateTypeList() }) {
onSuccess = { result ->
comTypeList.value = result.data?.mapNotNull { bean ->
if (bean.code != null && bean.name != null) {
KeyValue(bean.name, bean.code)
} else null
} ?: emptyList()
}
}
}
/**
@@ -91,6 +97,17 @@ class IntArrSupplementInfoViewModel : BaseViewModel() {
fun save() {
val formBean = dataBean.value ?: return
// 收货人必填校验
if (formBean.consigneeName.verifyNullOrEmpty("收货人名称不能为空")) return
if (formBean.consigneeCountryCode.verifyNullOrEmpty("收货人国家代码不能为空")) return
if (formBean.consigneeComType.verifyNullOrEmpty("收货人通讯方式不能为空")) return
if (formBean.consigneePNum.verifyNullOrEmpty("收货人联系号码不能为空")) return
// 发货人必填校验
if (formBean.consignorName.verifyNullOrEmpty("发货人名称不能为空")) return
if (formBean.consignorCountryCode.verifyNullOrEmpty("发货人国家代码不能为空")) return
if (formBean.consignorComType.verifyNullOrEmpty("发货人通讯方式不能为空")) return
if (formBean.consignorPNum.verifyNullOrEmpty("发货人联系号码不能为空")) return
if (manifestList.isEmpty()) {
showToast("无可保存的数据")
return

View File

@@ -0,0 +1,271 @@
package com.lukouguoji.gjj.viewModel
import android.content.Intent
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import androidx.recyclerview.widget.RecyclerView
import com.lukouguoji.gjj.R
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.FileBean
import com.lukouguoji.module_base.bean.GjAccidentVisaEditBean
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.common.DetailsPageType
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.impl.ImageSelectViewHolder
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.ktx.verifyNullOrEmpty
import com.lukouguoji.module_base.util.MediaUtil
import com.lukouguoji.module_base.util.UploadUtil
import dev.utils.app.info.KeyValue
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
class IntImpAccidentVisaEditViewModel : BaseViewModel(), IOnItemClickListener {
var id: Long = 0
val pageType = MutableLiveData(DetailsPageType.Add)
val dataBean = MutableLiveData(GjAccidentVisaEditBean())
// 图片列表
val itemLayoutId = R.layout.item_image_select
val itemViewHolder = ImageSelectViewHolder::class.java
var rv: RecyclerView? = null
// 下拉列表
val outerPackageList = MutableLiveData<List<KeyValue>>(emptyList())
val damageTypeList = MutableLiveData<List<KeyValue>>(emptyList())
val contentTypeList = MutableLiveData<List<KeyValue>>(emptyList())
val unusualTypeList = MutableLiveData<List<KeyValue>>(emptyList())
val photoList = MutableLiveData(
listOf(KeyValue("", ""), KeyValue("", ""))
)
// 航班级联查询
private var lastQueriedFlight = ""
///////////////////////////////////////////////////////////////////////////
// 初始化
///////////////////////////////////////////////////////////////////////////
fun initOnCreate(intent: Intent) {
id = intent.getLongExtra(Constant.Key.ID, 0)
pageType.value = if (id == 0L) DetailsPageType.Add else DetailsPageType.Modify
loadDropdownLists()
if (id != 0L) {
loadDetail()
}
rv?.post {
rv?.commonAdapter()?.addItem(FileBean())
}
}
private fun loadDropdownLists() {
launchCollect({ NetApply.api.getPackTypeList() }) {
onSuccess = { result ->
outerPackageList.value = result.data?.mapNotNull { bean ->
bean.name?.let { name -> KeyValue(name, name) }
} ?: emptyList()
}
}
launchCollect({ NetApply.api.getDamageTypeList() }) {
onSuccess = { result ->
damageTypeList.value = result.data?.mapNotNull { bean ->
bean.name?.let { name -> KeyValue(name, name) }
} ?: emptyList()
}
}
launchCollect({ NetApply.api.getContentTypeList() }) {
onSuccess = { result ->
contentTypeList.value = result.data?.mapNotNull { bean ->
bean.name?.let { name -> KeyValue(name, name) }
} ?: emptyList()
}
}
launchCollect({ NetApply.api.getUnusualTypeList() }) {
onSuccess = { result ->
unusualTypeList.value = result.data?.mapNotNull { bean ->
bean.name?.let { name -> KeyValue(name, name) }
} ?: emptyList()
}
}
}
private fun loadDetail() {
launchLoadingCollect({ NetApply.api.getGjAccidentVisaDetail(id) }) {
onSuccess = {
dataBean.value = it.data ?: GjAccidentVisaEditBean()
// 渲染图片
val bean = dataBean.value!!
val picList = bean.pic.split(",")
.filter { url -> url.isNotEmpty() }
.map { url -> FileBean(MediaUtil.fillUrl(url), url) }
val originalList = bean.originalPic.split(",")
.filter { url -> url.isNotEmpty() }
.map { url -> FileBean(MediaUtil.fillUrl(url)) }
for ((index, fileBean) in picList.withIndex()) {
if (index < originalList.size) {
picList[index].originalPic = originalList[index].path
}
}
rv?.commonAdapter()?.loadMore(picList)
}
}
}
///////////////////////////////////////////////////////////////////////////
// 航班级联查询
///////////////////////////////////////////////////////////////////////////
fun onFlightDateInputComplete() {
lastQueriedFlight = ""
queryFlightIfReady()
}
fun onFlightNoInputComplete() {
queryFlightIfReady()
}
private fun queryFlightIfReady() {
val bean = dataBean.value ?: return
val fdate = bean.fdate
val fno = bean.fno
if (fdate.isEmpty() || fno.isEmpty()) return
val key = "$fdate-$fno"
if (key == lastQueriedFlight) return
lastQueriedFlight = key
launchCollect({
NetApply.api.getGjFlightBean(
mapOf(
"fdate" to fdate,
"fno" to fno,
"ieFlag" to "I",
).toRequestBody()
)
}) {
onSuccess = {
if (it.verifySuccess() && it.data != null) {
val flight = it.data!!
val b = dataBean.value ?: GjAccidentVisaEditBean()
b.dep = flight.fdep.noNull()
b.dest = flight.fdest.noNull()
dataBean.value = b
} else {
val b = dataBean.value ?: GjAccidentVisaEditBean()
b.dep = ""
b.dest = ""
dataBean.value = b
showToast(it.msg.noNull("获取航班信息失败"))
}
}
onFailed = { _, _ ->
val b = dataBean.value ?: GjAccidentVisaEditBean()
b.dep = ""
b.dest = ""
dataBean.value = b
}
}
}
///////////////////////////////////////////////////////////////////////////
// 保存
///////////////////////////////////////////////////////////////////////////
fun onSaveClick() {
val bean = dataBean.value ?: return
if (bean.fdate.verifyNullOrEmpty("请输入航班日期")) return
if (bean.fno.verifyNullOrEmpty("请输入航班号")) return
if (bean.wbNo.verifyNullOrEmpty("请输入运单号")) return
(rv?.commonAdapter()?.items ?: emptyList())
.asFlow()
.map { it as FileBean }
.filter { it.path.isNotEmpty() && it.url.isEmpty() }
.onEach {
val data = UploadUtil.upload(it.path).data
it.url = data?.newName ?: ""
it.originalPic = data?.zipFileName ?: ""
}
.flowOn(Dispatchers.IO)
.onStart { showLoading() }
.catch {
showToast(it.message.noNull("上传图片失败"))
dismissLoading()
}
.onCompletion {
launchLoadingCollect({
val list = (rv?.commonAdapter()?.items as List<FileBean>)
.filter { it.path.isNotEmpty() }
bean.picNumber = list.size.toString()
bean.originalPic = list.joinToString(separator = ",") { MediaUtil.removeUrl(it.url) }
bean.pic = list.joinToString(separator = ",") { MediaUtil.removeUrl(it.originalPic) }
bean.idFlag = "1"
if (pageType.value == DetailsPageType.Add) {
NetApply.api.saveGjAccidentVisa(bean.toRequestBody())
} else {
NetApply.api.modifyGjAccidentVisa(bean.toRequestBody())
}
}) {
onSuccess = {
showToast(it.msg.noNull("${pageType.value!!.title}成功"))
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
getTopActivity().finish()
}
}
}
.launchIn(viewModelScope)
}
fun onCancelClick() {
getTopActivity().finish()
}
///////////////////////////////////////////////////////////////////////////
// 图片操作
///////////////////////////////////////////////////////////////////////////
override fun onItemClick(position: Int, type: Int) {
val adapter = rv!!.commonAdapter()!!
val bean = adapter.getItem(position) as FileBean
when (type) {
R.id.rl -> {
bean.canDelete.set(!bean.canDelete.get())
}
R.id.iv_delete -> {
adapter.removeItem(position)
}
else -> {}
}
}
}

View File

@@ -123,6 +123,10 @@ class IntImpAccidentVisaViewModel : BasePageViewModel() {
ScanModel.startScan(getTopActivity(), Constant.RequestCode.WAYBILL)
}
fun addClick() {
com.lukouguoji.gjj.activity.IntImpAccidentVisaEditActivity.start(getTopActivity())
}
fun searchClick() {
refresh()
}

View File

@@ -0,0 +1,86 @@
package com.lukouguoji.gjj.viewModel
import android.content.Intent
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.google.gson.Gson
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.GjjManifest
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.ktx.launchLoadingCollect
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody
import kotlinx.coroutines.launch
/**
* 国际进港装机单编辑 ViewModel
*/
class IntImpLoadingListEditViewModel : BaseViewModel() {
val dataBean = MutableLiveData(GjjManifest())
// 可编辑数值字段String 用于双向绑定)
val location = MutableLiveData("")
val totalPcStr = MutableLiveData("")
val pcStr = MutableLiveData("")
val weightStr = MutableLiveData("")
val cashWeightStr = MutableLiveData("")
fun initOnCreated(intent: Intent) {
val jsonData = intent.getStringExtra(Constant.Key.DATA) ?: ""
if (jsonData.isNotEmpty()) {
try {
val bean = Gson().fromJson(jsonData, GjjManifest::class.java)
dataBean.value = bean
// 初始化可编辑字段
location.value = bean.location
totalPcStr.value = bean.totalPc.toString()
pcStr.value = bean.pc.toString()
weightStr.value = bean.weight.toString()
cashWeightStr.value = bean.cashWeight.toString()
} catch (e: Exception) {
showToast("数据解析失败")
getTopActivity().finish()
}
} else {
showToast("未接收到数据")
getTopActivity().finish()
}
}
/**
* 保存修改
*/
fun submit() {
val bean = dataBean.value ?: return
// 同步可编辑字段回 bean
bean.location = location.value ?: ""
bean.totalPc = totalPcStr.value?.toLongOrNull() ?: 0
bean.pc = pcStr.value?.toLongOrNull() ?: 0
bean.weight = weightStr.value?.toDoubleOrNull() ?: 0.0
bean.cashWeight = cashWeightStr.value?.toDoubleOrNull() ?: 0.0
launchLoadingCollect({
NetApply.api.modifyIntImpLoadingList(bean.toRequestBody())
}) {
onSuccess = {
showToast("修改成功")
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
getTopActivity().finish()
}
}
}
/**
* 取消
*/
fun cancel() {
getTopActivity().finish()
}
}

View File

@@ -10,6 +10,7 @@ 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.interfaces.IOnItemClickListener
import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.launchLoadingCollect
@@ -23,7 +24,7 @@ import kotlinx.coroutines.launch
/**
* 国际进港装机单 ViewModel
*/
class IntImpLoadingListViewModel : BasePageViewModel() {
class IntImpLoadingListViewModel : BasePageViewModel(), IOnItemClickListener {
// ========== 搜索条件 ==========
val flightDate = MutableLiveData("") // 航班日期
@@ -35,7 +36,8 @@ class IntImpLoadingListViewModel : BasePageViewModel() {
// ========== 航班级联查询 ==========
private var lastQueriedFlight = ""
private var fid = ""
var fid = ""
var fdep = ""
fun onFlightDateInputComplete() {
lastQueriedFlight = ""
@@ -68,6 +70,7 @@ class IntImpLoadingListViewModel : BasePageViewModel() {
if (it.verifySuccess() && it.data != null) {
val flight = it.data!!
fid = flight.fid.noNull()
fdep = flight.fdep.noNull()
fdest.value = flight.fdest.noNull()
// 构建始发站下拉列表fdep + jtz经停港
@@ -81,6 +84,7 @@ class IntImpLoadingListViewModel : BasePageViewModel() {
sendAddress.value = flight.fdep.noNull()
} else {
fid = ""
fdep = ""
fdest.value = ""
sendAddressList.value = emptyList()
sendAddress.value = ""
@@ -90,6 +94,7 @@ class IntImpLoadingListViewModel : BasePageViewModel() {
onFailed = { _, _ ->
fid = ""
fdep = ""
fdest.value = ""
sendAddressList.value = emptyList()
sendAddress.value = ""
@@ -120,10 +125,67 @@ class IntImpLoadingListViewModel : BasePageViewModel() {
/**
* 搜索按钮点击
* 先查询航班信息获取FID再刷新列表与父页面逻辑保持一致
*/
fun searchClick() {
val fdate = flightDate.value
val fno = flightNo.value
if (!fdate.isNullOrEmpty() && !fno.isNullOrEmpty()) {
val key = "$fdate-$fno"
if (key != lastQueriedFlight || fid.isEmpty()) {
// 先查询航班信息获取FID
lastQueriedFlight = key
launchLoadingCollect({
NetApply.api.getGjFlightBean(
mapOf(
"fdate" to fdate,
"fno" to fno,
"ieFlag" to "I",
).toRequestBody()
)
}) {
onSuccess = {
if (it.verifySuccess() && it.data != null) {
val flight = it.data!!
fid = flight.fid.noNull()
fdep = flight.fdep.noNull()
fdest.value = flight.fdest.noNull()
val list = mutableListOf(
KeyValue(flight.fdep.noNull(), flight.fdep.noNull()),
)
if (!flight.jtz.isNullOrEmpty()) {
list.add(KeyValue(flight.jtz.noNull(), flight.jtz.noNull()))
}
sendAddressList.value = list
sendAddress.value = flight.fdep.noNull()
} else {
fid = ""
fdep = ""
fdest.value = ""
sendAddressList.value = emptyList()
sendAddress.value = ""
showToast(it.msg.noNull("获取航班信息失败"))
}
refresh()
}
onFailed = { _, _ ->
fid = ""
fdep = ""
fdest.value = ""
sendAddressList.value = emptyList()
sendAddress.value = ""
refresh()
}
}
} else {
refresh()
}
} else {
fid = ""
fdep = ""
refresh()
}
}
/**
* 全选按钮点击(切换全选状态)
@@ -165,7 +227,7 @@ class IntImpLoadingListViewModel : BasePageViewModel() {
"manifestList" to selectedItems
).toRequestBody()
launchLoadingCollect({ NetApply.api.modifyIntImpStorage(params) }) {
launchLoadingCollect({ NetApply.api.modifyIntImpLoadingStorage(params) }) {
onSuccess = {
showToast("修改库位成功")
viewModelScope.launch {
@@ -203,7 +265,7 @@ class IntImpLoadingListViewModel : BasePageViewModel() {
"manifestList" to selectedItems
).toRequestBody()
launchLoadingCollect({ NetApply.api.inIntImpStorage(params) }) {
launchLoadingCollect({ NetApply.api.inIntImpLoadingStorage(params) }) {
onSuccess = {
showToast("入库成功")
viewModelScope.launch {
@@ -217,16 +279,29 @@ class IntImpLoadingListViewModel : BasePageViewModel() {
}
}
/**
* 列表项点击回调(侧滑菜单)
*/
override fun onItemClick(position: Int, type: Int) {
when (type) {
2000 -> {
// 编辑操作
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjManifest> ?: return
val bean = list.getOrNull(position) ?: return
com.lukouguoji.gjj.activity.IntImpLoadingListEditActivity.start(getTopActivity(), bean)
}
}
}
/**
* 获取数据重写BasePageViewModel
* 查询参数与父页面国际进港舱单保持一致使用FID和FDGP
*/
override fun getData() {
// 构建搜索条件
// 构建搜索条件与父页面一致fid + fdep + wbNo
val filterParams = mapOf(
"fdate" to flightDate.value?.ifEmpty { null },
"fno" to flightNo.value?.ifEmpty { null },
"sendAddress" to sendAddress.value?.ifEmpty { null },
"fdest" to fdest.value?.ifEmpty { null },
"fid" to fid.ifEmpty { null },
"fdep" to fdep.ifEmpty { null },
"wbNo" to waybillNo.value?.ifEmpty { null }
)
@@ -242,19 +317,7 @@ class IntImpLoadingListViewModel : BasePageViewModel() {
// 获取列表带Loading
launchLoadingCollect({ NetApply.api.getIntImpLoadingList(listParams) }) {
onSuccess = { result ->
// 处理PageInfo结构
val pageInfo = result.data
if (pageInfo != null) {
val list = pageInfo.list ?: emptyList()
val pages = pageInfo.pages ?: 1
// 处理分页数据
pageModel.handleDataList(list)
pageModel.haveMore.postValue(pages > pageModel.page)
} else {
pageModel.handleDataList(emptyList())
pageModel.haveMore.postValue(false)
}
pageModel.handleListBean(result.toBaseListBean())
}
}

View File

@@ -0,0 +1,26 @@
package com.lukouguoji.gjj.viewModel
import android.content.Intent
import androidx.lifecycle.MutableLiveData
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.GjjManifest
import com.lukouguoji.module_base.common.Constant
/**
* 国际进港舱单详情 ViewModel
*/
class IntImpManifestDetailsViewModel : BaseViewModel() {
// 舱单数据
val dataBean = MutableLiveData(GjjManifest())
/**
* 初始化数据(从列表项携带的数据)
*/
fun initOnCreated(intent: Intent) {
val manifest = intent.getSerializableExtra(Constant.Key.DATA) as? GjjManifest
if (manifest != null) {
dataBean.value = manifest
}
}
}

View File

@@ -0,0 +1,144 @@
package com.lukouguoji.gjj.viewModel
import android.content.Intent
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.GjjHaWb
import com.lukouguoji.module_base.bean.GjjManifest
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.common.DetailsPageType
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.impl.FlowBus
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 kotlinx.coroutines.launch
/**
* 国际进港舱单-分单编辑 ViewModel
*/
class IntImpManifestSubEditViewModel : BaseViewModel() {
// 页面类型
val pageType = MutableLiveData(DetailsPageType.Add)
// 分单ID编辑时使用
var hawbId: Long = 0
// 主单ID
var mfId: Long = 0
// 运单号前缀和编号(从主单获取,保存时需传给接口)
var prefix: String = ""
var no: String = ""
// 表单字段
val waybillNo = MutableLiveData("") // 运单号(只读)
val mainSubCheck = MutableLiveData("") // 主分校验(只读)
val subNo = MutableLiveData("") // 分单号
val pc = MutableLiveData("") // 件数
val weight = MutableLiveData("") // 重量
val goodsCn = MutableLiveData("") // 品名(中)
/**
* 初始化从Intent获取参数
*/
fun initOnCreated(intent: Intent) {
pageType.value = DetailsPageType.valueOf(
intent.getStringExtra(Constant.Key.PAGE_TYPE) ?: DetailsPageType.Add.name
)
// 获取主单信息
val manifest = intent.getSerializableExtra(Constant.Key.BEAN) as? GjjManifest
if (manifest != null) {
mfId = manifest.mfId
prefix = manifest.prefix
no = manifest.no
waybillNo.value = manifest.getWaybillNo()
}
// 编辑模式:回填分单数据
if (pageType.value == DetailsPageType.Modify) {
val haWb = intent.getSerializableExtra("haWb") as? GjjHaWb
if (haWb != null) {
hawbId = haWb.hawbId
subNo.value = haWb.hno
pc.value = if (haWb.pc > 0) haWb.pc.toString() else ""
weight.value = if (haWb.weight > 0) haWb.weight.toString() else ""
goodsCn.value = haWb.goodsCn
}
}
// 获取主分校验数据
loadMainSubCheck()
}
/**
* 获取主单减去分单的件数重量
*/
private fun loadMainSubCheck() {
if (mfId == 0L) return
val params = mapOf("mfId" to mfId).toRequestBody()
launchCollect({ NetApply.api.getMaWbMinusHaWb(params) }) {
onSuccess = { result ->
if (result.verifySuccess() && result.data != null) {
val data = result.data!!
mainSubCheck.value = "剩余件数:${data.pc} 剩余重量:${data.weight}"
}
}
}
}
/**
* 保存
*/
fun onSaveClick() {
val params = mutableMapOf<String, Any?>(
"mfId" to mfId,
"prefix" to prefix,
"no" to no,
"hno" to subNo.value,
"pc" to pc.value?.toLongOrNull(),
"weight" to weight.value?.toDoubleOrNull(),
"goodsCn" to goodsCn.value,
"goods" to goodsCn.value
)
if (pageType.value == DetailsPageType.Modify) {
params["hawbId"] = hawbId
}
launchLoadingCollect({
if (pageType.value == DetailsPageType.Modify) {
NetApply.api.intImpManifestModifyHaWb(params.toRequestBody())
} else {
NetApply.api.intImpManifestAddHaWb(params.toRequestBody())
}
}) {
onSuccess = {
if (it.verifySuccess()) {
val msg = if (pageType.value == DetailsPageType.Modify) "修改成功" else "新增成功"
showToast(msg)
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
getTopActivity().finish()
} else {
showToast(it.msg.noNull("保存失败"))
}
}
}
}
/**
* 取消
*/
fun onCancelClick() {
getTopActivity().finish()
}
}

View File

@@ -6,6 +6,7 @@ import com.lukouguoji.gjj.R
import dev.utils.common.DateUtils
import com.lukouguoji.module_base.ktx.formatDate
import com.lukouguoji.gjj.activity.GjjManifestAddActivity
import com.lukouguoji.gjj.activity.IntImpManifestSubEditActivity
import com.lukouguoji.gjj.holder.IntImpManifestViewHolder
import com.lukouguoji.module_base.base.BasePageViewModel
import com.lukouguoji.module_base.bean.GjjManifest
@@ -19,6 +20,7 @@ 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.gjj.dialog.IntImpModifyStorageDialogModel
import com.lukouguoji.module_base.model.ConfirmDialogModel
import dev.utils.app.info.KeyValue
import com.lukouguoji.module_base.model.ScanModel
@@ -34,12 +36,13 @@ class IntImpManifestViewModel : BasePageViewModel() {
val flightNo = MutableLiveData("") // 航班号
val sendAddress = MutableLiveData("") // 始发站
val sendAddressList = MutableLiveData<List<KeyValue>>(emptyList())
val fdep = MutableLiveData("") // 目的站
val fdest = MutableLiveData("") // 目的站
val waybillNo = MutableLiveData("") // 运单号
// ========== 航班级联查询 ==========
private var lastQueriedFlight = ""
private var fid = ""
var fid = ""
var fdep = "" // 航班始发港(用于列表查询参数)
fun onFlightDateInputComplete() {
lastQueriedFlight = ""
@@ -72,7 +75,8 @@ class IntImpManifestViewModel : BasePageViewModel() {
if (it.verifySuccess() && it.data != null) {
val flight = it.data!!
fid = flight.fid.noNull()
fdep.value = flight.fdest.noNull()
fdep = flight.fdep.noNull()
fdest.value = flight.fdest.noNull()
// 构建始发站下拉列表fdep + jtz经停港
val list = mutableListOf(
@@ -85,7 +89,8 @@ class IntImpManifestViewModel : BasePageViewModel() {
sendAddress.value = flight.fdep.noNull()
} else {
fid = ""
fdep.value = ""
fdep = ""
fdest.value = ""
sendAddressList.value = emptyList()
sendAddress.value = ""
showToast(it.msg.noNull("获取航班信息失败"))
@@ -94,7 +99,8 @@ class IntImpManifestViewModel : BasePageViewModel() {
onFailed = { _, _ ->
fid = ""
fdep.value = ""
fdep = ""
fdest.value = ""
sendAddressList.value = emptyList()
sendAddress.value = ""
}
@@ -112,6 +118,9 @@ class IntImpManifestViewModel : BasePageViewModel() {
// ========== 展开/收起 ==========
val isAllExpanded = MutableLiveData(false)
// ========== 分单管理模式 ==========
val isSubManagementMode = MutableLiveData(false)
init {
// 监听全选状态,自动更新所有列表项(联动子列表)
isAllChecked.observeForever { checked ->
@@ -130,10 +139,67 @@ class IntImpManifestViewModel : BasePageViewModel() {
/**
* 搜索按钮点击
* 先查询航班信息获取FID再刷新列表
*/
fun searchClick() {
val fdate = flightDate.value
val fno = flightNo.value
if (!fdate.isNullOrEmpty() && !fno.isNullOrEmpty()) {
val key = "$fdate-$fno"
if (key != lastQueriedFlight || fid.isEmpty()) {
// 先查询航班信息获取FID
lastQueriedFlight = key
launchLoadingCollect({
NetApply.api.getGjFlightBean(
mapOf(
"fdate" to fdate,
"fno" to fno,
"ieFlag" to "I",
).toRequestBody()
)
}) {
onSuccess = {
if (it.verifySuccess() && it.data != null) {
val flight = it.data!!
fid = flight.fid.noNull()
fdep = flight.fdep.noNull()
fdest.value = flight.fdest.noNull()
val list = mutableListOf(
KeyValue(flight.fdep.noNull(), flight.fdep.noNull()),
)
if (!flight.jtz.isNullOrEmpty()) {
list.add(KeyValue(flight.jtz.noNull(), flight.jtz.noNull()))
}
sendAddressList.value = list
sendAddress.value = flight.fdep.noNull()
} else {
fid = ""
fdep = ""
fdest.value = ""
sendAddressList.value = emptyList()
sendAddress.value = ""
showToast(it.msg.noNull("获取航班信息失败"))
}
refresh()
}
onFailed = { _, _ ->
fid = ""
fdep = ""
fdest.value = ""
sendAddressList.value = emptyList()
sendAddress.value = ""
refresh()
}
}
} else {
refresh()
}
} else {
fid = ""
fdep = ""
refresh()
}
}
/**
* 全选按钮点击(切换全选状态,联动子列表)
@@ -159,11 +225,20 @@ class IntImpManifestViewModel : BasePageViewModel() {
val shouldExpand = !isAllExpanded.value!!
isAllExpanded.value = shouldExpand
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjManifest> ?: return
list.forEach {
if (!it.haWbList.isNullOrEmpty()) {
it.showMore.set(shouldExpand)
if (shouldExpand) {
// 展开:对没有分单数据的项按需加载
list.forEach { bean ->
if (bean.haWbList.isNullOrEmpty()) {
loadHaWbList(bean)
} else {
bean.showMore.set(true)
}
}
} else {
// 收起
list.forEach { it.showMore.set(false) }
}
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
}
@@ -182,51 +257,51 @@ class IntImpManifestViewModel : BasePageViewModel() {
context = getTopActivity(),
fid = fid,
dep = sendAddress.value ?: "",
dest = fdep.value ?: ""
dest = fdest.value ?: ""
)
}
/**
* Item点击处理侧滑按钮
* Item点击处理侧滑按钮 + 列表项点击
*/
override fun onItemClick(position: Int, type: Int) {
val bean = pageModel.rv?.commonAdapter()?.getItem(position) as? GjjManifest ?: return
when (type) {
101 -> {
// 编辑传递整个Bean对象
GjjManifestAddActivity.startForEdit(getTopActivity(), bean)
// 编辑传递整个Bean对象 + 当前筛选的航班日期和航班号
GjjManifestAddActivity.startForEdit(
getTopActivity(), bean,
flightDate = flightDate.value ?: "",
flightNo = flightNo.value ?: ""
)
}
102 -> {
// 删除
deleteManifest(bean)
}
103 -> {
// 展开 - 加载分单数据
loadHaWbList(bean)
}
else -> {
// 列表项点击 - 跳转详情页
com.lukouguoji.gjj.activity.IntImpManifestDetailsActivity.start(
getTopActivity(), bean
)
}
}
}
/**
* 删除单个舱单
* 删除单个舱单(通过批量删除接口,传单元素数组)
*/
private fun deleteManifest(bean: GjjManifest) {
ConfirmDialogModel(
message = "确定要删除运单号 ${bean.getWaybillNo()} 的舱单吗?",
title = "提示"
) {
val params = mapOf("mfId" to bean.mfId).toRequestBody()
launchLoadingCollect({ NetApply.api.gjjManifestDelete(params) }) {
onSuccess = {
if (it.verifySuccess()) {
showToast("删除成功")
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
refresh()
} else {
showToast(it.msg.noNull("删除失败"))
}
}
}
doDeleteByIds(listOf(bean.mfId))
}.show()
}
@@ -242,14 +317,94 @@ class IntImpManifestViewModel : BasePageViewModel() {
return
}
showToast("删除功能开发中")
ConfirmDialogModel(
message = "确定要删除选中的 ${selectedItems.size} 条舱单吗?",
title = "批量删除确认"
) {
doDeleteByIds(selectedItems.map { it.mfId })
}.show()
}
/**
* 分单管理(暂不实现
* 执行批量删除(统一接口,请求体为 mfId 数组
*/
private fun doDeleteByIds(mfIds: List<Long>) {
launchLoadingCollect({ NetApply.api.gjjManifestDeleteBatch(mfIds.toRequestBody()) }) {
onSuccess = {
if (it.verifySuccess()) {
showToast("删除成功")
isAllChecked.value = false
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
refresh()
} else {
showToast(it.msg.noNull("删除失败"))
}
}
}
}
/**
* 分单管理按钮点击 - 进入分单管理模式
*/
fun subManagementClick() {
showToast("分单管理功能开发中")
isSubManagementMode.value = true
}
/**
* 分单管理模式 - 返回按钮点击
*/
fun subManagementBackClick() {
isSubManagementMode.value = false
}
/**
* 新增分单 - 选中一个主单后打开新增页面
*/
fun addSubWaybillClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjManifest> ?: return
val selectedItems = list.filter { it.isSelected }
if (selectedItems.isEmpty()) {
showToast("请选择一个主单")
return
}
if (selectedItems.size > 1) {
showToast("只能选择一个主单")
return
}
IntImpManifestSubEditActivity.startForAdd(getTopActivity(), selectedItems[0])
}
/**
* 修改分单 - 选中一个分单后打开编辑页面
*/
fun modifySubWaybillClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjManifest> ?: return
// 收集所有已选中的分单及其所属主单
val selectedPairs = mutableListOf<Pair<GjjManifest, com.lukouguoji.module_base.bean.GjjHaWb>>()
list.forEach { manifest ->
manifest.haWbList?.forEach { haWb ->
if (haWb.isSelected) {
selectedPairs.add(manifest to haWb)
}
}
}
if (selectedPairs.isEmpty()) {
showToast("请选择一个分单")
return
}
if (selectedPairs.size > 1) {
showToast("只能选择一个分单")
return
}
val (parentManifest, selectedHaWb) = selectedPairs[0]
IntImpManifestSubEditActivity.startForModify(getTopActivity(), parentManifest, selectedHaWb)
}
/**
@@ -258,30 +413,55 @@ class IntImpManifestViewModel : BasePageViewModel() {
fun sortingTallyClick() {
com.alibaba.android.arouter.launcher.ARouter.getInstance()
.build(com.lukouguoji.module_base.router.ARouterConstants.ACTIVITY_URL_INT_IMP_LOADING_LIST)
.withString("fid", fid)
.withString("fdep", fdep)
.withString("fdate", flightDate.value ?: "")
.withString("fno", flightNo.value ?: "")
.withString("sendAddress", sendAddress.value ?: "")
.withString("fdest", fdep.value ?: "")
.withString("fdest", fdest.value ?: "")
.navigation()
}
/**
* 货物发放(暂不实现)
* 货物发放
*/
fun cargoReleaseClick() {
showToast("货物发放功能开发中")
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjManifest> ?: return
val selectedItems = list.filter { it.isSelected }
if (selectedItems.isEmpty()) {
showToast("请选择要发放的运单")
return
}
IntImpModifyStorageDialogModel { dialog ->
val params = mapOf(
"location" to dialog.locationName,
"locationId" to dialog.locationId.toLongOrNull(),
"manifestList" to selectedItems
).toRequestBody()
launchLoadingCollect({ NetApply.api.intImpManifestPutUpCargo(params) }) {
onSuccess = {
if (it.verifySuccess()) {
showToast(it.msg.noNull("货物发放成功"))
refresh()
} else {
showToast(it.msg.noNull("货物发放失败"))
}
}
}
}.show()
}
/**
* 获取数据重写BasePageViewModel
* 通过FID查询列表而不是直接通过航班号和航班日期
*/
override fun getData() {
// 构建搜索条件
// 构建搜索条件使用FID代替fdate/fno
val filterParams = mapOf(
"fdate" to flightDate.value?.ifEmpty { null },
"fno" to flightNo.value?.ifEmpty { null },
"sendAddress" to sendAddress.value?.ifEmpty { null },
"fdep" to fdep.value?.ifEmpty { null },
"fid" to fid.ifEmpty { null },
"fdep" to fdep.ifEmpty { null },
"wbNo" to waybillNo.value?.ifEmpty { null }
)
@@ -297,15 +477,7 @@ class IntImpManifestViewModel : BasePageViewModel() {
// 获取列表带Loading
launchLoadingCollect({ NetApply.api.getIntImpManifestList(listParams) }) {
onSuccess = { result ->
pageModel.handleListBean(result.data?.toBaseListBean())
// 列表加载完成后,加载分单数据
val items = pageModel.rv?.commonAdapter()?.items as? List<GjjManifest>
items?.forEach { bean ->
if (bean.haWbNum > 0) {
loadHaWbList(bean)
}
}
pageModel.handleListBean(result.toBaseListBean())
}
}
@@ -321,20 +493,17 @@ class IntImpManifestViewModel : BasePageViewModel() {
}
/**
* 加载主单下的分单列表
* 加载主单下的分单列表(按需加载,加载完成后自动展开)
*/
private fun loadHaWbList(bean: GjjManifest) {
val params = mapOf(
"mfId" to bean.mfId
).toRequestBody()
val params = bean.toRequestBody()
launchCollect({ NetApply.api.getIntImpManifestHaWbList(params) }) {
launchLoadingCollect({ NetApply.api.getIntImpManifestHaWbList(params) }) {
onSuccess = { result ->
if (result.verifySuccess() && !result.data.isNullOrEmpty()) {
bean.haWbList = result.data
bean.haWbList = result.data ?: emptyList()
bean.showMore.set(true)
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
}
}
}
}
}

View File

@@ -0,0 +1,133 @@
package com.lukouguoji.gjj.viewModel
import android.content.Intent
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.viewModelScope
import com.google.gson.Gson
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.IntImpPickUpRecordBean
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.ktx.launchLoadingCollect
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody
import kotlinx.coroutines.launch
/**
* 国际进港费用修改 ViewModel
*/
class IntImpPickUpChargeEditViewModel : BaseViewModel() {
val dataBean = MutableLiveData(IntImpPickUpRecordBean())
// 可编辑费用字段String 用于双向绑定)
val tranChargeStr = MutableLiveData("") // 信息费
val whsChargeStr = MutableLiveData("") // 仓储费
val drawBillChargeStr = MutableLiveData("") // 文件处理费
val svlChargeStr = MutableLiveData("") // 叉车费
val tallyChargeStr = MutableLiveData("") // 理货费
val pipFeeStr = MutableLiveData("") // 精密仪器处理费
val lapFeeStr = MutableLiveData("") // 活体动物处理费
val totalAmountStr = MutableLiveData("") // 总费用(实时计算)
// 总费用计算观察者
private val totalCalculator = Observer<String> { calculateTotal() }
private fun calculateTotal() {
val total = (tranChargeStr.value?.toDoubleOrNull() ?: 0.0) +
(whsChargeStr.value?.toDoubleOrNull() ?: 0.0) +
(drawBillChargeStr.value?.toDoubleOrNull() ?: 0.0) +
(svlChargeStr.value?.toDoubleOrNull() ?: 0.0) +
(tallyChargeStr.value?.toDoubleOrNull() ?: 0.0) +
(dataBean.value?.optCharge ?: 0.0) +
(pipFeeStr.value?.toDoubleOrNull() ?: 0.0) +
(lapFeeStr.value?.toDoubleOrNull() ?: 0.0)
totalAmountStr.value = if (total != 0.0) total.toString() else ""
}
fun initOnCreated(intent: Intent) {
val jsonData = intent.getStringExtra(Constant.Key.DATA) ?: ""
if (jsonData.isNotEmpty()) {
try {
val bean = Gson().fromJson(jsonData, IntImpPickUpRecordBean::class.java)
dataBean.value = bean
// 初始化可编辑费用字段
tranChargeStr.value = if (bean.tranCharge != 0.0) bean.tranCharge.toString() else ""
whsChargeStr.value = if (bean.whsCharge != 0.0) bean.whsCharge.toString() else ""
drawBillChargeStr.value = if (bean.drawBillCharge != 0.0) bean.drawBillCharge.toString() else ""
svlChargeStr.value = if (bean.svlCharge != 0.0) bean.svlCharge.toString() else ""
tallyChargeStr.value = if (bean.tallyCharge != 0.0) bean.tallyCharge.toString() else ""
pipFeeStr.value = if (bean.pipFee != 0.0) bean.pipFee.toString() else ""
lapFeeStr.value = if (bean.lapFee != 0.0) bean.lapFee.toString() else ""
// 注册总费用实时计算
tranChargeStr.observeForever(totalCalculator)
whsChargeStr.observeForever(totalCalculator)
drawBillChargeStr.observeForever(totalCalculator)
svlChargeStr.observeForever(totalCalculator)
tallyChargeStr.observeForever(totalCalculator)
pipFeeStr.observeForever(totalCalculator)
lapFeeStr.observeForever(totalCalculator)
// 初始计算一次
calculateTotal()
} catch (e: Exception) {
showToast("数据解析失败")
getTopActivity().finish()
}
} else {
showToast("未接收到数据")
getTopActivity().finish()
}
}
/**
* 保存修改
*/
fun submit() {
val bean = dataBean.value ?: return
// 同步可编辑费用字段回 bean
bean.tranCharge = tranChargeStr.value?.toDoubleOrNull() ?: 0.0
bean.whsCharge = whsChargeStr.value?.toDoubleOrNull() ?: 0.0
bean.drawBillCharge = drawBillChargeStr.value?.toDoubleOrNull() ?: 0.0
bean.svlCharge = svlChargeStr.value?.toDoubleOrNull() ?: 0.0
bean.tallyCharge = tallyChargeStr.value?.toDoubleOrNull() ?: 0.0
bean.pipFee = pipFeeStr.value?.toDoubleOrNull() ?: 0.0
bean.lapFee = lapFeeStr.value?.toDoubleOrNull() ?: 0.0
bean.amount = totalAmountStr.value?.toDoubleOrNull() ?: 0.0
launchLoadingCollect({
NetApply.api.modifyIntImpPickUpCharge(bean.toRequestBody())
}) {
onSuccess = {
showToast("修改成功")
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
getTopActivity().finish()
}
}
}
/**
* 取消
*/
fun cancel() {
getTopActivity().finish()
}
override fun onCleared() {
super.onCleared()
tranChargeStr.removeObserver(totalCalculator)
whsChargeStr.removeObserver(totalCalculator)
drawBillChargeStr.removeObserver(totalCalculator)
svlChargeStr.removeObserver(totalCalculator)
tallyChargeStr.removeObserver(totalCalculator)
pipFeeStr.removeObserver(totalCalculator)
lapFeeStr.removeObserver(totalCalculator)
}
}

View File

@@ -16,9 +16,12 @@ 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.showToast
import com.lukouguoji.module_base.ktx.formatDate
import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.model.ConfirmDialogModel
import com.lukouguoji.module_base.model.ScanModel
import dev.utils.app.info.KeyValue
import dev.utils.common.DateUtils
import kotlinx.coroutines.launch
/**
@@ -27,7 +30,7 @@ import kotlinx.coroutines.launch
class IntImpPickUpDLVViewModel : BasePageViewModel() {
// ========== 搜索条件 ==========
val paymentDateStart = MutableLiveData("") // 缴费日期起
val paymentDateStart = MutableLiveData(DateUtils.getCurrentTime().formatDate()) // 缴费日期起
val paymentDateEnd = MutableLiveData("") // 缴费日期止
val agentCode = MutableLiveData("") // 代理人
val wbNo = MutableLiveData("") // 运单号
@@ -116,6 +119,10 @@ class IntImpPickUpDLVViewModel : BasePageViewModel() {
return
}
ConfirmDialogModel(
message = "确定要将选中的${selectedItems.size}条记录确认出库吗?",
title = "确认出库"
) {
launchLoadingCollect({ NetApply.api.confirmIntImpPickUpDLV(selectedItems.toRequestBody()) }) {
onSuccess = {
showToast("确认出库成功")
@@ -125,6 +132,7 @@ class IntImpPickUpDLVViewModel : BasePageViewModel() {
refresh()
}
}
}.show()
}
/**

View File

@@ -2,41 +2,26 @@ package com.lukouguoji.gjj.viewModel
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.IntImpPickUpRecordBean
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.ktx.launchLoadingCollect
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody
/**
* 国际进港提取详情 ViewModel
*/
class IntImpPickUpRecordDetailsViewModel : BaseViewModel() {
var recordId: Long = 0
val dataBean = MutableLiveData(IntImpPickUpRecordBean())
fun initOnCreated(intent: Intent) {
recordId = intent.getLongExtra(Constant.Key.ID, 0)
if (recordId > 0) {
getData()
val json = intent.getStringExtra(Constant.Key.DATA) ?: ""
if (json.isNotEmpty()) {
dataBean.value = Gson().fromJson(json, IntImpPickUpRecordBean::class.java)
} else {
showToast("参数错误")
getTopActivity().finish()
}
}
private fun getData() {
val params = mapOf("id" to recordId).toRequestBody()
launchLoadingCollect({
NetApply.api.getIntImpPickUpRecordDetails(params)
}) {
onSuccess = {
dataBean.value = it.data ?: IntImpPickUpRecordBean()
}
}
}
}

View File

@@ -18,8 +18,10 @@ 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.ktx.formatDate
import com.lukouguoji.module_base.model.ScanModel
import com.lukouguoji.module_base.util.DictUtils
import dev.utils.common.DateUtils
import dev.utils.app.info.KeyValue
import kotlinx.coroutines.launch
@@ -29,7 +31,7 @@ import kotlinx.coroutines.launch
class IntImpPickUpRecordViewModel : BasePageViewModel() {
// ========== 筛选条件 ==========
val paymentDateStart = MutableLiveData("") // 缴费日期起
val paymentDateStart = MutableLiveData(DateUtils.getCurrentTime().formatDate()) // 缴费日期起
val paymentDateEnd = MutableLiveData("") // 缴费日期止
val agentCode = MutableLiveData("") // 代理人
val spCode = MutableLiveData("") // 特码
@@ -81,7 +83,7 @@ class IntImpPickUpRecordViewModel : BasePageViewModel() {
fun initSpecialCodeList() {
DictUtils.getSpecialCodeList(
flag = 1, // 国际
ieFlag = "I", // 进港
ieFlag = "",
parentcode = ""
) {
spCodeList.value = it
@@ -144,16 +146,16 @@ class IntImpPickUpRecordViewModel : BasePageViewModel() {
*/
override fun getData() {
val filterParams = mapOf(
"paymentDateStart" to paymentDateStart.value?.ifEmpty { null },
"paymentDateEnd" to paymentDateEnd.value?.ifEmpty { null },
"beginDate" to paymentDateStart.value?.ifEmpty { null },
"endDate" to paymentDateEnd.value?.ifEmpty { null },
"agentCode" to agentCode.value?.ifEmpty { null },
"spCode" to spCode.value?.ifEmpty { null },
"wbNo" to wbNo.value?.ifEmpty { null }
)
val listParams = (filterParams + mapOf(
"pageNum" to pageModel.page,
"pageSize" to pageModel.limit
"page" to pageModel.page,
"limit" to pageModel.limit
)).toRequestBody()
val totalParams = filterParams.toRequestBody()

View File

@@ -0,0 +1,124 @@
package com.lukouguoji.gjj.viewModel
import android.content.Intent
import androidx.lifecycle.MutableLiveData
import com.lukouguoji.gjj.fragment.IntImpQueryStorageFragment
import com.lukouguoji.gjj.fragment.IntImpQueryWarehouseFragment
import com.lukouguoji.gjj.fragment.IntImpQueryWaybillFragment
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.ktx.launchLoadingCollect
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody
/**
* 国际进港查询详情-ViewModel
*/
class IntImpQueryDetailsViewModel : BaseViewModel() {
// ==================== 基础数据 ====================
var prefix: String = "" // 运单号前缀
var no: String = "" // 运单号主体
// ==================== Tab管理 ====================
val currentTab = MutableLiveData(0) // 当前Tab索引 (0/1/2)
// ==================== 详情数据 ====================
val detailData = MutableLiveData<Map<String, Any>>(emptyMap())
// 运单信息 (maWb)
val maWbData = MutableLiveData<Map<String, Any>>(emptyMap())
// 仓库列表 (warehouseList)
val warehouseList = MutableLiveData<List<Map<String, Any>>>(emptyList())
// 库位列表 (storageUseList)
val storageUseList = MutableLiveData<List<Map<String, Any>>>(emptyList())
// ==================== Fragment列表 ====================
val fragmentList by lazy {
listOf(
IntImpQueryWaybillFragment.newInstance(this), // 运单信息
IntImpQueryWarehouseFragment.newInstance(this), // 仓库信息
IntImpQueryStorageFragment.newInstance(this) // 库位信息
)
}
// ==================== 方法区 ====================
/**
* 初始化(从Intent获取maWbId)
*/
fun initOnCreated(intent: Intent) {
prefix = intent.getStringExtra("prefix") ?: ""
no = intent.getStringExtra("no") ?: ""
}
/**
* Tab点击事件
*/
fun onTabClick(index: Int) {
currentTab.value = index
}
/**
* 加载详情数据
*/
fun loadDetails() {
if (prefix.isEmpty() || no.isEmpty()) {
showToast("运单号参数为空")
return
}
val params = mapOf("prefix" to prefix, "no" to no).toRequestBody()
launchLoadingCollect({ NetApply.api.getIntImpQueryDetails(params) }) {
onSuccess = { result ->
val data = result.data ?: emptyMap()
detailData.value = data
// 解析 maWb 对象
@Suppress("UNCHECKED_CAST")
val maWb = data["maWb"] as? Map<String, Any> ?: emptyMap()
// 合并数据并添加组合字段
val mergedData = mutableMapOf<String, Any>()
mergedData.putAll(maWb)
// 添加组合字段: wbNo = prefix + no
val prefix = maWb["prefix"] as? String ?: ""
val no = maWb["no"] as? String ?: ""
if (prefix.isNotEmpty() || no.isNotEmpty()) {
mergedData["wbNo"] = "$prefix$no"
}
// 锁定状态转中文
val lockState = maWb["lockState"]
if (lockState != null) {
val lockStateInt = when (lockState) {
is Double -> lockState.toInt()
is Int -> lockState
else -> null
}
mergedData["lockStateText"] = when (lockStateInt) {
0 -> "未锁定"
1 -> "已锁定"
else -> ""
}
}
maWbData.value = mergedData
// 解析 warehouseList 列表
@Suppress("UNCHECKED_CAST")
val whList = data["warehouseList"] as? List<Map<String, Any>> ?: emptyList()
warehouseList.value = whList
// 解析 storageUseList 列表
@Suppress("UNCHECKED_CAST")
val suList = data["storageUseList"] as? List<Map<String, Any>> ?: emptyList()
storageUseList.value = suList
}
}
}
}

View File

@@ -0,0 +1,368 @@
package com.lukouguoji.gjj.viewModel
import android.content.Intent
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.google.gson.Gson
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.IntImpQueryEditBean
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.ktx.launchCollect
import com.lukouguoji.module_base.ktx.launchLoadingCollect
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody
import dev.utils.app.info.KeyValue
import kotlinx.coroutines.launch
/**
* 国际进港运单修改 ViewModel
*/
class IntImpQueryEditViewModel : BaseViewModel() {
// 数据Bean
val dataBean = MutableLiveData(IntImpQueryEditBean())
// 运单标识
var maWbId: Long = 0
var prefix: String = ""
var no: String = ""
// ==================== 下拉列表 ====================
val agentList = MutableLiveData<List<KeyValue>>(emptyList())
val spCodeList = MutableLiveData<List<KeyValue>>(emptyList())
val packageTypeList = MutableLiveData<List<KeyValue>>(emptyList())
val waybillTypeList = MutableLiveData<List<KeyValue>>(emptyList())
val lockStateList = MutableLiveData(
listOf(
KeyValue("未锁", "0"),
KeyValue("锁定", "1")
)
)
/**
* 初始化数据
*/
fun initOnCreated(intent: Intent) {
maWbId = intent.getLongExtra("maWbId", 0L)
prefix = intent.getStringExtra("prefix") ?: ""
no = intent.getStringExtra("no") ?: ""
if (prefix.isEmpty() || no.isEmpty()) {
showToast("运单号参数为空")
getTopActivity().finish()
return
}
// 加载下拉列表
loadAgentList()
loadSpCodeList()
loadPackageTypeList()
loadWaybillTypeList()
// 加载详情
loadDetails()
}
/**
* 加载代理人下拉列表
*/
private fun loadAgentList() {
launchCollect({ NetApply.api.getIntImpAgentList() }) {
onSuccess = { result ->
val list = result.data?.mapNotNull { bean ->
if (bean.name != null && bean.code != null) {
KeyValue(bean.name, bean.code)
} else null
} ?: emptyList()
agentList.value = list
// 详情已加载时匹配代理人
matchAgent()
}
}
}
/**
* 加载特码下拉列表
* flag=1国际, ieFlag=I进港
*/
private fun loadSpCodeList() {
launchCollect({ NetApply.api.getSpecialCodeList(1, "", "") }) {
onSuccess = { result ->
val list = result.data?.mapNotNull { bean ->
if (bean.name != null && bean.code != null) {
KeyValue(bean.name, bean.code)
} else null
} ?: emptyList()
spCodeList.value = list
matchSpCode()
}
}
}
/**
* 加载包装类型下拉列表(国际进港专用)
*/
private fun loadPackageTypeList() {
launchCollect({ NetApply.api.getGjjPackTypeList() }) {
onSuccess = { result ->
val list = result.data?.mapNotNull { bean ->
if (bean.packageName.isNotEmpty()) {
KeyValue(bean.packageName, bean.packageName)
} else null
} ?: emptyList()
packageTypeList.value = list
matchPackageType()
}
}
}
/**
* 加载运单类型下拉列表
* type=II国际进港
*/
private fun loadWaybillTypeList() {
launchCollect({ NetApply.api.getWaybillTypeList("II") }) {
onSuccess = { result ->
val list = result.data?.mapNotNull { bean ->
if (bean.name != null && bean.code != null) {
KeyValue(bean.name, bean.code)
} else null
} ?: emptyList()
waybillTypeList.value = list
matchWaybillType()
}
}
}
/**
* 加载运单详情数据
*/
private fun loadDetails() {
val params = mapOf("prefix" to prefix, "no" to no).toRequestBody()
launchLoadingCollect({ NetApply.api.getIntImpQueryDetails(params) }) {
onSuccess = { result ->
val data = result.data ?: emptyMap()
// 提取 maWb 对象
val maWb = data["maWb"] as? Map<String, Any> ?: emptyMap()
// 提取 maWbM 对象
val maWbM = data["maWbM"] as? Map<String, Any> ?: emptyMap()
// 提取 warehouseList用于计算入库件数和入库重量
val warehouseList = data["warehouseList"] as? List<Map<String, Any>> ?: emptyList()
// 合并数据
val mergedData = mutableMapOf<String, Any>()
mergedData.putAll(maWb)
mergedData.putAll(maWbM)
// 运单号: 组合 prefix + no
val prefix = maWb["prefix"] as? String ?: ""
val no = maWb["no"] as? String ?: ""
if (prefix.isNotEmpty() && no.isNotEmpty()) {
mergedData["wbNo"] = "$prefix$no"
}
// 代理人名称
if (!mergedData.containsKey("agentName") || (mergedData["agentName"] as? String).isNullOrEmpty()) {
maWb["agentCode"]?.let { mergedData["agentName"] = it }
}
// 运单件数/重量映射
val pc = maWb["pc"]
when (pc) {
is Number -> mergedData["awbPc"] = pc.toLong()
is String -> mergedData["awbPc"] = pc.toLongOrNull() ?: 0L
}
val weight = maWb["weight"]
when (weight) {
is Number -> mergedData["awbWeight"] = weight.toDouble()
is String -> mergedData["awbWeight"] = weight.toDoubleOrNull() ?: 0.0
}
// 入库件数和入库重量: 从 warehouseList 计算总和
if (warehouseList.isNotEmpty()) {
var totalPc = 0L
var totalWeight = 0.0
warehouseList.forEach { warehouse ->
val wPc = warehouse["pc"]
when (wPc) {
is Number -> totalPc += wPc.toLong()
is String -> totalPc += wPc.toLongOrNull() ?: 0L
}
val wWeight = warehouse["weight"]
when (wWeight) {
is Number -> totalWeight += wWeight.toDouble()
is String -> totalWeight += wWeight.toDoubleOrNull() ?: 0.0
}
}
mergedData["inPc"] = totalPc
mergedData["inWeight"] = totalWeight
}
// lockState 转换为 StringSPINNER 绑定用)
val lockState = mergedData["lockState"]
when (lockState) {
is Number -> mergedData["lockState"] = lockState.toInt().toString()
is String -> mergedData["lockState"] = lockState
}
// 转换为 Bean
val bean = Gson().fromJson(Gson().toJson(mergedData), IntImpQueryEditBean::class.java)
// 匹配下拉列表
matchAgent(bean)
matchSpCode(bean)
matchPackageType(bean)
matchWaybillType(bean)
matchLockState(bean)
dataBean.value = bean
}
}
}
/**
* 匹配代理人
*/
private fun matchAgent(bean: IntImpQueryEditBean? = dataBean.value) {
bean ?: return
val currentCode = bean.agentCode
if (currentCode.isNullOrEmpty()) return
val list = agentList.value ?: return
if (list.isEmpty()) return
val match = list.find { it.value == currentCode }
if (match != null) {
bean.agentName = match.key
bean.agentCode = match.value
}
}
/**
* 匹配特码
*/
private fun matchSpCode(bean: IntImpQueryEditBean? = dataBean.value) {
bean ?: return
val currentCode = bean.spCode
if (currentCode.isNullOrEmpty()) return
val list = spCodeList.value ?: return
if (list.isEmpty()) return
val match = list.find { it.value == currentCode }
if (match != null) {
bean.spCode = match.value
}
}
/**
* 匹配包装类型
*/
private fun matchPackageType(bean: IntImpQueryEditBean? = dataBean.value) {
bean ?: return
val currentType = bean.packageType
if (currentType.isNullOrEmpty()) return
val list = packageTypeList.value ?: return
if (list.isEmpty()) return
val match = list.find { it.value?.contains(currentType) == true }
if (match != null) {
bean.packageType = match.value
}
}
/**
* 匹配运单类型
*/
private fun matchWaybillType(bean: IntImpQueryEditBean? = dataBean.value) {
bean ?: return
val currentCode = bean.awbType
if (currentCode.isNullOrEmpty()) return
val list = waybillTypeList.value ?: return
if (list.isEmpty()) return
val match = list.find { it.value == currentCode }
if (match != null) {
bean.awbType = match.value
}
}
/**
* 匹配锁定状态
*/
private fun matchLockState(bean: IntImpQueryEditBean? = dataBean.value) {
bean ?: return
val currentState = bean.lockState
if (currentState.isNullOrEmpty()) return
val list = lockStateList.value ?: return
val match = list.find { it.value == currentState }
if (match != null) {
bean.lockState = match.value
}
}
/**
* 保存修改
*/
fun submit() {
val bean = dataBean.value ?: return
// 构建提交数据(只提交需要的字段)
val submitData = mutableMapOf<String, Any?>()
submitData["maWbId"] = if (maWbId != 0L) maWbId else bean.maWbId
submitData["activeId"] = bean.activeId
submitData["prefix"] = bean.prefix
submitData["no"] = bean.no
submitData["wbNo"] = bean.wbNo
submitData["agentCode"] = bean.agentCode
submitData["spCode"] = bean.spCode
submitData["packageType"] = bean.packageType
submitData["awbType"] = bean.awbType
submitData["lockState"] = bean.lockState?.toIntOrNull()
submitData["remark"] = bean.remark
submitData["fno"] = bean.fno
submitData["fdate"] = bean.fdate
submitData["flight"] = bean.flight
submitData["pc"] = bean.pc
submitData["weight"] = bean.weight
submitData["volume"] = bean.volume
submitData["origin"] = bean.origin
submitData["dest"] = bean.dest
submitData["range"] = bean.range
submitData["goods"] = bean.goods
submitData["goodsCn"] = bean.goodsCn
submitData["cargoType"] = bean.cargoType
submitData["by1"] = bean.by1
submitData["subCode"] = bean.subCode
submitData["cashWeight"] = bean.cashWeight
submitData["unNumber"] = bean.unNumber
submitData["businessType"] = bean.businessType
submitData["carId"] = bean.carId
launchLoadingCollect({
NetApply.api.modifyIntImpMaWb(submitData.toRequestBody())
}) {
onSuccess = {
showToast("修改成功")
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
getTopActivity().finish()
}
}
}
/**
* 取消
*/
fun cancel() {
getTopActivity().finish()
}
}

View File

@@ -4,16 +4,22 @@ import android.app.Activity
import android.content.Intent
import androidx.lifecycle.MutableLiveData
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.activity.IntImpQueryEditActivity
import com.lukouguoji.gjj.dialog.IntImpQueryFilterDialogModel
import com.lukouguoji.gjj.holder.IntImpQueryViewHolder
import com.lukouguoji.gjj.activity.IntImpQueryDetailsActivity
import com.lukouguoji.module_base.base.BasePageViewModel
import com.lukouguoji.module_base.bean.IntImpQueryBean
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.http.net.NetApply
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.showToast
import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.model.ScanModel
import com.lukouguoji.module_base.util.DictUtils
import dev.utils.app.info.KeyValue
import dev.utils.common.DateUtils
import com.lukouguoji.module_base.ktx.formatDate
@@ -21,7 +27,7 @@ import com.lukouguoji.module_base.ktx.formatDate
/**
* 国际进港查询ViewModel
*/
class IntImpQueryViewModel : BasePageViewModel() {
class IntImpQueryViewModel : BasePageViewModel(), IOnItemClickListener {
// ==================== 搜索条件 ====================
val flightDateStart = MutableLiveData<String>(DateUtils.getCurrentTime().formatDate())
@@ -50,6 +56,9 @@ class IntImpQueryViewModel : BasePageViewModel() {
val totalPc = MutableLiveData("0")
val totalWeight = MutableLiveData("0")
// ==================== 特码下拉 ====================
val spCodeList = MutableLiveData<List<KeyValue>>(emptyList())
// ==================== 筛选条件 ====================
val spCode = MutableLiveData("")
val flightNo = MutableLiveData("")
@@ -73,6 +82,7 @@ class IntImpQueryViewModel : BasePageViewModel() {
fun filterClick() {
val filterDialog = IntImpQueryFilterDialogModel(
spCode = spCode,
spCodeList = spCodeList,
flightNo = flightNo,
dest = dest,
awbType = awbType,
@@ -85,8 +95,8 @@ class IntImpQueryViewModel : BasePageViewModel() {
override fun getData() {
val listParams = mapOf(
"pageNum" to pageModel.page,
"pageSize" to pageModel.limit,
"page" to pageModel.page,
"limit" to pageModel.limit,
"beginDate" to flightDateStart.value!!.ifEmpty { null },
"endDate" to flightDateEnd.value!!.ifEmpty { null },
"agentCode" to agentId.value!!.ifEmpty { null },
@@ -145,6 +155,32 @@ class IntImpQueryViewModel : BasePageViewModel() {
}
}
override fun onItemClick(position: Int, type: Int) {
val list = pageModel.rv?.commonAdapter()?.items as? List<IntImpQueryBean> ?: return
val bean = list.getOrNull(position) ?: return
when (type) {
2000 -> {
// 侧滑菜单 - 修改操作
IntImpQueryEditActivity.start(getTopActivity(), bean.maWbId, bean.prefix, bean.no)
}
else -> {
// 默认点击 - 进入详情
IntImpQueryDetailsActivity.start(getTopActivity(), bean.prefix, bean.no)
}
}
}
fun initSpecialCodeList() {
DictUtils.getSpecialCodeList(
flag = 1,
ieFlag = "",
parentcode = ""
) {
spCodeList.value = it
}
}
fun initAgentList() {
launchCollect({
NetApply.api.getIntImpAgentList()

View File

@@ -124,12 +124,9 @@ class IntImpStorageUseViewModel : BasePageViewModel() {
return
}
val params = mapOf(
"clearNormal" to clearNormal,
"maWbList" to maWbListForClear
).toRequestBody()
val body = maWbListForClear.toRequestBody()
launchLoadingCollect({ NetApply.api.clearIntImpStorage(params) }) {
launchLoadingCollect({ NetApply.api.clearIntImpStorage(clearNormal, body) }) {
onSuccess = {
showToast("清仓成功")
viewModelScope.launch {
@@ -188,13 +185,13 @@ class IntImpStorageUseViewModel : BasePageViewModel() {
/**
* 执行出库操作
*/
fun performOutStorage(selectedStorageList: List<com.lukouguoji.module_base.bean.GjcStorageUse>) {
if (selectedStorageList.isEmpty()) {
fun performOutStorage(maWbListForOutStorage: List<GjcMaWb>) {
if (maWbListForOutStorage.isEmpty()) {
showToast("请选择要出库的库位")
return
}
val params = selectedStorageList.toRequestBody()
val params = maWbListForOutStorage.toRequestBody()
launchLoadingCollect({ NetApply.api.outIntImpStorage(params) }) {
onSuccess = {
@@ -232,13 +229,9 @@ class IntImpStorageUseViewModel : BasePageViewModel() {
return
}
val params = mapOf(
"location" to locationName,
"locationId" to locationId.toLongOrNull(),
"maWbList" to maWbListForInStorage
).toRequestBody()
val body = maWbListForInStorage.toRequestBody()
launchLoadingCollect({ NetApply.api.inIntImpStorage(params) }) {
launchLoadingCollect({ NetApply.api.inIntImpStorage(locationName, body) }) {
onSuccess = {
showToast("入库成功")
viewModelScope.launch {
@@ -257,7 +250,8 @@ class IntImpStorageUseViewModel : BasePageViewModel() {
"fdate" to flightDate.value?.ifEmpty { null },
"fno" to flightNo.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 }
)
val listParams = (filterParams + mapOf(

View File

@@ -0,0 +1,26 @@
package com.lukouguoji.gjj.viewModel
import android.content.Intent
import androidx.lifecycle.MutableLiveData
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.GjjImportTally
import com.lukouguoji.module_base.common.Constant
/**
* 国际进港理货报告详情 ViewModel
*/
class IntImpTallyDetailsViewModel : BaseViewModel() {
// 理货数据
val dataBean = MutableLiveData(GjjImportTally())
/**
* 初始化数据(从列表项携带的数据)
*/
fun initOnCreated(intent: Intent) {
val tally = intent.getSerializableExtra(Constant.Key.DATA) as? GjjImportTally
if (tally != null) {
dataBean.value = tally
}
}
}

View File

@@ -3,10 +3,13 @@ package com.lukouguoji.gjj.viewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.dialog.IntImpTallyDeleteDialogModel
import com.lukouguoji.gjj.dialog.IntImpTallyResetDialogModel
import dev.utils.common.DateUtils
import com.lukouguoji.module_base.ktx.formatDate
import com.lukouguoji.gjj.holder.IntImpTallyViewHolder
import com.lukouguoji.module_base.base.BasePageViewModel
import com.lukouguoji.module_base.bean.GjjDeclareParam
import com.lukouguoji.module_base.bean.GjjImportTally
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent
@@ -40,10 +43,13 @@ class IntImpTallyViewModel : BasePageViewModel() {
val isAllChecked = MutableLiveData(false)
init {
// 监听全选状态,自动更新所有列表项
// 监听全选状态,自动更新所有列表项(联动子列表)
isAllChecked.observeForever { checked ->
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjImportTally> ?: return@observeForever
list.forEach { it.checked.set(checked) }
list.forEach {
it.checked.set(checked)
it.haWbList?.forEach { sub -> sub.checked.set(checked) }
}
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
}
}
@@ -65,9 +71,12 @@ class IntImpTallyViewModel : BasePageViewModel() {
fun checkAllClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjImportTally> ?: return
// 切换全选状态
// 切换全选状态(联动子列表)
val shouldCheckAll = !isAllChecked.value!!
list.forEach { it.checked.set(shouldCheckAll) }
list.forEach {
it.checked.set(shouldCheckAll)
it.haWbList?.forEach { sub -> sub.checked.set(shouldCheckAll) }
}
isAllChecked.value = shouldCheckAll
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
@@ -88,63 +97,158 @@ class IntImpTallyViewModel : BasePageViewModel() {
}
/**
* 人工放行(暂不实现)
* 收集选中的主单和分单
*/
private fun getSelectedData(): Pair<List<GjjImportTally>, List<GjjImportTally>> {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjImportTally>
?: return Pair(emptyList(), emptyList())
val selectedMaWb = list.filter { it.isSelected }
val selectedHaWb = mutableListOf<GjjImportTally>()
list.forEach { maWb ->
maWb.haWbList?.forEach { haWb ->
if (haWb.isSelected) selectedHaWb.add(haWb)
}
}
return Pair(selectedMaWb, selectedHaWb)
}
/**
* 人工放行
*/
fun manualReleaseClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjImportTally> ?: return
val selectedItems = list.filter { it.isSelected }
val (selectedMaWb, selectedHaWb) = getSelectedData()
if (selectedItems.isEmpty()) {
if (selectedMaWb.isEmpty() && selectedHaWb.isEmpty()) {
showToast("请选择要放行的记录")
return
}
showToast("人工放行功能开发中")
val param = GjjDeclareParam(
mtallyList = if (selectedMaWb.isNotEmpty()) selectedMaWb else null,
htallyList = if (selectedHaWb.isNotEmpty()) selectedHaWb else null
)
launchLoadingCollect({ NetApply.api.intImpTallyCustomCommand(param.toRequestBody()) }) {
onSuccess = {
showToast("人工放行成功")
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
refresh()
}
}
}
/**
* 状态重置(暂不实现)
* 状态重置
*/
fun statusResetClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjImportTally> ?: return
val selectedItems = list.filter { it.isSelected }
val (selectedMaWb, selectedHaWb) = getSelectedData()
if (selectedItems.isEmpty()) {
if (selectedMaWb.isEmpty() && selectedHaWb.isEmpty()) {
showToast("请选择要重置的记录")
return
}
showToast("状态重置功能开发中")
val dialog = IntImpTallyResetDialogModel { dialogModel ->
val param = GjjDeclareParam(
mtallyList = if (selectedMaWb.isNotEmpty()) selectedMaWb else null,
htallyList = if (selectedHaWb.isNotEmpty()) selectedHaWb else null,
restStatus = dialogModel.resetStatusCode
)
launchLoadingCollect({ NetApply.api.intImpTallyResetDeclare(param.toRequestBody()) }) {
onSuccess = {
showToast("状态重置成功")
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
refresh()
}
}
}
dialog.show()
}
/**
* 删除理货(暂不实现)
* 删除理货
*/
fun deleteTallyClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjImportTally> ?: return
val selectedItems = list.filter { it.isSelected }
val (selectedMaWb, selectedHaWb) = getSelectedData()
if (selectedItems.isEmpty()) {
if (selectedMaWb.isEmpty() && selectedHaWb.isEmpty()) {
showToast("请选择要删除的记录")
return
}
showToast("删除理货功能开发中")
// 校验所选单据状态是否为 01已申报
val invalidMaWb = selectedMaWb.firstOrNull { it.status != "01" }
if (invalidMaWb != null) {
showToast("运单 ${invalidMaWb.getWaybillNo()} 理货未申报,不允许删除理货")
return
}
val invalidHaWb = selectedHaWb.firstOrNull { it.status != "01" }
if (invalidHaWb != null) {
showToast("运单 ${invalidHaWb.getWaybillNo()} 理货未申报,不允许删除理货")
return
}
// 从接口获取删除原因列表
launchLoadingCollect({ NetApply.api.getDelReasonList() }) {
onSuccess = { result ->
val changeReasonList = result.data?.map { it.toKeyValue() } ?: emptyList()
val dialog = IntImpTallyDeleteDialogModel(changeReasonList) { dialogModel ->
val param = GjjDeclareParam(
dcode = dialogModel.changeReason.value ?: "",
dcontactsName = dialogModel.contactName.value ?: "",
dcontactsTel = dialogModel.contactPhone.value ?: "",
mtallyList = if (selectedMaWb.isNotEmpty()) selectedMaWb else null,
htallyList = if (selectedHaWb.isNotEmpty()) selectedHaWb else null
)
launchLoadingCollect({ NetApply.api.intImpTallyDeleteDeclare(param.toRequestBody()) }) {
onSuccess = {
showToast("删除申报成功")
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
refresh()
}
}
}
dialog.show()
}
}
}
/**
* 理货申报(暂不实现)
* 理货申报
*/
fun tallyDeclareClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjImportTally> ?: return
val selectedItems = list.filter { it.isSelected }
val (selectedMaWb, selectedHaWb) = getSelectedData()
if (selectedItems.isEmpty()) {
if (selectedMaWb.isEmpty() && selectedHaWb.isEmpty()) {
showToast("请选择要申报的记录")
return
}
showToast("理货申报功能开发中")
val param = GjjDeclareParam(
mtallyList = if (selectedMaWb.isNotEmpty()) selectedMaWb else null,
htallyList = if (selectedHaWb.isNotEmpty()) selectedHaWb else null
)
launchLoadingCollect({ NetApply.api.intImpTallyDeclare(param.toRequestBody()) }) {
onSuccess = {
showToast("理货申报成功")
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
refresh()
}
}
}
/**

View File

@@ -44,16 +44,17 @@
android:orientation="vertical"
android:padding="8dp">
<!-- 第1行航班日期、航班号、航程全部禁止编辑 -->
<!-- 第1行航班日期、航班号、航程新增可编辑,编辑禁止 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
enable="@{viewModel.pageType == DetailsPageType.Add}"
hint='@{"请选择航班日期"}'
required="@{false}"
setRefreshCallBack="@{viewModel::onFlightDateInputComplete}"
title='@{"航班日期"}'
titleLength="@{5}"
type="@{DataLayoutType.DATE}"
@@ -63,9 +64,11 @@
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
android:id="@+id/flightNoInput"
enable="@{viewModel.pageType == DetailsPageType.Add}"
hint='@{"请输入航班号"}'
required="@{false}"
setRefreshCallBack="@{viewModel::onFlightNoInputComplete}"
title='@{"航 班 号"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
@@ -77,12 +80,12 @@
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
hint='@{"请输入航程"}'
hint='@{"自动填充"}'
required="@{false}"
title='@{"航 程"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.range}'
value='@{viewModel.range}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
@@ -90,7 +93,7 @@
</LinearLayout>
<!-- 第2行运单号禁止编辑)、代理、特码 -->
<!-- 第2行运单号新增可编辑,编辑禁止)、代理、特码 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -98,7 +101,7 @@
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
enable="@{viewModel.pageType == DetailsPageType.Add}"
hint='@{"请输入运单号"}'
required="@{false}"
title='@{"运 单 号"}'

View File

@@ -49,8 +49,9 @@
value="@={viewModel.flightNo}"
setUpperCaseAlphanumeric="@{true}" />
<!-- 运单号 (带扫码) -->
<!-- 运单号 (带扫码+自动查询) -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
android:id="@+id/psl_waybill_no"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
@@ -58,7 +59,13 @@
icon="@{@drawable/img_scan}"
setOnIconClickListener="@{(v)-> viewModel.scanWaybill()}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.waybillNo}" />
value="@={viewModel.waybillNo}"
autoQueryEnabled="@{true}"
autoQueryUrl="@{`/IntImpAirManifest/queryWbNoList`}"
autoQueryParamKey="@{`wbNo`}"
autoQueryMinLength="@{4}"
autoQueryMaxLength="@{8}"
autoQueryTitle="@{`选择运单号`}" />
<!-- 分单号 (带扫码) -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout

View File

@@ -61,10 +61,10 @@
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"特码"}'
title='@{"航班信息"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.spCode}'
value='@{viewModel.dataBean.getFlightSplit()}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
@@ -132,7 +132,7 @@
title='@{"品名(中)"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.goodsCn}'
value='@{viewModel.dataBean.goodsCn != null &amp;&amp; !viewModel.dataBean.goodsCn.isEmpty() ? viewModel.dataBean.goodsCn : viewModel.dataBean.goods}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />

View File

@@ -59,6 +59,7 @@
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入名称"}'
required="@{true}"
title='@{"名称"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
@@ -71,6 +72,7 @@
enable="@{true}"
hint='@{"请选择国家代码"}'
list="@{viewModel.countryCodeList}"
required="@{true}"
title='@{"国家代码"}'
titleLength="@{5}"
type="@{DataLayoutType.SPINNER}"
@@ -83,6 +85,7 @@
enable="@{true}"
hint='@{"请选择通讯方式"}'
list="@{viewModel.comTypeList}"
required="@{true}"
title='@{"通讯方式"}'
titleLength="@{5}"
type="@{DataLayoutType.SPINNER}"
@@ -103,6 +106,7 @@
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入联系号码"}'
required="@{true}"
title='@{"联系号码"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
@@ -154,6 +158,7 @@
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入名称"}'
required="@{true}"
title='@{"名称"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
@@ -166,6 +171,7 @@
enable="@{true}"
hint='@{"请选择国家代码"}'
list="@{viewModel.countryCodeList}"
required="@{true}"
title='@{"国家代码"}'
titleLength="@{5}"
type="@{DataLayoutType.SPINNER}"
@@ -178,6 +184,7 @@
enable="@{true}"
hint='@{"请选择通讯方式"}'
list="@{viewModel.comTypeList}"
required="@{true}"
title='@{"通讯方式"}'
titleLength="@{5}"
type="@{DataLayoutType.SPINNER}"
@@ -198,6 +205,7 @@
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入联系号码"}'
required="@{true}"
title='@{"联系号码"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"

View File

@@ -99,18 +99,18 @@
android:src="@drawable/img_search" />
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="8dp"
android:padding="2dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="16dp"
android:onClick="@{()-> viewModel.addClick()}"
android:src="@drawable/img_add" />
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginStart="8dp"
android:layout_marginLeft="16dp"
android:onClick="@{()-> viewModel.deleteClick()}"
android:padding="2dp"
android:padding="4dp"
android:src="@drawable/img_delete" />
</LinearLayout>

View File

@@ -0,0 +1,363 @@
<?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.data.layout.DataLayoutType" />
<import type="com.lukouguoji.module_base.common.DetailsPageType" />
<variable
name="viewModel"
type="com.lukouguoji.gjj.viewModel.IntImpAccidentVisaEditViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_f2"
android:orientation="vertical">
<include layout="@layout/title_tool_bar" />
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_8"
android:orientation="vertical"
android:padding="15dp">
<!-- Row 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="@{true}"
hint='@{"请选择航班日期"}'
setRefreshCallBack="@{viewModel::onFlightDateInputComplete}"
title='@{"航班日期"}'
titleLength="@{6}"
type="@{DataLayoutType.DATE}"
value='@={viewModel.dataBean.fdate}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入航班号"}'
setRefreshCallBack="@{viewModel::onFlightNoInputComplete}"
title='@{"航班号"}'
titleLength="@{6}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.dataBean.fno}' />
</LinearLayout>
<!-- Row 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="@{6}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.dep}' />
<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="@{6}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.dest}' />
</LinearLayout>
<!-- Row 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="@{true}"
hint='@{"请输入运单号"}'
title='@{"运单号"}'
titleLength="@{6}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.dataBean.wbNo}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入不正常件数"}'
title='@{"不正常件数"}'
titleLength="@{6}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.dataBean.dpc}' />
</LinearLayout>
<!-- Row 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="@{true}"
hint='@{"请输入运单总件数"}'
title='@{"运单总件数"}'
titleLength="@{6}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.dataBean.pc}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入运单总重量"}'
title='@{"运单总重量"}'
titleLength="@{6}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.dataBean.weight}' />
</LinearLayout>
<!-- Row 5: 复称重量 | 品名 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入复称重量"}'
title='@{"复称重量"}'
titleLength="@{6}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.dataBean.reweight}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入品名"}'
title='@{"品名"}'
titleLength="@{6}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.dataBean.goods}' />
</LinearLayout>
<!-- Row 6: 外包装 | 包装破损情况 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
hint='@{"请选择外包装"}'
list="@{viewModel.outerPackageList}"
title='@{"外包装"}'
titleLength="@{6}"
type="@{DataLayoutType.SPINNER}"
value='@={viewModel.dataBean.opacking}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
hint='@{"请选择破损情况"}'
list="@{viewModel.damageTypeList}"
title='@{"包装破损情况"}'
titleLength="@{6}"
type="@{DataLayoutType.SPINNER}"
value='@={viewModel.dataBean.damage}' />
</LinearLayout>
<!-- Row 7: 内容物情况 | 不正常类型 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
hint='@{"请选择内容物情况"}'
list="@{viewModel.contentTypeList}"
title='@{"内容物情况"}'
titleLength="@{6}"
type="@{DataLayoutType.SPINNER}"
value='@={viewModel.dataBean.condition}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
hint='@{"请选择不正常类型"}'
list="@{viewModel.unusualTypeList}"
title='@{"不正常类型"}'
titleLength="@{6}"
type="@{DataLayoutType.SPINNER}"
value='@={viewModel.dataBean.problem}' />
</LinearLayout>
<!-- Row 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="@{true}"
hint='@{"请选择发现时间"}'
title='@{"发现时间"}'
titleLength="@{6}"
type="@{DataLayoutType.DATE}"
value='@={viewModel.dataBean.seachDate}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
hint='@{"请选择"}'
list="@{viewModel.photoList}"
title='@{"图片是否留底"}'
titleLength="@{6}"
type="@{DataLayoutType.SPINNER}"
value='@={viewModel.dataBean.photo}' />
</LinearLayout>
<!-- Row 9: 备注(整行) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="match_parent"
android:layout_height="wrap_content"
enable="@{true}"
hint='@{"请输入备注"}'
inputHeight="@{80}"
title='@{"备注"}'
titleLength="@{6}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.dataBean.remarks}' />
</LinearLayout>
</LinearLayout>
<!-- 上传图像区域 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="上传图像"
android:textColor="@color/text_normal"
android:textSize="16sp"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="4"
tools:listitem="@layout/item_image_select" />
<!-- 底部按钮 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginBottom="15dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
style="@style/tv_bottom_btn"
android:layout_width="120dp"
android:onClick="@{()-> viewModel.onCancelClick()}"
android:text="取消" />
<TextView
style="@style/tv_bottom_btn"
android:layout_width="120dp"
android:layout_marginLeft="20dp"
android:onClick="@{()-> viewModel.onSaveClick()}"
android:text="保存" />
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
</layout>

View File

@@ -77,11 +77,18 @@
<!-- 运单号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
android:id="@+id/psl_waybill_no"
hint='@{"请输入运单号"}'
icon="@{@drawable/img_scan}"
setOnIconClickListener="@{(v)-> viewModel.scanWaybill()}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.waybillNo}"
autoQueryEnabled="@{true}"
autoQueryUrl="@{`/IntImpManifest/pageQueryAirWbNoList`}"
autoQueryParamKey="@{`wbNo`}"
autoQueryMinLength="@{4}"
autoQueryMaxLength="@{8}"
autoQueryTitle="@{`选择运单号`}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />

View File

@@ -0,0 +1,216 @@
<?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="com.lukouguoji.module_base.ui.weight.data.layout.DataLayoutType" />
<variable
name="viewModel"
type="com.lukouguoji.gjj.viewModel.IntImpLoadingListEditViewModel" />
</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" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_8"
android:orientation="vertical"
android:padding="15dp">
<!-- 第一行运单号、始发站、ULD编号只读 -->
<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='@{viewModel.dataBean.getWaybillNo()}' />
<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.dataBean.origin}' />
<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='@{"ULD编号"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.ref}' />
</LinearLayout>
<!-- 第二行:品名、代理(只读)、库位号(可编辑) -->
<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.dataBean.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='@{viewModel.dataBean.agentCode}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入库位号"}'
title='@{"库位号"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.location}' />
</LinearLayout>
<!-- 第三行:总件数、件数、重量(可编辑) -->
<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="@{true}"
hint='@{"请输入总件数"}'
title='@{"总件数"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.totalPcStr}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入件数"}'
title='@{"件数"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.pcStr}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入重量"}'
title='@{"重量"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.weightStr}' />
</LinearLayout>
<!-- 第四行:计费重量(可编辑) -->
<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="@{true}"
hint='@{"请输入计费重量"}'
title='@{"计费重量"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.cashWeightStr}' />
<Space
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2" />
</LinearLayout>
</LinearLayout>
<!-- 底部操作按钮 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_marginTop="24dp"
android:gravity="center"
android:paddingHorizontal="15dp">
<TextView
style="@style/tv_bottom_btn"
android:layout_width="120dp"
android:layout_marginEnd="20dp"
android:onClick="@{()-> viewModel.cancel()}"
android:text="取消" />
<TextView
style="@style/tv_bottom_btn"
android:layout_width="120dp"
android:onClick="@{()-> viewModel.submit()}"
android:text="保存" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
</layout>

View File

@@ -6,6 +6,7 @@
<data>
<import type="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType" />
<import type="android.view.View" />
<variable
name="viewModel"
@@ -66,18 +67,25 @@
hint='@{"目的站"}'
enable="@{false}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.fdep}"
value="@={viewModel.fdest}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<!-- 运单号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
android:id="@+id/psl_waybill_no"
hint='@{"请输入运单号"}'
icon="@{@drawable/img_scan}"
setOnIconClickListener="@{(v)-> viewModel.scanWaybill()}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.waybillNo}"
autoQueryEnabled="@{true}"
autoQueryUrl="@{`/IntImpManifest/pageQueryWbNoList`}"
autoQueryParamKey="@{`wbNo`}"
autoQueryMinLength="@{4}"
autoQueryMaxLength="@{8}"
autoQueryTitle="@{`选择运单号`}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
@@ -101,11 +109,10 @@
<!-- 新增按钮 -->
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginLeft="16dp"
android:onClick="@{()-> viewModel.onAddClick()}"
android:padding="4dp"
android:src="@drawable/img_add" />
<!-- 删除按钮 -->
@@ -152,6 +159,22 @@
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<!-- 分单管理模式 - 返回按钮(列表区域右上方) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:paddingHorizontal="20dp"
android:visibility="@{viewModel.isSubManagementMode ? View.VISIBLE : View.GONE}">
<ImageView
android:layout_width="36dp"
android:layout_height="36dp"
android:onClick="@{()-> viewModel.subManagementBackClick()}"
android:src="@drawable/img_back_action" />
</LinearLayout>
<!-- 底部统计和操作按钮 -->
<LinearLayout
android:layout_width="match_parent"
@@ -222,12 +245,28 @@
</LinearLayout>
<!-- 操作按钮 -->
<!-- 操作按钮 - 默认模式 -->
<TextView
style="@style/tv_bottom_btn"
android:layout_marginEnd="15dp"
android:onClick="@{()-> viewModel.subManagementClick()}"
android:text="分单管理" />
android:text="分单管理"
android:visibility="@{viewModel.isSubManagementMode ? View.GONE : View.VISIBLE}" />
<!-- 操作按钮 - 分单管理模式 -->
<TextView
style="@style/tv_bottom_btn"
android:layout_marginEnd="15dp"
android:onClick="@{()-> viewModel.addSubWaybillClick()}"
android:text="新增分单"
android:visibility="@{viewModel.isSubManagementMode ? View.VISIBLE : View.GONE}" />
<TextView
style="@style/tv_bottom_btn"
android:layout_marginEnd="15dp"
android:onClick="@{()-> viewModel.modifySubWaybillClick()}"
android:text="修改分单"
android:visibility="@{viewModel.isSubManagementMode ? View.VISIBLE : View.GONE}" />
<TextView
style="@style/tv_bottom_btn"

View File

@@ -0,0 +1,293 @@
<?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" />
<variable
name="viewModel"
type="com.lukouguoji.gjj.viewModel.IntImpManifestDetailsViewModel" />
</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" />
<!-- 内容区域 -->
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="10dp">
<!-- 白色圆角卡片 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_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
enable="@{false}"
title='@{"运单号"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.wbNo}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"代理"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.agentName}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"特码"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.spCode}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
<!-- 第2行始发港、目的港、运单类型 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"始发港"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.origin}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"目的港"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.dest}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"运单类型"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.awbTypeName}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
<!-- 第3行总件数、实到件数、实到重量 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"总件数"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{String.valueOf(viewModel.dataBean.totalPc)}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"实到件数"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{String.valueOf(viewModel.dataBean.pc)}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"实到重量"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{String.valueOf(viewModel.dataBean.weight)}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
<!-- 第4行计费重量、品名(中)、品名(英) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"计费重量"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{String.valueOf(viewModel.dataBean.cashWeight)}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"品名(中)"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.goodsCn}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"品名(英)"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.goods}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
<!-- 第5行包装类型、业务类型、UN编号 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"包装类型"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.packageType}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"业务类型"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.businessType}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"UN编号"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.unNumber}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
<!-- 第6行备注全宽 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}"
title='@{"备注"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.remark}'
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<!-- 第7行交接图片预留位置 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="4dp"
android:text="交接图片"
android:textColor="@color/text_gray"
android:textSize="14sp" />
<LinearLayout
android:id="@+id/ll_images"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="14dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:minHeight="80dp"
android:orientation="horizontal">
<!-- 交接图片区域预留,后续对接图片数据 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暂无图片"
android:textColor="@color/text_gray"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
</layout>

View File

@@ -0,0 +1,180 @@
<?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="com.lukouguoji.module_base.common.DetailsPageType" />
<variable
name="viewModel"
type="com.lukouguoji.gjj.viewModel.IntImpManifestSubEditViewModel" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_f2">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/title_tool_bar" />
<!-- 主内容区域 -->
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_8"
android:orientation="vertical"
android:padding="8dp">
<!-- 第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}"
hint='@{"运单号"}'
required="@{false}"
title='@{"运 单 号"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.waybillNo}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_weight="1"
enable="@{false}"
hint='@{"主分校验"}'
required="@{false}"
title='@{"主分校验"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.mainSubCheck}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入分单号"}'
required="@{false}"
title='@{"分 单 号"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.subNo}' />
</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="@{true}"
hint='@{"请输入件数"}'
required="@{false}"
title='@{"件 数"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.pc}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入重量"}'
required="@{false}"
title='@{"重 量"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.weight}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入品名(中)"}'
required="@{false}"
title='@{"品名(中)"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.goodsCn}' />
</LinearLayout>
</LinearLayout>
<!-- 底部操作栏 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:padding="15dp">
<TextView
android:layout_width="150dp"
android:layout_height="50dp"
android:layout_marginEnd="30dp"
android:background="@drawable/bg_primary_radius_4"
android:gravity="center"
android:onClick="@{()-> viewModel.onCancelClick()}"
android:text="取消"
android:textColor="@color/white"
android:textSize="18sp" />
<TextView
android:layout_width="150dp"
android:layout_height="50dp"
android:background="@drawable/bg_primary_radius_4"
android:gravity="center"
android:onClick="@{()-> viewModel.onSaveClick()}"
android:text="保存"
android:textColor="@color/white"
android:textSize="18sp" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
</FrameLayout>
</layout>

View File

@@ -0,0 +1,314 @@
<?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" />
<variable
name="viewModel"
type="com.lukouguoji.gjj.viewModel.IntImpPickUpChargeEditViewModel" />
</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" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_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="@{7}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.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="@{7}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.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="@{7}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.spCode}' />
</LinearLayout>
<!-- 第2行提货编号、件数、重量只读 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
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="@{7}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.pkId}' />
<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="@{7}"
type="@{DataLayoutType.INPUT}"
value='@{String.valueOf(viewModel.dataBean.pc)}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"重量"}'
titleLength="@{7}"
type="@{DataLayoutType.INPUT}"
value='@{String.valueOf(viewModel.dataBean.weight)}' />
</LinearLayout>
<!-- 第3行计费重量只读、信息费可编辑、服务费只读 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
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="@{7}"
type="@{DataLayoutType.INPUT}"
value='@{String.valueOf(viewModel.dataBean.cashWeight)}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入信息费"}'
title='@{"信息费"}'
titleLength="@{7}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.tranChargeStr}' />
<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="@{7}"
type="@{DataLayoutType.INPUT}"
value='@{String.valueOf(viewModel.dataBean.optCharge)}' />
</LinearLayout>
<!-- 第4行仓储费、文件处理费、叉车费可编辑 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
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="@{true}"
hint='@{"请输入仓储费"}'
title='@{"仓储费"}'
titleLength="@{7}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.whsChargeStr}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入文件处理费"}'
title='@{"文件处理费"}'
titleLength="@{7}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.drawBillChargeStr}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入叉车费"}'
title='@{"叉车费"}'
titleLength="@{7}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.svlChargeStr}' />
</LinearLayout>
<!-- 第5行理货费、精密仪器处理费、活体动物处理费可编辑 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
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="@{true}"
hint='@{"请输入理货费"}'
title='@{"理货费"}'
titleLength="@{7}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.tallyChargeStr}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入精密仪器处理费"}'
title='@{"精密仪器处理费"}'
titleLength="@{7}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.pipFeeStr}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{true}"
hint='@{"请输入活体动物处理费"}'
title='@{"活体动物处理费"}'
titleLength="@{7}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.lapFeeStr}' />
</LinearLayout>
<!-- 第6行总费用只读实时计算 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
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="@{7}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.totalAmountStr}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="invisible"
enable="@{false}"
title='@{""}'
titleLength="@{7}"
type="@{DataLayoutType.INPUT}"
value='@{""}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="invisible"
enable="@{false}"
title='@{""}'
titleLength="@{7}"
type="@{DataLayoutType.INPUT}"
value='@{""}' />
</LinearLayout>
</LinearLayout>
<!-- 底部操作按钮 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_marginTop="24dp"
android:gravity="center"
android:paddingHorizontal="15dp">
<TextView
style="@style/tv_bottom_btn"
android:layout_width="120dp"
android:layout_marginEnd="20dp"
android:onClick="@{()-> viewModel.cancel()}"
android:text="取消" />
<TextView
style="@style/tv_bottom_btn"
android:layout_width="120dp"
android:onClick="@{()-> viewModel.submit()}"
android:text="保存" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
</layout>

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