Compare commits
69 Commits
116675c9db
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| ca20d70e8a | |||
| bad565085a | |||
| 6ea6833396 | |||
| 3da68b1eed | |||
| e4bf1f1fee | |||
| 69812bcc0b | |||
| 65c91a0233 | |||
| 2ed1f06a9d | |||
| 9eb9278676 | |||
| a7b560b048 | |||
| 1deca69a67 | |||
| 8e2f584f3a | |||
| 5e1e9e58a2 | |||
| 5f31cf5274 | |||
| d3ea88db08 | |||
| ff2649e063 | |||
| 6b655348e1 | |||
| 0f1dbe4e05 | |||
| a3fda12fd8 | |||
| b0b109de9a | |||
| 9a034c1653 | |||
| de8e49389a | |||
| a52259f951 | |||
| d6be019c3a | |||
| 80a0983459 | |||
| dbfcdb4a01 | |||
| 672c8308b8 | |||
| 9a327975bd | |||
| cd0cd89a66 | |||
| b37f330414 | |||
| 675b9d234e | |||
| 8b00597763 | |||
| e2f6cdde04 | |||
| ac4cd63abc | |||
| 7a5e06a5af | |||
| 3eee861486 | |||
| dfddf646f5 | |||
| a8d125ef9d | |||
| 0a506617c7 | |||
| 76183823b0 | |||
| 557874ab88 | |||
| 49151d0066 | |||
| 4e34a8f406 | |||
| ab4b1618c8 | |||
| ca81d8f8bb | |||
| caeb68f9fd | |||
| 23a6f1b596 | |||
| 8e3e604ed3 | |||
| fa6e5f01b4 | |||
| f19b0d7c68 | |||
| 085af11706 | |||
| 65ba31f9df | |||
| 38625562ef | |||
| 2b5e0a45aa | |||
| 774ba91aad | |||
| ff1c69f1dd | |||
| ac0ade9eab | |||
| c3c700c111 | |||
| e083165553 | |||
| 30678a54be | |||
| 7f812abc29 | |||
| 7560dcc980 | |||
| 3c35adc0ed | |||
| 28159ce738 | |||
| 0a27fed728 | |||
| 72a8c3107d | |||
| 978a9af821 | |||
| 85ea4649ef | |||
| f4606b7ba5 |
@@ -42,7 +42,17 @@
|
|||||||
"Bash(vfox list:*)",
|
"Bash(vfox list:*)",
|
||||||
"Bash(vf list:*)",
|
"Bash(vf list:*)",
|
||||||
"Bash(vfox use:*)",
|
"Bash(vfox use:*)",
|
||||||
"Bash(wait)"
|
"Bash(wait)",
|
||||||
|
"Bash(while read file)",
|
||||||
|
"Bash(do sed -i '' 's/MutableLiveData\\(DateUtils\\\\.getCurrentTime\\(\\)\\\\.formatDate\\(\\)\\)/MutableLiveData<String>\\(DateUtils.getCurrentTime\\(\\).formatDate\\(\\)\\)/g' \"$file\" echo \"Modified: $file\" done)",
|
||||||
|
"Bash(xargs sed:*)",
|
||||||
|
"Bash(while IFS= read -r 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(identify:*)",
|
||||||
|
"WebFetch(domain:github.com)",
|
||||||
|
"Bash(file:*)",
|
||||||
|
"Bash(xargs:*)"
|
||||||
],
|
],
|
||||||
"deny": [],
|
"deny": [],
|
||||||
"ask": []
|
"ask": []
|
||||||
|
|||||||
1
.gitignore
vendored
@@ -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/
|
||||||
|
|||||||
2
.vfox.toml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
[tools]
|
||||||
|
java = "17.0.17+10-amzn"
|
||||||
1
.vfox/sdks/java
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/Users/kid/.version-fox/cache/java/v-17.0.17+10-amzn/java-17.0.17+10-amzn
|
||||||
@@ -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"
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
@@ -133,6 +139,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.IntExpStorageUseActivity"
|
||||||
|
android:configChanges="orientation|keyboardHidden"
|
||||||
|
android:exported="false"
|
||||||
|
android:screenOrientation="userLandscape" />
|
||||||
<!-- 国际出港查询 -->
|
<!-- 国际出港查询 -->
|
||||||
<activity
|
<activity
|
||||||
android:name="com.lukouguoji.gjc.activity.GjcQueryActivity"
|
android:name="com.lukouguoji.gjc.activity.GjcQueryActivity"
|
||||||
|
|||||||
@@ -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,6 +419,12 @@ 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 -> {
|
||||||
|
ARouter.getInstance()
|
||||||
|
.build(ARouterConstants.ACTIVITY_URL_INT_EXP_STORAGE_USE)
|
||||||
|
.navigation()
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 国际进港
|
* 国际进港
|
||||||
*/
|
*/
|
||||||
@@ -434,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()
|
||||||
}
|
}
|
||||||
// 进港舱单
|
// 进港舱单
|
||||||
@@ -531,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
|
||||||
@@ -556,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(
|
||||||
@@ -573,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,
|
||||||
@@ -648,99 +636,111 @@ 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,
|
||||||
"出港计重"
|
"出港计重"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 3. 出港运抵
|
||||||
list.add(
|
list.add(
|
||||||
RightMenu(
|
RightMenu(
|
||||||
Constant.AuthName.GjcFuBangActivity,
|
Constant.AuthName.GjcIntExpArrive,
|
||||||
R.mipmap.gjc_fu_bang_icon,
|
R.drawable.img_gjc_chugang_diyun,
|
||||||
"板箱过磅"
|
"出港运抵"
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
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,
|
|
||||||
"出港移库"
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 4. 组装分配
|
||||||
list.add(
|
list.add(
|
||||||
RightMenu(
|
RightMenu(
|
||||||
Constant.AuthName.GjcAssembleAllocateActivity,
|
Constant.AuthName.GjcAssembleAllocateActivity,
|
||||||
com.lukouguoji.module_base.R.drawable.img_gjc_banxiangzuzhuang,
|
R.drawable.img_gjc_zuzhuangfenpei,
|
||||||
"组装分配"
|
"组装分配"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 5. 出港组装
|
||||||
list.add(
|
list.add(
|
||||||
RightMenu(
|
RightMenu(
|
||||||
Constant.AuthName.GjcIntExpOutHandover,
|
Constant.AuthName.GjcIntExpAssembleActivity,
|
||||||
com.lukouguoji.module_base.R.drawable.img_gjc_chuku_jiaojie,
|
R.drawable.img_gjc_banxiangzuzhuang,
|
||||||
"出库交接"
|
"出港组装"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 6. 板箱过磅
|
||||||
|
list.add(
|
||||||
|
RightMenu(
|
||||||
|
Constant.AuthName.GjcFuBangActivity,
|
||||||
|
R.drawable.img_gjc_banxiangguobang,
|
||||||
|
"板箱过磅"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// 7. 出港装载
|
||||||
list.add(
|
list.add(
|
||||||
RightMenu(
|
RightMenu(
|
||||||
Constant.AuthName.GjcIntExpLoad,
|
Constant.AuthName.GjcIntExpLoad,
|
||||||
com.lukouguoji.module_base.R.drawable.img_gjc_chugang_zhuangzai,
|
R.drawable.img_gjc_chugang_zhuangzai,
|
||||||
"出港装载"
|
"出港装载"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 8. 出库交接
|
||||||
|
list.add(
|
||||||
|
RightMenu(
|
||||||
|
Constant.AuthName.GjcIntExpOutHandover,
|
||||||
|
R.drawable.img_gjc_chuku_jiaojie,
|
||||||
|
"出库交接"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// 9. 出港理货
|
||||||
list.add(
|
list.add(
|
||||||
RightMenu(
|
RightMenu(
|
||||||
Constant.AuthName.GjcIntExpTally,
|
Constant.AuthName.GjcIntExpTally,
|
||||||
com.lukouguoji.module_base.R.drawable.img_gjc_chugang_lihuo,
|
R.drawable.img_gjc_chugang_lihuo,
|
||||||
"出港理货"
|
"出港理货"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 10. 出港移库
|
||||||
list.add(
|
list.add(
|
||||||
RightMenu(
|
RightMenu(
|
||||||
Constant.AuthName.GjcIntExpArrive,
|
Constant.AuthName.GjcYiKuListActivity,
|
||||||
com.lukouguoji.module_base.R.drawable.img_gjc_chugang_diyun,
|
R.drawable.gjc_yi_ku_icon,
|
||||||
"出港运抵"
|
"出港移库"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// 11. 出港仓库
|
||||||
|
list.add(
|
||||||
|
RightMenu(
|
||||||
|
Constant.AuthName.GjcIntExpStorageUse,
|
||||||
|
R.drawable.gjc_cang_ku_icon,
|
||||||
|
"出港仓库"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// 12. 出港查询
|
||||||
|
list.add(
|
||||||
|
RightMenu(
|
||||||
|
Constant.AuthName.GjcQueryListActivity,
|
||||||
|
R.drawable.gjc_query_icon,
|
||||||
|
"出港查询"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -138,6 +138,9 @@ dependencies {
|
|||||||
api 'io.github.lucksiege:pictureselector:v3.11.2'
|
api 'io.github.lucksiege:pictureselector:v3.11.2'
|
||||||
api "com.github.bumptech.glide:glide:4.15.1"
|
api "com.github.bumptech.glide:glide:4.15.1"
|
||||||
|
|
||||||
|
// PDF预览库
|
||||||
|
api 'com.github.barteksc:android-pdf-viewer:2.8.2'
|
||||||
|
|
||||||
|
|
||||||
// DevApp - Android 工具类库
|
// DevApp - Android 工具类库
|
||||||
api 'io.github.afkt:DevAppX:2.4.0'
|
api 'io.github.afkt:DevAppX:2.4.0'
|
||||||
@@ -153,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'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BIN
module_base/libs/sdk2-2.0.4.aar
Normal 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(),
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 no: 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 // 每页条数
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|
||||||
// 数据变化回调
|
// 数据变化回调
|
||||||
|
|||||||
@@ -47,17 +47,4 @@ class GjcExportLoad {
|
|||||||
fun getFullWaybillNo(): String {
|
fun getFullWaybillNo(): String {
|
||||||
return if (prefix.isNotEmpty()) "$prefix$no" else no
|
return if (prefix.isNotEmpty()) "$prefix$no" else no
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取装载状态显示文字
|
|
||||||
*/
|
|
||||||
fun getLoadStatusText(): String {
|
|
||||||
return when (loadStatus) {
|
|
||||||
"01" -> "已申报"
|
|
||||||
"02" -> "申报中"
|
|
||||||
"03" -> "申报失败"
|
|
||||||
"04" -> "已删除"
|
|
||||||
else -> loadStatus
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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" // 灰色-未知
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package com.lukouguoji.module_base.bean
|
package com.lukouguoji.module_base.bean
|
||||||
|
|
||||||
import androidx.databinding.ObservableBoolean
|
import androidx.databinding.ObservableBoolean
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 国际出港主单数据模型
|
* 国际出港主单数据模型
|
||||||
@@ -72,12 +74,14 @@ 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:收运中
|
||||||
var declareStatus: String? = null, // 申报状态
|
var declareStatus: String? = null, // 申报状态
|
||||||
var reviewStatus: String? = null, // 审核状态(0:未审核;1:通过;2:退回)
|
var reviewStatus: String? = null, // 审核状态(0:未审核;1:通过;2:退回)
|
||||||
var tranFlag: String? = null, // 转运标志
|
var tranFlag: String? = null, // 转运标志
|
||||||
|
var clearNormal: String? = null, // 清仓正常(0:否,1:是)
|
||||||
|
|
||||||
// ==================== 操作信息 ====================
|
// ==================== 操作信息 ====================
|
||||||
var opDate: String? = null, // 操作时间(入库时间)
|
var opDate: String? = null, // 操作时间(入库时间)
|
||||||
@@ -107,10 +111,14 @@ data class GjcMaWb(
|
|||||||
// ==================== 关联列表(非数据库字段,用于展示) ====================
|
// ==================== 关联列表(非数据库字段,用于展示) ====================
|
||||||
var haWbList: List<GjcHaWb>? = null, // 分单列表
|
var haWbList: List<GjcHaWb>? = null, // 分单列表
|
||||||
var storageUseList: List<GjcStorageUse>? = null, // 库位使用列表
|
var storageUseList: List<GjcStorageUse>? = null, // 库位使用列表
|
||||||
|
@Transient
|
||||||
var attachList: List<ComAttach>? = null // 附件列表
|
var attachList: List<ComAttach>? = null // 附件列表
|
||||||
) {
|
) {
|
||||||
// ==================== UI扩展字段 ====================
|
// ==================== UI扩展字段 ====================
|
||||||
|
@Transient
|
||||||
val checked: ObservableBoolean = ObservableBoolean(false) // 选中状态
|
val checked: ObservableBoolean = ObservableBoolean(false) // 选中状态
|
||||||
|
@Transient
|
||||||
|
val showMore: ObservableBoolean = ObservableBoolean(false) // 展开状态
|
||||||
|
|
||||||
// 兼容现有API的isSelected属性
|
// 兼容现有API的isSelected属性
|
||||||
var isSelected: Boolean
|
var isSelected: Boolean
|
||||||
@@ -140,6 +148,34 @@ data class GjcMaWb(
|
|||||||
"1" -> "提前运抵"
|
"1" -> "提前运抵"
|
||||||
else -> arriveFlag ?: ""
|
else -> arriveFlag ?: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 航班信息(格式化后)
|
||||||
|
* 格式: yyyyMMdd/航班号
|
||||||
|
* 示例: 20260108/MU2025
|
||||||
|
*/
|
||||||
|
val flightInfo: String
|
||||||
|
get() {
|
||||||
|
val dateFormat = SimpleDateFormat("yyyyMMdd", Locale.getDefault())
|
||||||
|
val formattedDate = fdate?.let { dateFormat.format(it) } ?: ""
|
||||||
|
val flightNo = fno ?: ""
|
||||||
|
return if (formattedDate.isNotEmpty() && flightNo.isNotEmpty()) {
|
||||||
|
"$formattedDate/$flightNo"
|
||||||
|
} else {
|
||||||
|
flight ?: "" // 如果无法格式化,回退到原始flight字段
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清仓正常状态中文
|
||||||
|
* 0-否,1-是
|
||||||
|
*/
|
||||||
|
val clearNormalText: String
|
||||||
|
get() = when (clearNormal) {
|
||||||
|
"0" -> "否"
|
||||||
|
"1" -> "是"
|
||||||
|
else -> clearNormal ?: ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -221,6 +257,7 @@ data class GjcHaWb(
|
|||||||
var activeId: Long? = null // 活动ID
|
var activeId: Long? = null // 活动ID
|
||||||
) {
|
) {
|
||||||
// ==================== UI扩展字段 ====================
|
// ==================== UI扩展字段 ====================
|
||||||
|
@Transient
|
||||||
val checked: ObservableBoolean = ObservableBoolean(false) // 选中状态
|
val checked: ObservableBoolean = ObservableBoolean(false) // 选中状态
|
||||||
|
|
||||||
// 兼容现有API的isSelected属性
|
// 兼容现有API的isSelected属性
|
||||||
@@ -237,9 +274,24 @@ data class GjcStorageUse(
|
|||||||
var maWbId: Long? = null, // 运单id
|
var maWbId: Long? = null, // 运单id
|
||||||
var prefix: String? = null, // 运单前缀
|
var prefix: String? = null, // 运单前缀
|
||||||
var no: String? = null, // 运单号
|
var no: String? = null, // 运单号
|
||||||
var storageCode: String? = null, // 库位号
|
var location: String? = null, // 库位号
|
||||||
var inDate: Date? = null, // 入库时间
|
var locationId: Long? = null, // 库位id
|
||||||
var inId: String? = null, // 入库人
|
var storageCode: String? = null, // 库位号(兼容字段)
|
||||||
var outDate: Date? = null, // 出库时间
|
var uld: String? = null, // 板箱号
|
||||||
var outId: String? = null // 出库人
|
var inDate: String? = null, // 入库时间
|
||||||
)
|
var inOpId: String? = null, // 入库人
|
||||||
|
var inId: String? = null, // 入库人(兼容字段)
|
||||||
|
var outDate: String? = null, // 出库时间
|
||||||
|
var outOpId: String? = null, // 出库人
|
||||||
|
var outId: String? = null, // 出库人(兼容字段)
|
||||||
|
var cargoStatus: String? = null // 货物状态
|
||||||
|
) {
|
||||||
|
// ==================== UI扩展字段 ====================
|
||||||
|
@Transient
|
||||||
|
val checked: ObservableBoolean = ObservableBoolean(false) // 选中状态
|
||||||
|
|
||||||
|
// 兼容现有API的isSelected属性
|
||||||
|
var isSelected: Boolean
|
||||||
|
get() = checked.get()
|
||||||
|
set(value) = checked.set(value)
|
||||||
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 "未复磅"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,5 +12,5 @@ class UldInfoBean {
|
|||||||
var totalPieces: String = "" // 总件数
|
var totalPieces: String = "" // 总件数
|
||||||
var totalWeight: String = "" // 总重量
|
var totalWeight: String = "" // 总重量
|
||||||
var status: String = "" // 状态(旧字段,保留兼容)
|
var status: String = "" // 状态(旧字段,保留兼容)
|
||||||
var useId: Long = 0 // ULD使用ID(来自getUld接口)
|
var useId: Long? = null // ULD使用ID(来自getUld接口)
|
||||||
}
|
}
|
||||||
|
|||||||
18
module_base/src/main/java/com/lukouguoji/module_base/cache/PdfCacheModel.kt
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package com.lukouguoji.module_base.cache
|
||||||
|
|
||||||
|
import dev.DevUtils
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PDF文件缓存管理
|
||||||
|
* 负责PDF文件的下载和本地缓存
|
||||||
|
*/
|
||||||
|
object PdfCacheModel : FileCacheModel() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PDF文件缓存目录
|
||||||
|
* 路径: /data/data/com.lukouguoji.aerologic/files/cacheFiles/pdf/
|
||||||
|
*/
|
||||||
|
override fun folderPath(): String {
|
||||||
|
return DevUtils.getContext().filesDir.toString() + "/cacheFiles/pdf/"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -253,6 +253,7 @@ interface Constant {
|
|||||||
const val GjcIntExpLoad = "AppIntExpLoad" //出港装载
|
const val GjcIntExpLoad = "AppIntExpLoad" //出港装载
|
||||||
const val GjcIntExpTally = "AppIntExpTally" //出港理货
|
const val GjcIntExpTally = "AppIntExpTally" //出港理货
|
||||||
const val GjcIntExpArrive = "AppIntExpArrive" //出港运抵
|
const val GjcIntExpArrive = "AppIntExpArrive" //出港运抵
|
||||||
|
const val GjcIntExpStorageUse = "AppIntExpStorageUse" //仓库
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 国际进港
|
* 国际进港
|
||||||
|
|||||||
@@ -432,7 +432,8 @@ interface Api {
|
|||||||
* 接口路径: /IntExpCheckInCheck/pass
|
* 接口路径: /IntExpCheckInCheck/pass
|
||||||
*/
|
*/
|
||||||
@POST("IntExpCheckInCheck/pass")
|
@POST("IntExpCheckInCheck/pass")
|
||||||
suspend fun passGjcInspection(@Body data: RequestBody): BaseResultBean<Boolean>
|
suspend fun passGjcInspection(
|
||||||
|
@Query("reason") reason: String, @Body data: RequestBody): BaseResultBean<Boolean>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 国际出港收运审核-退回(运单列表maWbId、wbNo必填)
|
* 国际出港收运审核-退回(运单列表maWbId、wbNo必填)
|
||||||
@@ -553,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>
|
||||||
|
|
||||||
// ==================== 国际出港-出港组装 ====================
|
// ==================== 国际出港-出港组装 ====================
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -580,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>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 国际出港组装-回填重量
|
* 国际出港组装-回填重量
|
||||||
@@ -653,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
|
||||||
@@ -675,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
|
||||||
@@ -810,6 +834,63 @@ interface Api {
|
|||||||
@POST("IntExpMove/move")
|
@POST("IntExpMove/move")
|
||||||
suspend fun submitIntExpMove(@Body data: RequestBody): BaseResultBean<SimpleResultBean>
|
suspend fun submitIntExpMove(@Body data: RequestBody): BaseResultBean<SimpleResultBean>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际出港库位操作-清仓
|
||||||
|
* 接口路径: /IntExpStorageUse/updateClear
|
||||||
|
*/
|
||||||
|
@POST("IntExpStorageUse/updateClear")
|
||||||
|
suspend fun clearIntExpStorage(@Body data: RequestBody): BaseResultBean<Boolean>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际出港库位操作-修改库位
|
||||||
|
* 接口路径: /IntExpStorageUse/modifyStorage
|
||||||
|
*/
|
||||||
|
@POST("IntExpStorageUse/modifyStorage")
|
||||||
|
suspend fun modifyIntExpStorage(@Body data: RequestBody): BaseResultBean<Boolean>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际出港库位操作-出库
|
||||||
|
* 接口路径: /IntExpStorageUse/outStorage
|
||||||
|
*/
|
||||||
|
@POST("IntExpStorageUse/outStorage")
|
||||||
|
suspend fun outIntExpStorage(@Body data: RequestBody): BaseResultBean<Boolean>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际出港库位操作-入库
|
||||||
|
* 接口路径: /IntExpStorageUse/inStorage
|
||||||
|
*/
|
||||||
|
@POST("IntExpStorageUse/inStorage")
|
||||||
|
suspend fun inIntExpStorage(@Body data: RequestBody): BaseResultBean<Boolean>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际出港仓库-分页查询
|
||||||
|
* 接口路径: /IntExpStorageUse/pageQuery
|
||||||
|
*/
|
||||||
|
@POST("IntExpStorageUse/pageQuery")
|
||||||
|
suspend fun getIntExpStorageUseList(@Body data: RequestBody): PageInfo<GjcMaWb>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际出港仓库-分页合计
|
||||||
|
* 接口路径: /IntExpStorageUse/pageQueryTotal
|
||||||
|
*/
|
||||||
|
@POST("IntExpStorageUse/pageQueryTotal")
|
||||||
|
suspend fun getIntExpStorageUseTotal(@Body data: RequestBody): BaseResultBean<ManifestTotalDto>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际出港仓库-运单号模糊查询(后四位)
|
||||||
|
* 接口路径: /IntExpStorageUse/queryWbNoList
|
||||||
|
*/
|
||||||
|
@POST("IntExpStorageUse/queryWbNoList")
|
||||||
|
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
|
||||||
@@ -824,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
|
||||||
@@ -885,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>
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// 国际进-电报解析
|
// 国际进-电报解析
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -146,6 +146,8 @@ object ARouterConstants {
|
|||||||
const val ACTIVITY_URL_INT_EXP_LOAD = "/gjc/IntExpLoadActivity" //国际出港 出港装载
|
const val ACTIVITY_URL_INT_EXP_LOAD = "/gjc/IntExpLoadActivity" //国际出港 出港装载
|
||||||
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_GJC_ASSEMBLE_WEIGHT_EDIT = "/gjc/GjcAssembleWeightEditActivity" //国际出港 修改组装重量
|
||||||
|
|
||||||
///////////////// 国际进港模块
|
///////////////// 国际进港模块
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,223 @@
|
|||||||
|
package com.lukouguoji.module_base.ui.page.preview
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.ActivityInfo
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener
|
||||||
|
import com.github.barteksc.pdfviewer.listener.OnPageChangeListener
|
||||||
|
import com.github.barteksc.pdfviewer.listener.OnErrorListener
|
||||||
|
import com.lukouguoji.module_base.R
|
||||||
|
import com.lukouguoji.module_base.base.BaseBindingActivity
|
||||||
|
import com.lukouguoji.module_base.cache.PdfCacheModel
|
||||||
|
import com.lukouguoji.module_base.common.Constant
|
||||||
|
import com.lukouguoji.module_base.databinding.ActivityPdfPreviewBinding
|
||||||
|
import com.lukouguoji.module_base.impl.EmptyViewModel
|
||||||
|
import com.lukouguoji.module_base.ktx.showToast
|
||||||
|
import com.lukouguoji.module_base.util.MediaUtil
|
||||||
|
import dev.utils.app.BarUtils
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PDF预览界面
|
||||||
|
* 支持在线PDF下载缓存和本地PDF文件预览
|
||||||
|
*/
|
||||||
|
class PdfPreviewActivity : BaseBindingActivity<ActivityPdfPreviewBinding, EmptyViewModel>() {
|
||||||
|
|
||||||
|
// PDF文件路径 (可能是在线URL或本地路径)
|
||||||
|
private var pdfPath: String = ""
|
||||||
|
|
||||||
|
// 当前页码 (从0开始)
|
||||||
|
private var currentPage = 0
|
||||||
|
|
||||||
|
// 总页数
|
||||||
|
private var totalPages = 0
|
||||||
|
|
||||||
|
override fun layoutId() = R.layout.activity_pdf_preview
|
||||||
|
override fun viewModelClass() = EmptyViewModel::class.java
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
// 强制横屏显示 (与项目其他页面保持一致)
|
||||||
|
resources?.let {
|
||||||
|
if (it.displayMetrics.widthPixels < it.displayMetrics.heightPixels) {
|
||||||
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
||||||
|
} else {
|
||||||
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SourceLockedOrientationActivity")
|
||||||
|
override fun initOnCreate(savedInstanceState: Bundle?) {
|
||||||
|
// 设置沉浸式状态栏
|
||||||
|
BarUtils.transparentStatusBar(this)
|
||||||
|
|
||||||
|
// 获取传递的PDF路径
|
||||||
|
pdfPath = intent.getStringExtra(Constant.Key.DATA) ?: ""
|
||||||
|
if (pdfPath.isEmpty()) {
|
||||||
|
showToast("PDF路径为空")
|
||||||
|
finish()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置关闭按钮
|
||||||
|
binding.ivClose.setOnClickListener {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载PDF文件
|
||||||
|
loadPdfFile()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载PDF文件 (支持在线和本地)
|
||||||
|
*/
|
||||||
|
private fun loadPdfFile() {
|
||||||
|
// val fullUrl = MediaUtil.fillUrl(pdfPath)
|
||||||
|
val fullUrl = pdfPath
|
||||||
|
|
||||||
|
// 判断是否为在线资源
|
||||||
|
if (isOnlineResource(fullUrl)) {
|
||||||
|
// 在线PDF: 先下载再加载
|
||||||
|
downloadAndLoadPdf(fullUrl)
|
||||||
|
} else {
|
||||||
|
// 本地PDF: 直接加载
|
||||||
|
loadLocalPdf(File(pdfPath))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否为在线资源
|
||||||
|
*/
|
||||||
|
private fun isOnlineResource(url: String): Boolean {
|
||||||
|
return url.startsWith("http://") || url.startsWith("https://")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载在线PDF并加载
|
||||||
|
*/
|
||||||
|
private fun downloadAndLoadPdf(url: String) {
|
||||||
|
// 显示Loading
|
||||||
|
showLoading()
|
||||||
|
|
||||||
|
lifecycleScope.launch(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
// 使用PdfCacheModel下载PDF
|
||||||
|
PdfCacheModel.saveFile(
|
||||||
|
url = url,
|
||||||
|
onProgress = { progress ->
|
||||||
|
// 更新下载进度
|
||||||
|
lifecycleScope.launch(Dispatchers.Main) {
|
||||||
|
binding.tvLoadingTip.text = "正在下载PDF... $progress%"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSuccess = { file ->
|
||||||
|
// 下载成功,切换到主线程加载PDF
|
||||||
|
lifecycleScope.launch(Dispatchers.Main) {
|
||||||
|
hideLoading()
|
||||||
|
loadLocalPdf(file)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onError = { errorMsg ->
|
||||||
|
// 下载失败
|
||||||
|
lifecycleScope.launch(Dispatchers.Main) {
|
||||||
|
hideLoading()
|
||||||
|
showToast("PDF下载失败: $errorMsg")
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
hideLoading()
|
||||||
|
showToast("PDF下载异常: ${e.message}")
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载本地PDF文件
|
||||||
|
*/
|
||||||
|
private fun loadLocalPdf(file: File) {
|
||||||
|
if (!file.exists()) {
|
||||||
|
showToast("PDF文件不存在")
|
||||||
|
finish()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
binding.pdfView.fromFile(file)
|
||||||
|
.defaultPage(0) // 默认显示第一页
|
||||||
|
.enableSwipe(true) // 启用滑动翻页
|
||||||
|
.swipeHorizontal(false) // 垂直滑动
|
||||||
|
.enableDoubletap(true) // 启用双击缩放
|
||||||
|
.enableAnnotationRendering(false) // 禁用注释渲染(提升性能)
|
||||||
|
.password(null) // PDF密码(如需要)
|
||||||
|
.scrollHandle(null) // 禁用默认滚动条
|
||||||
|
.onLoad(OnLoadCompleteListener { nbPages ->
|
||||||
|
// PDF加载完成
|
||||||
|
totalPages = nbPages
|
||||||
|
updatePageIndicator()
|
||||||
|
})
|
||||||
|
.onPageChange(OnPageChangeListener { page, pageCount ->
|
||||||
|
// 页面切换
|
||||||
|
currentPage = page
|
||||||
|
updatePageIndicator()
|
||||||
|
})
|
||||||
|
.onError(OnErrorListener { t ->
|
||||||
|
// 加载错误
|
||||||
|
showToast("PDF加载失败: ${t.message}")
|
||||||
|
finish()
|
||||||
|
})
|
||||||
|
.load()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
showToast("PDF渲染异常: ${e.message}")
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新页码指示器
|
||||||
|
*/
|
||||||
|
private fun updatePageIndicator() {
|
||||||
|
binding.tvPageIndicator.text = "${currentPage + 1} / $totalPages"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示Loading
|
||||||
|
*/
|
||||||
|
private fun showLoading() {
|
||||||
|
binding.loadingLayout.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 隐藏Loading
|
||||||
|
*/
|
||||||
|
private fun hideLoading() {
|
||||||
|
binding.loadingLayout.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* 启动PDF预览
|
||||||
|
* @param context 上下文
|
||||||
|
* @param pdfPath PDF路径 (支持在线URL或本地路径)
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
fun start(context: Context, pdfPath: String) {
|
||||||
|
val starter = Intent(context, PdfPreviewActivity::class.java)
|
||||||
|
.putExtra(Constant.Key.DATA, pdfPath)
|
||||||
|
context.startActivity(starter)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,8 @@ import com.lukouguoji.module_base.ktx.formatDate
|
|||||||
import com.lukouguoji.module_base.ktx.getActivity
|
import com.lukouguoji.module_base.ktx.getActivity
|
||||||
import com.lukouguoji.module_base.ktx.loge
|
import com.lukouguoji.module_base.ktx.loge
|
||||||
import com.lukouguoji.module_base.ktx.tryCatch
|
import com.lukouguoji.module_base.ktx.tryCatch
|
||||||
|
import com.lukouguoji.module_base.ui.weight.data.layout.AutoQueryConfig
|
||||||
|
import com.lukouguoji.module_base.ui.weight.search.layout.manager.SearchAutoQueryManager
|
||||||
import com.lukouguoji.module_base.util.Common
|
import com.lukouguoji.module_base.util.Common
|
||||||
import dev.utils.app.info.KeyValue
|
import dev.utils.app.info.KeyValue
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
@@ -102,6 +104,16 @@ class PadSearchLayout : LinearLayout {
|
|||||||
loadImage(iv, value)
|
loadImage(iv, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动查询配置
|
||||||
|
*/
|
||||||
|
var autoQueryConfig: AutoQueryConfig = AutoQueryConfig()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动查询管理器(延迟初始化)
|
||||||
|
*/
|
||||||
|
private var autoQueryManager: SearchAutoQueryManager? = null
|
||||||
|
|
||||||
// 选择日期
|
// 选择日期
|
||||||
private val dateClick: (v: View) -> Unit = {
|
private val dateClick: (v: View) -> Unit = {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
@@ -158,6 +170,30 @@ class PadSearchLayout : LinearLayout {
|
|||||||
setForType()
|
setForType()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用自动查询功能
|
||||||
|
*/
|
||||||
|
fun enableAutoQuery(config: AutoQueryConfig) {
|
||||||
|
this.autoQueryConfig = config
|
||||||
|
if (config.isValid()) {
|
||||||
|
// 初始化查询管理器
|
||||||
|
autoQueryManager = SearchAutoQueryManager(et, config) { newValue ->
|
||||||
|
// 更新值的回调
|
||||||
|
this.value = newValue
|
||||||
|
}
|
||||||
|
autoQueryManager?.attach()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 销毁时清理资源
|
||||||
|
*/
|
||||||
|
override fun onDetachedFromWindow() {
|
||||||
|
super.onDetachedFromWindow()
|
||||||
|
autoQueryManager?.detach()
|
||||||
|
autoQueryManager = null
|
||||||
|
}
|
||||||
|
|
||||||
private fun setForType() {
|
private fun setForType() {
|
||||||
when (type) {
|
when (type) {
|
||||||
SearchLayoutType.INPUT -> {
|
SearchLayoutType.INPUT -> {
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import com.lukouguoji.module_base.ktx.formatDate
|
|||||||
import com.lukouguoji.module_base.ktx.getActivity
|
import com.lukouguoji.module_base.ktx.getActivity
|
||||||
import com.lukouguoji.module_base.ktx.loge
|
import com.lukouguoji.module_base.ktx.loge
|
||||||
import com.lukouguoji.module_base.ktx.tryCatch
|
import com.lukouguoji.module_base.ktx.tryCatch
|
||||||
|
import com.lukouguoji.module_base.ui.weight.data.layout.AutoQueryConfig
|
||||||
|
import com.lukouguoji.module_base.ui.weight.search.layout.manager.SearchAutoQueryManager
|
||||||
import com.lukouguoji.module_base.util.Common
|
import com.lukouguoji.module_base.util.Common
|
||||||
import dev.utils.app.info.KeyValue
|
import dev.utils.app.info.KeyValue
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
@@ -104,6 +106,16 @@ class PadSearchLayoutNew : LinearLayout {
|
|||||||
loadImage(iv, value)
|
loadImage(iv, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动查询配置
|
||||||
|
*/
|
||||||
|
var autoQueryConfig: AutoQueryConfig = AutoQueryConfig()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动查询管理器(延迟初始化)
|
||||||
|
*/
|
||||||
|
private var autoQueryManager: SearchAutoQueryManager? = null
|
||||||
|
|
||||||
// 选择日期
|
// 选择日期
|
||||||
private val dateClick: (v: View) -> Unit = {
|
private val dateClick: (v: View) -> Unit = {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
@@ -179,6 +191,30 @@ class PadSearchLayoutNew : LinearLayout {
|
|||||||
setForType()
|
setForType()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用自动查询功能
|
||||||
|
*/
|
||||||
|
fun enableAutoQuery(config: AutoQueryConfig) {
|
||||||
|
this.autoQueryConfig = config
|
||||||
|
if (config.isValid()) {
|
||||||
|
// 初始化查询管理器
|
||||||
|
autoQueryManager = SearchAutoQueryManager(et, config) { newValue ->
|
||||||
|
// 更新值的回调
|
||||||
|
this.value = newValue
|
||||||
|
}
|
||||||
|
autoQueryManager?.attach()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 销毁时清理资源
|
||||||
|
*/
|
||||||
|
override fun onDetachedFromWindow() {
|
||||||
|
super.onDetachedFromWindow()
|
||||||
|
autoQueryManager?.detach()
|
||||||
|
autoQueryManager = null
|
||||||
|
}
|
||||||
|
|
||||||
private fun setForType() {
|
private fun setForType() {
|
||||||
when (type) {
|
when (type) {
|
||||||
SearchLayoutType.INPUT -> {
|
SearchLayoutType.INPUT -> {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import androidx.core.widget.doOnTextChanged
|
|||||||
import androidx.databinding.BindingAdapter
|
import androidx.databinding.BindingAdapter
|
||||||
import androidx.databinding.InverseBindingAdapter
|
import androidx.databinding.InverseBindingAdapter
|
||||||
import androidx.databinding.InverseBindingListener
|
import androidx.databinding.InverseBindingListener
|
||||||
|
import com.lukouguoji.module_base.ktx.UpperCaseAlphanumericInputFilter
|
||||||
import dev.utils.app.EditTextUtils
|
import dev.utils.app.EditTextUtils
|
||||||
import dev.utils.app.info.KeyValue
|
import dev.utils.app.info.KeyValue
|
||||||
|
|
||||||
@@ -289,3 +290,243 @@ fun setSearchLayoutNewInputWaybill(layout: PadSearchLayoutNew, isWaybill: Boolea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// 大写字母+数字输入限制 BindingAdapter
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为PadSearchLayout设置大写字母+数字输入限制
|
||||||
|
* 自动转换小写为大写,过滤中文、特殊符号、空格
|
||||||
|
*/
|
||||||
|
@BindingAdapter("setUpperCaseAlphanumeric", requireAll = false)
|
||||||
|
fun setUpperCaseAlphanumeric(layout: PadSearchLayout, enabled: Boolean) {
|
||||||
|
if (enabled) {
|
||||||
|
layout.et.filters = arrayOf(UpperCaseAlphanumericInputFilter())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// PadSearchLayout 自动查询功能 BindingAdapter
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用自动查询功能
|
||||||
|
* @param enabled 是否启用
|
||||||
|
*/
|
||||||
|
@BindingAdapter("autoQueryEnabled")
|
||||||
|
fun setSearchLayoutAutoQueryEnabled(layout: PadSearchLayout, enabled: Boolean) {
|
||||||
|
layout.autoQueryConfig.enabled = enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置查询接口地址
|
||||||
|
* @param url 接口地址(如:/IntExpCheckIn/queryWbNoList)
|
||||||
|
*/
|
||||||
|
@BindingAdapter("autoQueryUrl")
|
||||||
|
fun setSearchLayoutAutoQueryUrl(layout: PadSearchLayout, url: String?) {
|
||||||
|
layout.autoQueryConfig.url = url ?: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置查询参数的 key 名称
|
||||||
|
* @param paramKey 参数名(默认 "value")
|
||||||
|
*/
|
||||||
|
@BindingAdapter("autoQueryParamKey")
|
||||||
|
fun setSearchLayoutAutoQueryParamKey(layout: PadSearchLayout, paramKey: String?) {
|
||||||
|
layout.autoQueryConfig.paramKey = paramKey ?: "value"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置触发查询的最小长度
|
||||||
|
* @param minLength 最小长度(默认 4)
|
||||||
|
*/
|
||||||
|
@BindingAdapter("autoQueryMinLength")
|
||||||
|
fun setSearchLayoutAutoQueryMinLength(layout: PadSearchLayout, minLength: Int?) {
|
||||||
|
layout.autoQueryConfig.minLength = minLength ?: 4
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置触发查询的最大长度
|
||||||
|
* @param maxLength 最大长度(默认 8)
|
||||||
|
*/
|
||||||
|
@BindingAdapter("autoQueryMaxLength")
|
||||||
|
fun setSearchLayoutAutoQueryMaxLength(layout: PadSearchLayout, maxLength: Int?) {
|
||||||
|
layout.autoQueryConfig.maxLength = maxLength ?: 8
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置弹框标题
|
||||||
|
* @param title 标题(默认 "请选择")
|
||||||
|
*/
|
||||||
|
@BindingAdapter("autoQueryTitle")
|
||||||
|
fun setSearchLayoutAutoQueryTitle(layout: PadSearchLayout, title: String?) {
|
||||||
|
layout.autoQueryConfig.title = title ?: "请选择"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置防抖延迟
|
||||||
|
* @param debounceMillis 延迟毫秒数(默认 300ms)
|
||||||
|
*/
|
||||||
|
@BindingAdapter("autoQueryDebounce")
|
||||||
|
fun setSearchLayoutAutoQueryDebounce(layout: PadSearchLayout, debounceMillis: Long?) {
|
||||||
|
layout.autoQueryConfig.debounceMillis = debounceMillis ?: 300L
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一配置自动查询(所有属性设置完成后调用)
|
||||||
|
*
|
||||||
|
* ⚠️ 重要:必须在所有 autoQuery* 属性之后绑定,使用 requireAll = false
|
||||||
|
*/
|
||||||
|
@BindingAdapter(
|
||||||
|
"autoQueryEnabled",
|
||||||
|
"autoQueryUrl",
|
||||||
|
"autoQueryParamKey",
|
||||||
|
"autoQueryMinLength",
|
||||||
|
"autoQueryMaxLength",
|
||||||
|
"autoQueryTitle",
|
||||||
|
"autoQueryDebounce",
|
||||||
|
requireAll = false
|
||||||
|
)
|
||||||
|
fun configureSearchLayoutAutoQuery(
|
||||||
|
layout: PadSearchLayout,
|
||||||
|
enabled: Boolean?,
|
||||||
|
url: String?,
|
||||||
|
paramKey: String?,
|
||||||
|
minLength: Int?,
|
||||||
|
maxLength: Int?,
|
||||||
|
title: String?,
|
||||||
|
debounceMillis: Long?
|
||||||
|
) {
|
||||||
|
// 应用所有配置
|
||||||
|
enabled?.let { layout.autoQueryConfig.enabled = it }
|
||||||
|
url?.let { layout.autoQueryConfig.url = it }
|
||||||
|
paramKey?.let { layout.autoQueryConfig.paramKey = it }
|
||||||
|
minLength?.let { layout.autoQueryConfig.minLength = it }
|
||||||
|
maxLength?.let { layout.autoQueryConfig.maxLength = it }
|
||||||
|
title?.let { layout.autoQueryConfig.title = it }
|
||||||
|
debounceMillis?.let { layout.autoQueryConfig.debounceMillis = it }
|
||||||
|
|
||||||
|
// 验证并启用自动查询
|
||||||
|
if (layout.autoQueryConfig.isValid()) {
|
||||||
|
layout.enableAutoQuery(layout.autoQueryConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为PadSearchLayoutNew设置大写字母+数字输入限制
|
||||||
|
* 自动转换小写为大写,过滤中文、特殊符号、空格
|
||||||
|
*/
|
||||||
|
@BindingAdapter("setUpperCaseAlphanumeric", requireAll = false)
|
||||||
|
fun setSearchLayoutNewUpperCaseAlphanumeric(layout: PadSearchLayoutNew, enabled: Boolean) {
|
||||||
|
if (enabled) {
|
||||||
|
layout.et.filters = arrayOf(UpperCaseAlphanumericInputFilter())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// PadSearchLayoutNew 自动查询功能 BindingAdapter
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 启用自动查询功能
|
||||||
|
* @param enabled 是否启用
|
||||||
|
*/
|
||||||
|
@BindingAdapter("autoQueryEnabled")
|
||||||
|
fun setSearchLayoutNewAutoQueryEnabled(layout: PadSearchLayoutNew, enabled: Boolean) {
|
||||||
|
layout.autoQueryConfig.enabled = enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置查询接口地址
|
||||||
|
* @param url 接口地址(如:/IntExpCheckIn/checked/queryWbNoList)
|
||||||
|
*/
|
||||||
|
@BindingAdapter("autoQueryUrl")
|
||||||
|
fun setSearchLayoutNewAutoQueryUrl(layout: PadSearchLayoutNew, url: String?) {
|
||||||
|
layout.autoQueryConfig.url = url ?: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置查询参数的 key 名称
|
||||||
|
* @param paramKey 参数名(默认 "value")
|
||||||
|
*/
|
||||||
|
@BindingAdapter("autoQueryParamKey")
|
||||||
|
fun setSearchLayoutNewAutoQueryParamKey(layout: PadSearchLayoutNew, paramKey: String?) {
|
||||||
|
layout.autoQueryConfig.paramKey = paramKey ?: "value"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置触发查询的最小长度
|
||||||
|
* @param minLength 最小长度(默认 4)
|
||||||
|
*/
|
||||||
|
@BindingAdapter("autoQueryMinLength")
|
||||||
|
fun setSearchLayoutNewAutoQueryMinLength(layout: PadSearchLayoutNew, minLength: Int?) {
|
||||||
|
layout.autoQueryConfig.minLength = minLength ?: 4
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置触发查询的最大长度
|
||||||
|
* @param maxLength 最大长度(默认 8)
|
||||||
|
*/
|
||||||
|
@BindingAdapter("autoQueryMaxLength")
|
||||||
|
fun setSearchLayoutNewAutoQueryMaxLength(layout: PadSearchLayoutNew, maxLength: Int?) {
|
||||||
|
layout.autoQueryConfig.maxLength = maxLength ?: 8
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置弹框标题
|
||||||
|
* @param title 标题(默认 "请选择")
|
||||||
|
*/
|
||||||
|
@BindingAdapter("autoQueryTitle")
|
||||||
|
fun setSearchLayoutNewAutoQueryTitle(layout: PadSearchLayoutNew, title: String?) {
|
||||||
|
layout.autoQueryConfig.title = title ?: "请选择"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置防抖延迟
|
||||||
|
* @param debounceMillis 延迟毫秒数(默认 300ms)
|
||||||
|
*/
|
||||||
|
@BindingAdapter("autoQueryDebounce")
|
||||||
|
fun setSearchLayoutNewAutoQueryDebounce(layout: PadSearchLayoutNew, debounceMillis: Long?) {
|
||||||
|
layout.autoQueryConfig.debounceMillis = debounceMillis ?: 300L
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一配置自动查询(所有属性设置完成后调用)
|
||||||
|
*
|
||||||
|
* ⚠️ 重要:必须在所有 autoQuery* 属性之后绑定,使用 requireAll = false
|
||||||
|
*/
|
||||||
|
@BindingAdapter(
|
||||||
|
"autoQueryEnabled",
|
||||||
|
"autoQueryUrl",
|
||||||
|
"autoQueryParamKey",
|
||||||
|
"autoQueryMinLength",
|
||||||
|
"autoQueryMaxLength",
|
||||||
|
"autoQueryTitle",
|
||||||
|
"autoQueryDebounce",
|
||||||
|
requireAll = false
|
||||||
|
)
|
||||||
|
fun configureSearchLayoutNewAutoQuery(
|
||||||
|
layout: PadSearchLayoutNew,
|
||||||
|
enabled: Boolean?,
|
||||||
|
url: String?,
|
||||||
|
paramKey: String?,
|
||||||
|
minLength: Int?,
|
||||||
|
maxLength: Int?,
|
||||||
|
title: String?,
|
||||||
|
debounceMillis: Long?
|
||||||
|
) {
|
||||||
|
// 应用所有配置
|
||||||
|
enabled?.let { layout.autoQueryConfig.enabled = it }
|
||||||
|
url?.let { layout.autoQueryConfig.url = it }
|
||||||
|
paramKey?.let { layout.autoQueryConfig.paramKey = it }
|
||||||
|
minLength?.let { layout.autoQueryConfig.minLength = it }
|
||||||
|
maxLength?.let { layout.autoQueryConfig.maxLength = it }
|
||||||
|
title?.let { layout.autoQueryConfig.title = it }
|
||||||
|
debounceMillis?.let { layout.autoQueryConfig.debounceMillis = it }
|
||||||
|
|
||||||
|
// 验证并启用自动查询
|
||||||
|
if (layout.autoQueryConfig.isValid()) {
|
||||||
|
layout.enableAutoQuery(layout.autoQueryConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,181 @@
|
|||||||
|
package com.lukouguoji.module_base.ui.weight.search.layout.manager
|
||||||
|
|
||||||
|
import android.text.Editable
|
||||||
|
import android.text.TextWatcher
|
||||||
|
import android.widget.EditText
|
||||||
|
import androidx.lifecycle.ViewTreeLifecycleOwner
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.alibaba.fastjson.JSONArray
|
||||||
|
import com.lukouguoji.module_base.http.net.NetApply
|
||||||
|
import com.lukouguoji.module_base.ktx.getActivity
|
||||||
|
import com.lukouguoji.module_base.ktx.launchCollect
|
||||||
|
import com.lukouguoji.module_base.ktx.toJson
|
||||||
|
import com.lukouguoji.module_base.ktx.toRequestBody
|
||||||
|
import com.lukouguoji.module_base.ui.weight.data.layout.AutoQueryConfig
|
||||||
|
import com.lukouguoji.module_base.util.Common
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索框专用自动查询管理器
|
||||||
|
* 负责处理输入监听、防抖、查询请求、结果处理
|
||||||
|
*
|
||||||
|
* 功能:
|
||||||
|
* 1. 监听 EditText 输入变化
|
||||||
|
* 2. 防抖延迟(避免频繁请求)
|
||||||
|
* 3. 防重复查询(相同值不重复请求)
|
||||||
|
* 4. 调用接口查询数据
|
||||||
|
* 5. 处理查询结果(单条填充、多条弹框)
|
||||||
|
* 6. 自动管理协程生命周期
|
||||||
|
*/
|
||||||
|
class SearchAutoQueryManager(
|
||||||
|
private val editText: EditText,
|
||||||
|
private val config: AutoQueryConfig,
|
||||||
|
private val onValueSelected: (String) -> Unit
|
||||||
|
) {
|
||||||
|
|
||||||
|
/** 协程作用域(从 ViewTree 获取) */
|
||||||
|
private var scope: CoroutineScope? = null
|
||||||
|
|
||||||
|
/** 上次查询的值(防重复查询) */
|
||||||
|
private var lastQueriedValue: String = ""
|
||||||
|
|
||||||
|
/** 防抖任务 */
|
||||||
|
private var debounceJob: Job? = null
|
||||||
|
|
||||||
|
/** 文本监听器 */
|
||||||
|
private var textWatcher: TextWatcher? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定到视图(添加文本监听)
|
||||||
|
*/
|
||||||
|
fun attach() {
|
||||||
|
// 获取协程作用域(从 ViewTree 获取 LifecycleOwner)
|
||||||
|
val lifecycleOwner = ViewTreeLifecycleOwner.get(editText)
|
||||||
|
if (lifecycleOwner == null) {
|
||||||
|
// 延迟绑定(等待 ViewTree 附加)
|
||||||
|
editText.post { attach() }
|
||||||
|
return
|
||||||
|
}
|
||||||
|
scope = lifecycleOwner.lifecycleScope
|
||||||
|
|
||||||
|
// 添加文本监听
|
||||||
|
textWatcher = object : TextWatcher {
|
||||||
|
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
|
||||||
|
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
|
||||||
|
|
||||||
|
override fun afterTextChanged(s: Editable?) {
|
||||||
|
val text = s?.toString() ?: ""
|
||||||
|
handleTextChanged(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
editText.addTextChangedListener(textWatcher)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解绑(移除监听、取消协程)
|
||||||
|
*/
|
||||||
|
fun detach() {
|
||||||
|
textWatcher?.let { editText.removeTextChangedListener(it) }
|
||||||
|
textWatcher = null
|
||||||
|
debounceJob?.cancel()
|
||||||
|
debounceJob = null
|
||||||
|
scope = null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理文本变化
|
||||||
|
*/
|
||||||
|
private fun handleTextChanged(text: String) {
|
||||||
|
val trimmedText = text.trim()
|
||||||
|
val length = trimmedText.length
|
||||||
|
|
||||||
|
// 取消之前的防抖任务
|
||||||
|
debounceJob?.cancel()
|
||||||
|
|
||||||
|
// 判断是否需要触发查询
|
||||||
|
if (length in config.minLength..config.maxLength) {
|
||||||
|
// 防抖延迟
|
||||||
|
debounceJob = scope?.launch {
|
||||||
|
delay(config.debounceMillis)
|
||||||
|
performQuery(trimmedText)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 长度不符合,清空上次查询记录
|
||||||
|
lastQueriedValue = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行查询
|
||||||
|
*/
|
||||||
|
private fun performQuery(value: String) {
|
||||||
|
// 防重复查询
|
||||||
|
if (value == lastQueriedValue) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lastQueriedValue = value
|
||||||
|
|
||||||
|
// 构建查询参数
|
||||||
|
val params = mapOf(config.paramKey to value).toRequestBody()
|
||||||
|
|
||||||
|
// 发起网络请求
|
||||||
|
scope?.launchCollect({ NetApply.api.getWbNoList(config.url, params) }) {
|
||||||
|
onSuccess = { result ->
|
||||||
|
val results = result.data ?: emptyList()
|
||||||
|
handleQueryResults(results)
|
||||||
|
}
|
||||||
|
onFailed = { code, msg ->
|
||||||
|
// 查询失败,清空记录(允许重试)
|
||||||
|
lastQueriedValue = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理查询结果
|
||||||
|
*/
|
||||||
|
private fun handleQueryResults(results: List<String>) {
|
||||||
|
when {
|
||||||
|
// 1 条结果:直接填充
|
||||||
|
results.size == 1 -> {
|
||||||
|
onValueSelected(results[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
// 多条结果:显示弹框选择
|
||||||
|
results.size > 1 -> {
|
||||||
|
showSelectionDialog(results)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0 条结果:不做处理
|
||||||
|
else -> {
|
||||||
|
// 可选:showToast("未找到匹配数据")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示选择弹框
|
||||||
|
*/
|
||||||
|
private fun showSelectionDialog(results: List<String>) {
|
||||||
|
val activity = editText.context.getActivity()
|
||||||
|
|
||||||
|
// 转换为 Common.singleSelect 需要的格式
|
||||||
|
val jsonArray = JSONArray.parseArray(
|
||||||
|
results.map { mapOf("name" to it, "code" to it) }.toJson(false)
|
||||||
|
)
|
||||||
|
|
||||||
|
Common.singleSelect(
|
||||||
|
activity,
|
||||||
|
config.title,
|
||||||
|
jsonArray,
|
||||||
|
null
|
||||||
|
) { position, _ ->
|
||||||
|
// 用户选择后更新值
|
||||||
|
onValueSelected(results[position])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,13 @@
|
|||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
android:exported="true"/>
|
android:exported="true"/>
|
||||||
|
|
||||||
|
<!-- PDF预览Activity -->
|
||||||
|
<activity
|
||||||
|
android:name=".ui.page.preview.PdfPreviewActivity"
|
||||||
|
android:configChanges="orientation|keyboardHidden"
|
||||||
|
android:exported="false"
|
||||||
|
android:screenOrientation="userLandscape" />
|
||||||
|
|
||||||
<!-- 屏幕适配 -->
|
<!-- 屏幕适配 -->
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="design_width_in_dp"
|
android:name="design_width_in_dp"
|
||||||
|
|||||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
@@ -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>
|
||||||
11
module_base/src/main/res/drawable/ic_new_expand.xml
Normal 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>
|
||||||
14
module_base/src/main/res/drawable/radiobtn_checked_gray.xml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<!-- 圆形大小 -->
|
||||||
|
<size
|
||||||
|
android:width="15dp"
|
||||||
|
android:height="15dp" />
|
||||||
|
<!-- 深灰色填充 -->
|
||||||
|
<solid android:color="#808080" />
|
||||||
|
<!-- 黑色边框 -->
|
||||||
|
<stroke
|
||||||
|
android:width="1dp"
|
||||||
|
android:color="@color/black" />
|
||||||
|
</shape>
|
||||||
86
module_base/src/main/res/layout/activity_pdf_preview.xml
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layout xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<data>
|
||||||
|
<variable
|
||||||
|
name="viewModel"
|
||||||
|
type="com.lukouguoji.module_base.impl.EmptyViewModel" />
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/black">
|
||||||
|
|
||||||
|
<!-- PDF视图 -->
|
||||||
|
<com.github.barteksc.pdfviewer.PDFView
|
||||||
|
android:id="@+id/pdfView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<!-- Loading蒙层 (下载时显示) -->
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/loadingLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/black_tran50"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:background="@color/black_tran70"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="20dp">
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:indeterminateTint="@color/white" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvLoadingTip"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:text="正在加载PDF..."
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<!-- 页码指示器 -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvPageIndicator"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginBottom="30dp"
|
||||||
|
android:background="@color/black_tran50"
|
||||||
|
android:paddingLeft="15dp"
|
||||||
|
android:paddingTop="5dp"
|
||||||
|
android:paddingRight="15dp"
|
||||||
|
android:paddingBottom="5dp"
|
||||||
|
android:text="1 / 10"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<!-- 关闭按钮 -->
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/ivClose"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_marginTop="60dp"
|
||||||
|
android:layout_marginRight="30dp"
|
||||||
|
android:background="@color/black_tran30"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:src="@drawable/img_close" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
</layout>
|
||||||
BIN
module_base/src/main/res/mipmap-xhdpi/img_up.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
@@ -41,4 +41,9 @@
|
|||||||
|
|
||||||
<color name="bottom_tool_tips_text_color">#797979</color>
|
<color name="bottom_tool_tips_text_color">#797979</color>
|
||||||
|
|
||||||
|
<!-- 半透明黑色 (用于PDF预览) -->
|
||||||
|
<color name="black_tran30">#4D000000</color> <!-- 30%透明度 -->
|
||||||
|
<color name="black_tran50">#80000000</color> <!-- 50%透明度 -->
|
||||||
|
<color name="black_tran70">#B3000000</color> <!-- 70%透明度 -->
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|
||||||
|
|||||||
@@ -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?) {
|
||||||
|
|||||||
@@ -59,11 +59,6 @@ class IntExpLoadActivity :
|
|||||||
viewModel.waybillNo.value = codedContent
|
viewModel.waybillNo.value = codedContent
|
||||||
viewModel.searchClick()
|
viewModel.searchClick()
|
||||||
}
|
}
|
||||||
// 扫码分单号
|
|
||||||
Constant.RequestCode.CODE -> {
|
|
||||||
viewModel.houseWaybillNo.value = codedContent
|
|
||||||
viewModel.searchClick()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,198 @@
|
|||||||
|
package com.lukouguoji.gjc.activity
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import com.alibaba.android.arouter.facade.annotation.Route
|
||||||
|
import com.lukouguoji.gjc.R
|
||||||
|
import com.lukouguoji.gjc.databinding.ActivityIntExpStorageUseBinding
|
||||||
|
import com.lukouguoji.gjc.dialog.IntExpMoveClearDialogModel
|
||||||
|
import com.lukouguoji.gjc.dialog.IntExpModifyStorageDialogModel
|
||||||
|
import com.lukouguoji.gjc.dialog.IntExpInStorageDialogModel
|
||||||
|
import com.lukouguoji.gjc.viewModel.IntExpStorageUseViewModel
|
||||||
|
import com.lukouguoji.module_base.base.BaseBindingActivity
|
||||||
|
import com.lukouguoji.module_base.common.Constant
|
||||||
|
import com.lukouguoji.module_base.common.ConstantEvent
|
||||||
|
import com.lukouguoji.module_base.impl.FlowBus
|
||||||
|
import com.lukouguoji.module_base.impl.observe
|
||||||
|
import com.lukouguoji.module_base.ktx.commonAdapter
|
||||||
|
import com.lukouguoji.module_base.ktx.showToast
|
||||||
|
import com.lukouguoji.module_base.router.ARouterConstants
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际出港-仓库
|
||||||
|
*/
|
||||||
|
@Route(path = ARouterConstants.ACTIVITY_URL_INT_EXP_STORAGE_USE)
|
||||||
|
class IntExpStorageUseActivity :
|
||||||
|
BaseBindingActivity<ActivityIntExpStorageUseBinding, IntExpStorageUseViewModel>() {
|
||||||
|
|
||||||
|
override fun layoutId() = R.layout.activity_int_exp_storage_use
|
||||||
|
override fun viewModelClass() = IntExpStorageUseViewModel::class.java
|
||||||
|
|
||||||
|
override fun initOnCreate(savedInstanceState: Bundle?) {
|
||||||
|
setBackArrow("国际出港仓库")
|
||||||
|
binding.viewModel = viewModel
|
||||||
|
binding.activity = this
|
||||||
|
|
||||||
|
// 观察全选状态,更新图标透明度
|
||||||
|
viewModel.isAllChecked.observe(this) { isAllChecked ->
|
||||||
|
binding.checkIcon.alpha = if (isAllChecked) 1.0f else 0.5f
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绑定分页
|
||||||
|
viewModel.pageModel.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, this)
|
||||||
|
|
||||||
|
// 监听刷新事件
|
||||||
|
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).observe(this) {
|
||||||
|
viewModel.refresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始加载数据
|
||||||
|
viewModel.refresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示清仓操作对话框
|
||||||
|
*/
|
||||||
|
fun showClearDialog() {
|
||||||
|
val list = viewModel.pageModel.rv?.commonAdapter()?.items as? List<*> ?: return
|
||||||
|
val allItems = list.filterIsInstance<com.lukouguoji.module_base.bean.GjcMaWb>()
|
||||||
|
|
||||||
|
// 构建清仓数据:保留主列表结构,但只包含选中的子列表项
|
||||||
|
val maWbListForClear = allItems.mapNotNull { maWb ->
|
||||||
|
// 过滤出选中的子列表项
|
||||||
|
val selectedStorageList = maWb.storageUseList?.filter { it.isSelected } ?: emptyList()
|
||||||
|
|
||||||
|
// 只添加有选中子列表项的主列表项
|
||||||
|
if (selectedStorageList.isNotEmpty() || maWb.isSelected) {
|
||||||
|
// 创建主列表项的副本,只包含选中的子列表
|
||||||
|
maWb.copy(storageUseList = selectedStorageList)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maWbListForClear.isEmpty()) {
|
||||||
|
showToast("请至少选择一个库位")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示清仓对话框
|
||||||
|
IntExpMoveClearDialogModel { dialog ->
|
||||||
|
// 用户点击保存后,执行清仓操作
|
||||||
|
val clearNormal = dialog.clearNormal.value ?: ""
|
||||||
|
viewModel.performClear(clearNormal, maWbListForClear)
|
||||||
|
}.show(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示修改库位对话框
|
||||||
|
*/
|
||||||
|
fun showModifyStorageDialog() {
|
||||||
|
val list = viewModel.pageModel.rv?.commonAdapter()?.items as? List<*> ?: return
|
||||||
|
val allItems = list.filterIsInstance<com.lukouguoji.module_base.bean.GjcMaWb>()
|
||||||
|
|
||||||
|
// 收集所有选中的子列表项(库位)
|
||||||
|
val selectedStorageUseList = mutableListOf<com.lukouguoji.module_base.bean.GjcStorageUse>()
|
||||||
|
allItems.forEach { maWb ->
|
||||||
|
maWb.storageUseList?.filter { it.isSelected }?.let { selectedStorageUseList.addAll(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验:必须且只能选中一个库位
|
||||||
|
when {
|
||||||
|
selectedStorageUseList.isEmpty() -> {
|
||||||
|
showToast("请选择要修改的库位")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
selectedStorageUseList.size > 1 -> {
|
||||||
|
showToast("只能选择一个库位进行修改")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val selectedStorage = selectedStorageUseList[0]
|
||||||
|
|
||||||
|
// 显示修改库位对话框
|
||||||
|
IntExpModifyStorageDialogModel { dialog ->
|
||||||
|
// 用户点击保存后,执行修改库位操作
|
||||||
|
val locationName = dialog.locationName
|
||||||
|
val locationId = dialog.locationId
|
||||||
|
viewModel.performModifyStorage(locationName, locationId, selectedStorage)
|
||||||
|
}.show(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示出库二次确认对话框
|
||||||
|
*/
|
||||||
|
fun showOutStorageDialog() {
|
||||||
|
val list = viewModel.pageModel.rv?.commonAdapter()?.items as? List<*> ?: return
|
||||||
|
val allItems = list.filterIsInstance<com.lukouguoji.module_base.bean.GjcMaWb>()
|
||||||
|
|
||||||
|
// 收集所有选中的子列表项(库位)
|
||||||
|
val selectedStorageUseList = mutableListOf<com.lukouguoji.module_base.bean.GjcStorageUse>()
|
||||||
|
allItems.forEach { maWb ->
|
||||||
|
maWb.storageUseList?.filter { it.isSelected }?.let { selectedStorageUseList.addAll(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验:必须至少选中一个库位
|
||||||
|
if (selectedStorageUseList.isEmpty()) {
|
||||||
|
showToast("请选择要出库的库位")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示二次确认对话框
|
||||||
|
AlertDialog.Builder(this)
|
||||||
|
.setTitle("出库确认")
|
||||||
|
.setMessage("确定要将选中的 ${selectedStorageUseList.size} 个库位执行出库操作吗?")
|
||||||
|
.setPositiveButton("确定") { _, _ ->
|
||||||
|
// 用户确认后,执行出库操作
|
||||||
|
viewModel.performOutStorage(selectedStorageUseList)
|
||||||
|
}
|
||||||
|
.setNegativeButton("取消", null)
|
||||||
|
.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?) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
|
if (requestCode == Constant.RequestCode.WAYBILL && resultCode == Activity.RESULT_OK) {
|
||||||
|
viewModel.wbNo.value = data?.getStringExtra(Constant.Result.CODED_CONTENT)
|
||||||
|
viewModel.searchClick()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.DialogIntExpModifyStorageBinding
|
||||||
|
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 IntExpModifyStorageDialogModel(
|
||||||
|
private val callback: (IntExpModifyStorageDialogModel) -> Unit
|
||||||
|
) : BaseDialogModel<DialogIntExpModifyStorageBinding>(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_modify_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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package com.lukouguoji.gjc.dialog
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import com.lukouguoji.gjc.R
|
||||||
|
import com.lukouguoji.gjc.databinding.DialogIntExpMoveClearBinding
|
||||||
|
import com.lukouguoji.module_base.base.BaseDialogModel
|
||||||
|
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
|
||||||
|
import dev.utils.app.info.KeyValue
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际出港移库 - 清仓操作对话框
|
||||||
|
*/
|
||||||
|
class IntExpMoveClearDialogModel(
|
||||||
|
private val callback: (IntExpMoveClearDialogModel) -> Unit
|
||||||
|
) : BaseDialogModel<DialogIntExpMoveClearBinding>(DIALOG_TYPE_CENTER) {
|
||||||
|
|
||||||
|
// 清仓正常(存储的是 code:"0" 或 "1")
|
||||||
|
val clearNormal = MutableLiveData("")
|
||||||
|
|
||||||
|
// 清仓正常选项列表
|
||||||
|
val clearNormalList = MutableLiveData<List<KeyValue>>().apply {
|
||||||
|
value = listOf(
|
||||||
|
KeyValue("是", "1"),
|
||||||
|
KeyValue("否", "0")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun layoutId(): Int {
|
||||||
|
return R.layout.dialog_int_exp_move_clear
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDialogCreated(context: Context) {
|
||||||
|
binding.model = this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存按钮点击
|
||||||
|
*/
|
||||||
|
fun onSaveClick() {
|
||||||
|
if (clearNormal.value.verifyNullOrEmpty("请选择清仓正常")) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dismiss()
|
||||||
|
callback(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
package com.lukouguoji.gjc.holder
|
package com.lukouguoji.gjc.holder
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import com.lukouguoji.gjc.R
|
||||||
import com.lukouguoji.gjc.databinding.ItemIntExpArriveBinding
|
import com.lukouguoji.gjc.databinding.ItemIntExpArriveBinding
|
||||||
|
import com.lukouguoji.module_base.adapter.setCommonAdapter
|
||||||
import com.lukouguoji.module_base.base.BaseViewHolder
|
import com.lukouguoji.module_base.base.BaseViewHolder
|
||||||
import com.lukouguoji.module_base.bean.GjcMaWb
|
import com.lukouguoji.module_base.bean.GjcMaWb
|
||||||
|
import com.lukouguoji.module_base.ktx.refresh
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 国际出港-出港运抵 列表项ViewHolder
|
* 国际出港-出港运抵 列表项ViewHolder
|
||||||
@@ -25,5 +28,20 @@ class IntExpArriveViewHolder(view: View) :
|
|||||||
// 立即更新UI(图片自动切换)
|
// 立即更新UI(图片自动切换)
|
||||||
binding.executePendingBindings()
|
binding.executePendingBindings()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== 展开按钮点击事件 ==========
|
||||||
|
binding.ivShow.setOnClickListener {
|
||||||
|
bean.showMore.set(!bean.showMore.get())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 初始化子列表 RecyclerView ==========
|
||||||
|
setCommonAdapter(
|
||||||
|
binding.rvSub,
|
||||||
|
IntExpArriveSubViewHolder::class.java,
|
||||||
|
R.layout.item_int_exp_arrive_sub
|
||||||
|
)
|
||||||
|
|
||||||
|
// 刷新子列表数据
|
||||||
|
binding.rvSub.refresh(bean.haWbList ?: emptyList())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.lukouguoji.gjc.holder
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.lukouguoji.gjc.databinding.ItemIntExpStorageUseSubBinding
|
||||||
|
import com.lukouguoji.module_base.base.BaseViewHolder
|
||||||
|
import com.lukouguoji.module_base.bean.GjcMaWb
|
||||||
|
import com.lukouguoji.module_base.bean.GjcStorageUse
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际出港-仓库 库位明细行 ViewHolder
|
||||||
|
*/
|
||||||
|
class IntExpStorageUseSubViewHolder(view: View) :
|
||||||
|
BaseViewHolder<GjcStorageUse, ItemIntExpStorageUseSubBinding>(view) {
|
||||||
|
|
||||||
|
override fun onBind(item: Any?, position: Int) {
|
||||||
|
val bean = getItemBean(item) ?: return
|
||||||
|
binding.bean = bean
|
||||||
|
binding.position = position
|
||||||
|
binding.executePendingBindings()
|
||||||
|
|
||||||
|
// 单选框点击切换选择状态(反向联动主列表)
|
||||||
|
binding.ivCheckbox.setOnClickListener {
|
||||||
|
// 切换子列表项的选择状态
|
||||||
|
val newCheckedState = !bean.checked.get()
|
||||||
|
bean.checked.set(newCheckedState)
|
||||||
|
binding.executePendingBindings()
|
||||||
|
|
||||||
|
// 反向联动主列表项(仅在勾选时联动)
|
||||||
|
updateParentCheckState(newCheckedState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新父列表项的选择状态
|
||||||
|
* 规则:
|
||||||
|
* - 如果子项被勾选(newCheckedState = true),则自动勾选父项
|
||||||
|
* - 如果子项被取消勾选(newCheckedState = false),则不改变父项状态
|
||||||
|
*/
|
||||||
|
private fun updateParentCheckState(newCheckedState: Boolean) {
|
||||||
|
// 从RecyclerView的tag获取父Bean引用
|
||||||
|
val recyclerView = itemView.parent as? RecyclerView ?: return
|
||||||
|
val parentBean = recyclerView.tag as? GjcMaWb ?: return
|
||||||
|
|
||||||
|
// 只有当子项被勾选时,才联动勾选父项
|
||||||
|
if (newCheckedState) {
|
||||||
|
parentBean.checked.set(true)
|
||||||
|
}
|
||||||
|
// 当子项被取消勾选时,不影响父项状态
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.lukouguoji.gjc.holder
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import com.lukouguoji.gjc.R
|
||||||
|
import com.lukouguoji.gjc.databinding.ItemIntExpStorageUseBinding
|
||||||
|
import com.lukouguoji.module_base.adapter.setCommonAdapter
|
||||||
|
import com.lukouguoji.module_base.base.BaseViewHolder
|
||||||
|
import com.lukouguoji.module_base.bean.GjcMaWb
|
||||||
|
import com.lukouguoji.module_base.ktx.refresh
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际出港-仓库 ViewHolder
|
||||||
|
*/
|
||||||
|
class IntExpStorageUseViewHolder(view: View) :
|
||||||
|
BaseViewHolder<GjcMaWb, ItemIntExpStorageUseBinding>(view) {
|
||||||
|
|
||||||
|
override fun onBind(item: Any?, position: Int) {
|
||||||
|
val bean = getItemBean(item) ?: return
|
||||||
|
binding.bean = bean
|
||||||
|
binding.position = position
|
||||||
|
binding.executePendingBindings()
|
||||||
|
|
||||||
|
// 图标点击切换选择状态(联动子列表)
|
||||||
|
binding.ivIcon.setOnClickListener {
|
||||||
|
// 切换主列表项的选择状态
|
||||||
|
val newCheckedState = !bean.checked.get()
|
||||||
|
bean.checked.set(newCheckedState)
|
||||||
|
|
||||||
|
// 联动勾选/取消所有子列表项
|
||||||
|
bean.storageUseList?.forEach { storageUse ->
|
||||||
|
storageUse.checked.set(newCheckedState)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新UI
|
||||||
|
binding.executePendingBindings()
|
||||||
|
binding.rvSub.adapter?.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 展开按钮点击事件
|
||||||
|
binding.ivShow.setOnClickListener {
|
||||||
|
bean.showMore.set(!bean.showMore.get())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化库位明细子列表 RecyclerView
|
||||||
|
setCommonAdapter(
|
||||||
|
binding.rvSub,
|
||||||
|
IntExpStorageUseSubViewHolder::class.java,
|
||||||
|
R.layout.item_int_exp_storage_use_sub
|
||||||
|
)
|
||||||
|
|
||||||
|
// 刷新库位明细数据(传递父Bean引用)
|
||||||
|
val storageUseList = bean.storageUseList ?: emptyList()
|
||||||
|
// 为每个子列表项设置父Bean引用(通过tag传递)
|
||||||
|
binding.rvSub.tag = bean
|
||||||
|
binding.rvSub.refresh(storageUseList)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.lukouguoji.gjc.holder
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import com.lukouguoji.gjc.databinding.ItemIntExpTallySubBinding
|
||||||
|
import com.lukouguoji.module_base.base.BaseViewHolder
|
||||||
|
import com.lukouguoji.module_base.bean.GjcHaWb
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际出港-出港理货 子订单(分单) ViewHolder
|
||||||
|
*/
|
||||||
|
class IntExpTallySubViewHolder(view: View) :
|
||||||
|
BaseViewHolder<GjcHaWb, ItemIntExpTallySubBinding>(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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
package com.lukouguoji.gjc.holder
|
package com.lukouguoji.gjc.holder
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import com.lukouguoji.gjc.R
|
||||||
import com.lukouguoji.gjc.databinding.ItemIntExpTallyBinding
|
import com.lukouguoji.gjc.databinding.ItemIntExpTallyBinding
|
||||||
|
import com.lukouguoji.module_base.adapter.setCommonAdapter
|
||||||
import com.lukouguoji.module_base.base.BaseViewHolder
|
import com.lukouguoji.module_base.base.BaseViewHolder
|
||||||
import com.lukouguoji.module_base.bean.GjcMaWb
|
import com.lukouguoji.module_base.bean.GjcMaWb
|
||||||
|
import com.lukouguoji.module_base.ktx.refresh
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 国际出港-出港理货 ViewHolder
|
* 国际出港-出港理货 ViewHolder
|
||||||
@@ -17,10 +20,28 @@ class IntExpTallyViewHolder(view: View) :
|
|||||||
binding.position = position
|
binding.position = position
|
||||||
binding.executePendingBindings()
|
binding.executePendingBindings()
|
||||||
|
|
||||||
// 图标点击切换选择状态
|
// 图标点击切换选择状态(主单和分单独立,互不干扰)
|
||||||
binding.ivIcon.setOnClickListener {
|
binding.ivIcon.setOnClickListener {
|
||||||
|
// 只切换主单自己的选择状态,不同步到分单
|
||||||
bean.checked.set(!bean.checked.get())
|
bean.checked.set(!bean.checked.get())
|
||||||
|
|
||||||
|
// 刷新UI
|
||||||
binding.executePendingBindings()
|
binding.executePendingBindings()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== 新增:展开按钮点击事件 ==========
|
||||||
|
binding.ivShow.setOnClickListener {
|
||||||
|
bean.showMore.set(!bean.showMore.get())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 新增:初始化子列表 RecyclerView ==========
|
||||||
|
setCommonAdapter(
|
||||||
|
binding.rvSub,
|
||||||
|
IntExpTallySubViewHolder::class.java,
|
||||||
|
R.layout.item_int_exp_tally_sub
|
||||||
|
)
|
||||||
|
|
||||||
|
// 刷新子列表数据
|
||||||
|
binding.rvSub.refresh(bean.haWbList ?: emptyList())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ import com.lukouguoji.gjc.viewModel.IntExpAssembleStartViewModel
|
|||||||
import com.lukouguoji.module_base.base.BaseBindingActivity
|
import com.lukouguoji.module_base.base.BaseBindingActivity
|
||||||
import com.lukouguoji.module_base.base.CommonAdapter
|
import com.lukouguoji.module_base.base.CommonAdapter
|
||||||
import com.lukouguoji.module_base.common.Constant
|
import com.lukouguoji.module_base.common.Constant
|
||||||
|
import com.lukouguoji.module_base.common.ConstantEvent
|
||||||
|
import com.lukouguoji.module_base.impl.FlowBus
|
||||||
|
import com.lukouguoji.module_base.impl.observe
|
||||||
import com.lukouguoji.module_base.interfaces.IOnItemClickListener
|
import com.lukouguoji.module_base.interfaces.IOnItemClickListener
|
||||||
import com.lukouguoji.module_base.ktx.addOnItemClickListener
|
import com.lukouguoji.module_base.ktx.addOnItemClickListener
|
||||||
import com.lukouguoji.module_base.ktx.setUpperCaseAlphanumericFilter
|
import com.lukouguoji.module_base.ktx.setUpperCaseAlphanumericFilter
|
||||||
@@ -30,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
|
||||||
@@ -60,8 +81,30 @@ class IntExpAssembleStartActivity :
|
|||||||
// 加载组装人列表
|
// 加载组装人列表
|
||||||
viewModel.loadAssemblerList()
|
viewModel.loadAssemblerList()
|
||||||
|
|
||||||
|
// 监听登出事件,清空缓存
|
||||||
|
FlowBus.with<Any>(ConstantEvent.LOGOUT).observe(this) {
|
||||||
|
viewModel.clearCachedOperator()
|
||||||
|
}
|
||||||
|
|
||||||
// 观察数据变化
|
// 观察数据变化
|
||||||
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ class IntExpMoveActivity : BaseBindingActivity<ActivityIntExpMoveBinding, IntExp
|
|||||||
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).observe(this) {
|
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).observe(this) {
|
||||||
viewModel.refresh()
|
viewModel.refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 初始加载数据
|
||||||
|
viewModel.refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ 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.util.CheckUtil
|
import com.lukouguoji.module_base.util.CheckUtil
|
||||||
import dev.utils.app.info.KeyValue
|
import dev.utils.app.info.KeyValue
|
||||||
|
import dev.utils.common.DateUtils
|
||||||
|
import com.lukouguoji.module_base.ktx.formatDate
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,7 +31,7 @@ import kotlinx.coroutines.launch
|
|||||||
class GjcAssembleAllocateViewModel : BasePageViewModel() {
|
class GjcAssembleAllocateViewModel : BasePageViewModel() {
|
||||||
|
|
||||||
// 搜索条件
|
// 搜索条件
|
||||||
val flightDate = MutableLiveData("") // 航班日期
|
val flightDate = MutableLiveData<String>(DateUtils.getCurrentTime().formatDate()) // 航班日期
|
||||||
val flightNo = MutableLiveData("") // 航班号
|
val flightNo = MutableLiveData("") // 航班号
|
||||||
val destAirport = MutableLiveData("") // 目的站
|
val destAirport = MutableLiveData("") // 目的站
|
||||||
val assembler = MutableLiveData("") // 组装人
|
val assembler = MutableLiveData("") // 组装人
|
||||||
|
|||||||
@@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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("未组装,不可复磅")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ 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.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.common.DateUtils
|
||||||
|
import com.lukouguoji.module_base.ktx.formatDate
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 国际出港板箱过磅 ViewModel
|
* 国际出港板箱过磅 ViewModel
|
||||||
@@ -19,7 +21,7 @@ import com.lukouguoji.module_base.model.ScanModel
|
|||||||
class GjcBoxWeighingViewModel : BasePageViewModel() {
|
class GjcBoxWeighingViewModel : BasePageViewModel() {
|
||||||
|
|
||||||
// 搜索条件
|
// 搜索条件
|
||||||
val flightDate = MutableLiveData("") // 航班日期
|
val flightDate = MutableLiveData<String>(DateUtils.getCurrentTime().formatDate()) // 航班日期
|
||||||
val flightNo = MutableLiveData("") // 航班号
|
val flightNo = MutableLiveData("") // 航班号
|
||||||
val dest = MutableLiveData("") // 目的站
|
val dest = MutableLiveData("") // 目的站
|
||||||
val carId = MutableLiveData("") // 架子车号
|
val carId = MutableLiveData("") // 架子车号
|
||||||
@@ -31,20 +33,14 @@ 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") // 总重量
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// 方法区
|
// 方法区
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/**
|
|
||||||
* 扫码输入航班号
|
|
||||||
*/
|
|
||||||
fun flightNoScanClick() {
|
|
||||||
ScanModel.startScan(getTopActivity(), Constant.RequestCode.FLIGHT_NO)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扫码输入架子车号
|
* 扫码输入架子车号
|
||||||
*/
|
*/
|
||||||
@@ -121,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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,10 +129,6 @@ class GjcBoxWeighingViewModel : BasePageViewModel() {
|
|||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||||
when (requestCode) {
|
when (requestCode) {
|
||||||
Constant.RequestCode.FLIGHT_NO -> {
|
|
||||||
flightNo.value = data.getStringExtra(Constant.Result.CODED_CONTENT)
|
|
||||||
refresh()
|
|
||||||
}
|
|
||||||
Constant.RequestCode.CAR -> {
|
Constant.RequestCode.CAR -> {
|
||||||
carId.value = data.getStringExtra(Constant.Result.CODED_CONTENT)
|
carId.value = data.getStringExtra(Constant.Result.CODED_CONTENT)
|
||||||
refresh()
|
refresh()
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ 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.ui.page.preview.PreviewActivity
|
import com.lukouguoji.module_base.ui.page.preview.PreviewActivity
|
||||||
|
import com.lukouguoji.module_base.ui.page.preview.PdfPreviewActivity
|
||||||
import com.lukouguoji.module_base.util.MediaUtil
|
import com.lukouguoji.module_base.util.MediaUtil
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@@ -65,8 +66,9 @@ class GjcInspectionDetailsViewModel : BaseViewModel() {
|
|||||||
*/
|
*/
|
||||||
fun auditPass() {
|
fun auditPass() {
|
||||||
val bean = dataBean.value ?: return
|
val bean = dataBean.value ?: return
|
||||||
|
val reason = returnReason.value ?: ""
|
||||||
getTopActivity().showConfirmDialog("确定要通过该单证吗?") {
|
getTopActivity().showConfirmDialog("确定要通过该单证吗?") {
|
||||||
performAudit(bean, true, "通过", "")
|
performAudit(bean, true, "通过", reason)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +110,7 @@ class GjcInspectionDetailsViewModel : BaseViewModel() {
|
|||||||
// 根据审核状态调用不同接口
|
// 根据审核状态调用不同接口
|
||||||
launchLoadingCollect({
|
launchLoadingCollect({
|
||||||
if (isPass) {
|
if (isPass) {
|
||||||
NetApply.api.passGjcInspection(requestData)
|
NetApply.api.passGjcInspection(reason, requestData)
|
||||||
} else {
|
} else {
|
||||||
NetApply.api.backGjcInspection(reason, requestData)
|
NetApply.api.backGjcInspection(reason, requestData)
|
||||||
}
|
}
|
||||||
@@ -142,20 +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,
|
||||||
originalPic = attach.path
|
path = url,
|
||||||
|
originalPic = url
|
||||||
)
|
)
|
||||||
PreviewActivity.start(getTopActivity(), listOf(fileBean))
|
PreviewActivity.start(getTopActivity(), listOf(fileBean))
|
||||||
}
|
}
|
||||||
// PDF格式:提示暂不支持
|
// PDF格式:使用PdfPreviewActivity预览
|
||||||
attach.name.endsWith(".pdf", true) -> {
|
attach.name.endsWith(".pdf", true) -> {
|
||||||
showToast("PDF文件预览功能开发中")
|
PdfPreviewActivity.start(getTopActivity(), url)
|
||||||
}
|
}
|
||||||
// 其他格式
|
// 其他格式
|
||||||
else -> {
|
else -> {
|
||||||
@@ -163,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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ 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.CheckUtil
|
import com.lukouguoji.module_base.util.CheckUtil
|
||||||
import dev.utils.app.info.KeyValue
|
import dev.utils.app.info.KeyValue
|
||||||
|
import dev.utils.common.DateUtils
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ import java.util.Date
|
|||||||
class GjcInspectionViewModel : BasePageViewModel() {
|
class GjcInspectionViewModel : BasePageViewModel() {
|
||||||
|
|
||||||
// 搜索条件
|
// 搜索条件
|
||||||
val flightDate = MutableLiveData("") // 航班日期
|
val flightDate = MutableLiveData<String>(DateUtils.getCurrentTime().formatDate()) // 航班日期
|
||||||
val flightNo = MutableLiveData("") // 航班号
|
val flightNo = MutableLiveData("") // 航班号
|
||||||
val agentId = MutableLiveData("") // 代理ID
|
val agentId = MutableLiveData("") // 代理ID
|
||||||
val auditStatus = MutableLiveData("") // 审核状态
|
val auditStatus = MutableLiveData("") // 审核状态
|
||||||
@@ -47,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"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -212,7 +214,7 @@ class GjcInspectionViewModel : BasePageViewModel() {
|
|||||||
// 根据审核状态调用不同接口
|
// 根据审核状态调用不同接口
|
||||||
launchLoadingCollect({
|
launchLoadingCollect({
|
||||||
if (isPass) {
|
if (isPass) {
|
||||||
NetApply.api.passGjcInspection(requestData)
|
NetApply.api.passGjcInspection("", requestData)
|
||||||
} else {
|
} else {
|
||||||
NetApply.api.backGjcInspection(reason, requestData)
|
NetApply.api.backGjcInspection(reason, requestData)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,11 @@ 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.impl.FlowBus
|
||||||
import com.lukouguoji.module_base.ktx.launchLoadingCollect
|
import com.lukouguoji.module_base.ktx.launchLoadingCollect
|
||||||
|
import com.lukouguoji.module_base.ktx.launchCollect
|
||||||
import com.lukouguoji.module_base.ktx.showToast
|
import com.lukouguoji.module_base.ktx.showToast
|
||||||
import com.lukouguoji.module_base.ktx.toRequestBody
|
import com.lukouguoji.module_base.ktx.toRequestBody
|
||||||
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
|
import com.lukouguoji.module_base.ktx.verifyNullOrEmpty
|
||||||
|
import dev.utils.app.info.KeyValue
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -24,6 +26,15 @@ class GjcQueryEditViewModel : BaseViewModel() {
|
|||||||
// 数据Bean
|
// 数据Bean
|
||||||
val dataBean = MutableLiveData(GjcMaWb())
|
val dataBean = MutableLiveData(GjcMaWb())
|
||||||
|
|
||||||
|
// 运单ID(用于查询详情)
|
||||||
|
var maWbId: Long = 0
|
||||||
|
|
||||||
|
// 包装类型下拉列表
|
||||||
|
val packageTypeList = MutableLiveData<List<KeyValue>>(emptyList())
|
||||||
|
|
||||||
|
// 运单类型下拉列表
|
||||||
|
val waybillTypeList = MutableLiveData<List<KeyValue>>(emptyList())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化数据
|
* 初始化数据
|
||||||
*/
|
*/
|
||||||
@@ -31,7 +42,17 @@ class GjcQueryEditViewModel : BaseViewModel() {
|
|||||||
val jsonData = intent.getStringExtra(Constant.Key.DATA) ?: ""
|
val jsonData = intent.getStringExtra(Constant.Key.DATA) ?: ""
|
||||||
if (jsonData.isNotEmpty()) {
|
if (jsonData.isNotEmpty()) {
|
||||||
try {
|
try {
|
||||||
dataBean.value = Gson().fromJson(jsonData, GjcMaWb::class.java)
|
val tempBean = Gson().fromJson(jsonData, GjcMaWb::class.java)
|
||||||
|
maWbId = tempBean.maWbId ?: 0 // 保存ID用于查询详情
|
||||||
|
|
||||||
|
// 加载包装类型下拉列表
|
||||||
|
loadPackageTypeList()
|
||||||
|
|
||||||
|
// 加载运单类型下拉列表
|
||||||
|
loadWaybillTypeList()
|
||||||
|
|
||||||
|
// 调用详情接口获取完整数据
|
||||||
|
loadDetails()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
showToast("数据解析失败")
|
showToast("数据解析失败")
|
||||||
getTopActivity().finish()
|
getTopActivity().finish()
|
||||||
@@ -42,6 +63,165 @@ class GjcQueryEditViewModel : BaseViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载包装类型下拉列表
|
||||||
|
*/
|
||||||
|
private fun loadPackageTypeList() {
|
||||||
|
launchCollect({ NetApply.api.getPackTypeList() }) {
|
||||||
|
onSuccess = { result ->
|
||||||
|
// 转换为 KeyValue 列表,key 和 value 都使用 name(忽略 code)
|
||||||
|
val keyValueList = result.data?.mapNotNull { bean ->
|
||||||
|
bean.name?.let { name -> KeyValue(name, name) }
|
||||||
|
} ?: emptyList()
|
||||||
|
packageTypeList.value = keyValueList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载运单类型下拉列表
|
||||||
|
* 使用接口: POST /typeCode/awb?type=10 (10代表国际出港)
|
||||||
|
*/
|
||||||
|
private fun loadWaybillTypeList() {
|
||||||
|
launchCollect({ NetApply.api.getWaybillTypeList("10") }) {
|
||||||
|
onSuccess = { result ->
|
||||||
|
// 转换为 KeyValue 列表,key 使用 name(显示),value 使用 code(存储和提交)
|
||||||
|
val keyValueList = result.data?.mapNotNull { bean ->
|
||||||
|
if (bean.name != null && bean.code != null) {
|
||||||
|
KeyValue(bean.name, bean.code)
|
||||||
|
} else null
|
||||||
|
} ?: emptyList()
|
||||||
|
waybillTypeList.value = keyValueList
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载运单详情数据
|
||||||
|
*/
|
||||||
|
private fun loadDetails() {
|
||||||
|
if (maWbId == 0L) {
|
||||||
|
showToast("运单ID不存在")
|
||||||
|
getTopActivity().finish()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
launchLoadingCollect({ NetApply.api.getGjcQueryDetails(maWbId) }) {
|
||||||
|
onSuccess = { result ->
|
||||||
|
val data = result.data ?: emptyMap()
|
||||||
|
|
||||||
|
// 1. 提取 maWb 对象(主要数据)
|
||||||
|
val maWb = data["maWb"] as? Map<String, Any> ?: emptyMap()
|
||||||
|
|
||||||
|
// 2. 提取 maWbM 对象(海关扩展数据)
|
||||||
|
val maWbM = data["maWbM"] as? Map<String, Any> ?: emptyMap()
|
||||||
|
|
||||||
|
// 3. 提取 warehouseList(仓库列表,用于计算入库件数和入库重量)
|
||||||
|
val warehouseList = data["warehouseList"] as? List<Map<String, Any>> ?: emptyList()
|
||||||
|
|
||||||
|
// 4. 合并两个对象
|
||||||
|
val mergedData = mutableMapOf<String, Any>()
|
||||||
|
mergedData.putAll(maWb)
|
||||||
|
mergedData.putAll(maWbM)
|
||||||
|
|
||||||
|
// 5. 特殊字段处理
|
||||||
|
// 5.1 运单号: 组合 prefix + no
|
||||||
|
val prefix = maWb["prefix"] as? String ?: ""
|
||||||
|
val no = maWb["no"] as? String ?: ""
|
||||||
|
if (prefix.isNotEmpty() && no.isNotEmpty()) {
|
||||||
|
mergedData["wbNo"] = "$prefix$no"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.2 代理人: 如果 agentName 为空,使用 agentCode
|
||||||
|
if (!mergedData.containsKey("agentName") || (mergedData["agentName"] as? String).isNullOrEmpty()) {
|
||||||
|
maWb["agentCode"]?.let { mergedData["agentName"] = it }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.3 入库件数和入库重量: 从 warehouseList 计算总和
|
||||||
|
if (warehouseList.isNotEmpty()) {
|
||||||
|
var totalPc = 0L
|
||||||
|
var totalWeight = 0.0
|
||||||
|
|
||||||
|
warehouseList.forEach { warehouse ->
|
||||||
|
// 提取 pc(件数)并累加
|
||||||
|
val pc = warehouse["pc"]
|
||||||
|
when (pc) {
|
||||||
|
is Number -> totalPc += pc.toLong()
|
||||||
|
is String -> totalPc += pc.toLongOrNull() ?: 0L
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提取 weight(重量)并累加
|
||||||
|
val weight = warehouse["weight"]
|
||||||
|
when (weight) {
|
||||||
|
is Number -> totalWeight += weight.toDouble()
|
||||||
|
is String -> totalWeight += weight.toDoubleOrNull() ?: 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 覆盖原有的 arrivePc 和 arriveWeight
|
||||||
|
mergedData["arrivePc"] = totalPc
|
||||||
|
mergedData["arriveWeight"] = totalWeight
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 转换为 GjcMaWb 对象
|
||||||
|
val bean = Gson().fromJson(Gson().toJson(mergedData), GjcMaWb::class.java)
|
||||||
|
|
||||||
|
// 7. 匹配包装类型(支持 contains)
|
||||||
|
matchPackageType(bean)
|
||||||
|
|
||||||
|
// 8. 匹配运单类型(支持 contains)
|
||||||
|
matchWaybillType(bean)
|
||||||
|
|
||||||
|
dataBean.value = bean
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 匹配包装类型
|
||||||
|
* 使用 contains 匹配,支持简写值和完整值
|
||||||
|
*/
|
||||||
|
private fun matchPackageType(bean: GjcMaWb) {
|
||||||
|
val currentPackageType = bean.packageType
|
||||||
|
if (currentPackageType.isNullOrEmpty()) return
|
||||||
|
|
||||||
|
val packageList = packageTypeList.value ?: emptyList()
|
||||||
|
if (packageList.isEmpty()) return
|
||||||
|
|
||||||
|
// 使用 contains 匹配(完整值和简写值都支持)
|
||||||
|
val match = packageList.find { keyValue ->
|
||||||
|
keyValue.value?.contains(currentPackageType) == true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match != null) {
|
||||||
|
// 使用匹配到的完整值
|
||||||
|
bean.packageType = match.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 匹配运单类型
|
||||||
|
* 使用 code 进行匹配(bean.awbType 存储的是 code)
|
||||||
|
* 显示时使用 name,但实际存储和提交的是 code
|
||||||
|
*/
|
||||||
|
private fun matchWaybillType(bean: GjcMaWb) {
|
||||||
|
val currentAwbTypeCode = bean.awbType
|
||||||
|
if (currentAwbTypeCode.isNullOrEmpty()) return
|
||||||
|
|
||||||
|
val waybillList = waybillTypeList.value ?: emptyList()
|
||||||
|
if (waybillList.isEmpty()) return
|
||||||
|
|
||||||
|
// 使用 code 进行精确匹配(value 字段存储的是 code)
|
||||||
|
val match = waybillList.find { keyValue ->
|
||||||
|
keyValue.value == currentAwbTypeCode
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match != null) {
|
||||||
|
// 使用匹配到的 code 值(确保存储的是 code,而不是 name)
|
||||||
|
bean.awbType = match.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存修改
|
* 保存修改
|
||||||
*/
|
*/
|
||||||
@@ -53,7 +233,7 @@ class GjcQueryEditViewModel : BaseViewModel() {
|
|||||||
|
|
||||||
// 调用更新接口
|
// 调用更新接口
|
||||||
launchLoadingCollect({
|
launchLoadingCollect({
|
||||||
NetApply.api.updateGjcMaWb(Gson().toJson(bean).toRequestBody())
|
NetApply.api.updateGjcMaWb(bean.toRequestBody())
|
||||||
}) {
|
}) {
|
||||||
onSuccess = {
|
onSuccess = {
|
||||||
showToast("修改成功")
|
showToast("修改成功")
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ 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 dev.utils.common.DateUtils
|
||||||
|
import com.lukouguoji.module_base.ktx.formatDate
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 国际出港查询ViewModel
|
* 国际出港查询ViewModel
|
||||||
@@ -22,7 +24,7 @@ import dev.utils.app.info.KeyValue
|
|||||||
class GjcQueryViewModel : BasePageViewModel() {
|
class GjcQueryViewModel : BasePageViewModel() {
|
||||||
|
|
||||||
// ==================== 搜索条件 ====================
|
// ==================== 搜索条件 ====================
|
||||||
val flightDateStart = MutableLiveData("") // 航班日期起
|
val flightDateStart = MutableLiveData<String>(DateUtils.getCurrentTime().formatDate()) // 航班日期起
|
||||||
val flightDateEnd = MutableLiveData("") // 航班日期止
|
val flightDateEnd = MutableLiveData("") // 航班日期止
|
||||||
val agentId = MutableLiveData("") // 代理ID
|
val agentId = MutableLiveData("") // 代理ID
|
||||||
val outStatus = MutableLiveData("") // 出库状态
|
val outStatus = MutableLiveData("") // 出库状态
|
||||||
@@ -101,8 +103,8 @@ class GjcQueryViewModel : BasePageViewModel() {
|
|||||||
val listParams = mapOf(
|
val listParams = mapOf(
|
||||||
"pageNum" to pageModel.page,
|
"pageNum" to pageModel.page,
|
||||||
"pageSize" to pageModel.limit,
|
"pageSize" to pageModel.limit,
|
||||||
"fdateStart" to flightDateStart.value!!.ifEmpty { null },
|
"beginDate" to flightDateStart.value!!.ifEmpty { null },
|
||||||
"fdateEnd" to flightDateEnd.value!!.ifEmpty { null },
|
"endDate" to flightDateEnd.value!!.ifEmpty { null },
|
||||||
"agentCode" to agentId.value!!.ifEmpty { null },
|
"agentCode" to agentId.value!!.ifEmpty { null },
|
||||||
"outState" to outStatus.value!!.ifEmpty { null },
|
"outState" to outStatus.value!!.ifEmpty { null },
|
||||||
"wbNo" to waybillNo.value!!.ifEmpty { null },
|
"wbNo" to waybillNo.value!!.ifEmpty { null },
|
||||||
|
|||||||
@@ -7,13 +7,18 @@ 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
|
||||||
import dev.utils.app.info.KeyValue
|
import dev.utils.app.info.KeyValue
|
||||||
|
import dev.utils.common.DateUtils
|
||||||
|
import com.lukouguoji.module_base.ktx.formatDate
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 国际出港计重记录 ViewModel
|
* 国际出港计重记录 ViewModel
|
||||||
@@ -21,7 +26,7 @@ import dev.utils.app.info.KeyValue
|
|||||||
class GjcWeighingRecordViewModel : BasePageViewModel() {
|
class GjcWeighingRecordViewModel : BasePageViewModel() {
|
||||||
|
|
||||||
// 搜索条件
|
// 搜索条件
|
||||||
val flightDate = MutableLiveData("") // 航班日期
|
val flightDate = MutableLiveData<String>(DateUtils.getCurrentTime().formatDate()) // 航班日期
|
||||||
val flightNo = MutableLiveData("") // 航班号
|
val flightNo = MutableLiveData("") // 航班号
|
||||||
val agentCode = MutableLiveData("") // 代理人
|
val agentCode = MutableLiveData("") // 代理人
|
||||||
val spCode = MutableLiveData("") // 特码
|
val spCode = MutableLiveData("") // 特码
|
||||||
@@ -75,13 +80,6 @@ class GjcWeighingRecordViewModel : BasePageViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 扫码输入航班号
|
|
||||||
*/
|
|
||||||
fun flightNoScanClick() {
|
|
||||||
ScanModel.startScan(getTopActivity(), Constant.RequestCode.FLIGHT_NO)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扫码输入运单号
|
* 扫码输入运单号
|
||||||
*/
|
*/
|
||||||
@@ -97,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("只能选择一个单据")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,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()
|
||||||
|
|
||||||
// 构建查询参数(统计接口 - 使用相同的搜索条件)
|
// 构建查询参数(统计接口 - 使用相同的搜索条件)
|
||||||
@@ -124,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)
|
||||||
@@ -156,10 +179,6 @@ class GjcWeighingRecordViewModel : BasePageViewModel() {
|
|||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||||
when (requestCode) {
|
when (requestCode) {
|
||||||
Constant.RequestCode.FLIGHT_NO -> {
|
|
||||||
flightNo.value = data.getStringExtra(Constant.Result.CODED_CONTENT)
|
|
||||||
refresh()
|
|
||||||
}
|
|
||||||
Constant.RequestCode.WAYBILL -> {
|
Constant.RequestCode.WAYBILL -> {
|
||||||
waybillNo.value = data.getStringExtra(Constant.Result.CODED_CONTENT)
|
waybillNo.value = data.getStringExtra(Constant.Result.CODED_CONTENT)
|
||||||
refresh()
|
refresh()
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ 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.DictUtils
|
||||||
import dev.utils.app.info.KeyValue
|
import dev.utils.app.info.KeyValue
|
||||||
|
import dev.utils.common.DateUtils
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
@@ -35,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("")
|
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") // 地磅重量(右上角黄色显示区域)
|
||||||
|
|
||||||
// 可编辑字段(用于双向绑定)
|
// 可编辑字段(用于双向绑定)
|
||||||
@@ -59,6 +64,8 @@ class GjcWeighingStartViewModel : BaseViewModel() {
|
|||||||
val arriveWeight = MutableLiveData("") // 运抵重量
|
val arriveWeight = MutableLiveData("") // 运抵重量
|
||||||
val arriveVolume = MutableLiveData("") // 运抵体积
|
val arriveVolume = MutableLiveData("") // 运抵体积
|
||||||
|
|
||||||
|
val pageRemark = MutableLiveData("") // 备注
|
||||||
|
|
||||||
// 下拉选择数据源
|
// 下拉选择数据源
|
||||||
val channelList = MutableLiveData<List<KeyValue>>() // 通道号列表
|
val channelList = MutableLiveData<List<KeyValue>>() // 通道号列表
|
||||||
val agentList = MutableLiveData<List<KeyValue>>() // 代理人列表
|
val agentList = MutableLiveData<List<KeyValue>>() // 代理人列表
|
||||||
@@ -75,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 ?: ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 监听运抵重量变化,自动计算运抵体积
|
// 监听运抵重量变化,自动计算运抵体积
|
||||||
@@ -166,6 +168,7 @@ class GjcWeighingStartViewModel : BaseViewModel() {
|
|||||||
launchLoadingCollect({ NetApply.api.getIntExpCheckInWbById(maWbId) }) {
|
launchLoadingCollect({ NetApply.api.getIntExpCheckInWbById(maWbId) }) {
|
||||||
onSuccess = { result ->
|
onSuccess = { result ->
|
||||||
maWbBean.value = result.data ?: GjcMaWb()
|
maWbBean.value = result.data ?: GjcMaWb()
|
||||||
|
pageRemark.value = maWbBean.value?.remark
|
||||||
// 更新航班日期字符串
|
// 更新航班日期字符串
|
||||||
flightDate.value = result.data?.fdate?.formatDate() ?: ""
|
flightDate.value = result.data?.fdate?.formatDate() ?: ""
|
||||||
}
|
}
|
||||||
@@ -186,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 = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 航班日期点击
|
* 航班日期点击
|
||||||
*/
|
*/
|
||||||
@@ -223,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)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 托盘车号输入后查询自重
|
* 托盘车号输入后查询自重
|
||||||
*/
|
*/
|
||||||
@@ -232,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 = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -259,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
|
||||||
@@ -268,7 +374,10 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 构建请求数据(GjcMaWb转RequestBody,包含通道号)
|
// 3. 构建请求数据(GjcMaWb转RequestBody,包含通道号)
|
||||||
@@ -294,6 +403,9 @@ class GjcWeighingStartViewModel : BaseViewModel() {
|
|||||||
arrivePc.value = ""
|
arrivePc.value = ""
|
||||||
arriveWeight.value = ""
|
arriveWeight.value = ""
|
||||||
arriveVolume.value = ""
|
arriveVolume.value = ""
|
||||||
|
|
||||||
|
pageRemark.value = ""
|
||||||
|
|
||||||
maWbBean.value = maWbBean.value?.apply {
|
maWbBean.value = maWbBean.value?.apply {
|
||||||
carId = null
|
carId = null
|
||||||
remark = null
|
remark = null
|
||||||
@@ -317,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
|
||||||
|
|
||||||
@@ -350,9 +471,10 @@ class GjcWeighingStartViewModel : BaseViewModel() {
|
|||||||
"goodsCn" to bean.goodsCn,
|
"goodsCn" to bean.goodsCn,
|
||||||
"businessType" to bean.businessType,
|
"businessType" to bean.businessType,
|
||||||
"carId" to bean.carId,
|
"carId" to bean.carId,
|
||||||
"remark" to bean.remark,
|
"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({
|
||||||
@@ -406,6 +528,6 @@ class GjcWeighingStartViewModel : BaseViewModel() {
|
|||||||
*/
|
*/
|
||||||
override fun onCleared() {
|
override fun onCleared() {
|
||||||
super.onCleared()
|
super.onCleared()
|
||||||
diBangModel.cancelLooperGet()
|
// diBangModel.cancelLooperGet() // 已改为手动输入,不再使用地磅自动读取
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,20 +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.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 kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 国际出港计重 ViewModel
|
* 国际出港计重 ViewModel
|
||||||
@@ -24,7 +34,7 @@ import dev.utils.app.info.KeyValue
|
|||||||
class GjcWeighingViewModel : BasePageViewModel() {
|
class GjcWeighingViewModel : BasePageViewModel() {
|
||||||
|
|
||||||
// 搜索条件
|
// 搜索条件
|
||||||
val flightDate = MutableLiveData("") // 航班日期
|
val flightDate = MutableLiveData<String>(DateUtils.getCurrentTime().formatDate()) // 航班日期
|
||||||
val flightNo = MutableLiveData("") // 航班号
|
val flightNo = MutableLiveData("") // 航班号
|
||||||
val agentCode = MutableLiveData("") // 代理人
|
val agentCode = MutableLiveData("") // 代理人
|
||||||
val spCode = MutableLiveData("") // 特码
|
val spCode = MutableLiveData("") // 特码
|
||||||
@@ -43,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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// 方法区
|
// 方法区
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
@@ -79,13 +101,6 @@ class GjcWeighingViewModel : BasePageViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 扫码输入航班号
|
|
||||||
*/
|
|
||||||
fun flightNoScanClick() {
|
|
||||||
ScanModel.startScan(getTopActivity(), Constant.RequestCode.FLIGHT_NO)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扫码输入运单号
|
* 扫码输入运单号
|
||||||
*/
|
*/
|
||||||
@@ -114,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("提前运抵失败"))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -133,7 +193,7 @@ class GjcWeighingViewModel : 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()
|
||||||
|
|
||||||
// 构建查询参数(统计接口 - 使用相同的搜索条件)
|
// 构建查询参数(统计接口 - 使用相同的搜索条件)
|
||||||
@@ -142,7 +202,7 @@ class GjcWeighingViewModel : 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)
|
||||||
@@ -173,10 +233,6 @@ class GjcWeighingViewModel : BasePageViewModel() {
|
|||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||||
when (requestCode) {
|
when (requestCode) {
|
||||||
Constant.RequestCode.FLIGHT_NO -> {
|
|
||||||
flightNo.value = data.getStringExtra(Constant.Result.CODED_CONTENT)
|
|
||||||
refresh()
|
|
||||||
}
|
|
||||||
Constant.RequestCode.WAYBILL -> {
|
Constant.RequestCode.WAYBILL -> {
|
||||||
waybillNo.value = data.getStringExtra(Constant.Result.CODED_CONTENT)
|
waybillNo.value = data.getStringExtra(Constant.Result.CODED_CONTENT)
|
||||||
refresh()
|
refresh()
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -18,6 +20,8 @@ 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.common.DateUtils
|
||||||
|
import com.lukouguoji.module_base.ktx.formatDate
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,7 +30,7 @@ import kotlinx.coroutines.launch
|
|||||||
class IntExpArriveViewModel : BasePageViewModel() {
|
class IntExpArriveViewModel : BasePageViewModel() {
|
||||||
|
|
||||||
// ========== 搜索条件 ==========
|
// ========== 搜索条件 ==========
|
||||||
val flightDate = MutableLiveData("") // 航班日期
|
val flightDate = MutableLiveData<String>(DateUtils.getCurrentTime().formatDate()) // 航班日期
|
||||||
val flightNo = MutableLiveData("") // 航班号
|
val flightNo = MutableLiveData("") // 航班号
|
||||||
val waybillNo = MutableLiveData("") // 运单号
|
val waybillNo = MutableLiveData("") // 运单号
|
||||||
val hno = MutableLiveData("") // 分单号
|
val hno = MutableLiveData("") // 分单号
|
||||||
@@ -39,6 +43,14 @@ class IntExpArriveViewModel : BasePageViewModel() {
|
|||||||
// ========== 全选状态 ==========
|
// ========== 全选状态 ==========
|
||||||
val isAllChecked = MutableLiveData(false)
|
val isAllChecked = MutableLiveData(false)
|
||||||
|
|
||||||
|
// ========== 全局展开状态 ==========
|
||||||
|
/**
|
||||||
|
* 全局展开状态
|
||||||
|
* - true: 全部展开
|
||||||
|
* - false: 全部收起
|
||||||
|
*/
|
||||||
|
val isAllExpanded = MutableLiveData(false)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
// 监听全选状态,自动更新所有列表项
|
// 监听全选状态,自动更新所有列表项
|
||||||
isAllChecked.observeForever { checked ->
|
isAllChecked.observeForever { checked ->
|
||||||
@@ -73,6 +85,28 @@ class IntExpArriveViewModel : BasePageViewModel() {
|
|||||||
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
|
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换全局展开/收起状态
|
||||||
|
*/
|
||||||
|
fun toggleAllExpand() {
|
||||||
|
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return
|
||||||
|
|
||||||
|
// 切换全局状态
|
||||||
|
val shouldExpand = !isAllExpanded.value!!
|
||||||
|
isAllExpanded.value = shouldExpand
|
||||||
|
|
||||||
|
// 更新所有列表项的 showMore 状态
|
||||||
|
list.forEach { bean ->
|
||||||
|
// 只有当有子列表时才设置展开状态
|
||||||
|
if (!bean.haWbList.isNullOrEmpty()) {
|
||||||
|
bean.showMore.set(shouldExpand)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新列表UI
|
||||||
|
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扫码运单号
|
* 扫码运单号
|
||||||
*/
|
*/
|
||||||
@@ -92,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()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -117,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
|
||||||
}
|
}
|
||||||
@@ -131,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()
|
||||||
@@ -163,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 = {
|
||||||
@@ -191,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 }
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -206,7 +311,11 @@ class IntExpArriveViewModel : BasePageViewModel() {
|
|||||||
|
|
||||||
// 获取列表 (带Loading)
|
// 获取列表 (带Loading)
|
||||||
launchLoadingCollect({ NetApply.api.getIntExpArriveList(listParams) }) {
|
launchLoadingCollect({ NetApply.api.getIntExpArriveList(listParams) }) {
|
||||||
onSuccess = { pageModel.handleListBean(it) }
|
onSuccess = {
|
||||||
|
pageModel.handleListBean(it)
|
||||||
|
// 数据加载完成后,重置全局展开状态为收起
|
||||||
|
isAllExpanded.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取统计信息 (后台请求)
|
// 获取统计信息 (后台请求)
|
||||||
|
|||||||
@@ -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,20 +9,31 @@ 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(静态数据)
|
||||||
*/
|
*/
|
||||||
class IntExpAssembleStartViewModel : BaseViewModel() {
|
class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* 缓存用户上次选择的组装人
|
||||||
|
* 生命周期:本次App打开期间有效,退出登录后清空
|
||||||
|
*/
|
||||||
|
var lastSelectedOperator: String? = null
|
||||||
|
}
|
||||||
|
|
||||||
// ========== 搜索条件 ==========
|
// ========== 搜索条件 ==========
|
||||||
val searchText = MutableLiveData("")
|
val searchText = MutableLiveData("")
|
||||||
val uldSearchText = MutableLiveData("") // ULD搜索框
|
val uldSearchText = MutableLiveData("") // ULD搜索框
|
||||||
@@ -57,17 +69,73 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
// ========== 运单信息 ==========
|
// ========== 运单信息 ==========
|
||||||
val waybillInfo = MutableLiveData(WaybillInfoBean())
|
val waybillInfo = MutableLiveData(WaybillInfoBean())
|
||||||
|
|
||||||
|
// ========== 组装人(独立的LiveData,用于监听变化并更新缓存)==========
|
||||||
|
val operator = MutableLiveData<String>("")
|
||||||
|
|
||||||
// ========== 组装人列表 ==========
|
// ========== 组装人列表 ==========
|
||||||
val assemblerList = MutableLiveData<List<KeyValue>>(emptyList())
|
val assemblerList = MutableLiveData<List<KeyValue>>(emptyList())
|
||||||
|
|
||||||
// ========== 标记位,避免重复查询 ==========
|
// ========== 标记位,避免重复查询 ==========
|
||||||
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)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 装货按钮启用状态(非编辑模式时启用)
|
||||||
|
*/
|
||||||
|
val isLoadEnabled = MutableLiveData(true)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 卸货按钮启用状态(编辑模式时启用)
|
||||||
|
*/
|
||||||
|
val isUnloadEnabled = MutableLiveData(false)
|
||||||
|
|
||||||
|
init {
|
||||||
|
// 监听组装人变化,自动更新缓存和waybillInfo
|
||||||
|
operator.observeForever { value ->
|
||||||
|
if (!value.isNullOrEmpty()) {
|
||||||
|
lastSelectedOperator = value
|
||||||
|
// 同步到 waybillInfo
|
||||||
|
waybillInfo.value?.operator = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听ULD锁定状态,自动更新按钮启用状态
|
||||||
|
isUldNoLocked.observeForever { isLocked ->
|
||||||
|
if (isLocked == true) {
|
||||||
|
// 编辑模式:只能卸货
|
||||||
|
isLoadEnabled.value = false
|
||||||
|
isUnloadEnabled.value = true
|
||||||
|
} else {
|
||||||
|
// 非编辑模式:只能装货
|
||||||
|
isLoadEnabled.value = true
|
||||||
|
isUnloadEnabled.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载组装位置列表
|
* 加载组装位置列表
|
||||||
@@ -82,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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,6 +202,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 运单点击(单选切换)
|
* 运单点击(单选切换)
|
||||||
|
* 装货模式:从运单列表选择运单
|
||||||
*/
|
*/
|
||||||
fun onWaybillItemClick(position: Int) {
|
fun onWaybillItemClick(position: Int) {
|
||||||
val list = waybillList.value ?: return
|
val list = waybillList.value ?: return
|
||||||
@@ -133,12 +220,13 @@ 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
|
|
||||||
|
|
||||||
// 保存当前的组装人(始终保留)
|
// 【新增】清空卸货选中的子运单(切换到装货模式)
|
||||||
val previousOperator = waybillInfo.value?.operator ?: ""
|
selectedAssembleWaybill = null
|
||||||
|
|
||||||
|
// 保存当前的组装人(始终保留,从operator LiveData读取)
|
||||||
|
val previousOperator = operator.value ?: ""
|
||||||
|
|
||||||
// 判断是否需要保留组装件数和重量
|
// 判断是否需要保留组装件数和重量
|
||||||
val previousAssembleCount: String
|
val previousAssembleCount: String
|
||||||
@@ -164,7 +252,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
waybillWeight = selectedWaybill.weight
|
waybillWeight = selectedWaybill.weight
|
||||||
assembleCount = previousAssembleCount
|
assembleCount = previousAssembleCount
|
||||||
assembleWeight = previousAssembleWeight
|
assembleWeight = previousAssembleWeight
|
||||||
operator = previousOperator
|
operator = previousOperator // 从operator LiveData获取的值
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,13 +279,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
fun loadWaitingAssembleWaybills() {
|
fun loadWaitingAssembleWaybills() {
|
||||||
val wbNo = searchText.value?.trim() ?: ""
|
val wbNo = searchText.value?.trim() ?: ""
|
||||||
|
|
||||||
// 验证运单号不能为空
|
// 发起网络请求(空参数时相当于刷新列表)
|
||||||
if (wbNo.isEmpty()) {
|
|
||||||
showToast("请输入运单号")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 发起网络请求
|
|
||||||
launchLoadingCollect({ NetApply.api.queryWaitingAssemble(wbNo) }) {
|
launchLoadingCollect({ NetApply.api.queryWaitingAssemble(wbNo) }) {
|
||||||
onSuccess = { result ->
|
onSuccess = { result ->
|
||||||
// 数据转换: GjcWarehouse -> AssembleWaybillBean
|
// 数据转换: GjcWarehouse -> AssembleWaybillBean
|
||||||
@@ -224,7 +306,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
val existsInNewList = waybillBeanList.any { it.waybillNo == currentWaybillNo }
|
val existsInNewList = waybillBeanList.any { it.waybillNo == currentWaybillNo }
|
||||||
if (!existsInNewList) {
|
if (!existsInNewList) {
|
||||||
// 当前运单不在新列表中,清空表单
|
// 当前运单不在新列表中,清空表单
|
||||||
val previousOperator = waybillInfo.value?.operator ?: ""
|
val previousOperator = operator.value ?: ""
|
||||||
waybillInfo.value = WaybillInfoBean().apply {
|
waybillInfo.value = WaybillInfoBean().apply {
|
||||||
operator = previousOperator
|
operator = previousOperator
|
||||||
}
|
}
|
||||||
@@ -273,7 +355,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
val existsInNewList = waybillBeanList.any { it.waybillNo == currentWaybillNo }
|
val existsInNewList = waybillBeanList.any { it.waybillNo == currentWaybillNo }
|
||||||
if (!existsInNewList) {
|
if (!existsInNewList) {
|
||||||
// 当前运单不在新列表中,清空表单
|
// 当前运单不在新列表中,清空表单
|
||||||
val previousOperator = waybillInfo.value?.operator ?: ""
|
val previousOperator = operator.value ?: ""
|
||||||
waybillInfo.value = WaybillInfoBean().apply {
|
waybillInfo.value = WaybillInfoBean().apply {
|
||||||
operator = previousOperator
|
operator = previousOperator
|
||||||
}
|
}
|
||||||
@@ -302,15 +384,11 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
val keyValueList = list.map { KeyValue(it, it) }
|
val keyValueList = list.map { KeyValue(it, it) }
|
||||||
assemblerList.value = keyValueList
|
assemblerList.value = keyValueList
|
||||||
|
|
||||||
// 获取当前登录用户名
|
// 使用缓存的组装人,如果缓存存在且在列表中则自动填充
|
||||||
val currentUserName = SharedPreferenceUtil.getString(Constant.Share.userName)
|
if (!lastSelectedOperator.isNullOrEmpty() && list.contains(lastSelectedOperator)) {
|
||||||
|
operator.value = lastSelectedOperator // 设置到operator LiveData,会自动触发observer更新缓存和waybillInfo
|
||||||
// 如果当前用户名在列表中,设置为默认值;否则保持为空(显示 hint)
|
|
||||||
if (currentUserName.isNotEmpty() && list.contains(currentUserName)) {
|
|
||||||
waybillInfo.value?.operator = currentUserName
|
|
||||||
waybillInfo.value = waybillInfo.value // 触发LiveData更新
|
|
||||||
}
|
}
|
||||||
// 注意:不匹配时不需要显式设置为空,因为初始值已经是空字符串
|
// 如果缓存为空或不在列表中,保持为空(显示hint "请选择组装人")
|
||||||
}
|
}
|
||||||
onFailed = { code, message ->
|
onFailed = { code, message ->
|
||||||
showToast("加载组装人列表失败: $message")
|
showToast("加载组装人列表失败: $message")
|
||||||
@@ -333,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) }) {
|
||||||
@@ -354,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 ->
|
||||||
@@ -379,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. 验证必填字段
|
||||||
@@ -402,15 +503,62 @@ 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 "卸货件数"
|
||||||
|
showToast("请输入${countFieldName}")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val assembleWeight = waybillInfo.value?.assembleWeight?.trim() ?: ""
|
val assembleWeight = waybillInfo.value?.assembleWeight?.trim() ?: ""
|
||||||
// 组装重量为非必填,不进行验证
|
|
||||||
|
|
||||||
val operator = waybillInfo.value?.operator?.trim() ?: ""
|
// 【修改】区分校验逻辑
|
||||||
if (operator.isEmpty()) {
|
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() ?: ""
|
||||||
|
if (operatorValue.isEmpty()) {
|
||||||
showToast("请选择组装人")
|
showToast("请选择组装人")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -421,21 +569,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 获取或构建运单Bean
|
// 2. 构建useInfo(ULD信息)
|
||||||
// 从运单列表中获取选中的运单
|
|
||||||
val currentWaybillList = waybillList.value
|
|
||||||
if (currentWaybillList == null) {
|
|
||||||
showToast("运单列表为空")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val selectedWaybill = currentWaybillList.firstOrNull { it.isSelected.get() }
|
|
||||||
if (selectedWaybill == null) {
|
|
||||||
showToast("请选择运单")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 构建useInfo(ULD信息)
|
|
||||||
val useInfo = mapOf(
|
val useInfo = mapOf(
|
||||||
"uld" to uldNo,
|
"uld" to uldNo,
|
||||||
"consumeWeight" to materialWeight.toDoubleOrNull(),
|
"consumeWeight" to materialWeight.toDoubleOrNull(),
|
||||||
@@ -445,44 +579,77 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
else -> ""
|
else -> ""
|
||||||
},
|
},
|
||||||
"loadArea" to loadArea,
|
"loadArea" to loadArea,
|
||||||
"useId" to 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(),
|
||||||
"consumeWeight" to materialWeight.toDoubleOrNull(),
|
"consumeWeight" to materialWeight.toDoubleOrNull(),
|
||||||
"ldId" to operator,
|
"ldId" to operatorValue,
|
||||||
"loadArea" to loadArea,
|
"loadArea" to loadArea,
|
||||||
"useInfo" to useInfo,
|
"useInfo" to useInfo,
|
||||||
"wbInfo" to wbInfo,
|
"wbInfo" to wbInfo,
|
||||||
"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) {
|
||||||
@@ -493,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")
|
||||||
@@ -508,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")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -610,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
|
||||||
|
|
||||||
@@ -624,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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -650,31 +855,39 @@ 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
|
||||||
// 耗材重量、ULD状态保持不变
|
// 耗材重量、ULD状态保持不变
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存当前的组装人(在创建新对象前)
|
// 保存当前的组装人(在创建新对象前,从operator LiveData读取)
|
||||||
val previousOperator = waybillInfo.value?.operator ?: ""
|
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 // 保留之前选择的组装人
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -763,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
|
||||||
@@ -799,12 +1012,52 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
* 清空表单并退出编辑模式
|
* 清空表单并退出编辑模式
|
||||||
*/
|
*/
|
||||||
private fun clearForm() {
|
private fun clearForm() {
|
||||||
// 保留组装人的值(用户期望保留上一次的选择)
|
// 保留组装人的值(用户期望保留上一次的选择,从operator LiveData读取)
|
||||||
val previousOperator = waybillInfo.value?.operator ?: ""
|
val previousOperator = operator.value ?: ""
|
||||||
|
|
||||||
waybillInfo.value = WaybillInfoBean().apply {
|
waybillInfo.value = WaybillInfoBean().apply {
|
||||||
operator = previousOperator // 恢复组装人
|
operator = previousOperator // 恢复组装人
|
||||||
}
|
}
|
||||||
isUldNoLocked.value = false
|
isUldNoLocked.value = false
|
||||||
|
|
||||||
|
// 【新增】清空卸货选中的子运单
|
||||||
|
selectedAssembleWaybill = null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空缓存的组装人(登出时调用)
|
||||||
|
*/
|
||||||
|
fun clearCachedOperator() {
|
||||||
|
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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +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 kotlinx.coroutines.launch
|
import dev.utils.common.DateUtils
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 国际出港-出港组装ViewModel
|
* 国际出港-出港组装ViewModel
|
||||||
@@ -27,23 +24,24 @@ import kotlinx.coroutines.launch
|
|||||||
class IntExpAssembleViewModel : BasePageViewModel() {
|
class IntExpAssembleViewModel : BasePageViewModel() {
|
||||||
|
|
||||||
// ========== 搜索条件 ==========
|
// ========== 搜索条件 ==========
|
||||||
val flightDate = MutableLiveData("") // 航班日期
|
val flightDate = MutableLiveData<String>(DateUtils.getCurrentTime().formatDate()) // 航班日期
|
||||||
val flightNo = MutableLiveData("") // 航班号
|
val flightNo = MutableLiveData("") // 航班号
|
||||||
val uldNo = MutableLiveData("") // ULD编号
|
val uldNo = MutableLiveData("") // ULD编号
|
||||||
val reweighStatus = MutableLiveData("全部") // 复磅状态
|
|
||||||
|
val reweighStatus = MutableLiveData("") // 复磅状态
|
||||||
val reweighStatusList = MutableLiveData( // 复磅状态选项
|
val reweighStatusList = MutableLiveData( // 复磅状态选项
|
||||||
listOf(
|
listOf(
|
||||||
KeyValue("全部", "全部"),
|
KeyValue("全部", ""),
|
||||||
KeyValue("未复磅", "未复磅"),
|
KeyValue("未复磅", "0"),
|
||||||
KeyValue("已复磅", "已复磅")
|
KeyValue("已复磅", "1")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
val assembler = MutableLiveData("") // 组装人
|
val assembler = MutableLiveData("") // 组装人
|
||||||
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") // 合计票数
|
||||||
@@ -74,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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,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()
|
||||||
@@ -204,7 +258,7 @@ class IntExpAssembleViewModel : BasePageViewModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 回填重量按钮点击
|
* 回填重量按钮点击 - 跳转到修改组装重量页面
|
||||||
*/
|
*/
|
||||||
fun onBackfillWeightClick() {
|
fun onBackfillWeightClick() {
|
||||||
// 获取选中的数据
|
// 获取选中的数据
|
||||||
@@ -215,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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ 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 dev.utils.common.DateUtils
|
||||||
|
import com.lukouguoji.module_base.ktx.formatDate
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,10 +30,9 @@ import kotlinx.coroutines.launch
|
|||||||
class IntExpLoadViewModel : BasePageViewModel() {
|
class IntExpLoadViewModel : BasePageViewModel() {
|
||||||
|
|
||||||
// ========== 搜索条件 ==========
|
// ========== 搜索条件 ==========
|
||||||
val flightDate = MutableLiveData("") // 航班日期
|
val flightDate = MutableLiveData<String>(DateUtils.getCurrentTime().formatDate()) // 航班日期
|
||||||
val flightNo = MutableLiveData("") // 航班号
|
val flightNo = MutableLiveData("") // 航班号
|
||||||
val waybillNo = MutableLiveData("") // 运单号
|
val waybillNo = MutableLiveData("") // 运单号
|
||||||
val houseWaybillNo = MutableLiveData("") // 分单号
|
|
||||||
|
|
||||||
// ========== 统计信息 ==========
|
// ========== 统计信息 ==========
|
||||||
val totalCount = MutableLiveData("0") // 合计票数
|
val totalCount = MutableLiveData("0") // 合计票数
|
||||||
@@ -82,13 +83,6 @@ class IntExpLoadViewModel : BasePageViewModel() {
|
|||||||
ScanModel.startScan(getTopActivity(), Constant.RequestCode.WAYBILL)
|
ScanModel.startScan(getTopActivity(), Constant.RequestCode.WAYBILL)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 扫码分单号
|
|
||||||
*/
|
|
||||||
fun scanHouseWaybill() {
|
|
||||||
ScanModel.startScan(getTopActivity(), Constant.RequestCode.CODE)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 状态重置 (批量操作)
|
* 状态重置 (批量操作)
|
||||||
*/
|
*/
|
||||||
@@ -195,8 +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 },
|
||||||
no = waybillNo.value?.ifEmpty { null },
|
wbNo = waybillNo.value?.ifEmpty { null },
|
||||||
hno = houseWaybillNo.value?.ifEmpty { null },
|
|
||||||
pageNum = pageModel.page,
|
pageNum = pageModel.page,
|
||||||
pageSize = pageModel.limit
|
pageSize = pageModel.limit
|
||||||
)
|
)
|
||||||
@@ -208,8 +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 },
|
||||||
no = waybillNo.value?.ifEmpty { null },
|
wbNo = waybillNo.value?.ifEmpty { null }
|
||||||
hno = houseWaybillNo.value?.ifEmpty { null }
|
|
||||||
).toRequestBody()
|
).toRequestBody()
|
||||||
|
|
||||||
// 获取列表 (带Loading)
|
// 获取列表 (带Loading)
|
||||||
|
|||||||
@@ -31,18 +31,17 @@ class IntExpMoveViewModel : BasePageViewModel(), IOnItemClickListener {
|
|||||||
// ========== 运单类型下拉数据 ==========
|
// ========== 运单类型下拉数据 ==========
|
||||||
val awbTypeList = MutableLiveData<List<KeyValue>>().apply {
|
val awbTypeList = MutableLiveData<List<KeyValue>>().apply {
|
||||||
value = listOf(
|
value = listOf(
|
||||||
KeyValue("", "全部"),
|
KeyValue("全部", ""),
|
||||||
KeyValue("IOCO", "国际出港(经国内航班出境)"),
|
KeyValue("转国内出港", "IOCO")
|
||||||
KeyValue("IOSO", "国际出港(国际航班出境)")
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== 移库状态下拉数据 ==========
|
// ========== 移库状态下拉数据 ==========
|
||||||
val moveStateList = MutableLiveData<List<KeyValue>>().apply {
|
val moveStateList = MutableLiveData<List<KeyValue>>().apply {
|
||||||
value = listOf(
|
value = listOf(
|
||||||
KeyValue("", "全部"),
|
KeyValue("全部", ""),
|
||||||
KeyValue("0", "未移交"),
|
KeyValue("未移库", "0"),
|
||||||
KeyValue("1", "已移交")
|
KeyValue("已移库", "1")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,14 +145,14 @@ class IntExpMoveViewModel : BasePageViewModel(), IOnItemClickListener {
|
|||||||
* 获取列表数据
|
* 获取列表数据
|
||||||
*/
|
*/
|
||||||
override fun getData() {
|
override fun getData() {
|
||||||
// 构建筛选参数
|
// 构建筛选参数(只传递非空值)
|
||||||
val filterParams = mapOf(
|
val filterParams = mutableMapOf<String, Any>()
|
||||||
"awbType" to awbType.value.noNull(),
|
|
||||||
"by1" to by1.value.noNull(),
|
awbType.value?.takeIf { it.isNotEmpty() }?.let { filterParams["awbType"] = it }
|
||||||
"dest1" to dest1.value.noNull(),
|
by1.value?.takeIf { it.isNotEmpty() }?.let { filterParams["by1"] = it }
|
||||||
"moveState" to moveState.value.noNull(),
|
dest1.value?.takeIf { it.isNotEmpty() }?.let { filterParams["dest1"] = it }
|
||||||
"likeNo" to waybillNo.value.noNull()
|
moveState.value?.takeIf { it.isNotEmpty() }?.let { filterParams["moveState"] = it }
|
||||||
)
|
waybillNo.value?.takeIf { it.isNotEmpty() }?.let { filterParams["wbNo"] = it }
|
||||||
|
|
||||||
// 列表参数(含分页)
|
// 列表参数(含分页)
|
||||||
val listParams = (filterParams + mapOf(
|
val listParams = (filterParams + mapOf(
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -17,6 +18,8 @@ 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.common.DateUtils
|
||||||
|
import com.lukouguoji.module_base.ktx.formatDate
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,7 +28,7 @@ import kotlinx.coroutines.launch
|
|||||||
class IntExpOutHandoverViewModel : BasePageViewModel() {
|
class IntExpOutHandoverViewModel : BasePageViewModel() {
|
||||||
|
|
||||||
// ========== 搜索条件 ==========
|
// ========== 搜索条件 ==========
|
||||||
val flightDate = MutableLiveData("") // 航班日期
|
val flightDate = MutableLiveData<String>(DateUtils.getCurrentTime().formatDate()) // 航班日期
|
||||||
val flightNo = MutableLiveData("") // 航班号
|
val flightNo = MutableLiveData("") // 航班号
|
||||||
val fdest = MutableLiveData("") // 目的站
|
val fdest = MutableLiveData("") // 目的站
|
||||||
val uldNo = MutableLiveData("") // ULD编号
|
val uldNo = MutableLiveData("") // ULD编号
|
||||||
@@ -103,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)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,342 @@
|
|||||||
|
package com.lukouguoji.gjc.viewModel
|
||||||
|
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.lukouguoji.gjc.R
|
||||||
|
import com.lukouguoji.gjc.holder.IntExpStorageUseViewHolder
|
||||||
|
import com.lukouguoji.module_base.base.BasePageViewModel
|
||||||
|
import com.lukouguoji.module_base.bean.GjcMaWb
|
||||||
|
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.commonAdapter
|
||||||
|
import com.lukouguoji.module_base.ktx.formatDate
|
||||||
|
import com.lukouguoji.module_base.ktx.launchCollect
|
||||||
|
import com.lukouguoji.module_base.ktx.launchLoadingCollect
|
||||||
|
import com.lukouguoji.module_base.ktx.noNull
|
||||||
|
import com.lukouguoji.module_base.ktx.showToast
|
||||||
|
import com.lukouguoji.module_base.ktx.toRequestBody
|
||||||
|
import com.lukouguoji.module_base.model.ScanModel
|
||||||
|
import dev.utils.app.info.KeyValue
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import java.util.Date
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际出港-仓库 ViewModel
|
||||||
|
*/
|
||||||
|
class IntExpStorageUseViewModel : BasePageViewModel() {
|
||||||
|
|
||||||
|
// ========== 筛选条件 ==========
|
||||||
|
val flightDate = MutableLiveData(Date().formatDate()) // 航班日期,默认今天
|
||||||
|
val flightNo = MutableLiveData("") // 航班号
|
||||||
|
val clearResult = MutableLiveData("") // 清仓综合结果
|
||||||
|
val clearResultList = MutableLiveData<List<KeyValue>>() // 清仓综合结果列表
|
||||||
|
val wbNo = MutableLiveData("") // 运单号
|
||||||
|
val location = MutableLiveData("") // 库位号
|
||||||
|
|
||||||
|
// ========== 统计信息 ==========
|
||||||
|
val totalWbNumber = MutableLiveData("0") // 总票数
|
||||||
|
val totalPc = MutableLiveData("0") // 总件数
|
||||||
|
val totalWeight = MutableLiveData("0") // 总重量
|
||||||
|
|
||||||
|
// ========== 全选状态 ==========
|
||||||
|
val isAllChecked = MutableLiveData(false)
|
||||||
|
|
||||||
|
// ========== 全局展开状态 ==========
|
||||||
|
/**
|
||||||
|
* 全局展开状态
|
||||||
|
* - true: 全部展开
|
||||||
|
* - false: 全部收起
|
||||||
|
*/
|
||||||
|
val isAllExpanded = MutableLiveData(false)
|
||||||
|
|
||||||
|
init {
|
||||||
|
// 初始化清仓综合结果列表(根据实际需求配置)
|
||||||
|
clearResultList.value = listOf(
|
||||||
|
KeyValue("全部", ""),
|
||||||
|
KeyValue("正常", "0"),
|
||||||
|
KeyValue("异常", "1")
|
||||||
|
)
|
||||||
|
|
||||||
|
// 监听全选状态,自动更新所有列表项
|
||||||
|
isAllChecked.observeForever { checked ->
|
||||||
|
val list =
|
||||||
|
pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return@observeForever
|
||||||
|
list.forEach { it.checked.set(checked) }
|
||||||
|
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== 适配器配置 ==========
|
||||||
|
val itemViewHolder = IntExpStorageUseViewHolder::class.java
|
||||||
|
val itemLayoutId = R.layout.item_int_exp_storage_use
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索按钮点击
|
||||||
|
*/
|
||||||
|
fun searchClick() {
|
||||||
|
refresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全选按钮点击(联动勾选所有子列表项)
|
||||||
|
*/
|
||||||
|
fun checkAllClick() {
|
||||||
|
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return
|
||||||
|
|
||||||
|
val shouldCheckAll = !isAllChecked.value!!
|
||||||
|
|
||||||
|
// 联动勾选/取消主列表和子列表
|
||||||
|
list.forEach { maWb ->
|
||||||
|
maWb.checked.set(shouldCheckAll)
|
||||||
|
// 同时联动勾选/取消所有子列表项
|
||||||
|
maWb.storageUseList?.forEach { storageUse ->
|
||||||
|
storageUse.checked.set(shouldCheckAll)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isAllChecked.value = shouldCheckAll
|
||||||
|
|
||||||
|
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换全局展开/收起状态
|
||||||
|
*/
|
||||||
|
fun toggleAllExpand() {
|
||||||
|
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return
|
||||||
|
|
||||||
|
// 切换全局状态
|
||||||
|
val shouldExpand = !isAllExpanded.value!!
|
||||||
|
isAllExpanded.value = shouldExpand
|
||||||
|
|
||||||
|
// 更新所有列表项的 showMore 状态
|
||||||
|
list.forEach { bean ->
|
||||||
|
// 只有当有子列表时才设置展开状态
|
||||||
|
if (!bean.storageUseList.isNullOrEmpty()) {
|
||||||
|
bean.showMore.set(shouldExpand)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新列表UI
|
||||||
|
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扫码运单号
|
||||||
|
*/
|
||||||
|
fun scanWbNo() {
|
||||||
|
ScanModel.startScan(getTopActivity(), Constant.RequestCode.WAYBILL)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清仓操作(在Activity中调用,会显示对话框)
|
||||||
|
*/
|
||||||
|
fun clearStorage() {
|
||||||
|
// 由Activity显示对话框
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行清仓操作
|
||||||
|
* @param clearNormal 清仓正常("0"或"1")
|
||||||
|
* @param maWbListForClear 包含选中子列表项的主列表数据
|
||||||
|
*/
|
||||||
|
fun performClear(clearNormal: String, maWbListForClear: List<GjcMaWb>) {
|
||||||
|
if (maWbListForClear.isEmpty()) {
|
||||||
|
showToast("请至少选择一个库位")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建请求参数:完整的主子列表结构
|
||||||
|
val params = mapOf(
|
||||||
|
"clearNormal" to clearNormal,
|
||||||
|
"maWbList" to maWbListForClear
|
||||||
|
).toRequestBody()
|
||||||
|
|
||||||
|
launchLoadingCollect({ NetApply.api.clearIntExpStorage(params) }) {
|
||||||
|
onSuccess = {
|
||||||
|
showToast("清仓成功")
|
||||||
|
viewModelScope.launch {
|
||||||
|
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
|
||||||
|
}
|
||||||
|
refresh() // 刷新列表
|
||||||
|
}
|
||||||
|
onFailed = { _, msg ->
|
||||||
|
showToast(msg.noNull("清仓失败"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改库位
|
||||||
|
*/
|
||||||
|
fun modifyStorage() {
|
||||||
|
// 由Activity显示对话框
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行修改库位操作
|
||||||
|
* @param locationName 新的库位名称 (后端的location字段)
|
||||||
|
* @param locationId 新的库位ID (后端的locationId字段)
|
||||||
|
* @param storageUse 选中的单个库位使用对象
|
||||||
|
*/
|
||||||
|
fun performModifyStorage(
|
||||||
|
locationName: String,
|
||||||
|
locationId: String,
|
||||||
|
storageUse: com.lukouguoji.module_base.bean.GjcStorageUse
|
||||||
|
) {
|
||||||
|
if (locationName.isEmpty() || locationId.isEmpty()) {
|
||||||
|
showToast("请选择库位")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建更新后的库位对象(覆盖 location 和 locationId 字段)
|
||||||
|
val updatedStorage = storageUse.copy(
|
||||||
|
location = locationName,
|
||||||
|
locationId = locationId.toLongOrNull() ?: 0
|
||||||
|
)
|
||||||
|
|
||||||
|
// 直接使用更新后的对象构建请求参数
|
||||||
|
val params = updatedStorage.toRequestBody()
|
||||||
|
|
||||||
|
launchLoadingCollect({ NetApply.api.modifyIntExpStorage(params) }) {
|
||||||
|
onSuccess = {
|
||||||
|
showToast("修改库位成功")
|
||||||
|
viewModelScope.launch {
|
||||||
|
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
|
||||||
|
}
|
||||||
|
refresh() // 刷新列表
|
||||||
|
}
|
||||||
|
onFailed = { _, msg ->
|
||||||
|
showToast(msg.noNull("修改库位失败"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 出库操作(在Activity中调用,会显示二次确认对话框)
|
||||||
|
*/
|
||||||
|
fun outStorage() {
|
||||||
|
// 由Activity显示二次确认对话框
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行出库操作
|
||||||
|
* @param selectedStorageList 选中的子列表项(库位)
|
||||||
|
*/
|
||||||
|
fun performOutStorage(selectedStorageList: List<com.lukouguoji.module_base.bean.GjcStorageUse>) {
|
||||||
|
if (selectedStorageList.isEmpty()) {
|
||||||
|
showToast("请选择要出库的库位")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将选中的子列表项转换为RequestBody
|
||||||
|
val params = selectedStorageList.toRequestBody()
|
||||||
|
|
||||||
|
launchLoadingCollect({ NetApply.api.outIntExpStorage(params) }) {
|
||||||
|
onSuccess = {
|
||||||
|
showToast("出库成功")
|
||||||
|
viewModelScope.launch {
|
||||||
|
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
|
||||||
|
}
|
||||||
|
refresh() // 刷新列表
|
||||||
|
}
|
||||||
|
onFailed = { _, msg ->
|
||||||
|
showToast(msg.noNull("出库失败"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 入库操作
|
||||||
|
*/
|
||||||
|
fun inStorage() {
|
||||||
|
// 由Activity显示对话框
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行入库操作
|
||||||
|
* @param locationName 库位名称 (后端的location字段)
|
||||||
|
* @param locationId 库位ID (后端的locationId字段)
|
||||||
|
* @param maWbListForInStorage 包含选中子列表项的主列表数据
|
||||||
|
*/
|
||||||
|
fun performInStorage(
|
||||||
|
locationName: String,
|
||||||
|
locationId: String,
|
||||||
|
maWbListForInStorage: List<GjcMaWb>
|
||||||
|
) {
|
||||||
|
if (maWbListForInStorage.isEmpty()) {
|
||||||
|
showToast("请至少选择一个单据")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (locationName.isEmpty() || locationId.isEmpty()) {
|
||||||
|
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("入库失败"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取数据 (重写BasePageViewModel)
|
||||||
|
*/
|
||||||
|
override fun getData() {
|
||||||
|
// 构建搜索条件
|
||||||
|
val filterParams = mapOf(
|
||||||
|
"fdate" to flightDate.value?.ifEmpty { null },
|
||||||
|
"fno" to flightNo.value?.ifEmpty { null },
|
||||||
|
"wbNo" to wbNo.value?.ifEmpty { null },
|
||||||
|
"location" to location.value?.ifEmpty { null }
|
||||||
|
)
|
||||||
|
|
||||||
|
// 列表参数 (含分页)
|
||||||
|
val listParams = (filterParams + mapOf(
|
||||||
|
"pageNum" to pageModel.page,
|
||||||
|
"pageSize" to pageModel.limit
|
||||||
|
)).toRequestBody()
|
||||||
|
|
||||||
|
// 统计参数 (无分页)
|
||||||
|
val totalParams = filterParams.toRequestBody()
|
||||||
|
|
||||||
|
// 获取列表 (带Loading)
|
||||||
|
launchLoadingCollect({ NetApply.api.getIntExpStorageUseList(listParams) }) {
|
||||||
|
onSuccess = { result ->
|
||||||
|
// 手动处理 PageInfo 数据
|
||||||
|
pageModel.handleDataList(result.list)
|
||||||
|
pageModel.haveMore.postValue((result.pages) > pageModel.page)
|
||||||
|
// 数据加载完成后,重置全局展开状态为收起
|
||||||
|
isAllExpanded.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取统计信息 (后台请求,不阻塞列表)
|
||||||
|
launchCollect({ NetApply.api.getIntExpStorageUseTotal(totalParams) }) {
|
||||||
|
onSuccess = { result ->
|
||||||
|
val data = result.data
|
||||||
|
totalWbNumber.value = (data?.wbNumber ?: 0).toString()
|
||||||
|
totalPc.value = (data?.totalPc ?: 0).toString()
|
||||||
|
totalWeight.value = (data?.totalWeight ?: 0.0).toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -19,6 +21,8 @@ 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.common.DateUtils
|
||||||
|
import com.lukouguoji.module_base.ktx.formatDate
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,7 +31,7 @@ import kotlinx.coroutines.launch
|
|||||||
class IntExpTallyViewModel : BasePageViewModel() {
|
class IntExpTallyViewModel : BasePageViewModel() {
|
||||||
|
|
||||||
// ========== 搜索条件 ==========
|
// ========== 搜索条件 ==========
|
||||||
val flightDate = MutableLiveData("") // 航班日期
|
val flightDate = MutableLiveData<String>(DateUtils.getCurrentTime().formatDate()) // 航班日期
|
||||||
val flightNo = MutableLiveData("") // 航班号
|
val flightNo = MutableLiveData("") // 航班号
|
||||||
val waybillNo = MutableLiveData("") // 运单号
|
val waybillNo = MutableLiveData("") // 运单号
|
||||||
val houseWaybillNo = MutableLiveData("") // 分单号
|
val houseWaybillNo = MutableLiveData("") // 分单号
|
||||||
@@ -40,6 +44,14 @@ class IntExpTallyViewModel : BasePageViewModel() {
|
|||||||
// ========== 全选状态 ==========
|
// ========== 全选状态 ==========
|
||||||
val isAllChecked = MutableLiveData(false)
|
val isAllChecked = MutableLiveData(false)
|
||||||
|
|
||||||
|
// ========== 全局展开状态 ==========
|
||||||
|
/**
|
||||||
|
* 全局展开状态
|
||||||
|
* - true: 全部展开
|
||||||
|
* - false: 全部收起
|
||||||
|
*/
|
||||||
|
val isAllExpanded = MutableLiveData(false)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
// 监听全选状态,自动更新所有列表项
|
// 监听全选状态,自动更新所有列表项
|
||||||
isAllChecked.observeForever { checked ->
|
isAllChecked.observeForever { checked ->
|
||||||
@@ -61,12 +73,12 @@ 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 { it.checked.set(shouldCheckAll) }
|
||||||
isAllChecked.value = shouldCheckAll
|
isAllChecked.value = shouldCheckAll
|
||||||
@@ -74,6 +86,28 @@ class IntExpTallyViewModel : BasePageViewModel() {
|
|||||||
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
|
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换全局展开/收起状态
|
||||||
|
*/
|
||||||
|
fun toggleAllExpand() {
|
||||||
|
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return
|
||||||
|
|
||||||
|
// 切换全局状态
|
||||||
|
val shouldExpand = !isAllExpanded.value!!
|
||||||
|
isAllExpanded.value = shouldExpand
|
||||||
|
|
||||||
|
// 更新所有列表项的 showMore 状态
|
||||||
|
list.forEach { bean ->
|
||||||
|
// 只有当有子列表时才设置展开状态
|
||||||
|
if (!bean.haWbList.isNullOrEmpty()) {
|
||||||
|
bean.showMore.set(shouldExpand)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刷新列表UI
|
||||||
|
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 扫码运单号
|
* 扫码运单号
|
||||||
*/
|
*/
|
||||||
@@ -93,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 = {
|
||||||
@@ -143,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
|
||||||
}
|
}
|
||||||
@@ -157,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()
|
||||||
@@ -192,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 },
|
||||||
no = 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
|
||||||
@@ -205,13 +309,17 @@ 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 },
|
||||||
no = waybillNo.value?.ifEmpty { null },
|
wbNo = waybillNo.value?.ifEmpty { null },
|
||||||
hno = houseWaybillNo.value?.ifEmpty { null }
|
hno = houseWaybillNo.value?.ifEmpty { null }
|
||||||
).toRequestBody()
|
).toRequestBody()
|
||||||
|
|
||||||
// 获取列表 (带Loading)
|
// 获取列表 (带Loading)
|
||||||
launchLoadingCollect({ NetApply.api.getIntExpTallyList(listParams) }) {
|
launchLoadingCollect({ NetApply.api.getIntExpTallyList(listParams) }) {
|
||||||
onSuccess = { pageModel.handleListBean(it) }
|
onSuccess = {
|
||||||
|
pageModel.handleListBean(it)
|
||||||
|
// 数据加载完成后,重置全局展开状态为收起
|
||||||
|
isAllExpanded.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取统计信息 (后台请求,不阻塞列表)
|
// 获取统计信息 (后台请求,不阻塞列表)
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
BIN
module_gjc/src/main/res/drawable-mdpi/img_gjc_shouyunjiancha.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
module_gjc/src/main/res/drawable-mdpi/img_gjc_zuzhuangfenpei.png
Normal file
|
After Width: | Height: | Size: 28 KiB |