Compare commits

...

36 Commits

Author SHA1 Message Date
ca20d70e8a feat: opt 出港组装 2026-01-30 18:28:25 +08:00
bad565085a feat: opt 开始组装 2026-01-28 17:12:40 +08:00
6ea6833396 feat: optimize home icons 2026-01-28 15:34:20 +08:00
3da68b1eed feat: reorder home icon 2026-01-28 11:14:40 +08:00
e4bf1f1fee feat: fix home icon cache 2026-01-28 10:55:21 +08:00
69812bcc0b feat: some new home icon 2026-01-28 10:44:15 +08:00
65c91a0233 feat: rm useless file 2026-01-27 14:15:44 +08:00
2ed1f06a9d feat: fix print 2026-01-27 14:13:06 +08:00
9eb9278676 feat: opt 开始组装 2026-01-27 14:04:50 +08:00
a7b560b048 feat: button icon 2026-01-27 10:30:58 +08:00
1deca69a67 feat: opt print 2026-01-27 08:39:30 +08:00
8e2f584f3a feat: fix bugs 2026-01-26 16:22:27 +08:00
5e1e9e58a2 feat: fix int exp arrive sub list 2026-01-26 13:43:49 +08:00
5f31cf5274 feat: 出港组装 回填重量 2026-01-26 12:34:01 +08:00
d3ea88db08 feat: fix 国际出港 v2 2026-01-24 17:44:12 +08:00
ff2649e063 feat: fix 国际出港 2026-01-24 17:07:35 +08:00
6b655348e1 feat: 国际出港 出港组装 2026-01-21 13:51:58 +08:00
0f1dbe4e05 feat: 国际出港 出港组装 列表 2026-01-21 11:37:08 +08:00
a3fda12fd8 feat: 国际出港 附件查看 2026-01-21 10:49:03 +08:00
b0b109de9a feat: 国际出港 fix bugs 2026-01-20 18:34:45 +08:00
9a034c1653 feat: 国际出港 出港运抵、理货 状态重置 2026-01-20 12:02:59 +08:00
de8e49389a feat: fix sub rv 2026-01-20 11:19:36 +08:00
a52259f951 feat: 国际出港 出港计重 2026-01-17 21:05:48 +08:00
d6be019c3a feat: 国际出港 出港计重 opt v 2026-01-17 20:40:09 +08:00
80a0983459 feat: 国际出港 出港计重 opt 2026-01-17 19:48:33 +08:00
dbfcdb4a01 feat: 国际出港 板箱过磅 fix v2 2026-01-17 19:10:01 +08:00
672c8308b8 feat: 国际出港 板箱过磅 fix 2026-01-17 18:53:38 +08:00
9a327975bd feat: 国际出港 出港运抵 2026-01-17 18:36:19 +08:00
cd0cd89a66 feat: 国际出港 出港运抵 状态重置 2026-01-17 18:10:53 +08:00
b37f330414 feat: 国际出港 装货交接 待配运 2026-01-17 17:33:04 +08:00
675b9d234e feat: 国际出港 装货卸货 2026-01-17 17:01:47 +08:00
8b00597763 Merge branch 'main' of ssh://git.njcqit.com:2222/eric/aerologic-app 2026-01-17 16:30:33 +08:00
e2f6cdde04 feat: 国际出港 出港仓库 finish 2026-01-17 16:30:29 +08:00
ac4cd63abc feat: opt vfox 2026-01-17 13:26:18 +08:00
7a5e06a5af Merge branch 'main' of ssh://git.njcqit.com:2222/eric/aerologic-app 2026-01-16 20:02:47 +08:00
3eee861486 feat: ops 2026-01-16 20:02:42 +08:00
105 changed files with 3854 additions and 651 deletions

View File

@@ -50,7 +50,9 @@
"Bash(do if ! grep -q \"import com.lukouguoji.module_base.ktx.formatDate\" \"$file\")", "Bash(do if ! grep -q \"import com.lukouguoji.module_base.ktx.formatDate\" \"$file\")",
"Bash(then sed -i '' '/import dev.utils.common.DateUtils/a\\\\\nimport com.lukouguoji.module_base.ktx.formatDate\n' \"$file\" echo \"Added formatDate import to: $file\" fi done)", "Bash(then sed -i '' '/import dev.utils.common.DateUtils/a\\\\\nimport com.lukouguoji.module_base.ktx.formatDate\n' \"$file\" echo \"Added formatDate import to: $file\" fi done)",
"Bash(identify:*)", "Bash(identify:*)",
"WebFetch(domain:github.com)" "WebFetch(domain:github.com)",
"Bash(file:*)",
"Bash(xargs:*)"
], ],
"deny": [], "deny": [],
"ask": [] "ask": []

1
.gitignore vendored
View File

@@ -191,3 +191,4 @@ fabric.properties
!/gradle/wrapper/gradle-wrapper.jar !/gradle/wrapper/gradle-wrapper.jar
# End of https://www.toptal.com/developers/gitignore/api/androidstudio,gradle,java,kotlin # End of https://www.toptal.com/developers/gitignore/api/androidstudio,gradle,java,kotlin
.vfox/

View File

@@ -1,2 +1,2 @@
[tools] [tools]
java = "17.0.16+8-amzn" java = "17.0.17+10-amzn"

View File

@@ -1 +1 @@
/Users/kid/.version-fox/cache/java/v-17.0.16+8-amzn/java-17.0.16+8-amzn /Users/kid/.version-fox/cache/java/v-17.0.17+10-amzn/java-17.0.17+10-amzn

View File

@@ -26,8 +26,8 @@ android {
applicationId "com.lukouguoji.aerologic" applicationId "com.lukouguoji.aerologic"
minSdkVersion 24 minSdkVersion 24
targetSdkVersion 30 targetSdkVersion 30
versionCode 84 versionCode 85
versionName "1.8.4" versionName "1.8.5"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View File

@@ -109,6 +109,12 @@
android:configChanges="orientation|keyboardHidden" android:configChanges="orientation|keyboardHidden"
android:exported="false" android:exported="false"
android:screenOrientation="userLandscape" /> android:screenOrientation="userLandscape" />
<!-- 国际出港修改组装重量 -->
<activity
android:name="com.lukouguoji.gjc.activity.GjcAssembleWeightEditActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="userLandscape" />
<!-- 国际出港出库交接 --> <!-- 国际出港出库交接 -->
<activity <activity
android:name="com.lukouguoji.gjc.activity.IntExpOutHandoverActivity" android:name="com.lukouguoji.gjc.activity.IntExpOutHandoverActivity"

View File

@@ -1,6 +1,5 @@
package com.lukouguoji.aerologic.ui.fragment package com.lukouguoji.aerologic.ui.fragment
import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
@@ -15,19 +14,15 @@ import androidx.recyclerview.widget.RecyclerView
import com.alibaba.android.arouter.launcher.ARouter import com.alibaba.android.arouter.launcher.ARouter
import com.alibaba.fastjson.JSON import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONObject import com.alibaba.fastjson.JSONObject
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.lukouguoji.aerologic.R import com.lukouguoji.aerologic.R
import com.lukouguoji.aerologic.page.accident.visa.list.AccidentVisaListActivity import com.lukouguoji.aerologic.page.accident.visa.list.AccidentVisaListActivity
import com.lukouguoji.aerologic.page.car.list.CarListActivity import com.lukouguoji.aerologic.page.car.list.CarListActivity
import com.lukouguoji.aerologic.page.flight.query.list.FlightQueryListActivity import com.lukouguoji.aerologic.page.flight.query.list.FlightQueryListActivity
import com.lukouguoji.aerologic.page.gnj.jiaojie.GnjHandoverListActivity import com.lukouguoji.aerologic.page.gnj.jiaojie.GnjHandoverListActivity
import com.lukouguoji.aerologic.page.gnj.manifest.list.GnjManifestListActivity import com.lukouguoji.aerologic.page.gnj.manifest.list.GnjManifestListActivity
import com.lukouguoji.aerologic.page.gnj.stash.list.GnjStashListActivity
import com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListActivity import com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListActivity
import com.lukouguoji.aerologic.page.gnj.query.details.GnjQueryDetailsActivity
import com.lukouguoji.aerologic.page.gnj.query.list.GnjQueryListActivity import com.lukouguoji.aerologic.page.gnj.query.list.GnjQueryListActivity
import com.lukouguoji.aerologic.page.gnj.stash.list.GnjStashListActivity
import com.lukouguoji.aerologic.page.gnj.unload.list.GnjUnloadListActivity import com.lukouguoji.aerologic.page.gnj.unload.list.GnjUnloadListActivity
import com.lukouguoji.aerologic.page.log.list.LogListActivity import com.lukouguoji.aerologic.page.log.list.LogListActivity
import com.lukouguoji.aerologic.page.message.list.MessageListActivity import com.lukouguoji.aerologic.page.message.list.MessageListActivity
@@ -40,7 +35,6 @@ import com.lukouguoji.gnc.page.distribution.home.GncDistributionHomeActivity
import com.lukouguoji.gnc.page.fubang.list.GncFuBangListActivity import com.lukouguoji.gnc.page.fubang.list.GncFuBangListActivity
import com.lukouguoji.gnc.page.shouyun.unlist.GncShouYunUnListActivity import com.lukouguoji.gnc.page.shouyun.unlist.GncShouYunUnListActivity
import com.lukouguoji.module_base.MyApplication import com.lukouguoji.module_base.MyApplication
import com.lukouguoji.module_base.adapter.loadImage
import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.db.perference.SharedPreferenceUtil import com.lukouguoji.module_base.db.perference.SharedPreferenceUtil
import com.lukouguoji.module_base.router.ARouterConstants import com.lukouguoji.module_base.router.ARouterConstants
@@ -179,7 +173,8 @@ class HomeFragment : Fragment() {
// 跳过特殊菜单(航班查询、货物查询) // 跳过特殊菜单(航班查询、货物查询)
if (Constant.AuthName.Flight == leftMenuTemp.id || if (Constant.AuthName.Flight == leftMenuTemp.id ||
Constant.AuthName.CargoStatus == leftMenuTemp.id) { Constant.AuthName.CargoStatus == leftMenuTemp.id
) {
return return
} }
@@ -424,9 +419,10 @@ class HomeFragment : Fragment() {
ARouter.getInstance().build(ARouterConstants.ACTIVITY_URL_INT_EXP_ARRIVE) ARouter.getInstance().build(ARouterConstants.ACTIVITY_URL_INT_EXP_ARRIVE)
.navigation() .navigation()
} }
// 仓库 // 出港仓库
Constant.AuthName.GjcIntExpStorageUse -> { Constant.AuthName.GjcIntExpStorageUse -> {
ARouter.getInstance().build(ARouterConstants.ACTIVITY_URL_INT_EXP_STORAGE_USE) ARouter.getInstance()
.build(ARouterConstants.ACTIVITY_URL_INT_EXP_STORAGE_USE)
.navigation() .navigation()
} }
/** /**
@@ -439,7 +435,8 @@ class HomeFragment : Fragment() {
} }
// 原始舱单 // 原始舱单
Constant.AuthName.IntArrAirManifest -> { Constant.AuthName.IntArrAirManifest -> {
ARouter.getInstance().build(ARouterConstants.ACTIVITY_URL_INT_ARR_AIR_MANIFEST) ARouter.getInstance()
.build(ARouterConstants.ACTIVITY_URL_INT_ARR_AIR_MANIFEST)
.navigation() .navigation()
} }
// 进港舱单 // 进港舱单
@@ -536,23 +533,10 @@ class HomeFragment : Fragment() {
} }
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
var item = rightMenuList[position] val item = rightMenuList[position]
holder.itemText.text = item.text holder.itemText.text = item.text
// holder.itemImg.setImageResource(item.img) // 直接设置本地资源,避免 Glide 缓存导致的图标错乱问题
loadPreviewImage(holder.itemView.context, item.img, holder.itemImg) holder.itemImg.setImageResource(item.img)
}
private fun loadPreviewImage(context: Context, url: Any, target: ImageView) {
val requestOptions = RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.override(
com.bumptech.glide.request.target.Target.SIZE_ORIGINAL,
com.bumptech.glide.request.target.Target.SIZE_ORIGINAL
)
Glide.with(context)
.setDefaultRequestOptions(requestOptions)
.load(url)
.into(target)
} }
override fun getItemCount() = rightMenuList.size override fun getItemCount() = rightMenuList.size
@@ -561,7 +545,7 @@ class HomeFragment : Fragment() {
inner class RightMenu(val id: String, val img: Int, val text: String) inner class RightMenu(val id: String, val img: Int, val text: String)
private fun getRightMenu4Id(id: String): List<RightMenu> { private fun getRightMenu4Id(id: String): List<RightMenu> {
var list = arrayListOf<RightMenu>() val list = arrayListOf<RightMenu>()
when (id) { when (id) {
Constant.AuthName.DomExp -> { Constant.AuthName.DomExp -> {
list.add( list.add(
@@ -578,7 +562,6 @@ class HomeFragment : Fragment() {
"出港复磅" "出港复磅"
) )
) )
// list.add(RightMenu(Constant.AuthName.AppDomExpTransport, R.mipmap.gnc_zhuanyun, "转运确认"))
list.add( list.add(
RightMenu( RightMenu(
Constant.AuthName.AppDomExpAssemble, Constant.AuthName.AppDomExpAssemble,
@@ -653,110 +636,114 @@ class HomeFragment : Fragment() {
} }
Constant.AuthName.IntExp -> { Constant.AuthName.IntExp -> {
// list.add( // 1. 收运检查
// RightMenu(
// Constant.AuthName.GjcAppDomExpCheckin,
// R.mipmap.gjc_shou_yun_icon,
// "出港收运"
// )
// )
list.add( list.add(
RightMenu( RightMenu(
Constant.AuthName.GjcInspectionActivity, Constant.AuthName.GjcInspectionActivity,
R.mipmap.gnc_cha, R.drawable.img_gjc_shouyunjiancha,
"收运检查" "收运检查"
) )
) )
// 2. 出港计重
list.add( list.add(
RightMenu( RightMenu(
Constant.AuthName.GjcCheckWeighing, Constant.AuthName.GjcCheckWeighing,
R.mipmap.gjc_fu_bang_icon, R.drawable.img_gjc_chugangjizhong,
"出港计重" "出港计重"
) )
) )
list.add( // 3. 出港运抵
RightMenu(
Constant.AuthName.GjcFuBangActivity,
R.mipmap.gjc_fu_bang_icon,
"板箱过磅"
)
)
list.add(
RightMenu(
Constant.AuthName.GjcIntExpAssembleActivity,
com.lukouguoji.module_base.R.drawable.img_gjc_banxiangzuzhuang,
"出港组装"
)
)
list.add(
RightMenu(
Constant.AuthName.GjcQueryListActivity,
R.mipmap.gjc_query_icon,
"出港查询"
)
)
list.add(
RightMenu(
Constant.AuthName.GjcYiKuListActivity,
R.mipmap.gjc_yi_ku_icon,
"出港移库"
)
)
list.add(
RightMenu(
Constant.AuthName.GjcAssembleAllocateActivity,
com.lukouguoji.module_base.R.drawable.img_gnc_fenpei,
"组装分配"
)
)
list.add(
RightMenu(
Constant.AuthName.GjcIntExpOutHandover,
com.lukouguoji.module_base.R.drawable.img_gjc_chuku_jiaojie,
"出库交接"
)
)
list.add(
RightMenu(
Constant.AuthName.GjcIntExpLoad,
com.lukouguoji.module_base.R.drawable.img_gjc_chugang_zhuangzai,
"出港装载"
)
)
list.add(
RightMenu(
Constant.AuthName.GjcIntExpTally,
com.lukouguoji.module_base.R.drawable.img_gjc_chugang_lihuo,
"出港理货"
)
)
list.add( list.add(
RightMenu( RightMenu(
Constant.AuthName.GjcIntExpArrive, Constant.AuthName.GjcIntExpArrive,
com.lukouguoji.module_base.R.drawable.img_gjc_chugang_diyun, R.drawable.img_gjc_chugang_diyun,
"出港运抵" "出港运抵"
) )
) )
// 4. 组装分配
list.add(
RightMenu(
Constant.AuthName.GjcAssembleAllocateActivity,
R.drawable.img_gjc_zuzhuangfenpei,
"组装分配"
)
)
// 5. 出港组装
list.add(
RightMenu(
Constant.AuthName.GjcIntExpAssembleActivity,
R.drawable.img_gjc_banxiangzuzhuang,
"出港组装"
)
)
// 6. 板箱过磅
list.add(
RightMenu(
Constant.AuthName.GjcFuBangActivity,
R.drawable.img_gjc_banxiangguobang,
"板箱过磅"
)
)
// 7. 出港装载
list.add(
RightMenu(
Constant.AuthName.GjcIntExpLoad,
R.drawable.img_gjc_chugang_zhuangzai,
"出港装载"
)
)
// 8. 出库交接
list.add(
RightMenu(
Constant.AuthName.GjcIntExpOutHandover,
R.drawable.img_gjc_chuku_jiaojie,
"出库交接"
)
)
// 9. 出港理货
list.add(
RightMenu(
Constant.AuthName.GjcIntExpTally,
R.drawable.img_gjc_chugang_lihuo,
"出港理货"
)
)
// 10. 出港移库
list.add(
RightMenu(
Constant.AuthName.GjcYiKuListActivity,
R.drawable.gjc_yi_ku_icon,
"出港移库"
)
)
// 11. 出港仓库
list.add( list.add(
RightMenu( RightMenu(
Constant.AuthName.GjcIntExpStorageUse, Constant.AuthName.GjcIntExpStorageUse,
R.mipmap.gjc_cang_ku_icon, R.drawable.gjc_cang_ku_icon,
"出港仓库" "出港仓库"
) )
) )
// 12. 出港查询
list.add(
RightMenu(
Constant.AuthName.GjcQueryListActivity,
R.drawable.gjc_query_icon,
"出港查询"
)
)
// list.add( // list.add(
// RightMenu( // RightMenu(
// Constant.AuthName.GjcWareHouseActivity, // Constant.AuthName.GjcWareHouseActivity,

View File

@@ -7,7 +7,6 @@
# Specifies the JVM arguments used for the daemon process. # Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings. # 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
org.gradle.java.home=/Users/kid/.version-fox/cache/java/v-17.0.16+8-amzn/java-17.0.16+8-amzn
kapt.use.worker.api=false kapt.use.worker.api=false
kapt.include.compile.classpath=false kapt.include.compile.classpath=false
# When configured, Gradle will run in incubating parallel mode. # When configured, Gradle will run in incubating parallel mode.

View File

@@ -156,7 +156,7 @@ dependencies {
// exclude group: 'com.jcraft' // exclude group: 'com.jcraft'
// } // }
// api(name: 'sdk2-2.1.6-20250901.051214-1', ext: 'aar') { // api(name: 'sdk2-2.1.6-20250901.051214-1', ext: 'aar') {
api(name: 'sdk2-2.0.3', ext: 'aar') { api(name: 'sdk2-2.0.4', ext: 'aar') {
exclude group: 'com.jcraft' exclude group: 'com.jcraft'
} }
} }

Binary file not shown.

Binary file not shown.

View File

@@ -41,7 +41,7 @@ import me.jessyan.autosize.internal.CustomAdapt
* ========== 开发调试开关 ========== * ========== 开发调试开关 ==========
* TODO: 正式发布前务必设置为 false * TODO: 正式发布前务必设置为 false
*/ */
private const val DEV_AUTO_LOGIN = true // 自动登录开关 private const val DEV_AUTO_LOGIN = false // 自动登录开关
@Route(path = ARouterConstants.ACTIVITY_URL_LOGIN) @Route(path = ARouterConstants.ACTIVITY_URL_LOGIN)
class LoginActivity : BaseActivity(), class LoginActivity : BaseActivity(),

View File

@@ -28,7 +28,7 @@ import java.util.concurrent.TimeUnit
class MyApplication : Application() { class MyApplication : Application() {
//ARouter debug开关true-open;false-close //ARouter debug开关true-open;false-close
private val isDebugARouter = true private val isDebugARouter = false
companion object { companion object {
lateinit var context: Context lateinit var context: Context

View File

@@ -7,7 +7,7 @@ package com.lukouguoji.module_base.bean
data class GjcCheckInPage( data class GjcCheckInPage(
var fdate: String? = null, // 航班日期 var fdate: String? = null, // 航班日期
var fno: String? = null, // 航班号 var fno: String? = null, // 航班号
var whNo: String? = null, // 运单号 var wbNo: String? = null, // 运单号
var hno: String? = null, // 分单号 var hno: String? = null, // 分单号
var pageNum: Int = 1, // 页码 var pageNum: Int = 1, // 页码
var pageSize: Int = 10 // 每页条数 var pageSize: Int = 10 // 每页条数

View File

@@ -21,7 +21,8 @@ data class GjcCheckInRecord(
var pc: Long = 0, // 运抵件数 var pc: Long = 0, // 运抵件数
var weight: Double = 0.0, // 运抵重量 var weight: Double = 0.0, // 运抵重量
var volume: Double = 0.0, // 运抵体积 var volume: Double = 0.0, // 运抵体积
var whId: Long = 0 // GJC_WAREHOUSE.ID var whId: Long = 0, // GJC_WAREHOUSE.ID
var carWeight: String = "" // 托盘自重
) : BaseObservable() { ) : BaseObservable() {
// 数据变化回调 // 数据变化回调

View File

@@ -60,9 +60,9 @@ class GjcInspectionBean : ICheck {
*/ */
fun getReviewStatusName(): String { fun getReviewStatusName(): String {
return when (reviewStatus) { return when (reviewStatus) {
"1" -> "已通过" "1" -> "未审核"
"2" -> "退回" "2" -> "已通过"
"0" -> "未审核" "3" -> "退回"
else -> "未知" else -> "未知"
} }
} }
@@ -72,9 +72,10 @@ class GjcInspectionBean : ICheck {
*/ */
fun getReviewStatusColor(): String { fun getReviewStatusColor(): String {
return when (reviewStatus) { return when (reviewStatus) {
"1" -> "#4CAF50" // 绿色-已通过 "1" -> "#9E9E9E" // 色-未审核
"2" -> "#F44336" // 色-退回 "2" -> "#4CAF50" // 绿色-已通过
else -> "#9E9E9E" // 色-未审核 "3" -> "#F44336" // 色-退回
else -> "#9E9E9E" // 灰色-未知
} }
} }

View File

@@ -74,6 +74,7 @@ data class GjcMaWb(
var carId: String? = null, // 平板车号 var carId: String? = null, // 平板车号
var carNumber: String? = null, // 车牌号 var carNumber: String? = null, // 车牌号
var passageWay: String? = null, // 通道号 var passageWay: String? = null, // 通道号
var passageWayId: String? = null,
// ==================== 状态信息 ==================== // ==================== 状态信息 ====================
var checkIn: String? = null, // 收运状态。0待收运1已收运2收运中 var checkIn: String? = null, // 收运状态。0待收运1已收运2收运中

View File

@@ -43,6 +43,8 @@ data class GjcMove(
var remark: String = "", // 备注 var remark: String = "", // 备注
var likeNo: String = "", // 部分运单号no模糊查询 var likeNo: String = "", // 部分运单号no模糊查询
var range: String = "",
// UI扩展字段 - 使用ObservableBoolean实现自动UI更新 // UI扩展字段 - 使用ObservableBoolean实现自动UI更新
val checked: ObservableBoolean = ObservableBoolean(false) val checked: ObservableBoolean = ObservableBoolean(false)
) : Serializable, ICheck { ) : Serializable, ICheck {

View File

@@ -1,12 +1,13 @@
package com.lukouguoji.module_base.bean package com.lukouguoji.module_base.bean
import androidx.databinding.ObservableBoolean import androidx.databinding.ObservableBoolean
import java.io.Serializable
/** /**
* 国际出港板箱过磅-ULD使用记录Bean * 国际出港板箱过磅-ULD使用记录Bean
* 对应API: IntExpWeighting/pageQuery * 对应API: IntExpWeighting/pageQuery
*/ */
class GjcUldUseBean { class GjcUldUseBean : Serializable {
var useId: Long = 0 // 使用id var useId: Long = 0 // 使用id
var uld: String = "" // uld编号 var uld: String = "" // uld编号
var carId: String = "" // 板车号 var carId: String = "" // 板车号
@@ -26,6 +27,8 @@ class GjcUldUseBean {
var fdep: String = "" // 起始站 var fdep: String = "" // 起始站
var fdest: String = "" // 目的港 var fdest: String = "" // 目的港
var fClose: String = "" // 航班关闭时间 var fClose: String = "" // 航班关闭时间
var flight: String = "" // 航班信息
var transArea: String = "" // 库位号
// 格式化后的航班日期(只保留年月日) // 格式化后的航班日期(只保留年月日)
val fdateFormatted: String val fdateFormatted: String
@@ -50,22 +53,59 @@ class GjcUldUseBean {
var dgrCode: String = "" // IMP代码 var dgrCode: String = "" // IMP代码
var height: String = "" // 高度 var height: String = "" // 高度
var passageway: String = "" // 通道号 var passageway: String = "" // 通道号
var passagewayId: String = ""
var passagewayName: String = "" // 通道号(中文) var passagewayName: String = "" // 通道号(中文)
var piClose: String = "" // 探板/收口 var plClose: String = "" // 探板/收口
var piCloseSize: String = "" // 探板尺寸(CM) var plCloseSize: String = "" // 探板尺寸(CM)
var location: String = "" // 位置 var location: String = "" // 位置
var pieces: String = "" // 件数 var pieces: String = "" // 件数(字符串格式)
var remark: String = "" // 备注 var remark: String = "" // 备注
var checkFlag: String = "" // 检查标记 var checkFlag: String = "" // 检查标记
var emptyUld: String = "" // 空ULD var emptyUld: String = "" // 空ULD
var loadArea: String = "" // 组装区
var pc: Long = 0 // 组装件数
var fillWeightFlag: String = "" // 回填状态0-未回填1-部分回填2-已回填
// 回填状态文本
val fillWeightFlagText: String
get() = when (fillWeightFlag) {
"0" -> "未回填"
"1" -> "部分回填"
"2" -> "已回填"
else -> ""
}
// 回填状态是否显示绿色(已回填时显示绿色)
val isFillWeightGreen: Boolean
get() = fillWeightFlag == "2"
// ========== 出港组装页面扩展字段 ========== // ========== 出港组装页面扩展字段 ==========
var isExpanded: Boolean = false // 展开状态 var isExpanded: Boolean = false // 展开状态(旧版保留)
@Transient
val checked: ObservableBoolean = ObservableBoolean(false) // 选中状态(Observable) val checked: ObservableBoolean = ObservableBoolean(false) // 选中状态(Observable)
@Transient
val showMore: ObservableBoolean = ObservableBoolean(false) // 展开状态(Observable)
@Transient
val isLoading: ObservableBoolean = ObservableBoolean(false) // 子列表加载中状态
@Transient
var waybillDetailsLoaded: Boolean = false // 子列表是否已加载过(用于区分"未加载"和"加载后为空"
var waybillDetails: MutableList<GjcWarehouse>? = null // 运单明细缓存 var waybillDetails: MutableList<GjcWarehouse>? = null // 运单明细缓存
// 子列表是否有数据
val hasWaybillDetails: Boolean
get() = waybillDetails != null && waybillDetails!!.isNotEmpty()
// 是否显示"暂无数据"(已加载但无数据)
val showEmptyView: Boolean
get() = waybillDetailsLoaded && !hasWaybillDetails
// 兼容原有代码的isSelected属性 // 兼容原有代码的isSelected属性
var isSelected: Boolean var isSelected: Boolean
get() = checked.get() get() = checked.get()
set(value) = checked.set(value) set(value) = checked.set(value)
// 复磅状态文本
val wtStatusText: String
get() = if (wtDate.isNotEmpty()) "已复磅" else "未复磅"
} }

View File

@@ -1,16 +1,22 @@
package com.lukouguoji.module_base.bean package com.lukouguoji.module_base.bean
import java.io.Serializable
/** /**
* 国际出港-运单明细Bean * 国际出港-运单明细Bean
* 对应API: IntExpAssemble/queryAssembled * 对应API: IntExpAssemble/queryAssembled
*/ */
class GjcWarehouse { class GjcWarehouse : Serializable {
var whId: Long = 0 // ID var whId: Long = 0 // ID
var no: String = "" // 运单号11位 var no: String = "" // 运单号11位
var prefix: String = "" // 运单前缀 var prefix: String = "" // 运单前缀
var wbNo: String = "" // 主运单编号 var wbNo: String = "" // 主运单编号
var pc: Long = 0 // 件数 var pc: Long = 0 // 件数
var weight: Double = 0.0 // 重量 var weight: Double = 0.0 // 重量
set(value) {
field = value
onDataChanged?.invoke()
}
var volume: Double = 0.0 // 体积 var volume: Double = 0.0 // 体积
var agentCode: String = "" // 代理code var agentCode: String = "" // 代理code
var agentName: String = "" // 代理名称 var agentName: String = "" // 代理名称
@@ -33,5 +39,26 @@ class GjcWarehouse {
var location: String = "" // uld var location: String = "" // uld
var checkInPc: Long = 0 // 入库件数 var checkInPc: Long = 0 // 入库件数
var checkInWeight: Double = 0.0 // 入库重量 var checkInWeight: Double = 0.0 // 入库重量
set(value) {
field = value
onDataChanged?.invoke()
}
var assembleCount: Int = 0 // 已经组装的数量 var assembleCount: Int = 0 // 已经组装的数量
// ========== UI扩展字段 ==========
/**
* 重量字符串用于双向绑定EditText
*/
var checkInWeightStr: String
get() = if (checkInWeight == 0.0) "" else checkInWeight.toString()
set(value) {
checkInWeight = value.toDoubleOrNull() ?: 0.0
}
/**
* 数据变化回调(用于实时计算统计)
*/
@Transient
var onDataChanged: (() -> Unit)? = null
} }

View File

@@ -1,5 +1,6 @@
package com.lukouguoji.module_base.bean package com.lukouguoji.module_base.bean
import androidx.databinding.ObservableBoolean
import com.lukouguoji.module_base.ktx.noNull import com.lukouguoji.module_base.ktx.noNull
import dev.utils.DevFinal import dev.utils.DevFinal
import dev.utils.common.DateUtils import dev.utils.common.DateUtils
@@ -96,6 +97,14 @@ class GjcWeighingBean {
var storageUseList: List<Any>? = null // 库位使用列表 var storageUseList: List<Any>? = null // 库位使用列表
var attachList: List<Any>? = null // 附件列表 var attachList: List<Any>? = null // 附件列表
// ========== UI扩展字段 ==========
val checked: ObservableBoolean = ObservableBoolean(false) // 选中状态
// 兼容现有API的isSelected属性
var isSelected: Boolean
get() = checked.get()
set(value) = checked.set(value)
/** /**
* 预计起飞时间 - 仅时分格式 (HH:mm) * 预计起飞时间 - 仅时分格式 (HH:mm)
*/ */

View File

@@ -1,5 +1,6 @@
package com.lukouguoji.module_base.bean package com.lukouguoji.module_base.bean
import androidx.databinding.ObservableBoolean
import java.io.Serializable import java.io.Serializable
/** /**
@@ -98,4 +99,12 @@ class GjcWeighingRecordBean : Serializable {
var haWbList: List<Any>? = null // 分单列表 var haWbList: List<Any>? = null // 分单列表
var storageUseList: List<Any>? = null // 库位使用列表 var storageUseList: List<Any>? = null // 库位使用列表
var attachList: List<Any>? = null // 附件列表 var attachList: List<Any>? = null // 附件列表
// ========== UI扩展字段 ==========
val checked: ObservableBoolean = ObservableBoolean(false) // 选中状态
// 兼容现有API的isSelected属性
var isSelected: Boolean
get() = checked.get()
set(value) = checked.set(value)
} }

View File

@@ -554,6 +554,13 @@ interface Api {
@POST("IntExpWeighting/weight") @POST("IntExpWeighting/weight")
suspend fun submitGjcBoxWeighing(@Body data: RequestBody): BaseResultBean<SimpleResultBean> suspend fun submitGjcBoxWeighing(@Body data: RequestBody): BaseResultBean<SimpleResultBean>
/**
* 国际出港板箱过磅-根据ULD查询正在使用的记录
* 接口路径: /IntExpWeighting/queryUsingUldByUld
*/
@GET("IntExpWeighting/queryUsingUldByUld")
suspend fun queryUsingUldByUld(@Query("uld") uld: String): BaseResultBean<GjcUldUseBean>
// ==================== 国际出港-出港组装 ==================== // ==================== 国际出港-出港组装 ====================
/** /**
@@ -581,10 +588,10 @@ interface Api {
/** /**
* 国际出港组装-删除记录 * 国际出港组装-删除记录
* 接口路径: /IntExpAssemble/delete * 接口路径: /IntExpAssemble/delete
* @param ids ULD使用记录ID多个用逗号分隔 * @param data GjcUldUseBean数组
*/ */
@POST("IntExpAssemble/delete") @POST("IntExpAssemble/delete")
suspend fun deleteIntExpAssemble(@Query("ids") ids: String): BaseResultBean<SimpleResultBean> suspend fun deleteIntExpAssemble(@Body data: RequestBody): BaseResultBean<Boolean>
/** /**
* 国际出港组装-回填重量 * 国际出港组装-回填重量
@@ -654,6 +661,14 @@ interface Api {
@POST("IntExpAssemble/queryAssembledByUld") @POST("IntExpAssemble/queryAssembledByUld")
suspend fun getAssembledWaybillsByUld(@Body data: RequestBody): BaseResultBean<List<GjcWarehouse>> suspend fun getAssembledWaybillsByUld(@Body data: RequestBody): BaseResultBean<List<GjcWarehouse>>
/**
* 国际出港组装 - 修改列表(批量更新运单重量)
* 接口路径: /IntExpAssemble/update
* @param data GjcWarehouse数组
*/
@POST("IntExpAssemble/update")
suspend fun updateIntExpAssemble(@Body data: RequestBody): BaseResultBean<Boolean>
/** /**
* 国际出港出库交接-分页查询 * 国际出港出库交接-分页查询
* 接口路径: /IntExpOutHandover/pageQuery * 接口路径: /IntExpOutHandover/pageQuery
@@ -676,6 +691,14 @@ interface Api {
@POST("IntExpOutHandover/handover") @POST("IntExpOutHandover/handover")
suspend fun completeHandover(@Body data: RequestBody): BaseResultBean<Boolean> suspend fun completeHandover(@Body data: RequestBody): BaseResultBean<Boolean>
/**
* 国际出港出库交接-待配运
* 接口路径: /IntExpOutHandover/waitingTrans
* @param data 请求参数GjcStorageParam (包含库位信息和ULD列表)
*/
@POST("IntExpOutHandover/waitingTrans")
suspend fun waitingTrans(@Body data: RequestBody): BaseResultBean<String>
/** /**
* 国际出港-出港装载 分页查询 * 国际出港-出港装载 分页查询
* 接口路径: /IntExpLoad/pageQuery * 接口路径: /IntExpLoad/pageQuery
@@ -832,6 +855,13 @@ interface Api {
@POST("IntExpStorageUse/outStorage") @POST("IntExpStorageUse/outStorage")
suspend fun outIntExpStorage(@Body data: RequestBody): BaseResultBean<Boolean> suspend fun outIntExpStorage(@Body data: RequestBody): BaseResultBean<Boolean>
/**
* 国际出港库位操作-入库
* 接口路径: /IntExpStorageUse/inStorage
*/
@POST("IntExpStorageUse/inStorage")
suspend fun inIntExpStorage(@Body data: RequestBody): BaseResultBean<Boolean>
/** /**
* 国际出港仓库-分页查询 * 国际出港仓库-分页查询
* 接口路径: /IntExpStorageUse/pageQuery * 接口路径: /IntExpStorageUse/pageQuery
@@ -853,6 +883,14 @@ interface Api {
@POST("IntExpStorageUse/queryWbNoList") @POST("IntExpStorageUse/queryWbNoList")
suspend fun getIntExpStorageWbNoList(@Body data: RequestBody): BaseResultBean<List<String>> suspend fun getIntExpStorageWbNoList(@Body data: RequestBody): BaseResultBean<List<String>>
/**
* 获取库位列表
* 接口路径: /typeCode/locationByFlag
* @param flag 库位标志2表示国际出港库位
*/
@GET("typeCode/locationByFlag")
suspend fun getLocationList(@Query("flag") flag: Int): BaseResultBean<List<DictLocationBean>>
/** /**
* 国际出港待计重-分页搜索 * 国际出港待计重-分页搜索
* 接口路径: /IntExpCheckIn/pageQuery * 接口路径: /IntExpCheckIn/pageQuery
@@ -867,6 +905,21 @@ interface Api {
@POST("IntExpCheckIn/pageQueryTotal") @POST("IntExpCheckIn/pageQueryTotal")
suspend fun getGjcWeighingStatistics(@Body data: RequestBody): BaseResultBean<GjcWeighingStatisticsBean> suspend fun getGjcWeighingStatistics(@Body data: RequestBody): BaseResultBean<GjcWeighingStatisticsBean>
/**
* 国际出港待计重-运单号模糊查询(用于自动补全)
* 接口路径: /IntExpCheckIn/queryWbNoList
*/
@POST("IntExpCheckIn/queryWbNoList")
suspend fun getIntExpCheckInWbNoList(@Body data: RequestBody): BaseResultBean<List<String>>
/**
* 国际出港待计重-根据11位具体运单号查询运单信息
* 接口路径: /IntExpCheckIn/queryWbByNo
* @param wbNo 11位运单号
*/
@POST("IntExpCheckIn/queryWbByNo")
suspend fun getIntExpCheckInWbByNo(@Query("wbNo") wbNo: String): BaseResultBean<GjcMaWb>
/** /**
* 国际出港待计重-开始计重-根据wbId查询详情 * 国际出港待计重-开始计重-根据wbId查询详情
* 接口路径: /IntExpCheckIn/queryWbById * 接口路径: /IntExpCheckIn/queryWbById
@@ -928,6 +981,14 @@ interface Api {
@POST("IntExpCheckIn/updateRecordList") @POST("IntExpCheckIn/updateRecordList")
suspend fun updateGjcCheckInRecordList(@Body data: List<GjcCheckInRecord>): BaseResultBean<Boolean> suspend fun updateGjcCheckInRecordList(@Body data: List<GjcCheckInRecord>): BaseResultBean<Boolean>
/**
* 国际出港待计重-提前运抵
* 接口路径: /IntExpCheckIn/preArrive
* 参数: List<GjcMaWb> - 运单列表
*/
@POST("IntExpCheckIn/preArrive")
suspend fun preArrive(@Body data: List<GjcMaWb>): BaseResultBean<String>
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// 国际进-电报解析 // 国际进-电报解析
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////

View File

@@ -147,6 +147,7 @@ object ARouterConstants {
const val ACTIVITY_URL_INT_EXP_TALLY = "/gjc/IntExpTallyActivity" //国际出港 出港理货 const val ACTIVITY_URL_INT_EXP_TALLY = "/gjc/IntExpTallyActivity" //国际出港 出港理货
const val ACTIVITY_URL_INT_EXP_ARRIVE = "/gjc/IntExpArriveActivity" //国际出港 出港运抵 const val ACTIVITY_URL_INT_EXP_ARRIVE = "/gjc/IntExpArriveActivity" //国际出港 出港运抵
const val ACTIVITY_URL_INT_EXP_STORAGE_USE = "/gjc/IntExpStorageUseActivity" //国际出港 仓库 const val ACTIVITY_URL_INT_EXP_STORAGE_USE = "/gjc/IntExpStorageUseActivity" //国际出港 仓库
const val ACTIVITY_URL_GJC_ASSEMBLE_WEIGHT_EDIT = "/gjc/GjcAssembleWeightEditActivity" //国际出港 修改组装重量
///////////////// 国际进港模块 ///////////////// 国际进港模块
/** /**

View File

@@ -459,7 +459,7 @@ object PrinterUtils {
addSize(100, 100) addSize(100, 100)
addGap(3) addGap(3)
addCls() addCls()
addTextByBitmap(80, 80, 0, 130, "扬州泰州机场", Typeface.DEFAULT) addTextByBitmap(80, 80, 0, 130, "合肥新桥国际机场", Typeface.DEFAULT)
// 绘制表格横线 // 绘制表格横线
for (i in 0..rows.size) { for (i in 0..rows.size) {
@@ -567,7 +567,7 @@ object PrinterUtils {
fun printTest() { fun printTest() {
getConnectedPrinters().forEach { getConnectedPrinters().forEach {
val bytes = v(Instruction.TSC.toString(), null).bytes val bytes = v(Instruction.TSC).bytes
showLog("打印测试页 - ${it.printerDevice.printerName} \n${bytes.commonToUtf8String()}") showLog("打印测试页 - ${it.printerDevice.printerName} \n${bytes.commonToUtf8String()}")
it.print(bytes, null) it.print(bytes, null)
} }

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"> <shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="8dp" /> <corners android:radius="8dp" />
<solid android:color="#008000" /> <solid android:color="#E8F5E9" />
</shape> </shape>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="1408dp"
android:height="1024dp"
android:viewportWidth="1408"
android:viewportHeight="1024">
<path
android:fillColor="#599dff"
android:pathData="M1327.05296 200.971963H427.464174c-38.280374 0-76.560748-38.280374-76.560747-76.560748s31.900312-76.560748 76.560747-76.560748h899.588786c38.280374 0 76.560748 38.280374 76.560747 76.560748s-31.900312 76.560748-76.560747 76.560748zM669.906542 519.975078v-12.760125c-6.380062-19.140187-12.760125-31.900312-25.520249-44.660436l-25.520249-25.520249h708.186916c44.660436 0 76.560748 31.900312 76.560747 76.560748s-31.900312 76.560748-76.560747 76.560747H618.866044l25.520249-25.520249c12.760125-12.760125 19.140187-25.520249 25.520249-44.660436zM350.903427 513.595016L25.520249 169.071651C12.760125 149.931464 0 130.791277 0 98.890966s12.760125-51.040498 25.520249-70.180686c38.280374-38.280374 95.700935-38.280374 133.981309 0l382.803738 401.943926 25.520249 25.520249c12.760125 12.760125 19.140187 25.520249 25.520249 44.660436V513.595016c-6.380062 25.520249-12.760125 38.280374-25.520249 51.040498L542.305296 590.155763 159.501558 992.099688c-19.140187 19.140187-44.660436 31.900312-63.800623 31.900312-25.520249 0-51.040498-12.760125-63.800623-31.900312-19.140187-12.760125-31.900312-38.280374-31.900312-63.800623s12.760125-51.040498 25.520249-70.180685L350.903427 513.595016z m76.560747 312.623053h899.588786c38.280374 0 76.560748 38.280374 76.560747 76.560747s-31.900312 76.560748-76.560747 76.560748H427.464174c-38.280374 0-76.560748-38.280374-76.560747-76.560748s38.280374-76.560748 76.560747-76.560747z" />
</vector>

View File

@@ -0,0 +1,69 @@
package com.lukouguoji.gjc.activity
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.alibaba.android.arouter.facade.annotation.Route
import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.ActivityGjcAssembleWeightEditBinding
import com.lukouguoji.gjc.holder.GjcAssembleWeightEditViewHolder
import com.lukouguoji.gjc.viewModel.GjcAssembleWeightEditViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.base.CommonAdapter
import com.lukouguoji.module_base.bean.GjcUldUseBean
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.router.ARouterConstants
/**
* 国际出港-修改组装重量页面
*/
@Route(path = ARouterConstants.ACTIVITY_URL_GJC_ASSEMBLE_WEIGHT_EDIT)
class GjcAssembleWeightEditActivity :
BaseBindingActivity<ActivityGjcAssembleWeightEditBinding, GjcAssembleWeightEditViewModel>() {
private lateinit var adapter: CommonAdapter
override fun layoutId() = R.layout.activity_gjc_assemble_weight_edit
override fun viewModelClass() = GjcAssembleWeightEditViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("修改组装重量")
binding.viewModel = viewModel
// 初始化RecyclerView
val layoutManager = LinearLayoutManager(this)
binding.recyclerView.layoutManager = layoutManager
// 添加分割线
val divider = DividerItemDecoration(this, DividerItemDecoration.VERTICAL)
binding.recyclerView.addItemDecoration(divider)
adapter = CommonAdapter(
this,
R.layout.item_gjc_assemble_weight_edit,
GjcAssembleWeightEditViewHolder::class.java
)
binding.recyclerView.adapter = adapter
// 监听数据变化更新RecyclerView
viewModel.waybillList.observe(this) { records ->
adapter.refresh(records)
}
// 初始化数据
viewModel.initOnCreated(intent)
}
companion object {
@JvmStatic
fun start(context: Context, bean: GjcUldUseBean) {
val starter = Intent(context, GjcAssembleWeightEditActivity::class.java)
.putExtra(Constant.Key.BEAN, bean)
context.startActivity(starter)
}
}
}

View File

@@ -24,10 +24,11 @@ class GjcBoxWeighingAddActivity :
binding.viewModel = viewModel binding.viewModel = viewModel
viewModel.initOnCreated(this) viewModel.initOnCreated(this)
// 为架子车号、ULD编码、IMP代码添加大写字母和数字的输入限制 // 为架子车号、ULD编码、IMP代码、航班号添加大写字母和数字的输入限制
binding.carIdInput.et.setUpperCaseAlphanumericFilter() binding.carIdInput.et.setUpperCaseAlphanumericFilter()
binding.uldNoInput.et.setUpperCaseAlphanumericFilter() binding.uldNoInput.et.setUpperCaseAlphanumericFilter()
binding.impCodeInput.et.setUpperCaseAlphanumericFilter() binding.impCodeInput.et.setUpperCaseAlphanumericFilter()
binding.flightNoInput.et.setUpperCaseAlphanumericFilter()
} }
companion object { companion object {

View File

@@ -30,6 +30,11 @@ class GjcWeighingListActivity :
binding.viewModel = viewModel binding.viewModel = viewModel
// 观察全选状态,更新图标透明度
viewModel.isAllChecked.observe(this) { isAllChecked ->
binding.checkIcon.alpha = if (isAllChecked) 1.0f else 0.5f
}
// 初始化代理人列表从API获取 // 初始化代理人列表从API获取
viewModel.initAgentList() viewModel.initAgentList()

View File

@@ -3,7 +3,9 @@ package com.lukouguoji.gjc.activity
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import com.alibaba.android.arouter.facade.annotation.Autowired
import com.alibaba.android.arouter.facade.annotation.Route import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.ActivityIntExpArriveBinding import com.lukouguoji.gjc.databinding.ActivityIntExpArriveBinding
import com.lukouguoji.gjc.viewModel.IntExpArriveViewModel import com.lukouguoji.gjc.viewModel.IntExpArriveViewModel
@@ -22,13 +24,26 @@ import com.lukouguoji.module_base.router.ARouterConstants
class IntExpArriveActivity : class IntExpArriveActivity :
BaseBindingActivity<ActivityIntExpArriveBinding, IntExpArriveViewModel>() { BaseBindingActivity<ActivityIntExpArriveBinding, IntExpArriveViewModel>() {
@JvmField
@Autowired
var wbNoParam: String? = null
override fun layoutId() = R.layout.activity_int_exp_arrive override fun layoutId() = R.layout.activity_int_exp_arrive
override fun viewModelClass() = IntExpArriveViewModel::class.java override fun viewModelClass() = IntExpArriveViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) { override fun initOnCreate(savedInstanceState: Bundle?) {
// 注入 ARouter 参数
ARouter.getInstance().inject(this)
setBackArrow("出港运抵") setBackArrow("出港运抵")
binding.viewModel = viewModel binding.viewModel = viewModel
// 如果有传入运单号,自动填充并触发搜索
if (!wbNoParam.isNullOrEmpty()) {
viewModel.waybillNo.value = wbNoParam
viewModel.searchClick()
}
// 观察全选状态,更新图标透明度 // 观察全选状态,更新图标透明度
viewModel.isAllChecked.observe(this) { isAllChecked -> viewModel.isAllChecked.observe(this) { isAllChecked ->
binding.checkIcon.alpha = if (isAllChecked) 1.0f else 0.5f binding.checkIcon.alpha = if (isAllChecked) 1.0f else 0.5f
@@ -45,8 +60,10 @@ class IntExpArriveActivity :
viewModel.refresh() viewModel.refresh()
} }
// 初始加载数据 // 初始加载数据(如果没有传入运单号,才执行初始加载)
viewModel.refresh() if (wbNoParam.isNullOrEmpty()) {
viewModel.refresh()
}
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

View File

@@ -9,6 +9,7 @@ import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.ActivityIntExpStorageUseBinding import com.lukouguoji.gjc.databinding.ActivityIntExpStorageUseBinding
import com.lukouguoji.gjc.dialog.IntExpMoveClearDialogModel import com.lukouguoji.gjc.dialog.IntExpMoveClearDialogModel
import com.lukouguoji.gjc.dialog.IntExpModifyStorageDialogModel import com.lukouguoji.gjc.dialog.IntExpModifyStorageDialogModel
import com.lukouguoji.gjc.dialog.IntExpInStorageDialogModel
import com.lukouguoji.gjc.viewModel.IntExpStorageUseViewModel import com.lukouguoji.gjc.viewModel.IntExpStorageUseViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.common.Constant
@@ -115,8 +116,9 @@ class IntExpStorageUseActivity :
// 显示修改库位对话框 // 显示修改库位对话框
IntExpModifyStorageDialogModel { dialog -> IntExpModifyStorageDialogModel { dialog ->
// 用户点击保存后,执行修改库位操作 // 用户点击保存后,执行修改库位操作
val newLocation = dialog.location.value ?: "" val locationName = dialog.locationName
viewModel.performModifyStorage(newLocation, selectedStorage) val locationId = dialog.locationId
viewModel.performModifyStorage(locationName, locationId, selectedStorage)
}.show(this) }.show(this)
} }
@@ -151,6 +153,41 @@ class IntExpStorageUseActivity :
.show() .show()
} }
/**
* 显示入库操作对话框
*/
fun showInStorageDialog() {
val list = viewModel.pageModel.rv?.commonAdapter()?.items as? List<*> ?: return
val allItems = list.filterIsInstance<com.lukouguoji.module_base.bean.GjcMaWb>()
// 构建入库数据:保留主列表结构,但只包含选中的子列表项
val maWbListForInStorage = allItems.mapNotNull { maWb ->
// 过滤出选中的子列表项
val selectedStorageList = maWb.storageUseList?.filter { it.isSelected } ?: emptyList()
// 只添加有选中子列表项的主列表项
if (selectedStorageList.isNotEmpty() || maWb.isSelected) {
// 创建主列表项的副本,只包含选中的子列表
maWb.copy(storageUseList = selectedStorageList)
} else {
null
}
}
if (maWbListForInStorage.isEmpty()) {
showToast("请至少选择一个单据")
return
}
// 显示入库对话框
IntExpInStorageDialogModel { dialog ->
// 用户点击保存后,执行入库操作
val locationName = dialog.locationName
val locationId = dialog.locationId
viewModel.performInStorage(locationName, locationId, maWbListForInStorage)
}.show(this)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
if (requestCode == Constant.RequestCode.WAYBILL && resultCode == Activity.RESULT_OK) { if (requestCode == Constant.RequestCode.WAYBILL && resultCode == Activity.RESULT_OK) {

View File

@@ -0,0 +1,66 @@
package com.lukouguoji.gjc.dialog
import android.content.Context
import androidx.lifecycle.MutableLiveData
import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.DialogIntExpArriveResetBinding
import com.lukouguoji.module_base.base.BaseDialogModel
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import dev.utils.app.info.KeyValue
/**
* 国际出港运抵 - 状态重置对话框
*/
class IntExpArriveResetDialogModel(
private val callback: (IntExpArriveResetDialogModel) -> Unit
) : BaseDialogModel<DialogIntExpArriveResetBinding>(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_exp_arrive_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,74 @@
package com.lukouguoji.gjc.dialog
import android.content.Context
import androidx.lifecycle.MutableLiveData
import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.DialogIntExpInStorageBinding
import com.lukouguoji.module_base.base.BaseDialogModel
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import dev.utils.app.info.KeyValue
/**
* 国际出港仓库 - 入库操作对话框
*/
class IntExpInStorageDialogModel(
private val callback: (IntExpInStorageDialogModel) -> Unit
) : BaseDialogModel<DialogIntExpInStorageBinding>(DIALOG_TYPE_CENTER) {
// 库位列表
val locationList = MutableLiveData<List<KeyValue>>()
// 选中的库位存储的是code
val selectedLocationCode = MutableLiveData("")
// 库位ID (后端需要的code)
var locationId: String = ""
// 库位名称 (后端需要的name)
var locationName: String = ""
override fun layoutId(): Int {
return R.layout.dialog_int_exp_in_storage
}
override fun onDialogCreated(context: Context) {
binding.model = this
loadLocationList()
// 监听选择变化更新locationId和locationName
selectedLocationCode.observeForever { code ->
val selectedItem = locationList.value?.find { it.value == code }
locationId = selectedItem?.value ?: ""
locationName = selectedItem?.key ?: ""
}
}
/**
* 加载库位列表
*/
private fun loadLocationList() {
launchCollect({ NetApply.api.getLocationList(flag = 2) }) {
onSuccess = { result ->
val list = result.data?.map { it.toKeyValue() } ?: emptyList()
locationList.value = list
}
onFailed = { _, msg ->
showToast(msg ?: "加载库位列表失败")
}
}
}
/**
* 保存按钮点击
*/
fun onSaveClick() {
if (selectedLocationCode.value.verifyNullOrEmpty("请选择库位")) {
return
}
dismiss()
callback(this)
}
}

View File

@@ -5,7 +5,11 @@ import androidx.lifecycle.MutableLiveData
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.DialogIntExpModifyStorageBinding import com.lukouguoji.gjc.databinding.DialogIntExpModifyStorageBinding
import com.lukouguoji.module_base.base.BaseDialogModel import com.lukouguoji.module_base.base.BaseDialogModel
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import dev.utils.app.info.KeyValue
/** /**
* 国际出港 - 修改库位对话框 * 国际出港 - 修改库位对话框
@@ -14,8 +18,17 @@ class IntExpModifyStorageDialogModel(
private val callback: (IntExpModifyStorageDialogModel) -> Unit private val callback: (IntExpModifyStorageDialogModel) -> Unit
) : BaseDialogModel<DialogIntExpModifyStorageBinding>(DIALOG_TYPE_CENTER) { ) : BaseDialogModel<DialogIntExpModifyStorageBinding>(DIALOG_TYPE_CENTER) {
// 库位 // 库位列表
val location = MutableLiveData("") val locationList = MutableLiveData<List<KeyValue>>()
// 选中的库位存储的是code
val selectedLocationCode = MutableLiveData("")
// 库位ID (后端需要的code)
var locationId: String = ""
// 库位名称 (后端需要的name)
var locationName: String = ""
override fun layoutId(): Int { override fun layoutId(): Int {
return R.layout.dialog_int_exp_modify_storage return R.layout.dialog_int_exp_modify_storage
@@ -23,13 +36,36 @@ class IntExpModifyStorageDialogModel(
override fun onDialogCreated(context: Context) { override fun onDialogCreated(context: Context) {
binding.model = this binding.model = this
loadLocationList()
// 监听选择变化更新locationId和locationName
selectedLocationCode.observeForever { code ->
val selectedItem = locationList.value?.find { it.value == code }
locationId = selectedItem?.value ?: ""
locationName = selectedItem?.key ?: ""
}
}
/**
* 加载库位列表
*/
private fun loadLocationList() {
launchCollect({ NetApply.api.getLocationList(flag = 2) }) {
onSuccess = { result ->
val list = result.data?.map { it.toKeyValue() } ?: emptyList()
locationList.value = list
}
onFailed = { _, msg ->
showToast(msg ?: "加载库位列表失败")
}
}
} }
/** /**
* 保存按钮点击 * 保存按钮点击
*/ */
fun onSaveClick() { fun onSaveClick() {
if (location.value.verifyNullOrEmpty("输入库位")) { if (selectedLocationCode.value.verifyNullOrEmpty("选择库位")) {
return return
} }
dismiss() dismiss()

View File

@@ -0,0 +1,74 @@
package com.lukouguoji.gjc.dialog
import android.content.Context
import androidx.lifecycle.MutableLiveData
import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.DialogIntExpOutWaitingTransBinding
import com.lukouguoji.module_base.base.BaseDialogModel
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import dev.utils.app.info.KeyValue
/**
* 国际出港出库交接 - 待配运操作对话框
*/
class IntExpOutWaitingTransDialogModel(
private val callback: (IntExpOutWaitingTransDialogModel) -> Unit
) : BaseDialogModel<DialogIntExpOutWaitingTransBinding>(DIALOG_TYPE_CENTER) {
// 库位列表
val locationList = MutableLiveData<List<KeyValue>>()
// 选中的库位存储的是code
val selectedLocationCode = MutableLiveData("")
// 库位ID (后端需要的code)
var locationId: String = ""
// 库位名称 (后端需要的name)
var locationName: String = ""
override fun layoutId(): Int {
return R.layout.dialog_int_exp_out_waiting_trans
}
override fun onDialogCreated(context: Context) {
binding.model = this
loadLocationList()
// 监听选择变化更新locationId和locationName
selectedLocationCode.observeForever { code ->
val selectedItem = locationList.value?.find { it.value == code }
locationId = selectedItem?.value ?: ""
locationName = selectedItem?.key ?: ""
}
}
/**
* 加载库位列表
*/
private fun loadLocationList() {
launchCollect({ NetApply.api.getLocationList(flag = 2) }) {
onSuccess = { result ->
val list = result.data?.map { it.toKeyValue() } ?: emptyList()
locationList.value = list
}
onFailed = { _, msg ->
showToast(msg ?: "加载库位列表失败")
}
}
}
/**
* 保存按钮点击
*/
fun onSaveClick() {
if (selectedLocationCode.value.verifyNullOrEmpty("请选择库位")) {
return
}
dismiss()
callback(this)
}
}

View File

@@ -0,0 +1,66 @@
package com.lukouguoji.gjc.dialog
import android.content.Context
import androidx.lifecycle.MutableLiveData
import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.DialogIntExpTallyResetBinding
import com.lukouguoji.module_base.base.BaseDialogModel
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import dev.utils.app.info.KeyValue
/**
* 国际出港理货 - 状态重置对话框
*/
class IntExpTallyResetDialogModel(
private val callback: (IntExpTallyResetDialogModel) -> Unit
) : BaseDialogModel<DialogIntExpTallyResetBinding>(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_exp_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,21 @@
package com.lukouguoji.gjc.holder
import android.view.View
import com.lukouguoji.gjc.databinding.ItemGjcAssembleWeightEditBinding
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjcWarehouse
/**
* 国际出港-修改组装重量列表 ViewHolder
*/
class GjcAssembleWeightEditViewHolder(view: View) :
BaseViewHolder<GjcWarehouse, ItemGjcAssembleWeightEditBinding>(view) {
override fun onBind(item: Any?, position: Int) {
val warehouse = getItemBean(item) ?: return
binding.bean = warehouse
binding.position = position
binding.executePendingBindings()
}
}

View File

@@ -15,6 +15,16 @@ class GjcWeighingRecordViewHolder(view: View) :
override fun onBind(item: Any?, position: Int) { override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item)!! val bean = getItemBean(item)!!
binding.bean = bean binding.bean = bean
binding.executePendingBindings()
// 图标点击 - 切换选择状态
binding.ivIcon.setOnClickListener {
// 反转checked状态
bean.checked.set(!bean.checked.get())
// 立即更新UI (图片自动切换)
binding.executePendingBindings()
}
// 整行点击跳转到计重明细页 // 整行点击跳转到计重明细页
binding.ll.setOnClickListener { binding.ll.setOnClickListener {

View File

@@ -15,6 +15,17 @@ class GjcWeighingViewHolder(view: View) :
override fun onBind(item: Any?, position: Int) { override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item)!! val bean = getItemBean(item)!!
binding.bean = bean binding.bean = bean
binding.position = position
binding.executePendingBindings()
// 选择图标点击事件 - 切换选择状态
binding.ivIcon.setOnClickListener {
// 反转checked状态
bean.checked.set(!bean.checked.get())
// 立即更新UI (图片自动切换)
binding.executePendingBindings()
}
// 整行点击跳转到开始计重页面 // 整行点击跳转到开始计重页面
binding.ll.setOnClickListener { binding.ll.setOnClickListener {

View File

@@ -0,0 +1,26 @@
package com.lukouguoji.gjc.holder
import android.view.View
import com.lukouguoji.gjc.databinding.ItemIntExpArriveSubBinding
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjcHaWb
/**
* 国际出港-出港理货 子订单(分单) ViewHolder
*/
class IntExpArriveSubViewHolder(view: View) :
BaseViewHolder<GjcHaWb, ItemIntExpArriveSubBinding>(view) {
override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item) ?: return
binding.bean = bean
binding.position = position + 1 // 序号从 1 开始
binding.executePendingBindings()
// checkbox点击切换选择状态
binding.ivCheckbox.setOnClickListener {
bean.checked.set(!bean.checked.get())
binding.executePendingBindings()
}
}
}

View File

@@ -37,8 +37,8 @@ class IntExpArriveViewHolder(view: View) :
// ========== 初始化子列表 RecyclerView ========== // ========== 初始化子列表 RecyclerView ==========
setCommonAdapter( setCommonAdapter(
binding.rvSub, binding.rvSub,
IntExpTallySubViewHolder::class.java, IntExpArriveSubViewHolder::class.java,
R.layout.item_int_exp_tally_sub R.layout.item_int_exp_arrive_sub
) )
// 刷新子列表数据 // 刷新子列表数据

View File

@@ -0,0 +1,62 @@
package com.lukouguoji.gjc.holder
import android.view.View
import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.ItemIntExpAssembleBinding
import com.lukouguoji.module_base.adapter.setCommonAdapter
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjcUldUseBean
import com.lukouguoji.module_base.ktx.refresh
/**
* 国际出港-出港组装 列表项ViewHolder
* 参考出港运抵页面的实现
*/
class IntExpAssembleItemViewHolder(view: View) :
BaseViewHolder<GjcUldUseBean, ItemIntExpAssembleBinding>(view) {
override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item) ?: return
binding.bean = bean
binding.position = position
binding.executePendingBindings()
// 添加图标点击事件 - 切换选择状态
binding.ivIcon.setOnClickListener {
// 反转checked状态
bean.checked.set(!bean.checked.get())
// 立即更新UI图片自动切换
binding.executePendingBindings()
}
// ========== 展开按钮点击事件 ==========
// 通过回调通知ViewModel处理展开逻辑需要加载数据
binding.ivShow.setOnClickListener {
clickListener?.onItemClick(position, 1000) // type=1000表示展开操作
}
// ========== 侧滑菜单按钮点击事件 ==========
// 修改按钮
binding.btnEdit.setOnClickListener {
binding.swipeMenu.quickClose()
clickListener?.onItemClick(position, 2000) // type=2000表示修改操作
}
// 删除按钮
binding.btnDelete.setOnClickListener {
binding.swipeMenu.quickClose()
clickListener?.onItemClick(position, 2001) // type=2001表示删除操作
}
// ========== 初始化子列表 RecyclerView ==========
setCommonAdapter(
binding.rvSub,
IntExpAssembleSubViewHolder::class.java,
R.layout.item_int_exp_assemble_sub
)
// 刷新子列表数据
binding.rvSub.refresh(bean.waybillDetails ?: emptyList())
}
}

View File

@@ -0,0 +1,21 @@
package com.lukouguoji.gjc.holder
import android.view.View
import com.lukouguoji.gjc.databinding.ItemIntExpAssembleSubBinding
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjcWarehouse
/**
* 国际出港-出港组装 子列表ViewHolder
* 显示运单明细信息
*/
class IntExpAssembleSubViewHolder(view: View) :
BaseViewHolder<GjcWarehouse, ItemIntExpAssembleSubBinding>(view) {
override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item) ?: return
binding.bean = bean
binding.position = position + 1 // 序号从1开始
binding.executePendingBindings()
}
}

View File

@@ -20,20 +20,13 @@ class IntExpTallyViewHolder(view: View) :
binding.position = position binding.position = position
binding.executePendingBindings() binding.executePendingBindings()
// 图标点击切换选择状态(单向同步到子列表 // 图标点击切换选择状态(主单和分单独立,互不干扰
binding.ivIcon.setOnClickListener { binding.ivIcon.setOnClickListener {
// 切换主列表项的选择状态 // 切换主单自己的选择状态,不同步到分单
val newCheckedState = !bean.checked.get() bean.checked.set(!bean.checked.get())
bean.checked.set(newCheckedState)
// 单向同步:主列表选择状态同步到所有子列表项
bean.haWbList?.forEach { haWb ->
haWb.checked.set(newCheckedState)
}
// 刷新UI // 刷新UI
binding.executePendingBindings() binding.executePendingBindings()
binding.rvSub.adapter?.notifyDataSetChanged()
} }
// ========== 新增:展开按钮点击事件 ========== // ========== 新增:展开按钮点击事件 ==========

View File

@@ -33,11 +33,29 @@ class IntExpAssembleStartActivity :
private var waybillAdapter: CommonAdapter? = null private var waybillAdapter: CommonAdapter? = null
companion object { companion object {
private const val EXTRA_ULD_NO = "uld"
private const val EXTRA_EDIT_MODE = "edit_mode"
private const val EXTRA_LOAD_AREA = "load_area"
@JvmStatic @JvmStatic
fun start(context: Context) { fun start(context: Context) {
val starter = Intent(context, IntExpAssembleStartActivity::class.java) val starter = Intent(context, IntExpAssembleStartActivity::class.java)
context.startActivity(starter) context.startActivity(starter)
} }
/**
* 从列表页"修改"模式启动
* @param uldNo ULD编号将被锁定整个页面生命周期内不可编辑
* @param loadArea 组装位置(用于自动选中对应的组装位置)
*/
@JvmStatic
fun startForEdit(context: Context, uldNo: String, loadArea: String) {
val starter = Intent(context, IntExpAssembleStartActivity::class.java)
.putExtra(EXTRA_ULD_NO, uldNo)
.putExtra(EXTRA_EDIT_MODE, true)
.putExtra(EXTRA_LOAD_AREA, loadArea)
context.startActivity(starter)
}
} }
override fun layoutId() = R.layout.activity_int_exp_assemble_start override fun layoutId() = R.layout.activity_int_exp_assemble_start
@@ -70,6 +88,23 @@ class IntExpAssembleStartActivity :
// 观察数据变化 // 观察数据变化
observeData() observeData()
// 处理修改模式(从列表页侧滑"修改"跳转)
handleEditModeIntent()
}
/**
* 处理修改模式的 Intent 参数
*/
private fun handleEditModeIntent() {
val isEditMode = intent.getBooleanExtra(EXTRA_EDIT_MODE, false)
if (isEditMode) {
val uldNo = intent.getStringExtra(EXTRA_ULD_NO) ?: ""
val loadArea = intent.getStringExtra(EXTRA_LOAD_AREA) ?: ""
if (uldNo.isNotEmpty()) {
viewModel.initFromEditMode(uldNo, loadArea)
}
}
} }
/** /**

View File

@@ -0,0 +1,220 @@
package com.lukouguoji.gjc.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.GjcUldUseBean
import com.lukouguoji.module_base.bean.GjcWarehouse
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 GjcAssembleWeightEditViewModel : BaseViewModel() {
///////////////////////////////////////////////////////////////////////////
// 数据字段
///////////////////////////////////////////////////////////////////////////
// ULD信息Bean从列表页传入
val uldBean = MutableLiveData<GjcUldUseBean>()
// 运单列表
val waybillList = MutableLiveData<List<GjcWarehouse>>(emptyList())
///////////////////////////////////////////////////////////////////////////
// ULD信息显示字段
///////////////////////////////////////////////////////////////////////////
val uldNo = MutableLiveData("") // ULD编号
val totalPc = MutableLiveData("") // 总件数
val totalWeight = MutableLiveData("") // 总重量
val cargoWeight = MutableLiveData("") // 货重
///////////////////////////////////////////////////////////////////////////
// 底部统计字段
///////////////////////////////////////////////////////////////////////////
val sumCargoWeight = MutableLiveData("0") // 总货重
val weightError = MutableLiveData("0%") // 重量误差百分比
// 传递参数用于API调用
private var useId: Long = 0
private var uld: String = ""
private var fdate: String = ""
private var fno: String = ""
init {
// 监听 waybillList 变化,自动触发统计计算
waybillList.observeForever {
calculateStatistics()
}
}
///////////////////////////////////////////////////////////////////////////
// 初始化
///////////////////////////////////////////////////////////////////////////
fun initOnCreated(intent: Intent) {
// 接收传入的完整 Bean 对象
val bean = intent.getSerializableExtra(Constant.Key.BEAN) as? GjcUldUseBean
bean?.let {
uldBean.value = it
// 提取ULD信息字段
uldNo.value = it.uld
totalPc.value = it.pc.toString()
totalWeight.value = it.totalWeight.toString()
cargoWeight.value = it.cargoWeight.toString()
// 保存参数用于API调用
useId = it.useId
uld = it.uld
fdate = it.fdate
fno = it.fno
// 加载运单数据
loadData()
} ?: run {
showToast("参数错误")
}
}
///////////////////////////////////////////////////////////////////////////
// 数据加载
///////////////////////////////////////////////////////////////////////////
private fun loadData() {
val params = mapOf(
"useId" to useId,
"uld" to uld,
"fdate" to fdate,
"fno" to fno
).toRequestBody()
launchLoadingCollect({ NetApply.api.getAssembledWaybillsByUld(params) }) {
onSuccess = { result ->
val list = result.data ?: emptyList()
// 为每个运单设置数据变化回调
list.forEach { warehouse ->
warehouse.onDataChanged = {
// 数据变化时重新计算统计
calculateStatistics()
}
}
waybillList.value = list
if (list.isEmpty()) {
showToast("暂无运单数据")
}
}
onFailed = { code, msg ->
showToast("加载失败:$msg")
}
}
}
/**
* 计算统计数据:总货重、重量误差
* - 总货重:运单列表中所有 checkInWeight入库重量/组装重量)之和
* - 重量误差:(总货重 - ULD货重) / ULD货重 * 100%
*/
private fun calculateStatistics() {
val records = waybillList.value ?: emptyList()
// 计算总货重(所有运单 checkInWeight 之和,即列表中显示的重量)
val sumWeight = records.sumOf { it.checkInWeight }
sumCargoWeight.value = String.format("%.2f", sumWeight)
// 计算重量误差百分比相对于ULD的货重
val uldCargoWeight = cargoWeight.value?.toDoubleOrNull() ?: 0.0
val error = if (sumWeight > 0 && uldCargoWeight > 0) {
((sumWeight - uldCargoWeight) / uldCargoWeight * 100)
} else {
0.0
}
weightError.value = String.format("%.1f%%", error)
}
///////////////////////////////////////////////////////////////////////////
// 按钮事件
///////////////////////////////////////////////////////////////////////////
/**
* 点击"取消"按钮
*/
fun onCancelClick() {
getTopActivity().finish()
}
/**
* 点击"保存"按钮
*/
fun onSaveClick() {
val records = waybillList.value ?: return
if (records.isEmpty()) {
showToast("没有可保存的数据")
return
}
// 验证数据
if (!validateRecords(records)) return
// 调用批量更新接口
saveRecords(records)
}
///////////////////////////////////////////////////////////////////////////
// 业务逻辑
///////////////////////////////////////////////////////////////////////////
/**
* 验证数据
*/
private fun validateRecords(records: List<GjcWarehouse>): Boolean {
records.forEachIndexed { index, record ->
if (record.weight < 0) {
showToast("${index + 1}条记录的重量不能为负数")
return false
}
}
return true
}
/**
* 批量保存运单重量
*/
private fun saveRecords(records: List<GjcWarehouse>) {
launchLoadingCollect({
NetApply.api.updateIntExpAssemble(records.toRequestBody())
}) {
onSuccess = { result ->
if (result.verifySuccess()) {
showToast("保存成功")
// 发送刷新事件通知列表页
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
// 关闭页面
getTopActivity().finish()
} else {
showToast("保存失败")
}
}
onFailed = { code, msg ->
showToast("保存失败:$msg")
}
}
}
}

View File

@@ -10,7 +10,6 @@ import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.GjcUldUseBean import com.lukouguoji.module_base.bean.GjcUldUseBean
import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.http.net.DiBangWeightModel
import com.lukouguoji.module_base.http.net.NetApply import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.impl.FlowBus import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.ktx.formatDate import com.lukouguoji.module_base.ktx.formatDate
@@ -24,7 +23,6 @@ import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import com.lukouguoji.module_base.model.BluetoothDialogModel import com.lukouguoji.module_base.model.BluetoothDialogModel
import com.lukouguoji.module_base.model.ScanModel import com.lukouguoji.module_base.model.ScanModel
import com.lukouguoji.module_base.util.Common import com.lukouguoji.module_base.util.Common
import com.lukouguoji.module_base.util.DictUtils
import com.lukouguoji.module_base.util.PrinterUtils import com.lukouguoji.module_base.util.PrinterUtils
import dev.utils.app.info.KeyValue import dev.utils.app.info.KeyValue
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -39,6 +37,9 @@ class GjcBoxWeighingAddViewModel : BaseViewModel() {
// 数据Bean // 数据Bean
val dataBean = MutableLiveData(GjcUldUseBean()) val dataBean = MutableLiveData(GjcUldUseBean())
// 保存 queryUsingUldByUld 返回的数据(用于复磅场景)
private var usingUldData: GjcUldUseBean? = null
// 地磅集成 - 暂时注释 // 地磅集成 - 暂时注释
// val diBangModel = DiBangWeightModel() // val diBangModel = DiBangWeightModel()
val channel = MutableLiveData("") // 通道号用于控制地磅key val channel = MutableLiveData("") // 通道号用于控制地磅key
@@ -59,7 +60,7 @@ class GjcBoxWeighingAddViewModel : BaseViewModel() {
// 下拉选择数据源 // 下拉选择数据源
val passagewayList = MutableLiveData<List<KeyValue>>() // 通道号列表 val passagewayList = MutableLiveData<List<KeyValue>>() // 通道号列表
val piCloseList = MutableLiveData<List<KeyValue>>() // 探板收口列表 val plCloseList = MutableLiveData<List<KeyValue>>() // 探板收口列表
// 打印挂签 // 打印挂签
val printTag = MutableLiveData(false) val printTag = MutableLiveData(false)
@@ -105,7 +106,7 @@ class GjcBoxWeighingAddViewModel : BaseViewModel() {
// 加载下拉列表数据 // 加载下拉列表数据
loadPassagewayList() loadPassagewayList()
loadPiCloseList() loadPlCloseList()
// 初始化航班日期为今天 // 初始化航班日期为今天
val today = Date().formatDate() val today = Date().formatDate()
@@ -204,12 +205,18 @@ class GjcBoxWeighingAddViewModel : BaseViewModel() {
/** /**
* 加载探板收口列表 * 加载探板收口列表
*/ */
private fun loadPiCloseList() { private fun loadPlCloseList() {
// 探板收口选项(是/否) launchCollect({
piCloseList.value = listOf( NetApply.api.getDictList("PICLOSE")
KeyValue("1", ""), }) {
KeyValue("0", "") onSuccess = {
) // 将 DictIdValueBean 转换为 KeyValue
// 显示和提交都使用 value 字段
plCloseList.value = (it.data ?: emptyList()).map { b ->
KeyValue(b.value, b.value)
}
}
}
} }
/** /**
@@ -289,6 +296,9 @@ class GjcBoxWeighingAddViewModel : BaseViewModel() {
lastQueriedFlight = "" lastQueriedFlight = ""
lastQueriedCarId = "" lastQueriedCarId = ""
lastQueriedUld = "" lastQueriedUld = ""
// 重置 ULD 使用记录
usingUldData = null
} }
/** /**
@@ -302,21 +312,31 @@ class GjcBoxWeighingAddViewModel : BaseViewModel() {
bean.uld = uldNo.value ?: "" bean.uld = uldNo.value ?: ""
bean.fno = flightNo.value ?: "" bean.fno = flightNo.value ?: ""
bean.fdate = flightDate.value ?: "" bean.fdate = flightDate.value ?: ""
bean.passageway = passagewayList.value?.firstOrNull{ it.value == channel.value }?.key ?: ""
bean.passagewayId = channel.value ?: ""
// 验证必填字段 // 验证必填字段
if (bean.carId.verifyNullOrEmpty("请输入架子车号")) return if (bean.carId.verifyNullOrEmpty("请输入架子车号")) return
if (bean.uld.verifyNullOrEmpty("请输入ULD编号")) return if (bean.uld.verifyNullOrEmpty("请输入ULD编号")) return
if (bean.passageway.verifyNullOrEmpty("请选择通道号")) return
// 提交数据 // 验证是否已组装(复磅场景必须有 useId
val params = mapOf( if (usingUldData == null || usingUldData?.useId == 0L) {
showToast("未组装,不可复磅")
return
}
// 构建基础提交参数
val baseParams = mutableMapOf(
"carId" to bean.carId, "carId" to bean.carId,
"passageway" to bean.passageway, "passageway" to bean.passageway,
"passagewayId" to bean.passagewayId,
"uld" to bean.uld, "uld" to bean.uld,
"dgrCode" to bean.dgrCode, "dgrCode" to bean.dgrCode,
"boardType" to bean.boardType, "boardType" to bean.boardType,
"height" to bean.height, "height" to bean.height,
"piClose" to bean.piClose, "plClose" to bean.plClose,
"piCloseSize" to bean.piCloseSize, "plCloseSize" to bean.plCloseSize,
"carWeight" to bean.carWeight, "carWeight" to bean.carWeight,
"uldWeight" to bean.uldWeight, "uldWeight" to bean.uldWeight,
"fdate" to bean.fdate, "fdate" to bean.fdate,
@@ -327,7 +347,38 @@ class GjcBoxWeighingAddViewModel : BaseViewModel() {
"netWeight" to bean.netWeight, "netWeight" to bean.netWeight,
"cargoWeight" to bean.cargoWeight, "cargoWeight" to bean.cargoWeight,
"printTag" to printTag.value "printTag" to printTag.value
).toRequestBody(removeEmptyOrNull = true) )
// 如果有 usingUldData复磅场景将其所有字段添加到提交参数
usingUldData?.let { usingData ->
baseParams["useId"] = usingData.useId
baseParams["cargoType"] = usingData.cargoType
baseParams["consumeWeight"] = usingData.consumeWeight
baseParams["volume"] = usingData.volume
baseParams["maxVolume"] = usingData.maxVolume
baseParams["maxWeight"] = usingData.maxWeight
baseParams["fdep"] = usingData.fdep
baseParams["fClose"] = usingData.fClose
baseParams["wtId"] = usingData.wtId
baseParams["wtUsername"] = usingData.wtUsername
baseParams["wtDate"] = usingData.wtDate
baseParams["ldId"] = usingData.ldId
baseParams["ldUserName"] = usingData.ldUserName
baseParams["ldDate"] = usingData.ldDate
baseParams["hoId"] = usingData.hoId
baseParams["hoUserName"] = usingData.hoUserName
baseParams["hoDate"] = usingData.hoDate
baseParams["uldCarrier"] = usingData.uldCarrier
baseParams["uldFlag"] = usingData.uldFlag
baseParams["status"] = usingData.status
baseParams["passagewayName"] = usingData.passagewayName
baseParams["location"] = usingData.location
baseParams["checkFlag"] = usingData.checkFlag
baseParams["emptyUld"] = usingData.emptyUld
}
// 转换为 RequestBody
val params = baseParams.toRequestBody(removeEmptyOrNull = true)
launchLoadingCollect({ launchLoadingCollect({
NetApply.api.submitGjcBoxWeighing(params) NetApply.api.submitGjcBoxWeighing(params)
@@ -345,7 +396,7 @@ class GjcBoxWeighingAddViewModel : BaseViewModel() {
viewModelScope.launch { viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh") FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
} }
getTopActivity().finish() // getTopActivity().finish()
} else { } else {
showToast(result.msg.noNull("添加失败")) showToast(result.msg.noNull("添加失败"))
} }
@@ -410,6 +461,26 @@ class GjcBoxWeighingAddViewModel : BaseViewModel() {
} }
} }
} }
// 查询正在使用的 ULD 记录(复磅场景)
launchCollect({ NetApply.api.queryUsingUldByUld(uldNo) }) {
onSuccess = { result ->
val usingData = result.data
if (usingData != null && usingData.useId > 0) {
// 保存返回的数据,用于提交时传递
usingUldData = usingData
} else {
// 没有 useId说明未组装不可复磅
usingUldData = null
showToast("未组装,不可复磅")
}
}
onFailed = { _, _ ->
// 接口报错时也认为未组装
usingUldData = null
showToast("未组装,不可复磅")
}
}
} }
/** /**

View File

@@ -33,7 +33,8 @@ class GjcBoxWeighingViewModel : BasePageViewModel() {
// 统计数据 // 统计数据
val totalCount = MutableLiveData("0") // 合计票数 val totalCount = MutableLiveData("0") // 合计票数
val totalPc = MutableLiveData("0") // 总件数 val totalPc = MutableLiveData("0")
val cargoWeight = MutableLiveData("0")// 总件数
val totalWeight = MutableLiveData("0") // 总重量 val totalWeight = MutableLiveData("0") // 总重量
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@@ -116,6 +117,7 @@ class GjcBoxWeighingViewModel : BasePageViewModel() {
val data = result.data val data = result.data
totalCount.value = (data?.wbNumber ?: 0).toString() totalCount.value = (data?.wbNumber ?: 0).toString()
totalPc.value = (data?.totalPc ?: 0).toString() totalPc.value = (data?.totalPc ?: 0).toString()
cargoWeight.value = (data?.cargoWeight ?: 0).toString()
totalWeight.value = (data?.totalWeight ?: 0.0).toString() totalWeight.value = (data?.totalWeight ?: 0.0).toString()
} }
} }

View File

@@ -144,22 +144,24 @@ class GjcInspectionDetailsViewModel : BaseViewModel() {
* @param attach 附件对象 * @param attach 附件对象
*/ */
fun onAttachClick(attach: ComAttach) { fun onAttachClick(attach: ComAttach) {
// 处理URL先处理转义字符再判断是否需要组装完整URL
val url = processAttachUrl(attach.path)
when { when {
// 图片格式使用PreviewActivity预览 // 图片格式使用PreviewActivity预览
attach.name.endsWith(".jpg", true) || attach.name.endsWith(".jpg", true) ||
attach.name.endsWith(".png", true) || attach.name.endsWith(".png", true) ||
attach.name.endsWith(".jpeg", true) -> { attach.name.endsWith(".jpeg", true) -> {
val fileBean = FileBean( val fileBean = FileBean(
// url = MediaUtil.fillUrl(attach.path), url = url,
// 服务器返回全url无需本地组装 path = url,
url = attach.path, originalPic = url
originalPic = attach.path
) )
PreviewActivity.start(getTopActivity(), listOf(fileBean)) PreviewActivity.start(getTopActivity(), listOf(fileBean))
} }
// PDF格式使用PdfPreviewActivity预览 // PDF格式使用PdfPreviewActivity预览
attach.name.endsWith(".pdf", true) -> { attach.name.endsWith(".pdf", true) -> {
PdfPreviewActivity.start(getTopActivity(), attach.path) PdfPreviewActivity.start(getTopActivity(), url)
} }
// 其他格式 // 其他格式
else -> { else -> {
@@ -167,4 +169,21 @@ class GjcInspectionDetailsViewModel : BaseViewModel() {
} }
} }
} }
/**
* 处理附件URL
* 1. 处理转义字符(如 \/ 替换为 /
* 2. 如果不是以http开头则使用MediaUtil.fillUrl组装完整URL
*/
private fun processAttachUrl(path: String): String {
// 先处理转义字符:\/ -> /
val cleanPath = path.replace("\\/", "/")
// 判断是否已是完整URL
return if (cleanPath.startsWith("http://", true) || cleanPath.startsWith("https://", true)) {
cleanPath
} else {
MediaUtil.fillUrl(cleanPath)
}
}
} }

View File

@@ -48,8 +48,9 @@ class GjcInspectionViewModel : BasePageViewModel() {
val auditStatusList = MutableLiveData( val auditStatusList = MutableLiveData(
listOf( listOf(
KeyValue("全部", ""), KeyValue("全部", ""),
KeyValue("未审核", "0"), KeyValue("未审核", "1"),
KeyValue("通过", "1"), KeyValue("通过", "2"),
KeyValue("退回", "3"),
) )
) )

View File

@@ -7,9 +7,12 @@ import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.holder.GjcWeighingRecordViewHolder import com.lukouguoji.gjc.holder.GjcWeighingRecordViewHolder
import com.lukouguoji.module_base.base.BasePageViewModel import com.lukouguoji.module_base.base.BasePageViewModel
import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.bean.GjcWeighingRecordBean
import com.lukouguoji.module_base.http.net.NetApply import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.launchCollect import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.launchLoadingCollect 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.toRequestBody
import com.lukouguoji.module_base.model.ScanModel import com.lukouguoji.module_base.model.ScanModel
import com.lukouguoji.module_base.util.DictUtils import com.lukouguoji.module_base.util.DictUtils
@@ -92,10 +95,35 @@ class GjcWeighingRecordViewModel : BasePageViewModel() {
} }
/** /**
* 运抵申报按钮点击(暂未实现) * 运抵申报按钮点击
*/ */
fun declareClick() { fun declareClick() {
// TODO: 跳转到运抵申报页面(待实现) // 获取列表数据
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcWeighingRecordBean> ?: emptyList()
// 过滤选中项
val selectedItems = list.filter { it.isSelected }
when (selectedItems.size) {
0 -> {
// 没有选择单据:直接跳转(不带参数)
com.alibaba.android.arouter.launcher.ARouter.getInstance()
.build(com.lukouguoji.module_base.router.ARouterConstants.ACTIVITY_URL_INT_EXP_ARRIVE)
.navigation()
}
1 -> {
// 选择一个单据:跳转到出港运抵页面,携带运单号
val waybillNo = selectedItems[0].wbNo
com.alibaba.android.arouter.launcher.ARouter.getInstance()
.build(com.lukouguoji.module_base.router.ARouterConstants.ACTIVITY_URL_INT_EXP_ARRIVE)
.withString("wbNoParam", waybillNo)
.navigation()
}
else -> {
// 选择多个单据Toast 提示
showToast("只能选择一个单据")
}
}
} }
/** /**
@@ -110,7 +138,7 @@ class GjcWeighingRecordViewModel : BasePageViewModel() {
"fno" to flightNo.value!!.ifEmpty { null }, "fno" to flightNo.value!!.ifEmpty { null },
"agentCode" to agentCode.value!!.ifEmpty { null }, "agentCode" to agentCode.value!!.ifEmpty { null },
"spCode" to spCode.value!!.ifEmpty { null }, "spCode" to spCode.value!!.ifEmpty { null },
"likeNo" to waybillNo.value!!.ifEmpty { null }, "wbNo" to waybillNo.value!!.ifEmpty { null },
).toRequestBody() ).toRequestBody()
// 构建查询参数(统计接口 - 使用相同的搜索条件) // 构建查询参数(统计接口 - 使用相同的搜索条件)
@@ -119,7 +147,7 @@ class GjcWeighingRecordViewModel : BasePageViewModel() {
"fno" to flightNo.value!!.ifEmpty { null }, "fno" to flightNo.value!!.ifEmpty { null },
"agentCode" to agentCode.value!!.ifEmpty { null }, "agentCode" to agentCode.value!!.ifEmpty { null },
"spCode" to spCode.value!!.ifEmpty { null }, "spCode" to spCode.value!!.ifEmpty { null },
"likeNo" to waybillNo.value!!.ifEmpty { null }, "wbNo" to waybillNo.value!!.ifEmpty { null },
).toRequestBody() ).toRequestBody()
// 获取列表数据显示loading // 获取列表数据显示loading

View File

@@ -36,20 +36,24 @@ import java.util.Date
*/ */
class GjcWeighingStartViewModel : BaseViewModel() { class GjcWeighingStartViewModel : BaseViewModel() {
// 运单ID从列表页传入 // 运单ID从列表页传入,或通过运单号查询获得
var maWbId: Long = 0 var maWbId: Long = 0
// 运单数据Bean // 运单数据Bean
val maWbBean = MutableLiveData(GjcMaWb()) val maWbBean = MutableLiveData(GjcMaWb())
// 用于防止重复查询的标记
private var lastQueriedWbNo: String = ""
private var lastQueriedCarId: String = ""
// 航班日期格式化为字符串用于DataBinding // 航班日期格式化为字符串用于DataBinding
val flightDate = MutableLiveData<String>(DateUtils.getCurrentTime().formatDate()) val flightDate = MutableLiveData<String>(DateUtils.getCurrentTime().formatDate())
// 地磅集成 // 地磅集成(已改为手动输入,暂时注释)
val diBangModel = DiBangWeightModel() // val diBangModel = DiBangWeightModel()
val channel = MutableLiveData("") // 通道号用于控制地磅key val channel = MutableLiveData("") // 通道号
// 地磅称重显示 // 地磅称重显示(手动输入,单向同步到运抵重量)
val diBangWeight = MutableLiveData("0") // 地磅重量(右上角黄色显示区域) val diBangWeight = MutableLiveData("0") // 地磅重量(右上角黄色显示区域)
// 可编辑字段(用于双向绑定) // 可编辑字段(用于双向绑定)
@@ -78,15 +82,10 @@ class GjcWeighingStartViewModel : BaseViewModel() {
// 获取传入的运单ID // 获取传入的运单ID
maWbId = intent.getLongExtra(Constant.Key.MAWB_ID, 0) maWbId = intent.getLongExtra(Constant.Key.MAWB_ID, 0)
// 监听地磅重量变化 // 监听地磅称重输入,单向同步到运抵重量
diBangModel.weight.observe(activity as LifecycleOwner) { weight -> diBangWeight.observe(activity as LifecycleOwner) { weight ->
val w = weight?.toDoubleOrNull() ?: 0.0 // 同步到运抵重量(单向,不做反向同步)
diBangWeight.value = if (w > 0) String.format("%.0f", w) else "0" arriveWeight.value = weight ?: "0"
}
// 监听通道号变化设置地磅的key
channel.observe(activity as LifecycleOwner) {
diBangModel.key = it ?: ""
} }
// 监听运抵重量变化,自动计算运抵体积 // 监听运抵重量变化,自动计算运抵体积
@@ -190,6 +189,67 @@ class GjcWeighingStartViewModel : BaseViewModel() {
} }
} }
/**
* 运单号输入完成时调用(添加模式专用)
* 当用户输入完整运单号后,自动根据运单号查询并填充表单
*/
fun onWaybillNoInputComplete() {
val wbNo = maWbBean.value?.wbNo ?: ""
// 验证运单号是否为空
if (wbNo.isEmpty()) {
return
}
// 防止重复查询
if (wbNo == lastQueriedWbNo) {
return
}
// 验证运单号长度11位
if (wbNo.length != 11) {
showToast("请输入完整的11位运单号")
return
}
// 更新查询标记
lastQueriedWbNo = wbNo
// 直接根据运单号查询运单详情
launchLoadingCollect({ NetApply.api.getIntExpCheckInWbByNo(wbNo) }) {
onSuccess = { result ->
val data = result.data
if (data != null) {
// 保存 maWbId
maWbId = data.maWbId ?: 0
// 更新整个 maWbBean
maWbBean.value = data
// 更新航班日期字符串
flightDate.value = data.fdate?.formatDate() ?: ""
// 更新备注
pageRemark.value = data.remark
// 加载实时计重数据(如果 maWbId 有效)
if (maWbId > 0) {
loadRealTimeRecord()
}
} else {
showToast("未找到该运单信息")
// 清空查询标记,允许重新查询
lastQueriedWbNo = ""
}
}
onFailed = { code, msg ->
showToast("查询失败: $msg")
// 清空查询标记,允许重新查询
lastQueriedWbNo = ""
}
}
}
/** /**
* 航班日期点击 * 航班日期点击
*/ */
@@ -227,6 +287,30 @@ class GjcWeighingStartViewModel : BaseViewModel() {
ScanModel.startScan(getTopActivity(), Constant.RequestCode.CAR) ScanModel.startScan(getTopActivity(), Constant.RequestCode.CAR)
} }
/**
* 托盘车号输入完成时调用
* 当用户输入完整托盘车号后,自动查询平板车信息并填充自重
*/
fun onCarIdInputComplete() {
val carId = maWbBean.value?.carId ?: ""
// 验证托盘车号是否为空
if (carId.isEmpty()) {
return
}
// 防止重复查询
if (carId == lastQueriedCarId) {
return
}
// 更新查询标记
lastQueriedCarId = carId
// 调用接口查询平板车信息
queryCarWeight(carId)
}
/** /**
* 托盘车号输入后查询自重 * 托盘车号输入后查询自重
*/ */
@@ -236,18 +320,26 @@ class GjcWeighingStartViewModel : BaseViewModel() {
return return
} }
val params = mapOf(
"carId" to carId
).toRequestBody()
launchCollect({ launchCollect({
// 查询托盘车自重接口(待确认具体接口) NetApply.api.getFlatcarInfo(carId)
// 暂时使用模拟数据
// NetApply.api.queryCarWeight(params)
carWeight.value = "0" // 模拟返回
}) { }) {
onSuccess = { onSuccess = { result ->
// carWeight.value = it.data?.weight?.toString() ?: "0" val data = result.data
if (data != null) {
// 填充托盘车自重
carWeight.value = data.carWeight.ifEmpty { "0" }
} else {
showToast("未找到该平板车信息")
carWeight.value = "0"
// 清空查询标记,允许重新查询
lastQueriedCarId = ""
}
}
onFailed = { code, msg ->
showToast("查询平板车失败: $msg")
carWeight.value = "0"
// 清空查询标记,允许重新查询
lastQueriedCarId = ""
} }
} }
} }
@@ -263,7 +355,17 @@ class GjcWeighingStartViewModel : BaseViewModel() {
if (bean.fno.verifyNullOrEmpty("请输入航班号")) return if (bean.fno.verifyNullOrEmpty("请输入航班号")) return
if (channel.value.verifyNullOrEmpty("请选择通道号")) return if (channel.value.verifyNullOrEmpty("请选择通道号")) return
// 2. 收集当前表单数据,更新到 bean // 2. 校验件数: 运抵件数 + 实时件数 不能大于 预配件数
val realTimePcVal = realTimePc.value?.toLongOrNull() ?: 0L
val arrivePcVal = arrivePc.value?.toLongOrNull() ?: bean.arrivePc ?: 0L
val preallocatedPc = bean.pc ?: 0L
if (arrivePcVal + realTimePcVal > preallocatedPc) {
showToast("运抵件数 + 实时件数不能大于预配件数")
return
}
// 3. 收集当前表单数据,更新到 bean
bean.apply { bean.apply {
// 更新运抵数据(如果用户已编辑) // 更新运抵数据(如果用户已编辑)
arrivePc = this@GjcWeighingStartViewModel.arrivePc.value?.toLongOrNull() ?: arrivePc arrivePc = this@GjcWeighingStartViewModel.arrivePc.value?.toLongOrNull() ?: arrivePc
@@ -272,7 +374,8 @@ class GjcWeighingStartViewModel : BaseViewModel() {
arriveVolume = arriveVolume =
this@GjcWeighingStartViewModel.arriveVolume.value?.toDoubleOrNull() ?: arriveVolume this@GjcWeighingStartViewModel.arriveVolume.value?.toDoubleOrNull() ?: arriveVolume
// 添加通道号 // 添加通道号
passageWay = this@GjcWeighingStartViewModel.channel.value passageWay = this@GjcWeighingStartViewModel.channelList.value?.firstOrNull{ it.value == channel.value }?.key ?: ""
passageWayId = this@GjcWeighingStartViewModel.channel.value
remark = pageRemark.value remark = pageRemark.value
} }
@@ -326,8 +429,17 @@ class GjcWeighingStartViewModel : BaseViewModel() {
if (bean.fno.verifyNullOrEmpty("请输入航班号")) return if (bean.fno.verifyNullOrEmpty("请输入航班号")) return
if (channel.value.verifyNullOrEmpty("请选择通道号")) return if (channel.value.verifyNullOrEmpty("请选择通道号")) return
// 校验件数: 运抵件数 + 实时件数 不能大于 预配件数
val realTimePcVal = realTimePc.value?.toLongOrNull() ?: 0L
val arrivePcVal = arrivePc.value?.toLongOrNull() ?: bean.arrivePc ?: 0L
val preallocatedPc = bean.pc ?: 0L
if (arrivePcVal + realTimePcVal > preallocatedPc) {
showToast("运抵件数 + 实时件数不能大于预配件数")
return
}
// 从编辑字段获取数值 // 从编辑字段获取数值
val arrivePcVal = arrivePc.value?.toLongOrNull() ?: bean.arrivePc
val arriveWeightVal = arriveWeight.value?.toDoubleOrNull() ?: bean.arriveWeight val arriveWeightVal = arriveWeight.value?.toDoubleOrNull() ?: bean.arriveWeight
val arriveVolumeVal = arriveVolume.value?.toDoubleOrNull() ?: bean.arriveVolume val arriveVolumeVal = arriveVolume.value?.toDoubleOrNull() ?: bean.arriveVolume
@@ -361,7 +473,8 @@ class GjcWeighingStartViewModel : BaseViewModel() {
"carId" to bean.carId, "carId" to bean.carId,
"remark" to pageRemark.value, "remark" to pageRemark.value,
"checkIn" to "1", // 收运状态设置为已收运 "checkIn" to "1", // 收运状态设置为已收运
"passageWay" to channel.value // 通道号参数 "passageWayId" to channel.value, // 通道号参数
"passageWay" to (channelList.value?.firstOrNull{ it.value == channel.value }?.key ?: "")
).toRequestBody(removeEmptyOrNull = true) ).toRequestBody(removeEmptyOrNull = true)
launchLoadingCollect({ launchLoadingCollect({
@@ -415,6 +528,6 @@ class GjcWeighingStartViewModel : BaseViewModel() {
*/ */
override fun onCleared() { override fun onCleared() {
super.onCleared() super.onCleared()
diBangModel.cancelLooperGet() // diBangModel.cancelLooperGet() // 已改为手动输入,不再使用地磅自动读取
} }
} }

View File

@@ -3,22 +3,30 @@ package com.lukouguoji.gjc.viewModel
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.activity.GjcWeighingRecordListActivity import com.lukouguoji.gjc.activity.GjcWeighingRecordListActivity
import com.lukouguoji.gjc.activity.GjcWeighingStartActivity import com.lukouguoji.gjc.activity.GjcWeighingStartActivity
import com.lukouguoji.gjc.holder.GjcWeighingViewHolder import com.lukouguoji.gjc.holder.GjcWeighingViewHolder
import com.lukouguoji.module_base.base.BasePageViewModel import com.lukouguoji.module_base.base.BasePageViewModel
import com.lukouguoji.module_base.bean.GjcMaWb
import com.lukouguoji.module_base.bean.GjcWeighingBean
import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.http.net.NetApply import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.launchCollect import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.launchLoadingCollect import com.lukouguoji.module_base.ktx.launchLoadingCollect
import com.lukouguoji.module_base.ktx.formatDate import com.lukouguoji.module_base.ktx.formatDate
import com.lukouguoji.module_base.ktx.noNull
import com.lukouguoji.module_base.ktx.showToast import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.model.ScanModel import com.lukouguoji.module_base.model.ScanModel
import com.lukouguoji.module_base.util.DictUtils import com.lukouguoji.module_base.util.DictUtils
import dev.utils.app.info.KeyValue import dev.utils.app.info.KeyValue
import dev.utils.common.DateUtils import dev.utils.common.DateUtils
import kotlinx.coroutines.launch
/** /**
* 国际出港计重 ViewModel * 国际出港计重 ViewModel
@@ -45,6 +53,18 @@ class GjcWeighingViewModel : BasePageViewModel() {
val totalPc = MutableLiveData("0") // 总件数 val totalPc = MutableLiveData("0") // 总件数
val totalWeight = MutableLiveData("0") // 总重量 val totalWeight = MutableLiveData("0") // 总重量
// 全选状态
val isAllChecked = MutableLiveData(false)
init {
// 监听全选状态,自动更新所有列表项
isAllChecked.observeForever { checked ->
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcWeighingBean> ?: return@observeForever
list.forEach { it.checked.set(checked) }
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
}
}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// 方法区 // 方法区
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@@ -109,11 +129,56 @@ class GjcWeighingViewModel : BasePageViewModel() {
GjcWeighingRecordListActivity.start(getTopActivity()) GjcWeighingRecordListActivity.start(getTopActivity())
} }
/**
* 全选按钮点击 (切换全选状态)
*/
fun checkAllClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcWeighingBean> ?: return
// 切换全选状态
val shouldCheckAll = !isAllChecked.value!!
list.forEach { it.checked.set(shouldCheckAll) }
isAllChecked.value = shouldCheckAll
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
}
/** /**
* 提前运抵 * 提前运抵
*/ */
fun arrivedAhead() { fun arrivedAhead() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcWeighingBean> ?: return
val selectedItems = list.filter { it.isSelected }
if (selectedItems.isEmpty()) {
showToast("请选择要提前运抵的运单")
return
}
// 转换为GjcMaWb对象列表只传递必要字段
val maWbList = selectedItems.map { bean ->
GjcMaWb(
maWbId = bean.maWbId,
no = bean.no,
prefix = bean.prefix,
wbNo = bean.wbNo,
arriveFlag = "1" // 设置提前运抵标识
)
}
launchLoadingCollect({ NetApply.api.preArrive(maWbList) }) {
onSuccess = {
showToast("提前运抵成功")
// 发送刷新事件
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
refresh()
}
onFailed = { code, msg ->
showToast(msg.noNull("提前运抵失败"))
}
}
} }
/** /**

View File

@@ -4,9 +4,11 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.dialog.IntExpArriveDeleteDialogModel import com.lukouguoji.gjc.dialog.IntExpArriveDeleteDialogModel
import com.lukouguoji.gjc.dialog.IntExpArriveResetDialogModel
import com.lukouguoji.gjc.holder.IntExpArriveViewHolder import com.lukouguoji.gjc.holder.IntExpArriveViewHolder
import com.lukouguoji.module_base.base.BasePageViewModel import com.lukouguoji.module_base.base.BasePageViewModel
import com.lukouguoji.module_base.bean.GjcDeclareParam import com.lukouguoji.module_base.bean.GjcDeclareParam
import com.lukouguoji.module_base.bean.GjcHaWb
import com.lukouguoji.module_base.bean.GjcMaWb import com.lukouguoji.module_base.bean.GjcMaWb
import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent import com.lukouguoji.module_base.common.ConstantEvent
@@ -124,24 +126,59 @@ class IntExpArriveViewModel : BasePageViewModel() {
*/ */
fun resetDeclareClick() { fun resetDeclareClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return
val selectedItems = list.filter { it.isSelected }
if (selectedItems.isEmpty()) { // 收集选中的主单
val selectedMaWbList = list.filter { it.isSelected }
// 收集选中的分单
val selectedHaWbList = mutableListOf<GjcHaWb>()
list.forEach { maWb ->
maWb.haWbList?.forEach { haWb ->
if (haWb.isSelected) {
selectedHaWbList.add(haWb)
}
}
}
// 检查是否有选中项
if (selectedMaWbList.isEmpty() && selectedHaWbList.isEmpty()) {
showToast("请选择要重置的运单") showToast("请选择要重置的运单")
return return
} }
val requestData = mapOf("maWbList" to selectedItems).toRequestBody() // 创建并显示弹框
val dialog = IntExpArriveResetDialogModel { dialogModel ->
// 弹框确认后的回调
// 构建请求参数(区分主单和分单)
val params = mutableMapOf<String, Any?>()
if (selectedMaWbList.isNotEmpty()) {
params["maWbList"] = selectedMaWbList
}
if (selectedHaWbList.isNotEmpty()) {
params["haWbList"] = selectedHaWbList
}
launchLoadingCollect({ NetApply.api.resetArriveDeclare(requestData) }) { // 根据选择添加restStatus参数
onSuccess = { // 选择"正常"时传递 "01",选择"未申报"时不传递此参数
showToast("状态重置成功") if (dialogModel.resetStatusCode != null) {
viewModelScope.launch { params["restStatus"] = dialogModel.resetStatusCode
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh") }
val requestData = params.toRequestBody()
// 调用重置接口
launchLoadingCollect({ NetApply.api.resetArriveDeclare(requestData) }) {
onSuccess = {
showToast("状态重置成功")
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
refresh()
} }
refresh()
} }
} }
dialog.show()
} }
/** /**
@@ -149,9 +186,22 @@ class IntExpArriveViewModel : BasePageViewModel() {
*/ */
fun deleteDeclareClick() { fun deleteDeclareClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return
val selectedItems = list.filter { it.isSelected }
if (selectedItems.isEmpty()) { // 收集选中的主单
val selectedMaWbList = list.filter { it.isSelected }
// 收集选中的分单
val selectedHaWbList = mutableListOf<GjcHaWb>()
list.forEach { maWb ->
maWb.haWbList?.forEach { haWb ->
if (haWb.isSelected) {
selectedHaWbList.add(haWb)
}
}
}
// 检查是否有选中项(主单和分单分开判断,互不影响)
if (selectedMaWbList.isEmpty() && selectedHaWbList.isEmpty()) {
showToast("请选择要删除申报的记录") showToast("请选择要删除申报的记录")
return return
} }
@@ -163,12 +213,13 @@ class IntExpArriveViewModel : BasePageViewModel() {
// 创建并显示弹框 // 创建并显示弹框
val dialog = IntExpArriveDeleteDialogModel(changeReasonList) { dialogModel -> val dialog = IntExpArriveDeleteDialogModel(changeReasonList) { dialogModel ->
// 弹框确认后的回调 // 弹框确认后的回调(区分主单和分单)
val param = GjcDeclareParam( val param = GjcDeclareParam(
dcode = dialogModel.changeReason.value, dcode = dialogModel.changeReason.value,
dcontactsName = dialogModel.contactName.value, dcontactsName = dialogModel.contactName.value,
dcontactsTel = dialogModel.contactPhone.value, dcontactsTel = dialogModel.contactPhone.value,
maWbList = selectedItems maWbList = if (selectedMaWbList.isNotEmpty()) selectedMaWbList else null,
haWbList = if (selectedHaWbList.isNotEmpty()) selectedHaWbList else null
) )
val requestData = param.toRequestBody() val requestData = param.toRequestBody()
@@ -195,14 +246,36 @@ class IntExpArriveViewModel : BasePageViewModel() {
*/ */
fun arriveReportClick() { fun arriveReportClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return
val selectedItems = list.filter { it.isSelected }
if (selectedItems.isEmpty()) { // 收集选中的主单
val selectedMaWbList = list.filter { it.isSelected }
// 收集选中的分单
val selectedHaWbList = mutableListOf<GjcHaWb>()
list.forEach { maWb ->
maWb.haWbList?.forEach { haWb ->
if (haWb.isSelected) {
selectedHaWbList.add(haWb)
}
}
}
// 检查是否有选中项
if (selectedMaWbList.isEmpty() && selectedHaWbList.isEmpty()) {
showToast("请选择要申报的运单") showToast("请选择要申报的运单")
return return
} }
val requestData = mapOf("maWbList" to selectedItems).toRequestBody() // 构建请求参数(区分主单和分单)
val params = mutableMapOf<String, Any?>()
if (selectedMaWbList.isNotEmpty()) {
params["maWbList"] = selectedMaWbList
}
if (selectedHaWbList.isNotEmpty()) {
params["haWbList"] = selectedHaWbList
}
val requestData = params.toRequestBody()
launchLoadingCollect({ NetApply.api.arriveDeclare(requestData) }) { launchLoadingCollect({ NetApply.api.arriveDeclare(requestData) }) {
onSuccess = { onSuccess = {
@@ -223,7 +296,7 @@ class IntExpArriveViewModel : BasePageViewModel() {
val filterParams = mapOf( val filterParams = mapOf(
"fdate" to flightDate.value?.ifEmpty { null }, "fdate" to flightDate.value?.ifEmpty { null },
"fno" to flightNo.value?.ifEmpty { null }, "fno" to flightNo.value?.ifEmpty { null },
"likeNo" to waybillNo.value?.ifEmpty { null }, "wbNo" to waybillNo.value?.ifEmpty { null },
"hno" to hno.value?.ifEmpty { null } "hno" to hno.value?.ifEmpty { null }
) )

View File

@@ -1,6 +1,7 @@
package com.lukouguoji.gjc.viewModel package com.lukouguoji.gjc.viewModel
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.holder.AssembleInfoViewHolder import com.lukouguoji.gjc.holder.AssembleInfoViewHolder
import com.lukouguoji.gjc.holder.AssemblePositionViewHolder import com.lukouguoji.gjc.holder.AssemblePositionViewHolder
@@ -8,14 +9,17 @@ import com.lukouguoji.gjc.holder.AssembleWaybillViewHolder
import com.lukouguoji.module_base.base.BaseViewModel import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.* import com.lukouguoji.module_base.bean.*
import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.db.perference.SharedPreferenceUtil import com.lukouguoji.module_base.db.perference.SharedPreferenceUtil
import com.lukouguoji.module_base.http.net.NetApply 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.launchCollect
import com.lukouguoji.module_base.ktx.launchLoadingCollect import com.lukouguoji.module_base.ktx.launchLoadingCollect
import com.lukouguoji.module_base.ktx.showToast import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.model.ScanModel import com.lukouguoji.module_base.model.ScanModel
import dev.utils.app.info.KeyValue import dev.utils.app.info.KeyValue
import kotlinx.coroutines.launch
/** /**
* 国际出港-开始组装ViewModel静态数据 * 国际出港-开始组装ViewModel静态数据
@@ -74,11 +78,30 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
// ========== 标记位,避免重复查询 ========== // ========== 标记位,避免重复查询 ==========
private var lastQueriedUldNo = "" private var lastQueriedUldNo = ""
// ========== 修改模式待匹配的组装位置 ==========
private var pendingLoadArea: String = ""
/** /**
* ULD编号锁定状态 * ULD编号锁定状态(页面内编辑模式)
*/ */
val isUldNoLocked = MutableLiveData(false) val isUldNoLocked = MutableLiveData(false)
/**
* 卸货时选中的组装信息子运单数据
* 用于:
* 1. 卸货校验时对比组装件数/重量
* 2. 卸货提交时构建 wbInfo
*/
private var selectedAssembleWaybill: AssembleInfoBean? = null
/**
* 是否从列表页"修改"模式进入
* 与 isUldNoLocked 的区别:
* - isFromEditMode整个页面生命周期内 ULD 编号锁定,但不影响装货/卸货按钮
* - isUldNoLocked页面内编辑模式影响装货/卸货按钮
*/
val isFromEditMode = MutableLiveData(false)
/** /**
* 装货按钮启用状态(非编辑模式时启用) * 装货按钮启用状态(非编辑模式时启用)
*/ */
@@ -127,12 +150,30 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
} }
}?.toMutableList() ?: mutableListOf() }?.toMutableList() ?: mutableListOf()
assemblePositionList.value = list // 检查是否有待匹配的组装位置(修改模式)
if (pendingLoadArea.isNotEmpty() && list.isNotEmpty()) {
// 保存默认选中的第一项 // 取消所有选中状态
if (list.isNotEmpty()) { list.forEach { it.isSelected = false }
// 查找并选中匹配项
val matchedItem = list.find { it.positionName == pendingLoadArea }
if (matchedItem != null) {
matchedItem.isSelected = true
selectedPosition.value = matchedItem
} else {
// 未找到匹配项,选中第一项
list[0].isSelected = true
selectedPosition.value = list[0]
}
// 清空待匹配标记
pendingLoadArea = ""
// 触发组装信息列表查询
loadAssembledList()
} else if (list.isNotEmpty()) {
// 非修改模式,选中第一项
selectedPosition.value = list[0] selectedPosition.value = list[0]
} }
assemblePositionList.value = list
} }
} }
} }
@@ -161,6 +202,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
/** /**
* 运单点击(单选切换) * 运单点击(单选切换)
* 装货模式:从运单列表选择运单
*/ */
fun onWaybillItemClick(position: Int) { fun onWaybillItemClick(position: Int) {
val list = waybillList.value ?: return val list = waybillList.value ?: return
@@ -178,9 +220,10 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
if (selectedWaybill != null) { if (selectedWaybill != null) {
selectedWaybill.isSelected.set(true) selectedWaybill.isSelected.set(true)
// 自动提取航班号和航班日期 // 【删除】不再从运单提取航班信息航班信息改为从ULD查询接口获取
assembleFlightNo.value = selectedWaybill.fno
assembleFlightDate.value = selectedWaybill.fdate // 【新增】清空卸货选中的子运单(切换到装货模式)
selectedAssembleWaybill = null
// 保存当前的组装人始终保留从operator LiveData读取 // 保存当前的组装人始终保留从operator LiveData读取
val previousOperator = operator.value ?: "" val previousOperator = operator.value ?: ""
@@ -368,6 +411,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
/** /**
* 查询ULD信息状态和耗材重量 * 查询ULD信息状态和耗材重量
* 同时从ULD信息提取航班信息并触发组装信息列表查询
*/ */
private fun queryUldInfo(uldNo: String) { private fun queryUldInfo(uldNo: String) {
launchCollect({ NetApply.api.getUldWithConsumeWeight(uldNo) }) { launchCollect({ NetApply.api.getUldWithConsumeWeight(uldNo) }) {
@@ -389,6 +433,20 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
// 保存useId用于装货/卸货接口) // 保存useId用于装货/卸货接口)
useId = uldBean.useId useId = uldBean.useId
} }
// 【新增】从ULD信息提取航班信息
if (uldBean.fno.isNotEmpty() && uldBean.fdate.isNotEmpty()) {
assembleFlightNo.value = uldBean.fno
assembleFlightDate.value = uldBean.fdateFormatted // 使用格式化后的日期(只保留年月日)
// 清除防抖标记,触发组装信息列表查询
lastQueriedAssembledParams = ""
loadAssembledList()
} else {
// 航班信息为空,清空组装信息列表,但允许继续装货
assembleFlightNo.value = ""
assembleFlightDate.value = ""
assembleInfoList.value = mutableListOf()
}
} }
} }
onFailed = { code, message -> onFailed = { code, message ->
@@ -414,6 +472,14 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
/** /**
* 执行组装操作(卸货或装货) * 执行组装操作(卸货或装货)
* @param isLoad true-装货false-卸货 * @param isLoad true-装货false-卸货
*
* 装货与卸货的区别:
* 1. 校验逻辑不同:
* - 装货:与运单列表中的件数/重量对比
* - 卸货:与组装信息中的组装件数/重量对比
* 2. wbInfo 来源不同:
* - 装货:从运单列表选中项获取
* - 卸货:从组装信息选中的子运单获取
*/ */
private fun performAssembleOperation(isLoad: Boolean) { private fun performAssembleOperation(isLoad: Boolean) {
// 1. 验证必填字段 // 1. 验证必填字段
@@ -437,22 +503,59 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
val assembleCount = waybillInfo.value?.assembleCount?.trim() ?: "" val assembleCount = waybillInfo.value?.assembleCount?.trim() ?: ""
if (assembleCount.isEmpty()) { if (assembleCount.isEmpty()) {
showToast("请输入组装件数") val countFieldName = if (isLoad) "装货件数" else "卸货件数"
return showToast("请输入${countFieldName}")
}
// 校验组装件数不能大于运单件数
val waybillPieces = waybillInfo.value?.waybillPieces?.trim() ?: ""
val assembleCountInt = assembleCount.toLongOrNull() ?: 0L
val waybillPiecesInt = waybillPieces.toLongOrNull() ?: 0L
if (assembleCountInt > waybillPiecesInt) {
showToast("组装件数不能大于运单件数")
return return
} }
val assembleWeight = waybillInfo.value?.assembleWeight?.trim() ?: "" val assembleWeight = waybillInfo.value?.assembleWeight?.trim() ?: ""
// 组装重量为非必填,不进行验证
// 【修改】区分校验逻辑
val assembleCountInt = assembleCount.toLongOrNull() ?: 0L
val assembleWeightDouble = assembleWeight.toDoubleOrNull() ?: 0.0
if (isLoad) {
// 装货校验:与运单列表中的件数/重量对比
val waybillPieces = waybillInfo.value?.waybillPieces?.trim() ?: ""
val waybillPiecesInt = waybillPieces.toLongOrNull() ?: 0L
if (waybillPiecesInt > 0 && assembleCountInt > waybillPiecesInt) {
showToast("装货件数不能大于运单件数")
return
}
if (assembleWeight.isNotEmpty()) {
val waybillWeight = waybillInfo.value?.waybillWeight?.trim() ?: ""
val waybillWeightDouble = waybillWeight.toDoubleOrNull() ?: 0.0
if (waybillWeightDouble > 0 && assembleWeightDouble > waybillWeightDouble) {
showToast("装货重量不能大于运单重量")
return
}
}
} else {
// 卸货校验:与组装信息中的组装件数/重量对比
val assembleInfo = selectedAssembleWaybill?.waybillData
if (assembleInfo == null) {
showToast("请从组装信息列表选择要卸货的运单")
return
}
// originalPieces 对应 checkInPc已组装件数
val maxPieces = assembleInfo.originalPieces.toLongOrNull() ?: 0L
// originalWeight 对应 checkInWeight已组装重量
val maxWeight = assembleInfo.originalWeight.toDoubleOrNull() ?: 0.0
if (maxPieces > 0 && assembleCountInt > maxPieces) {
showToast("卸货件数不能大于已组装件数")
return
}
if (assembleWeight.isNotEmpty() && maxWeight > 0 && assembleWeightDouble > maxWeight) {
showToast("卸货重量不能大于已组装重量")
return
}
}
val operatorValue = operator.value?.trim() ?: "" val operatorValue = operator.value?.trim() ?: ""
if (operatorValue.isEmpty()) { if (operatorValue.isEmpty()) {
@@ -466,21 +569,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
return return
} }
// 2. 获取或构建运单Bean // 2. 构建useInfoULD信息
// 从运单列表中获取选中的运单
val currentWaybillList = waybillList.value
if (currentWaybillList == null) {
showToast("运单列表为空")
return
}
val selectedWaybill = currentWaybillList.firstOrNull { it.isSelected.get() }
if (selectedWaybill == null) {
showToast("请选择运单")
return
}
// 3. 构建useInfoULD信息
val useInfo = mapOf( val useInfo = mapOf(
"uld" to uldNo, "uld" to uldNo,
"consumeWeight" to materialWeight.toDoubleOrNull(), "consumeWeight" to materialWeight.toDoubleOrNull(),
@@ -493,29 +582,62 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
"useId" to if (uldInfo.value?.useId == 0L) null else uldInfo.value?.useId // 添加useId来自getUld接口 "useId" to if (uldInfo.value?.useId == 0L) null else uldInfo.value?.useId // 添加useId来自getUld接口
) )
// 4. 构建wbInfo运单信息 // 3. 【修改】区分 wbInfo 构建
// 使用原始运单件数/重量(如果有),否则使用当前件数/重量 val wbInfo: Map<String, Any?>
val waybillPc = if (selectedWaybill.originalPieces.isNotEmpty()) {
selectedWaybill.originalPieces.toLongOrNull() if (isLoad) {
// 装货:从运单列表获取
val currentWaybillList = waybillList.value
if (currentWaybillList == null) {
showToast("运单列表为空")
return
}
val selectedWaybill = currentWaybillList.firstOrNull { it.isSelected.get() }
if (selectedWaybill == null) {
showToast("请选择运单")
return
}
// 使用原始运单件数/重量(如果有),否则使用当前件数/重量
val waybillPc = if (selectedWaybill.originalPieces.isNotEmpty()) {
selectedWaybill.originalPieces.toLongOrNull()
} else {
selectedWaybill.pieces.toLongOrNull()
}
val waybillWeight = if (selectedWaybill.originalWeight.isNotEmpty()) {
selectedWaybill.originalWeight.toDoubleOrNull()
} else {
selectedWaybill.weight.toDoubleOrNull()
}
wbInfo = mapOf(
"wbNo" to selectedWaybill.waybillNo,
"pc" to waybillPc,
"weight" to waybillWeight,
"fdate" to selectedWaybill.fdate,
"fno" to selectedWaybill.fno,
"whId" to selectedWaybill.whId
)
} else { } else {
selectedWaybill.pieces.toLongOrNull() // 卸货:从组装信息子运单获取
} val assembleWaybill = selectedAssembleWaybill?.waybillData
val waybillWeight = if (selectedWaybill.originalWeight.isNotEmpty()) { if (assembleWaybill == null) {
selectedWaybill.originalWeight.toDoubleOrNull() showToast("请从组装信息列表选择要卸货的运单")
} else { return
selectedWaybill.weight.toDoubleOrNull() }
wbInfo = mapOf(
"wbNo" to assembleWaybill.waybillNo,
"pc" to assembleWaybill.pieces.toLongOrNull(), // 运单件数
"weight" to assembleWaybill.weight.toDoubleOrNull(), // 运单重量
"fdate" to assembleWaybill.fdate,
"fno" to assembleWaybill.fno,
"whId" to assembleWaybill.whId
)
} }
val wbInfo = mapOf( // 4. 构建完整请求参数
"wbNo" to selectedWaybill.waybillNo,
"pc" to waybillPc,
"weight" to waybillWeight,
"fdate" to selectedWaybill.fdate,
"fno" to selectedWaybill.fno,
"whId" to selectedWaybill.whId
)
// 5. 构建完整请求参数
val params = mapOf( val params = mapOf(
"abPc" to assembleCount.toLongOrNull(), "abPc" to assembleCount.toLongOrNull(),
"abWeight" to assembleWeight.toDoubleOrNull(), "abWeight" to assembleWeight.toDoubleOrNull(),
@@ -527,7 +649,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
"userId" to SharedPreferenceUtil.getString(Constant.Share.account) "userId" to SharedPreferenceUtil.getString(Constant.Share.account)
).toRequestBody() ).toRequestBody()
// 6. 调用接口带Loading等待接口返回 // 5. 调用接口带Loading等待接口返回
val operationName = if (isLoad) "装货" else "卸货" val operationName = if (isLoad) "装货" else "卸货"
launchLoadingCollect({ launchLoadingCollect({
if (isLoad) { if (isLoad) {
@@ -538,7 +660,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
}) { }) {
onSuccess = { result -> onSuccess = { result ->
// 接口成功后才显示成功提示并刷新列表 // 接口成功后才显示成功提示并刷新列表
handleOperationSuccess(operationName, isLoad, uldNo, selectedWaybill, assembleCount, assembleWeight) handleOperationSuccess(operationName, isLoad, uldNo, assembleCount, assembleWeight)
} }
onFailed = { code, message -> onFailed = { code, message ->
showToast("${operationName}失败: $message") showToast("${operationName}失败: $message")
@@ -553,20 +675,55 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
operationName: String, operationName: String,
isLoad: Boolean, isLoad: Boolean,
uldNo: String, uldNo: String,
selectedWaybill: AssembleWaybillBean,
assembleCount: String, assembleCount: String,
assembleWeight: String assembleWeight: String
) { ) {
showToast("${operationName}成功") showToast("${operationName}成功")
// 重新查询组装信息列表(刷新数据 // 发送刷新事件,通知出港组装列表页面更新数据
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
// 清空表单(在刷新数据前清空,避免刷新时的状态冲突)
clearForm()
// 清除防抖标记,强制刷新组装信息列表
lastQueriedAssembledParams = ""
loadAssembledList() loadAssembledList()
// 刷新运单列表 // 刷新运单列表(使用当前搜索条件)
loadInitialWaitingAssemble() refreshWaybillList()
}
// 清空表单 /**
clearForm() * 刷新运单列表(保留当前搜索条件)
*/
private fun refreshWaybillList() {
val wbNo = searchText.value?.trim() ?: ""
launchLoadingCollect({ NetApply.api.queryWaitingAssemble(wbNo) }) {
onSuccess = { result ->
val warehouseList = result.data ?: mutableListOf()
val waybillBeanList = warehouseList.map { warehouse ->
AssembleWaybillBean().apply {
waybillNo = warehouse.wbNo
pieces = warehouse.pc.toString()
weight = String.format("%.1f", warehouse.weight)
flight = warehouse.flight
fno = warehouse.fno
fdate = warehouse.fdate
whId = warehouse.whId
isMarked = false
}
}.toMutableList()
waybillList.value = waybillBeanList
}
onFailed = { code, message ->
showToast("刷新运单列表失败: $message")
}
}
} }
/** /**
@@ -655,8 +812,8 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
itemType = AssembleInfoBean.ItemType.WAYBILL_DETAIL itemType = AssembleInfoBean.ItemType.WAYBILL_DETAIL
parentUldNo = uldItem.uldNo parentUldNo = uldItem.uldNo
wbNo = warehouse.wbNo wbNo = warehouse.wbNo
waybillPieces = warehouse.pc.toInt() waybillPieces = warehouse.checkInPc.toInt()
waybillWeight = warehouse.weight waybillWeight = warehouse.checkInWeight
showIndent = true showIndent = true
showIndex = false showIndex = false
@@ -669,6 +826,9 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
fno = warehouse.fno fno = warehouse.fno
fdate = warehouse.fdate fdate = warehouse.fdate
whId = warehouse.whId whId = warehouse.whId
// 设置原始运单件数/重量使用checkInPc/checkInWeight
originalPieces = warehouse.checkInPc.toString()
originalWeight = String.format("%.1f", warehouse.checkInWeight)
} }
} }
} }
@@ -695,14 +855,23 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
} }
/** /**
* 从二级运单行填充表单(编辑模式) * 从二级运单行填充表单(卸货模式)
* 1. 填充ULD信息并锁定ULD编号 * 1. 存储选中的组装信息子运单(用于卸货校验和提交
* 2. 填充运单信息(使用原始运单件数/重量,只读 * 2. 填充ULD信息并锁定ULD编号
* 3. 保留组装件数、组装重量、组装人为可编辑 * 3. 填充运单信息(字段对调:运单件数/组装件数对调,运单重量/组装重量对调)
*
* 卸货时字段映射:
* - 运单件数 ← pieces (pc原始运单件数)
* - 运单重量 ← weight (weight原始运单重量)
* - 组装件数 ← originalPieces (checkInPc已组装件数可编辑卸货数量)
* - 组装重量 ← originalWeight (checkInWeight已组装重量可编辑卸货数量)
*/ */
private fun fillFormFromWaybillDetail(item: AssembleInfoBean) { private fun fillFormFromWaybillDetail(item: AssembleInfoBean) {
val waybill = item.waybillData ?: return val waybill = item.waybillData ?: return
// 【新增】存储选中的组装信息子运单(用于卸货校验和提交)
selectedAssembleWaybill = item
// 1. 填充ULD信息 // 1. 填充ULD信息
uldInfo.value = uldInfo.value?.apply { uldInfo.value = uldInfo.value?.apply {
uldNo = item.parentUldNo uldNo = item.parentUldNo
@@ -712,14 +881,13 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
// 保存当前的组装人在创建新对象前从operator LiveData读取 // 保存当前的组装人在创建新对象前从operator LiveData读取
val previousOperator = operator.value ?: "" val previousOperator = operator.value ?: ""
// 2. 填充运单信息 // 2. 填充运单信息(【修改】对调字段填充)
waybillInfo.value = WaybillInfoBean().apply { waybillInfo.value = WaybillInfoBean().apply {
waybillNo = waybill.waybillNo waybillNo = waybill.waybillNo
waybillPieces = waybill.originalPieces // 使用原始运单件数 waybillPieces = waybill.pieces // 【对调】显示运单件数pc
waybillWeight = waybill.originalWeight // 使用原始运单重量 waybillWeight = waybill.weight // 【对调】显示运单重量weight
// 填充已累积的组装件数和组装重量(可编辑) assembleCount = waybill.originalPieces // 【对调】显示组装件数checkInPc可编辑卸货数量
assembleCount = waybill.pieces assembleWeight = waybill.originalWeight // 【对调】显示组装重量checkInWeight可编辑卸货数量
assembleWeight = waybill.weight
operator = previousOperator // 保留之前选择的组装人 operator = previousOperator // 保留之前选择的组装人
} }
@@ -808,9 +976,9 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
uldBean.waybillDetails = warehouseList uldBean.waybillDetails = warehouseList
} }
// 计算总件数和总重量(从运单列表求和) // 计算总件数和总重量(从子列表的checkInPc、checkInWeight求和)
val calculatedPieces = warehouseList?.sumOf { it.pc.toInt() } ?: 0 val calculatedPieces = warehouseList?.sumOf { it.checkInPc.toInt() } ?: 0
val calculatedWeight = warehouseList?.sumOf { it.weight } ?: 0.0 val calculatedWeight = warehouseList?.sumOf { it.checkInWeight } ?: 0.0
AssembleInfoBean().apply { AssembleInfoBean().apply {
itemType = AssembleInfoBean.ItemType.ULD_HEADER itemType = AssembleInfoBean.ItemType.ULD_HEADER
@@ -851,6 +1019,9 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
operator = previousOperator // 恢复组装人 operator = previousOperator // 恢复组装人
} }
isUldNoLocked.value = false isUldNoLocked.value = false
// 【新增】清空卸货选中的子运单
selectedAssembleWaybill = null
} }
/** /**
@@ -859,4 +1030,34 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
fun clearCachedOperator() { fun clearCachedOperator() {
lastSelectedOperator = null lastSelectedOperator = null
} }
/**
* 从列表页"修改"模式初始化
* @param uldNo ULD编号
* @param loadArea 组装位置(用于自动选中对应的组装位置)
*/
fun initFromEditMode(uldNo: String, loadArea: String = "") {
if (uldNo.isEmpty()) return
// 标记为修改模式(整个页面生命周期内 ULD 编号锁定)
isFromEditMode.value = true
// 保存待匹配的组装位置(在组装位置列表加载完成后进行匹配选择)
if (loadArea.isNotEmpty()) {
pendingLoadArea = loadArea
}
// 填充 ULD 编号
uldInfo.value = uldInfo.value?.apply {
this.uldNo = uldNo
} ?: UldInfoBean().apply {
this.uldNo = uldNo
}
// 更新防抖标记,确保查询能触发
lastQueriedUldNo = ""
// 触发 ULD 编码查询
onUldNoInputComplete()
}
} }

View File

@@ -1,27 +1,22 @@
package com.lukouguoji.gjc.viewModel package com.lukouguoji.gjc.viewModel
import android.text.InputType
import android.widget.EditText
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.alibaba.android.arouter.launcher.ARouter import com.alibaba.android.arouter.launcher.ARouter
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.holder.IntExpAssembleViewHolder import com.lukouguoji.gjc.holder.IntExpAssembleItemViewHolder
import com.lukouguoji.module_base.base.BasePageViewModel import com.lukouguoji.module_base.base.BasePageViewModel
import com.lukouguoji.module_base.bean.GjcUldUseBean import com.lukouguoji.module_base.bean.GjcUldUseBean
import com.lukouguoji.module_base.http.net.NetApply import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.ktx.commonAdapter import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.formatDate
import com.lukouguoji.module_base.ktx.launchCollect import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.launchLoadingCollect import com.lukouguoji.module_base.ktx.launchLoadingCollect
import com.lukouguoji.module_base.ktx.showConfirmDialog
import com.lukouguoji.module_base.ktx.showToast import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
import com.lukouguoji.module_base.router.ARouterConstants import com.lukouguoji.module_base.router.ARouterConstants
import dev.utils.app.info.KeyValue import dev.utils.app.info.KeyValue
import dev.utils.common.DateUtils import dev.utils.common.DateUtils
import com.lukouguoji.module_base.ktx.formatDate
import kotlinx.coroutines.launch
/** /**
* 国际出港-出港组装ViewModel * 国际出港-出港组装ViewModel
@@ -45,8 +40,8 @@ class IntExpAssembleViewModel : BasePageViewModel() {
val assemblerList = MutableLiveData<List<KeyValue>>(emptyList()) // 组装人列表 val assemblerList = MutableLiveData<List<KeyValue>>(emptyList()) // 组装人列表
// ========== 适配器配置 ========== // ========== 适配器配置 ==========
val itemViewHolder = IntExpAssembleViewHolder::class.java val itemViewHolder = IntExpAssembleItemViewHolder::class.java
val itemLayoutId = R.layout.item_int_exp_assemble_uld val itemLayoutId = R.layout.item_int_exp_assemble
// ========== 底部统计 ========== // ========== 底部统计 ==========
val totalCount = MutableLiveData("0") // 合计票数 val totalCount = MutableLiveData("0") // 合计票数
@@ -77,33 +72,54 @@ class IntExpAssembleViewModel : BasePageViewModel() {
/** /**
* 切换展开/收起状态 * 切换展开/收起状态
* 首次展开时加载运单明细数据
*/ */
fun toggleExpand(position: Int) { fun toggleExpand(position: Int) {
val bean = pageModel.rv?.commonAdapter()?.getItem(position) as? GjcUldUseBean ?: return val bean = pageModel.rv?.commonAdapter()?.getItem(position) as? GjcUldUseBean ?: return
bean.isExpanded = !bean.isExpanded val isCurrentlyExpanded = bean.showMore.get()
if (bean.isExpanded && bean.waybillDetails == null) { if (isCurrentlyExpanded) {
// 首次展开,加载运单明细 // 当前是展开状态,收起
loadWaybillDetails(position, bean) bean.showMore.set(false)
} else { } else {
// 已有数据直接刷新item显示/隐藏 // 当前是收起状态,展开
pageModel.rv?.commonAdapter()?.notifyItemChanged(position) bean.showMore.set(true)
// 如果未加载过数据,则加载
if (!bean.waybillDetailsLoaded) {
loadWaybillDetails(position, bean)
}
} }
} }
/** /**
* 加载运单明细 * 加载运单明细
* 使用接口: /IntExpAssemble/queryAssembledByUld
*/ */
private fun loadWaybillDetails(position: Int, bean: GjcUldUseBean) { private fun loadWaybillDetails(position: Int, bean: GjcUldUseBean) {
val params = mapOf("useId" to bean.useId).toRequestBody() // 设置加载中状态
bean.isLoading.set(true)
pageModel.rv?.commonAdapter()?.notifyItemChanged(position)
launchCollect({ NetApply.api.getIntExpAssembleWaybillDetails(params) }) { // 构建请求参数 - 传递完整的GjcUldUseBean信息
val params = mapOf(
"useId" to bean.useId,
"uld" to bean.uld,
"fdate" to bean.fdate,
"fno" to bean.fno
).toRequestBody()
launchCollect({ NetApply.api.getAssembledWaybillsByUld(params) }) {
onSuccess = { result -> onSuccess = { result ->
bean.waybillDetails = result.data ?: mutableListOf() bean.waybillDetails = result.data?.toMutableList()
bean.waybillDetailsLoaded = true
bean.isLoading.set(false)
pageModel.rv?.commonAdapter()?.notifyItemChanged(position) pageModel.rv?.commonAdapter()?.notifyItemChanged(position)
} }
onFailed = { _, msg -> onFailed = { _, msg ->
bean.isExpanded = false // 加载失败,恢复展开状态 bean.waybillDetailsLoaded = true // 标记为已加载(即使失败也显示暂无数据)
bean.waybillDetails = mutableListOf() // 设置空列表
bean.isLoading.set(false)
pageModel.rv?.commonAdapter()?.notifyItemChanged(position)
showToast(msg) showToast(msg)
} }
} }
@@ -150,8 +166,49 @@ class IntExpAssembleViewModel : BasePageViewModel() {
* Item点击事件处理 * Item点击事件处理
*/ */
override fun onItemClick(position: Int, type: Int) { override fun onItemClick(position: Int, type: Int) {
if (type == 1000) { // 展开/收起操作 when (type) {
toggleExpand(position) 1000 -> toggleExpand(position) // 展开/收起操作
2000 -> onEditItem(position) // 修改操作
2001 -> onDeleteSingleItem(position) // 删除操作
}
}
/**
* 修改单个列表项 - 跳转到开始组装页面(修改模式)
* ULD 编号将被锁定,整个页面生命周期内不可编辑
* 同时传递组装位置,用于自动选中对应项
*/
private fun onEditItem(position: Int) {
val bean = pageModel.rv?.commonAdapter()?.getItem(position) as? GjcUldUseBean ?: return
com.lukouguoji.gjc.page.assemble.IntExpAssembleStartActivity.startForEdit(
getTopActivity(),
bean.uld,
bean.loadArea
)
}
/**
* 删除单个列表项(侧滑操作)
*/
private fun onDeleteSingleItem(position: Int) {
val bean = pageModel.rv?.commonAdapter()?.getItem(position) as? GjcUldUseBean ?: return
getTopActivity().showConfirmDialog("确定要删除该条记录吗?") {
deleteSingleItem(bean)
}
}
/**
* 执行单项删除
*/
private fun deleteSingleItem(bean: GjcUldUseBean) {
val requestData = listOf(bean).toRequestBody()
launchLoadingCollect({ NetApply.api.deleteIntExpAssemble(requestData) }) {
onSuccess = {
showToast("删除成功")
refresh()
}
} }
} }
@@ -181,24 +238,18 @@ class IntExpAssembleViewModel : BasePageViewModel() {
} }
// 显示确认对话框 // 显示确认对话框
val activity = getTopActivity() getTopActivity().showConfirmDialog("确定要删除选中的 ${selectedItems.size} 条记录吗?") {
AlertDialog.Builder(activity) deleteSelectedItems(selectedItems)
.setTitle("删除确认") }
.setMessage("确定要删除选中的 ${selectedItems.size} 条记录吗?")
.setPositiveButton("删除") { _, _ ->
deleteSelectedItems(selectedItems)
}
.setNegativeButton("取消", null)
.show()
} }
/** /**
* 删除选中项 * 删除选中项
*/ */
private fun deleteSelectedItems(items: List<GjcUldUseBean>) { private fun deleteSelectedItems(items: List<GjcUldUseBean>) {
val ids = items.mapNotNull { it.useId }.joinToString(",") val requestData = items.toRequestBody()
launchLoadingCollect({ NetApply.api.deleteIntExpAssemble(ids) }) { launchLoadingCollect({ NetApply.api.deleteIntExpAssemble(requestData) }) {
onSuccess = { onSuccess = {
showToast("删除成功") showToast("删除成功")
refresh() refresh()
@@ -207,7 +258,7 @@ class IntExpAssembleViewModel : BasePageViewModel() {
} }
/** /**
* 回填重量按钮点击 * 回填重量按钮点击 - 跳转到修改组装重量页面
*/ */
fun onBackfillWeightClick() { fun onBackfillWeightClick() {
// 获取选中的数据 // 获取选中的数据
@@ -218,55 +269,17 @@ class IntExpAssembleViewModel : BasePageViewModel() {
.filter { it.isSelected } .filter { it.isSelected }
if (selectedItems.isEmpty()) { if (selectedItems.isEmpty()) {
showToast("请选择要回填重量的记录") showToast("请选择要修改重量的ULD")
return return
} }
// 显示输入对话框 if (selectedItems.size > 1) {
showBackfillWeightDialog(selectedItems) showToast("每次只能选择一个ULD进行重量修改")
} return
/**
* 显示回填重量对话框
*/
private fun showBackfillWeightDialog(items: List<GjcUldUseBean>) {
val activity = getTopActivity()
// 创建输入框
val input = EditText(activity).apply {
hint = "请输入重量(KG)"
inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
setPadding(40, 40, 40, 40)
} }
AlertDialog.Builder(activity) // 跳转到修改组装重量页面
.setTitle("回填重量") val bean = selectedItems.first()
.setMessage("共选中 ${items.size} 条记录") com.lukouguoji.gjc.activity.GjcAssembleWeightEditActivity.start(getTopActivity(), bean)
.setView(input)
.setPositiveButton("确定") { _, _ ->
val weight = input.text.toString()
if (weight.verifyNullOrEmpty("请输入重量")) return@setPositiveButton
backfillWeight(items, weight)
}
.setNegativeButton("取消", null)
.show()
}
/**
* 回填重量API调用
*/
private fun backfillWeight(items: List<GjcUldUseBean>, weight: String) {
val ids = items.mapNotNull { it.useId }.joinToString(",")
val params = mapOf(
"ids" to ids,
"weight" to weight
).toRequestBody()
launchLoadingCollect({ NetApply.api.backfillIntExpAssembleWeight(params) }) {
onSuccess = {
showToast("回填重量成功")
refresh()
}
}
} }
} }

View File

@@ -189,7 +189,7 @@ class IntExpLoadViewModel : BasePageViewModel() {
val pageParams = GjcCheckInPage( val pageParams = GjcCheckInPage(
fdate = flightDate.value?.ifEmpty { null }, fdate = flightDate.value?.ifEmpty { null },
fno = flightNo.value?.ifEmpty { null }, fno = flightNo.value?.ifEmpty { null },
whNo = waybillNo.value?.ifEmpty { null }, wbNo = waybillNo.value?.ifEmpty { null },
pageNum = pageModel.page, pageNum = pageModel.page,
pageSize = pageModel.limit pageSize = pageModel.limit
) )
@@ -201,7 +201,7 @@ class IntExpLoadViewModel : BasePageViewModel() {
val totalParams = GjcCheckInPage( val totalParams = GjcCheckInPage(
fdate = flightDate.value?.ifEmpty { null }, fdate = flightDate.value?.ifEmpty { null },
fno = flightNo.value?.ifEmpty { null }, fno = flightNo.value?.ifEmpty { null },
whNo = waybillNo.value?.ifEmpty { null } wbNo = waybillNo.value?.ifEmpty { null }
).toRequestBody() ).toRequestBody()
// 获取列表 (带Loading) // 获取列表 (带Loading)

View File

@@ -4,6 +4,7 @@ import android.app.Activity
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.dialog.IntExpOutWaitingTransDialogModel
import com.lukouguoji.gjc.holder.IntExpOutHandoverViewHolder import com.lukouguoji.gjc.holder.IntExpOutHandoverViewHolder
import com.lukouguoji.module_base.base.BasePageViewModel import com.lukouguoji.module_base.base.BasePageViewModel
import com.lukouguoji.module_base.bean.GjcUldUseBean import com.lukouguoji.module_base.bean.GjcUldUseBean
@@ -105,6 +106,59 @@ class IntExpOutHandoverViewModel : BasePageViewModel() {
} }
} }
/**
* 待配运按钮点击
*/
fun waitingTransClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcUldUseBean> ?: return
val selectedItems = list.filter { it.isSelected }
if (selectedItems.isEmpty()) {
showToast("请选择要待配运的ULD")
return
}
// 显示待配运弹框
showWaitingTransDialog(selectedItems)
}
/**
* 显示待配运弹框
*/
private fun showWaitingTransDialog(selectedItems: List<GjcUldUseBean>) {
val dialog = IntExpOutWaitingTransDialogModel { model ->
// 弹框确定回调
performWaitingTrans(selectedItems, model.locationId, model.locationName)
}
dialog.show()
}
/**
* 执行待配运操作
*/
private fun performWaitingTrans(
selectedItems: List<GjcUldUseBean>,
locationId: String,
locationName: String
) {
// 构建请求参数
val params = mapOf(
"location" to locationName,
"locationId" to locationId.toLongOrNull(),
"uldUseList" to selectedItems
).toRequestBody()
launchLoadingCollect({ NetApply.api.waitingTrans(params) }) {
onSuccess = {
showToast("待配运操作成功")
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
refresh()
}
}
}
/** /**
* 获取数据 (重写BasePageViewModel) * 获取数据 (重写BasePageViewModel)
*/ */

View File

@@ -177,17 +177,25 @@ class IntExpStorageUseViewModel : BasePageViewModel() {
/** /**
* 执行修改库位操作 * 执行修改库位操作
* @param newLocation 新的库位 * @param locationName 新的库位名称 (后端的location字段)
* @param locationId 新的库位ID (后端的locationId字段)
* @param storageUse 选中的单个库位使用对象 * @param storageUse 选中的单个库位使用对象
*/ */
fun performModifyStorage(newLocation: String, storageUse: com.lukouguoji.module_base.bean.GjcStorageUse) { fun performModifyStorage(
if (newLocation.isEmpty()) { locationName: String,
showToast("请输入新的库位号") locationId: String,
storageUse: com.lukouguoji.module_base.bean.GjcStorageUse
) {
if (locationName.isEmpty() || locationId.isEmpty()) {
showToast("请选择库位")
return return
} }
// 创建更新后的库位对象(覆盖 location 字段) // 创建更新后的库位对象(覆盖 location 和 locationId 字段)
val updatedStorage = storageUse.copy(location = newLocation) val updatedStorage = storageUse.copy(
location = locationName,
locationId = locationId.toLongOrNull() ?: 0
)
// 直接使用更新后的对象构建请求参数 // 直接使用更新后的对象构建请求参数
val params = updatedStorage.toRequestBody() val params = updatedStorage.toRequestBody()
@@ -244,21 +252,49 @@ class IntExpStorageUseViewModel : BasePageViewModel() {
* 入库操作 * 入库操作
*/ */
fun inStorage() { fun inStorage() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return // 由Activity显示对话框
}
// 收集所有选中的子列表项(库位) /**
val selectedStorageUseList = mutableListOf<com.lukouguoji.module_base.bean.GjcStorageUse>() * 执行入库操作
list.forEach { maWb -> * @param locationName 库位名称 (后端的location字段)
maWb.storageUseList?.filter { it.isSelected }?.let { selectedStorageUseList.addAll(it) } * @param locationId 库位ID (后端的locationId字段)
} * @param maWbListForInStorage 包含选中子列表项的主列表数据
*/
if (selectedStorageUseList.isEmpty()) { fun performInStorage(
showToast("请选择要入库的库位") locationName: String,
locationId: String,
maWbListForInStorage: List<GjcMaWb>
) {
if (maWbListForInStorage.isEmpty()) {
showToast("请至少选择一个单据")
return return
} }
// TODO: 实现入库接口调用 if (locationName.isEmpty() || locationId.isEmpty()) {
showToast("入库功能待实现") showToast("请选择库位")
return
}
// 构建请求参数:库位名称 + 库位ID + 完整的主子列表结构
val params = mapOf(
"location" to locationName,
"locationId" to locationId.toLongOrNull(),
"maWbList" to maWbListForInStorage
).toRequestBody()
launchLoadingCollect({ NetApply.api.inIntExpStorage(params) }) {
onSuccess = {
showToast("入库成功")
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
refresh() // 刷新列表
}
onFailed = { _, msg ->
showToast(msg.noNull("入库失败"))
}
}
} }
/** /**

View File

@@ -4,10 +4,12 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.dialog.IntExpTallyDeleteDialogModel import com.lukouguoji.gjc.dialog.IntExpTallyDeleteDialogModel
import com.lukouguoji.gjc.dialog.IntExpTallyResetDialogModel
import com.lukouguoji.gjc.holder.IntExpTallyViewHolder import com.lukouguoji.gjc.holder.IntExpTallyViewHolder
import com.lukouguoji.module_base.base.BasePageViewModel import com.lukouguoji.module_base.base.BasePageViewModel
import com.lukouguoji.module_base.bean.GjcCheckInPage import com.lukouguoji.module_base.bean.GjcCheckInPage
import com.lukouguoji.module_base.bean.GjcDeclareParam import com.lukouguoji.module_base.bean.GjcDeclareParam
import com.lukouguoji.module_base.bean.GjcHaWb
import com.lukouguoji.module_base.bean.GjcMaWb import com.lukouguoji.module_base.bean.GjcMaWb
import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent import com.lukouguoji.module_base.common.ConstantEvent
@@ -71,23 +73,14 @@ class IntExpTallyViewModel : BasePageViewModel() {
} }
/** /**
* 全选按钮点击 (切换全选状态,单向同步到子列表) * 全选按钮点击 (切换主单的全选状态,分单选择独立)
*/ */
fun checkAllClick() { fun checkAllClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return
// 切换全选状态 // 切换全选状态(只针对主单)
val shouldCheckAll = !isAllChecked.value!! val shouldCheckAll = !isAllChecked.value!!
list.forEach { it.checked.set(shouldCheckAll) }
// 单向同步:主列表和子列表都设置为相同的选择状态
list.forEach { maWb ->
maWb.checked.set(shouldCheckAll)
// 同步到所有子列表项
maWb.haWbList?.forEach { haWb ->
haWb.checked.set(shouldCheckAll)
}
}
isAllChecked.value = shouldCheckAll isAllChecked.value = shouldCheckAll
pageModel.rv?.commonAdapter()?.notifyDataSetChanged() pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
@@ -134,39 +127,95 @@ class IntExpTallyViewModel : BasePageViewModel() {
*/ */
fun resetDeclare() { fun resetDeclare() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return
val selectedItems = list.filter { it.isSelected }
if (selectedItems.isEmpty()) { // 收集选中的主单
val selectedMaWbList = list.filter { it.isSelected }
// 收集选中的分单
val selectedHaWbList = mutableListOf<GjcHaWb>()
list.forEach { maWb ->
maWb.haWbList?.forEach { haWb ->
if (haWb.isSelected) {
selectedHaWbList.add(haWb)
}
}
}
// 检查是否有选中项
if (selectedMaWbList.isEmpty() && selectedHaWbList.isEmpty()) {
showToast("请选择要重置的记录") showToast("请选择要重置的记录")
return return
} }
val requestData = selectedItems.toRequestBody() // 创建并显示弹框
val dialog = IntExpTallyResetDialogModel { dialogModel ->
// 弹框确认后的回调
// 构建请求参数(区分主单和分单)
val params = mutableMapOf<String, Any?>()
if (selectedMaWbList.isNotEmpty()) {
params["maWbList"] = selectedMaWbList
}
if (selectedHaWbList.isNotEmpty()) {
params["haWbList"] = selectedHaWbList
}
launchLoadingCollect({ NetApply.api.resetTallyDeclare(requestData) }) { // 根据选择添加restStatus参数
onSuccess = { // 选择"正常"时传递 "01",选择"未申报"时不传递此参数
showToast("状态重置成功") if (dialogModel.resetStatusCode != null) {
viewModelScope.launch { params["restStatus"] = dialogModel.resetStatusCode
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh") }
val requestData = params.toRequestBody()
launchLoadingCollect({ NetApply.api.resetTallyDeclare(requestData) }) {
onSuccess = {
showToast("状态重置成功")
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
refresh()
} }
refresh()
} }
} }
dialog.show()
} }
/** /**
* 理货申报 (批量操作) * 理货申报 (批量操作,主单和分单分开)
*/ */
fun declareTally() { fun declareTally() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return
val selectedItems = list.filter { it.isSelected }
if (selectedItems.isEmpty()) { // 收集选中的主单
val selectedMaWbList = list.filter { it.isSelected }
// 收集选中的分单
val selectedHaWbList = mutableListOf<GjcHaWb>()
list.forEach { maWb ->
maWb.haWbList?.forEach { haWb ->
if (haWb.isSelected) {
selectedHaWbList.add(haWb)
}
}
}
// 检查是否有选中项
if (selectedMaWbList.isEmpty() && selectedHaWbList.isEmpty()) {
showToast("请选择要理货的记录") showToast("请选择要理货的记录")
return return
} }
val requestData = selectedItems.toRequestBody() // 构建请求参数(区分主单和分单)
val params = mutableMapOf<String, Any?>()
if (selectedMaWbList.isNotEmpty()) {
params["maWbList"] = selectedMaWbList
}
if (selectedHaWbList.isNotEmpty()) {
params["haWbList"] = selectedHaWbList
}
val requestData = params.toRequestBody()
launchLoadingCollect({ NetApply.api.declareTally(requestData) }) { launchLoadingCollect({ NetApply.api.declareTally(requestData) }) {
onSuccess = { onSuccess = {
@@ -184,9 +233,22 @@ class IntExpTallyViewModel : BasePageViewModel() {
*/ */
fun deleteTally() { fun deleteTally() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return
val selectedItems = list.filter { it.isSelected }
if (selectedItems.isEmpty()) { // 收集选中的主单
val selectedMaWbList = list.filter { it.isSelected }
// 收集选中的分单
val selectedHaWbList = mutableListOf<GjcHaWb>()
list.forEach { maWb ->
maWb.haWbList?.forEach { haWb ->
if (haWb.isSelected) {
selectedHaWbList.add(haWb)
}
}
}
// 检查是否有选中项(主单和分单分开判断,互不影响)
if (selectedMaWbList.isEmpty() && selectedHaWbList.isEmpty()) {
showToast("请选择要删除申报的记录") showToast("请选择要删除申报的记录")
return return
} }
@@ -198,12 +260,13 @@ class IntExpTallyViewModel : BasePageViewModel() {
// 创建并显示弹框 // 创建并显示弹框
val dialog = IntExpTallyDeleteDialogModel(changeReasonList) { dialogModel -> val dialog = IntExpTallyDeleteDialogModel(changeReasonList) { dialogModel ->
// 弹框确认后的回调 // 弹框确认后的回调(区分主单和分单)
val param = GjcDeclareParam( val param = GjcDeclareParam(
dcode = dialogModel.changeReason.value, dcode = dialogModel.changeReason.value,
dcontactsName = dialogModel.contactName.value, dcontactsName = dialogModel.contactName.value,
dcontactsTel = dialogModel.contactPhone.value, dcontactsTel = dialogModel.contactPhone.value,
maWbList = selectedItems maWbList = if (selectedMaWbList.isNotEmpty()) selectedMaWbList else null,
haWbList = if (selectedHaWbList.isNotEmpty()) selectedHaWbList else null
) )
val requestData = param.toRequestBody() val requestData = param.toRequestBody()
@@ -233,7 +296,7 @@ class IntExpTallyViewModel : BasePageViewModel() {
val pageParams = GjcCheckInPage( val pageParams = GjcCheckInPage(
fdate = flightDate.value?.ifEmpty { null }, fdate = flightDate.value?.ifEmpty { null },
fno = flightNo.value?.ifEmpty { null }, fno = flightNo.value?.ifEmpty { null },
whNo = waybillNo.value?.ifEmpty { null }, wbNo = waybillNo.value?.ifEmpty { null },
hno = houseWaybillNo.value?.ifEmpty { null }, hno = houseWaybillNo.value?.ifEmpty { null },
pageNum = pageModel.page, pageNum = pageModel.page,
pageSize = pageModel.limit pageSize = pageModel.limit
@@ -246,7 +309,7 @@ class IntExpTallyViewModel : BasePageViewModel() {
val totalParams = GjcCheckInPage( val totalParams = GjcCheckInPage(
fdate = flightDate.value?.ifEmpty { null }, fdate = flightDate.value?.ifEmpty { null },
fno = flightNo.value?.ifEmpty { null }, fno = flightNo.value?.ifEmpty { null },
whNo = waybillNo.value?.ifEmpty { null }, wbNo = waybillNo.value?.ifEmpty { null },
hno = houseWaybillNo.value?.ifEmpty { null } hno = houseWaybillNo.value?.ifEmpty { null }
).toRequestBody() ).toRequestBody()

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

View File

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="1024dp"
android:height="1024dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<!-- 圆形背景 - 填满整个画布 (与 ic_btn_record 一致) -->
<path
android:fillColor="#599dff"
android:pathData="M512 512m-512 0a512 512 0 1 0 1024 0 512 512 0 1 0-1024 0Z" />
<!-- 海关图标内容 (白色,使用 group 进行缩放和居中) -->
<group
android:pivotX="512"
android:pivotY="512"
android:scaleX="0.85"
android:scaleY="0.85">
<path
android:fillColor="#FFFFFF"
android:pathData="M756.8 529.6s-12-32.8-12-77.6c0 0-2.4-8-4.8-0.8 0 0-1.6 41.6 0 44.8 0 0-11.2 0-14.4-48.8 0 0-0.8-8-2.4 0 0 0 0 42.4-7.2 16.8 0 0-6.4-23.2-7.2-37.6 0 0-4 2.4-6.4 13.6 0 0-7.2 0.8-9.6-29.6 0 0-2.4-7.2-4.8 0 0 0-3.2 11.2-1.6 16.8 0 0-10.4-1.6-9.6-32.8 0 0-6.4 3.2-4.8 14.4 0 0 0 7.2-4.8 0 0 0-13.6-12-28-7.2 0 0-4-0.8-14.4 10.4l-35.2 36.8s11.2 22.4 35.2 12.8c0 0 5.6-0.8 12-6.4 0 0 0.8-16 10.4-18.4 0 0 12.8-2.4 23.2 9.6 0 0 11.2 14.4-0.8 27.2 0 0-13.6 37.6-83.2 13.6 0 0 8.8 33.6-34.4 45.6l-3.2 3.2 61.6 52s12 11.2 26.4 0.8c0 0 41.6-26.4 77.6-3.2 0 0 53.6 35.2 31.2 107.2 0 0-27.2 88-112 73.6 0 0-73.6-31.2-56-96.8l6.4-20s8-12-8-22.4l-61.6-55.2s-12 32.8-62.4 33.6c0 0 4 61.6-64 51.2L291.2 767.2l-4-3.2 87.2-120s-16-64.8 46.4-64l4-4s-15.2-42.4 28-60l-192-166.4s-11.2-8.8 0.8-27.2c0 0 16-8.8 29.6 4l192 153.6 4.8-4.8s3.2-38.4 45.6-42.4c0 0 3.2-12.8-6.4-28.8 0 0-12.8-22.4 0-40.8 0 0 10.4-16.8 32.8-8 0 0 21.6 9.6 10.4 23.2 0 0-8.8 8-13.6 8.8 0 0-3.2 34.4 18.4 32l36.8-40.8s10.4-12-4.8-24c0 0-13.6-7.2 3.2-12 0 0 6.4 0.8 7.2-4.8 0 0 1.6-3.2-12-3.2 0 0-21.6 2.4-20-5.6l19.2-3.2s7.2-3.2-2.4-3.2l-21.6-0.8s-11.2 0.8-16-6.4l24-0.8s6.4 0 4.8-5.6c0 0 0-2.4-8-2.4l-49.6-1.6s-3.2-4.8 10.4-5.6l24.8-0.8s6.4-0.8-0.8-4.8c0 0 1.6-0.8-9.6-2.4l-46.4-3.2s-11.2-6.4-0.8-8l50.4-1.6s6.4-4 0-7.2H478.4s-4.8 1.6-9.6-6.4c0 0-1.6-4.8 7.2-6.4l114.4-2.4s37.6 0.8 44 36.8c0 0 2.4 11.2 1.6 27.2 0 0 4 11.2 12 8.8 0 0 8 3.2 17.6-9.6 0 0 2.4-8 3.2-13.6 0 0 0.8-16.8 25.6-15.2 0 0 17.6 7.2 25.6 23.2 0 0 8.8 9.6-3.2 20 0 0-7.2 10.4-21.6 10.4 0 0-15.2 4-14.4 18.4 0 0 0.8 21.6 24.8 18.4 0 0 17.6-12 31.2-4.8 0 0 21.6 8.8 21.6 46.4L768 540s-5.6 6.4-11.2-10.4z" />
</group>
</vector>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="1024dp"
android:height="1024dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#599dff"
android:pathData="M512 512m-512 0a512 512 0 1 0 1024 0 512 512 0 1 0-1024 0Z" />
<path
android:fillColor="#FFFFFF"
android:pathData="M716.731364 238.0814H307.26683c-19.711273 0-35.840813 16.127734-35.840813 35.840813v476.157381c0 19.713079 16.12954 35.840813 35.840813 35.840812h409.464534c19.711273 0 35.840813-16.127734 35.840812-35.840812V273.920406c0-19.713079-16.127734-35.839007-35.840812-35.839006z m-339.422956 78.156922H660.137089c11.263585 0 20.480722 7.828155 20.480723 17.397506 0 9.567544-9.217138 17.3957-20.480723 17.3957H377.308408c-11.263585 0-20.480722-7.828155-20.480722-17.3957 0-9.569351 9.215332-17.397506 20.480722-17.397506z m301.486928 96.883806c0 9.569351-9.217138 17.399312-20.480722 17.399312H378.24403c-11.263585 0-20.480722-7.829961-20.480722-17.399312s9.217138-17.399312 20.480722-17.399312h280.070584c11.263585 0 20.480722 7.829961 20.480722 17.399312z m-321.032028 77.147246c0-9.569351 9.217138-17.399312 20.480722-17.399312h98.372131c11.263585 0 20.480722 7.829961 20.480722 17.399312 0 9.567544-9.217138 17.397506-20.480722 17.397506h-98.372131c-11.263585-0.001806-20.480722-7.831768-20.480722-17.397506z m173.897391 204.287033c-18.475819 6.856409-36.964281 13.705593-55.53583 20.314551-6.9991 2.494389-11.191336 0.986196-7.961815-7.562641 7.127342-18.864156 14.272746-37.726506 21.627671-56.502158 2.483552-6.350668 6.852797-8.960655 12.55142-3.424592 11.514649 11.184111 22.799908 22.60303 34.061686 34.040012 1.497356 1.526255 2.27403 3.767774 2.992906 5.005035-0.827249 5.364472-4.315058 6.856409-7.736038 8.129793z m126.229453-122.947552c-31.709989 31.58536-63.241162 63.344117-94.905995 94.9656-2.209006 2.201782-5.026709 3.803898-6.84196 5.149532-4.790094 0.211328-6.950332-2.423947-9.193657-4.641984-10.174434-10.047999-20.095998-20.372349-30.429379-30.254176-6.224232-5.956912-5.033934-10.687401 0.559928-16.254169a17171.620059 17171.620059 0 0 0 94.80846-95.072168c5.581218-5.644436 10.149147-6.854603 16.116896-0.541865 9.822221 10.387568 19.974981 20.489754 30.302944 30.373386 6.161015 5.902725 5.200106 10.680176-0.417237 16.275844z m24.620578-25.568843c-5.438527 3.514903-8.615667 0.825442-11.958979-2.45104-10.210559-10.006456-20.04723-20.412086-30.525109-30.133159-6.926852-6.415692-5.732941-11.352089 0.648433-17.052518 6.881696-6.151983 12.887376-13.555677 21.838999-12.847639 12.423177 0.149916 33.456603 18.168762 36.724054 30.095229 2.94775 10.784936-4.520967 24.485111-16.727398 32.389127z" />
</vector>

View File

@@ -0,0 +1,232 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable
name="viewModel"
type="com.lukouguoji.gjc.viewModel.GjcAssembleWeightEditViewModel" />
</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" />
<!-- ULD信息区域 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:background="@drawable/bg_white_radius_8"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="8dp"
android:text="ULD信息"
android:textColor="@color/color_33"
android:textSize="17sp"
android:textStyle="bold" />
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="15dp">
<!-- ULD编号 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ULD编号"
android:textColor="@color/text_gray"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.uldNo}"
android:textColor="@color/text_normal"
android:textSize="16sp" />
</LinearLayout>
<!-- 总件数 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="总件数:"
android:textColor="@color/text_gray"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.totalPc}"
android:textColor="@color/text_normal"
android:textSize="16sp" />
</LinearLayout>
<!-- 总重量 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="总重量:"
android:textColor="@color/text_gray"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.totalWeight}"
android:textColor="@color/text_normal"
android:textSize="16sp" />
</LinearLayout>
<!-- 货重 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="货重:"
android:textColor="@color/text_gray"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.cargoWeight}"
android:textColor="@color/text_normal"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- 运单信息区域 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginHorizontal="15dp"
android:layout_marginBottom="15dp"
android:layout_weight="1"
android:background="@drawable/bg_white_radius_8"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="8dp"
android:text="运单信息"
android:textColor="@color/color_33"
android:textSize="17sp"
android:textStyle="bold" />
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#e7e7e7" />
<!-- 运单列表 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/item_gjc_assemble_weight_edit" />
</LinearLayout>
<!-- 取消+保存按钮组(居中) -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginHorizontal="15dp"
android:layout_marginBottom="15dp"
android:orientation="horizontal">
<!-- 取消按钮 -->
<TextView
android:id="@+id/btnCancel"
style="@style/tv_bottom_btn"
android:layout_marginEnd="10dp"
android:onClick="@{() -> viewModel.onCancelClick()}"
android:text="取消" />
<!-- 保存按钮 -->
<TextView
android:id="@+id/btnSave"
style="@style/tv_bottom_btn"
android:onClick="@{() -> viewModel.onSaveClick()}"
android:text="保存" />
</LinearLayout>
<!-- 底部统计区域 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="64dp"
android:background="@color/white"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="15dp">
<!-- 总货重 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{`总货重:` + viewModel.sumCargoWeight}"
android:textColor="@color/text_gray"
android:textSize="16sp" />
<!-- 重量误差(红色) -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text="@{`重量误差:` + viewModel.weightError}"
android:textColor="@color/text_red"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
</layout>

View File

@@ -67,7 +67,8 @@
icon="@{@drawable/img_scan}" icon="@{@drawable/img_scan}"
setOnIconClickListener="@{()-> viewModel.carIdScanClick()}" setOnIconClickListener="@{()-> viewModel.carIdScanClick()}"
type="@{SearchLayoutType.INPUT}" type="@{SearchLayoutType.INPUT}"
value="@={viewModel.carId}" /> value="@={viewModel.carId}"
setUpperCaseAlphanumeric="@{true}" />
<!-- ULD编号 --> <!-- ULD编号 -->
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout <com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
@@ -78,7 +79,8 @@
icon="@{@drawable/img_scan}" icon="@{@drawable/img_scan}"
setOnIconClickListener="@{()-> viewModel.uldScanClick()}" setOnIconClickListener="@{()-> viewModel.uldScanClick()}"
type="@{SearchLayoutType.INPUT}" type="@{SearchLayoutType.INPUT}"
value="@={viewModel.uld}" /> value="@={viewModel.uld}"
setUpperCaseAlphanumeric="@{true}" />
<!-- 搜索和添加按钮 --> <!-- 搜索和添加按钮 -->
<LinearLayout <LinearLayout
@@ -146,21 +148,20 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text='@{"合计:"+viewModel.totalCount+"票"}' android:text="合计:"
android:textColor="@color/bottom_tool_tips_text_color" android:textColor="@color/bottom_tool_tips_text_color"
android:textSize="18sp" android:textSize="18sp"
android:textStyle="bold" android:textStyle="bold"
tools:text="合计:1票" /> tools:text="合计:" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="20dp" android:text='@{"总货重:"+viewModel.cargoWeight}'
android:text='@{"总件数:"+viewModel.totalPc}'
android:textColor="@color/bottom_tool_tips_text_color" android:textColor="@color/bottom_tool_tips_text_color"
android:textSize="18sp" android:textSize="18sp"
android:textStyle="bold" android:textStyle="bold"
tools:text="总件数100" /> tools:text="总货重100" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@@ -75,6 +75,7 @@
titleLength="@{5}" titleLength="@{5}"
type="@{DataLayoutType.SPINNER}" type="@{DataLayoutType.SPINNER}"
value='@={viewModel.channel}' value='@={viewModel.channel}'
required="@{true}"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="15dp" android:layout_marginStart="15dp"
@@ -225,11 +226,11 @@
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew <com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
hint='@{"请选择探板收口"}' hint='@{"请选择探板收口"}'
list="@{viewModel.piCloseList}" list="@{viewModel.plCloseList}"
title='@{"探板收口"}' title='@{"探板收口"}'
titleLength="@{5}" titleLength="@{5}"
type="@{DataLayoutType.SPINNER}" type="@{DataLayoutType.SPINNER}"
value='@={viewModel.dataBean.piClose}' value='@={viewModel.dataBean.plClose}'
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" /> android:layout_weight="1" />
@@ -239,7 +240,7 @@
title='@{"探板尺寸"}' title='@{"探板尺寸"}'
titleLength="@{5}" titleLength="@{5}"
type="@{DataLayoutType.INPUT}" type="@{DataLayoutType.INPUT}"
value='@={viewModel.dataBean.piCloseSize}' value='@={viewModel.dataBean.plCloseSize}'
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="15dp" android:layout_marginStart="15dp"
@@ -342,33 +343,21 @@
</LinearLayout> </LinearLayout>
<!-- 第7行件数、备注、空 --> <!-- 第7行备注 -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:orientation="horizontal"> android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
hint='@{"请输入件数"}'
title='@{"件数"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.dataBean.pieces}'
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew <com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
hint='@{"请输入备注"}' hint='@{"请输入备注"}'
title='@{"备注"}' title='@{"备注"}'
titleLength="@{5}" titleLength="@{5}"
type="@{DataLayoutType.INPUT}" type="@{DataLayoutType.INPUT}"
value='@={viewModel.dataBean.remark}' value='@={viewModel.dataBean.remark}'
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content" />
android:layout_marginStart="15dp"
android:layout_weight="2" />
</LinearLayout> </LinearLayout>

View File

@@ -56,7 +56,7 @@
title='@{"通道号"}' title='@{"通道号"}'
titleLength="@{5}" titleLength="@{5}"
type="@{DataLayoutType.INPUT}" type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.passagewayName}' value='@{viewModel.dataBean.passageway}'
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" /> android:layout_weight="1" />
@@ -163,7 +163,7 @@
title='@{"探板收口"}' title='@{"探板收口"}'
titleLength="@{5}" titleLength="@{5}"
type="@{DataLayoutType.INPUT}" type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.piClose}' value='@{viewModel.dataBean.plClose}'
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" /> android:layout_weight="1" />
@@ -173,7 +173,7 @@
title='@{"探板尺寸"}' title='@{"探板尺寸"}'
titleLength="@{5}" titleLength="@{5}"
type="@{DataLayoutType.INPUT}" type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.piCloseSize}' value='@{viewModel.dataBean.plCloseSize}'
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" /> android:layout_weight="1" />
@@ -236,16 +236,6 @@
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:orientation="horizontal"> 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="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew <com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{false}" enable="@{false}"
title='@{"备注"}' title='@{"备注"}'

View File

@@ -141,13 +141,36 @@
android:gravity="center_vertical" android:gravity="center_vertical"
android:paddingHorizontal="15dp"> android:paddingHorizontal="15dp">
<!-- 全选按钮 (图标+文字) -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:onClick="@{()-> viewModel.checkAllClick()}">
<ImageView
android:id="@+id/checkIcon"
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/img_check_all" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="全选"
android:textColor="@color/bottom_tool_tips_text_color"
android:textSize="18sp" />
</LinearLayout>
<!-- 统计信息 --> <!-- 统计信息 -->
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal"
android:paddingStart="20dp">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"

View File

@@ -64,6 +64,7 @@
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew <com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
hint='@{"请输入运单号"}' hint='@{"请输入运单号"}'
required="@{true}" required="@{true}"
setRefreshCallBack="@{viewModel::onWaybillNoInputComplete}"
title='@{"运单号"}' title='@{"运单号"}'
titleLength="@{5}" titleLength="@{5}"
type="@{DataLayoutType.INPUT}" type="@{DataLayoutType.INPUT}"
@@ -153,13 +154,18 @@
android:background="@drawable/bg_shouyun_dbzl" android:background="@drawable/bg_shouyun_dbzl"
android:minHeight="60dp"> android:minHeight="60dp">
<TextView <EditText
android:id="@+id/tvWeight" android:id="@+id/etWeight"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_centerInParent="true" android:layout_centerInParent="true"
android:text="@{viewModel.diBangWeight}" android:background="@null"
android:gravity="center"
android:hint="0"
android:inputType="numberDecimal"
android:text="@={viewModel.diBangWeight}"
android:textColor="@color/text_red" android:textColor="@color/text_red"
android:textColorHint="@color/text_red"
android:textSize="45sp" android:textSize="45sp"
android:textStyle="bold" android:textStyle="bold"
tools:text="1655" /> tools:text="1655" />
@@ -167,11 +173,11 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignBaseline="@id/tvWeight" android:layout_alignBaseline="@id/etWeight"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_toEndOf="@id/tvWeight" android:layout_toEndOf="@id/etWeight"
android:text="kg" android:text="kg"
android:textColor="@color/black" android:textColor="@color/text_red"
android:textSize="24sp" android:textSize="24sp"
android:textStyle="bold" /> android:textStyle="bold" />
@@ -357,6 +363,7 @@
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew <com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
hint='@{"请输入托盘车号"}' hint='@{"请输入托盘车号"}'
setRefreshCallBack="@{viewModel::onCarIdInputComplete}"
title='@{"托盘车号"}' title='@{"托盘车号"}'
titleLength="@{5}" titleLength="@{5}"
type="@{DataLayoutType.INPUT}" type="@{DataLayoutType.INPUT}"
@@ -459,7 +466,7 @@
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
android:layout_marginEnd="25dp" android:layout_marginEnd="25dp"
android:layout_marginBottom="70dp" android:layout_marginBottom="70dp"
android:background="@drawable/bg_float_button" android:background="@drawable/ic_btn_customs"
android:visibility="gone" /> android:visibility="gone" />
<!-- 子按钮2 --> <!-- 子按钮2 -->
@@ -470,7 +477,7 @@
android:layout_gravity="bottom|end" android:layout_gravity="bottom|end"
android:layout_marginEnd="70dp" android:layout_marginEnd="70dp"
android:layout_marginBottom="25dp" android:layout_marginBottom="25dp"
android:background="@drawable/bg_float_button" android:background="@drawable/ic_btn_record"
android:visibility="gone" /> android:visibility="gone" />
<!-- 主浮动按钮 --> <!-- 主浮动按钮 -->

View File

@@ -101,9 +101,9 @@
android:layout_height="36dp" android:layout_height="36dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="@{()-> viewModel.toggleAllExpand()}" android:onClick="@{()-> viewModel.toggleAllExpand()}"
android:padding="2dp" android:padding="4dp"
android:scaleType="fitCenter" android:scaleType="fitCenter"
loadImage="@{viewModel.isAllExpanded ? R.mipmap.img_up : R.mipmap.img_down}" loadImage="@{viewModel.isAllExpanded ? R.drawable.ic_new_expand : R.drawable.ic_new_expand}"
android:contentDescription="展开/收起全部子列表" /> android:contentDescription="展开/收起全部子列表" />
</LinearLayout> </LinearLayout>

View File

@@ -132,8 +132,10 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:overScrollMode="never" android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
tools:itemCount="3" tools:itemCount="3"
tools:listitem="@layout/item_int_exp_assemble_uld" /> tools:listitem="@layout/item_int_exp_assemble" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout> </com.scwang.smart.refresh.layout.SmartRefreshLayout>

View File

@@ -254,7 +254,7 @@
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew <com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:id="@+id/uldNoInput" android:id="@+id/uldNoInput"
enable="@{!viewModel.isUldNoLocked}" enable="@{!viewModel.isUldNoLocked &amp;&amp; !viewModel.isFromEditMode}"
required="@{false}" required="@{false}"
setRefreshCallBack="@{viewModel::onUldNoInputComplete}" setRefreshCallBack="@{viewModel::onUldNoInputComplete}"
title='@{"ULD编号"}' title='@{"ULD编号"}'

View File

@@ -172,6 +172,12 @@
</LinearLayout> </LinearLayout>
<!-- 待配运按钮 -->
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()-> viewModel.waitingTransClick()}"
android:text="配运" />
<!-- 交接完成按钮 --> <!-- 交接完成按钮 -->
<TextView <TextView
style="@style/tv_bottom_btn" style="@style/tv_bottom_btn"

View File

@@ -108,13 +108,13 @@
<!-- 全局展开/收起按钮 --> <!-- 全局展开/收起按钮 -->
<ImageView <ImageView
loadImage="@{viewModel.isAllExpanded ? R.mipmap.img_up : R.mipmap.img_down}" loadImage="@{viewModel.isAllExpanded ? R.drawable.ic_new_expand : R.drawable.ic_new_expand}"
android:layout_width="36dp" android:layout_width="36dp"
android:layout_height="36dp" android:layout_height="36dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:contentDescription="展开/收起全部子列表" android:contentDescription="展开/收起全部子列表"
android:onClick="@{()-> viewModel.toggleAllExpand()}" android:onClick="@{()-> viewModel.toggleAllExpand()}"
android:padding="2dp" android:padding="4dp"
android:scaleType="fitCenter" /> android:scaleType="fitCenter" />
</LinearLayout> </LinearLayout>
@@ -240,7 +240,7 @@
<!-- 入库按钮 --> <!-- 入库按钮 -->
<TextView <TextView
style="@style/tv_bottom_btn" style="@style/tv_bottom_btn"
android:onClick="@{()-> viewModel.inStorage()}" android:onClick="@{()-> activity.showInStorageDialog()}"
android:text="入 库" /> android:text="入 库" />
</LinearLayout> </LinearLayout>

View File

@@ -102,9 +102,9 @@
android:layout_height="36dp" android:layout_height="36dp"
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:onClick="@{()-> viewModel.toggleAllExpand()}" android:onClick="@{()-> viewModel.toggleAllExpand()}"
android:padding="2dp" android:padding="4dp"
android:scaleType="fitCenter" android:scaleType="fitCenter"
loadImage="@{viewModel.isAllExpanded ? R.mipmap.img_up : R.mipmap.img_down}" loadImage="@{viewModel.isAllExpanded ? R.drawable.ic_new_expand : R.drawable.ic_new_expand}"
android:contentDescription="展开/收起全部子列表" /> android:contentDescription="展开/收起全部子列表" />
</LinearLayout> </LinearLayout>

View File

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

View File

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

View File

@@ -55,9 +55,10 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
type="@{SearchLayoutType.INPUT}" type="@{SearchLayoutType.SPINNER}"
hint='@{"请输入库位"}' hint='@{"请选择库位"}'
value="@={model.location}" /> list="@{model.locationList}"
value="@={model.selectedLocationCode}" />
</LinearLayout> </LinearLayout>

View File

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

View File

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

View File

@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="android.view.View" />
<import type="com.lukouguoji.module_base.ui.weight.data.layout.DataLayoutType" />
<variable
name="bean"
type="com.lukouguoji.module_base.bean.GjcWarehouse" />
<variable
name="position"
type="Integer" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_8"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="15dp"
android:paddingVertical="8dp">
<!-- 运单号(只读) -->
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.5"
enable="@{false}"
title="@{`运单号`}"
titleLength="@{3}"
type="@{DataLayoutType.INPUT}"
value="@{bean.wbNo}" />
<!-- 件数(只读) -->
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_weight="1"
enable="@{false}"
title="@{`件数`}"
titleLength="@{2}"
type="@{DataLayoutType.INPUT}"
value="@{String.valueOf(bean.checkInPc)}" />
<!-- 重量(可编辑) -->
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_weight="1"
enable="@{true}"
hint="@{`请输入重量`}"
inputType="@{android.text.InputType.TYPE_CLASS_NUMBER | android.text.InputType.TYPE_NUMBER_FLAG_DECIMAL}"
title="@{`重量`}"
titleLength="@{2}"
type="@{DataLayoutType.INPUT}"
value="@={bean.checkInWeightStr}" />
</LinearLayout>
</layout>

View File

@@ -77,7 +77,7 @@
title="@{`托盘自重`}" title="@{`托盘自重`}"
titleLength="@{4}" titleLength="@{4}"
type="@{DataLayoutType.INPUT}" type="@{DataLayoutType.INPUT}"
value="@{`100`}" /> value="@{record.carWeight}" />
<!-- 计重时间字段(只读) --> <!-- 计重时间字段(只读) -->
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew <com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew

View File

@@ -38,7 +38,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1.5" android:layout_weight="1.5"
android:gravity="center" android:gravity="center"
android:text="@{bean.storageCode ?? `--`}" android:text="@{bean.location ?? `--`}"
android:textColor="@android:color/black" android:textColor="@android:color/black"
android:textSize="14sp" /> android:textSize="14sp" />
@@ -48,7 +48,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:gravity="center" android:gravity="center"
android:text="@{bean.inId ?? `--`}" android:text="@{bean.inOpId ?? `--`}"
android:textColor="@android:color/black" android:textColor="@android:color/black"
android:textSize="14sp" /> android:textSize="14sp" />
@@ -68,7 +68,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="1"
android:gravity="center" android:gravity="center"
android:text="@{bean.outId ?? `--`}" android:text="@{bean.outOpId ?? `--`}"
android:textColor="@android:color/black" android:textColor="@android:color/black"
android:textSize="14sp" /> android:textSize="14sp" />

View File

@@ -9,6 +9,10 @@
<variable <variable
name="bean" name="bean"
type="com.lukouguoji.module_base.bean.GjcWeighingBean" /> type="com.lukouguoji.module_base.bean.GjcWeighingBean" />
<variable
name="position"
type="int" />
</data> </data>
<androidx.appcompat.widget.LinearLayoutCompat <androidx.appcompat.widget.LinearLayoutCompat
@@ -17,13 +21,14 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp" android:layout_marginHorizontal="15dp"
android:layout_marginVertical="5dp" android:layout_marginVertical="5dp"
android:background="@drawable/bg_item" android:background="@{bean.checkIn.equals(`2`) ? @drawable/bg_item_green : @drawable/bg_item}"
android:orientation="horizontal" android:orientation="horizontal"
android:padding="10dp"> android:padding="10dp">
<!-- 飞机图标 --> <!-- 飞机图标 (根据checked状态切换图片) -->
<ImageView <ImageView
android:id="@+id/iv_icon" android:id="@+id/iv_icon"
loadImage="@{bean.checked.get() ? @drawable/img_plane_s : @drawable/img_plane}"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"
android:layout_gravity="center" android:layout_gravity="center"

View File

@@ -25,6 +25,7 @@
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"
android:layout_gravity="center" android:layout_gravity="center"
loadImage="@{bean.checked.get() ? @drawable/img_plane_s : @drawable/img_plane}"
android:src="@drawable/img_plane" /> android:src="@drawable/img_plane" />
<LinearLayout <LinearLayout

View File

@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:loadImage="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="bean"
type="com.lukouguoji.module_base.bean.GjcHaWb" />
<variable
name="position"
type="Integer" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginVertical="8dp"
android:paddingHorizontal="10dp">
<!-- 选项 - 圆形checkbox -->
<ImageView
android:id="@+id/iv_checkbox"
loadImage="@{bean.checked.get() ? @drawable/radiobtn_checked_gray : @drawable/radiobtn_unchecked_gray}"
android:layout_width="0dp"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:layout_weight="0.5"
app:tint="@color/color_66"
android:src="@drawable/radiobtn_unchecked_style" />
<!-- 分单号 (前缀-编号-H编号) -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.2"
android:gravity="center"
android:text="@{bean.hno ?? ``}"
android:textColor="@color/colorPrimary"
android:textSize="14sp"
android:textStyle="bold" />
<!-- 件数 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="@{String.valueOf(bean.hpc ?? bean.pc)}"
android:textColor="@color/text_normal"
android:textSize="14sp" />
<!-- 重量 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="@{String.valueOf((int)(bean.hweight ?? bean.weight))}"
android:textColor="@color/text_normal"
android:textSize="14sp" />
<!-- 申报状态 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@{bean.arrivalStatus ?? ``}"
android:textColor="@color/text_normal"
android:textSize="14sp" />
<!-- 品名(中) -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@{bean.goodsCn ?? bean.goods}"
android:textColor="@color/text_normal"
android:textSize="14sp" />
<!-- 申报次数 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.9"
android:gravity="center"
android:text="@{bean.arrivalSCount != null ? String.valueOf((int)bean.arrivalSCount.doubleValue()) : `0`}"
android:textColor="@color/text_normal"
android:textSize="14sp" />
<!-- 申报费率 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.9"
android:gravity="center"
android:text="@{bean.arrivalSRate != null ? String.valueOf(bean.arrivalSRate) : `0`}"
android:textColor="@color/text_normal"
android:textSize="14sp" />
<!-- 删除次数 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.9"
android:gravity="center"
android:text="@{bean.arrivalDCount != null ? String.valueOf((int)bean.arrivalDCount.doubleValue()) : `0`}"
android:textColor="@color/text_normal"
android:textSize="14sp" />
<!-- 删除费率 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.9"
android:gravity="center"
android:text="@{bean.arrivalDRate != null ? String.valueOf(bean.arrivalDRate) : `0`}"
android:textColor="@color/text_normal"
android:textSize="14sp" />
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/c999999" />
</LinearLayout>
</layout>

View File

@@ -0,0 +1,529 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<variable
name="bean"
type="com.lukouguoji.module_base.bean.GjcUldUseBean" />
<variable
name="position"
type="Integer" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:orientation="vertical">
<!-- 侧滑布局 -->
<com.mcxtzhang.swipemenulib.SwipeMenuLayout
android:id="@+id/swipe_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 白色卡片 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_8"
android:orientation="vertical">
<!-- 主要内容区域 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="15dp">
<!-- 选中图标 (飞机图标,根据选择状态切换图片) -->
<ImageView
android:id="@+id/iv_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
loadImage="@{bean.checked.get() ? @drawable/img_plane_s : @drawable/img_plane}"
android:src="@drawable/img_plane" />
<!-- ULD信息区域 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_weight="0.8"
android:orientation="vertical">
<!-- 第一行ULD编码、总重、货重、件数、复磅状态 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<!-- ULD编码 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="ULD编码"
android:textColor="@color/text_normal"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.uld}"
android:textColor="@color/colorPrimary"
android:textSize="16sp" />
</LinearLayout>
<!-- 货重 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{4}"
android:text="货重:"
android:textColor="@color/text_normal"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf((int)bean.cargoWeight)}"
android:textColor="@color/text_normal"
android:textSize="16sp" />
</LinearLayout>
<!-- 件数 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{4}"
android:text="件数:"
android:textColor="@color/text_normal"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf(bean.pc)}"
android:textColor="@color/text_normal"
android:textSize="16sp" />
</LinearLayout>
<!-- 复磅状态 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="复磅状态:"
android:textColor="@color/text_normal"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.wtDate != null &amp;&amp; !bean.wtDate.isEmpty() ? `已复磅` : `未复磅`}"
android:textColor="@{bean.wtDate != null &amp;&amp; !bean.wtDate.isEmpty() ? @color/text_green : @color/text_normal}"
android:textSize="16sp" />
</LinearLayout>
<!-- 回填状态 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="回填状态:"
android:textColor="@color/text_normal"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.fillWeightFlagText}"
android:textColor="@{bean.isFillWeightGreen ? @color/text_green : @color/text_normal}"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
<!-- 第二行:航班日期、航班号、组装人、组装区、组装时间 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<!-- 航班日期 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="航班日期:"
android:textColor="@color/text_normal"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.fdateFormatted}"
android:textColor="@color/text_normal"
android:textSize="16sp" />
</LinearLayout>
<!-- 航班号 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{4}"
android:text="航班号:"
android:textColor="@color/text_normal"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.fno}"
android:textColor="@color/text_normal"
android:textSize="16sp" />
</LinearLayout>
<!-- 组装人 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{4}"
android:text="组装人:"
android:textColor="@color/text_normal"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.ldId}"
android:textColor="@color/text_normal"
android:textSize="16sp" />
</LinearLayout>
<!-- 组装区 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="组装区:"
android:textColor="@color/text_normal"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.loadArea}"
android:textColor="@color/text_normal"
android:textSize="16sp" />
</LinearLayout>
<!-- 组装时间 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="组装时间:"
android:textColor="@color/text_normal"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.ldDate}"
android:textColor="@color/text_normal"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- 展开按钮 - 始终显示 -->
<ImageView
android:id="@+id/iv_show"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:padding="5dp"
android:rotation="@{bean.showMore.get() ? 180f : 0f}"
android:src="@mipmap/img_down" />
</LinearLayout>
<!-- 侧滑菜单区域 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- 修改按钮 -->
<TextView
android:id="@+id/btn_edit"
style="@style/tv_item_action"
android:background="@color/colorPrimary"
android:text="修改" />
<!-- 删除按钮 -->
<TextView
android:id="@+id/btn_delete"
style="@style/tv_item_action"
android:background="@color/red"
android:text="删除" />
</androidx.appcompat.widget.LinearLayoutCompat>
</com.mcxtzhang.swipemenulib.SwipeMenuLayout>
<!-- 子列表容器 -->
<LinearLayout
visible="@{bean.showMore}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:background="#e3f6e0"
android:orientation="vertical"
android:visibility="gone">
<!-- 加载中状态 -->
<LinearLayout
visible="@{bean.isLoading}"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center"
android:orientation="horizontal"
android:visibility="gone">
<ProgressBar
android:layout_width="24dp"
android:layout_height="24dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="加载中..."
android:textColor="@color/text_gray"
android:textSize="14sp" />
</LinearLayout>
<!-- 暂无数据占位UI -->
<TextView
visible="@{bean.showEmptyView &amp;&amp; !bean.isLoading.get()}"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center"
android:text="暂无数据"
android:textColor="@color/text_gray"
android:textSize="14sp"
android:visibility="gone" />
<!-- 表头 (有数据时显示) -->
<LinearLayout
visible="@{bean.hasWaybillDetails &amp;&amp; !bean.isLoading.get()}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="10dp"
android:orientation="horizontal"
android:paddingHorizontal="10dp"
android:visibility="gone">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:gravity="center"
android:text="序号"
android:textColor="@color/text_normal"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="center"
android:text="运单号"
android:textColor="@color/text_normal"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="件数"
android:textColor="@color/text_normal"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center"
android:text="重量(KG)"
android:textColor="@color/text_normal"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="代理"
android:textColor="@color/text_normal"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="目的港"
android:textColor="@color/text_normal"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="特码"
android:textColor="@color/text_normal"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="center"
android:text="品名(中)"
android:textColor="@color/text_normal"
android:textSize="14sp"
android:textStyle="bold" />
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
visible="@{bean.hasWaybillDetails &amp;&amp; !bean.isLoading.get()}"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/c999999"
android:visibility="gone" />
<!-- 子列表 RecyclerView (有数据时显示) -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_sub"
visible="@{bean.hasWaybillDetails &amp;&amp; !bean.isLoading.get()}"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
</LinearLayout>
</layout>

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