feat: 开始组装 opt
This commit is contained in:
@@ -39,6 +39,9 @@ class AssembleInfoBean {
|
|||||||
// 原始运单数据(用于同步更新和填充表单)
|
// 原始运单数据(用于同步更新和填充表单)
|
||||||
var waybillData: AssembleWaybillBean? = null
|
var waybillData: AssembleWaybillBean? = null
|
||||||
|
|
||||||
|
// 关联的原始数据(用于存储GjcUldUseBean等对象)
|
||||||
|
var tag: Any? = null
|
||||||
|
|
||||||
// ========== 视觉样式字段 ==========
|
// ========== 视觉样式字段 ==========
|
||||||
var hasArrow: Boolean = false // 是否显示箭头(一级ULD行为true)
|
var hasArrow: Boolean = false // 是否显示箭头(一级ULD行为true)
|
||||||
var isOrange: Boolean = false // 是否橙色文字(暂保留)
|
var isOrange: Boolean = false // 是否橙色文字(暂保留)
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.lukouguoji.module_base.bean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际出港组装记录Bean
|
||||||
|
* 对应API: /IntExpAssemble/queryAssembled
|
||||||
|
*/
|
||||||
|
class GjcAssembled {
|
||||||
|
var uldUse: GjcUldUseBean? = null // ULD信息
|
||||||
|
var warehouseList: MutableList<GjcWarehouse>? = null // 运单列表
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ import com.lukouguoji.module_base.bean.FlightBean
|
|||||||
import com.lukouguoji.module_base.bean.FlightFilterBean
|
import com.lukouguoji.module_base.bean.FlightFilterBean
|
||||||
import com.lukouguoji.module_base.bean.GbCarOrUldBean
|
import com.lukouguoji.module_base.bean.GbCarOrUldBean
|
||||||
import com.lukouguoji.module_base.bean.GjcAssembleAllocate
|
import com.lukouguoji.module_base.bean.GjcAssembleAllocate
|
||||||
|
import com.lukouguoji.module_base.bean.GjcAssembled
|
||||||
import com.lukouguoji.module_base.bean.GjcBoxAddInsertBean
|
import com.lukouguoji.module_base.bean.GjcBoxAddInsertBean
|
||||||
import com.lukouguoji.module_base.bean.GjcBoxAssembleBean
|
import com.lukouguoji.module_base.bean.GjcBoxAssembleBean
|
||||||
import com.lukouguoji.module_base.bean.GjcBoxDetailsBean
|
import com.lukouguoji.module_base.bean.GjcBoxDetailsBean
|
||||||
@@ -628,6 +629,25 @@ interface Api {
|
|||||||
@POST("IntExpAssemble/assemble")
|
@POST("IntExpAssemble/assemble")
|
||||||
suspend fun assembleLoadCargo(@Body data: RequestBody): BaseResultBean<GjcWarehouse>
|
suspend fun assembleLoadCargo(@Body data: RequestBody): BaseResultBean<GjcWarehouse>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际出港组装 - 查询已组装的ULD列表
|
||||||
|
* 接口路径: /IntExpAssemble/queryAssembled
|
||||||
|
* @param data 请求参数:fno(航班号,必填)、fdate(航班日期,必填)、
|
||||||
|
* loadArea(组装位置,必填)、uld(ULD编号,可选)
|
||||||
|
* @return 返回已组装的ULD列表(包含ULD信息和运单列表)
|
||||||
|
*/
|
||||||
|
@POST("IntExpAssemble/queryAssembled")
|
||||||
|
suspend fun getAssembledList(@Body data: RequestBody): BaseResultBean<List<GjcAssembled>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国际出港组装 - 根据ULD查询已组装的运单列表
|
||||||
|
* 接口路径: /IntExpAssemble/queryAssembledByUld
|
||||||
|
* @param data 请求参数:GjcUldUseBean对象(包含useId、uld等信息)
|
||||||
|
* @return 返回该ULD下的运单列表
|
||||||
|
*/
|
||||||
|
@POST("IntExpAssemble/queryAssembledByUld")
|
||||||
|
suspend fun getAssembledWaybillsByUld(@Body data: RequestBody): BaseResultBean<List<GjcWarehouse>>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 国际出港出库交接-分页查询
|
* 国际出港出库交接-分页查询
|
||||||
* 接口路径: /IntExpOutHandover/pageQuery
|
* 接口路径: /IntExpOutHandover/pageQuery
|
||||||
|
|||||||
@@ -24,6 +24,14 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
|
|
||||||
// ========== 搜索条件 ==========
|
// ========== 搜索条件 ==========
|
||||||
val searchText = MutableLiveData("")
|
val searchText = MutableLiveData("")
|
||||||
|
val uldSearchText = MutableLiveData("") // ULD搜索框
|
||||||
|
|
||||||
|
// ========== 组装参数(从选中运单自动提取)==========
|
||||||
|
val assembleFlightNo = MutableLiveData("") // 航班号
|
||||||
|
val assembleFlightDate = MutableLiveData("") // 航班日期
|
||||||
|
|
||||||
|
// ========== 防抖标记 ==========
|
||||||
|
private var lastQueriedAssembledParams = "" // 避免重复查询
|
||||||
|
|
||||||
// ========== 左侧组装信息列表 ==========
|
// ========== 左侧组装信息列表 ==========
|
||||||
val assembleInfoList = MutableLiveData<MutableList<AssembleInfoBean>>()
|
val assembleInfoList = MutableLiveData<MutableList<AssembleInfoBean>>()
|
||||||
@@ -55,27 +63,6 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
// ========== 标记位,避免重复查询 ==========
|
// ========== 标记位,避免重复查询 ==========
|
||||||
private var lastQueriedUldNo = ""
|
private var lastQueriedUldNo = ""
|
||||||
|
|
||||||
// ========== 本地存储(页面生命周期内)==========
|
|
||||||
/**
|
|
||||||
* 已组装货物的本地存储
|
|
||||||
* Key: ULD编号
|
|
||||||
* Value: 该ULD下的运单列表
|
|
||||||
*/
|
|
||||||
private val assembledCargoMap = mutableMapOf<String, MutableList<AssembleWaybillBean>>()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 扁平化的组装信息列表(包含一级和二级行)
|
|
||||||
* 用于RecyclerView显示
|
|
||||||
*/
|
|
||||||
private val flatAssembleInfoList = mutableListOf<AssembleInfoBean>()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 编辑模式标记
|
|
||||||
* null: 新增模式
|
|
||||||
* 非null: 编辑模式,存储原始ULD编号和运单号
|
|
||||||
*/
|
|
||||||
private var editMode: Pair<String, String>? = null // Pair<ULD编号, 运单号>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ULD编号锁定状态
|
* ULD编号锁定状态
|
||||||
*/
|
*/
|
||||||
@@ -122,6 +109,9 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
|
|
||||||
// 刷新列表
|
// 刷新列表
|
||||||
assemblePositionList.value = list
|
assemblePositionList.value = list
|
||||||
|
|
||||||
|
// 触发组装信息列表查询
|
||||||
|
loadAssembledList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -143,6 +133,10 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
if (selectedWaybill != null) {
|
if (selectedWaybill != null) {
|
||||||
selectedWaybill.isSelected.set(true)
|
selectedWaybill.isSelected.set(true)
|
||||||
|
|
||||||
|
// 自动提取航班号和航班日期
|
||||||
|
assembleFlightNo.value = selectedWaybill.fno
|
||||||
|
assembleFlightDate.value = selectedWaybill.fdate
|
||||||
|
|
||||||
// 保存当前的组装人(始终保留)
|
// 保存当前的组装人(始终保留)
|
||||||
val previousOperator = waybillInfo.value?.operator ?: ""
|
val previousOperator = waybillInfo.value?.operator ?: ""
|
||||||
|
|
||||||
@@ -155,11 +149,8 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
previousAssembleCount = ""
|
previousAssembleCount = ""
|
||||||
previousAssembleWeight = ""
|
previousAssembleWeight = ""
|
||||||
|
|
||||||
// 如果在编辑模式,退出编辑模式并解锁 ULD
|
// 解锁ULD编号
|
||||||
if (editMode != null) {
|
|
||||||
editMode = null
|
|
||||||
isUldNoLocked.value = false
|
isUldNoLocked.value = false
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// 同一个运单:保留组装件数和组装重量
|
// 同一个运单:保留组装件数和组装重量
|
||||||
previousAssembleCount = waybillInfo.value?.assembleCount ?: ""
|
previousAssembleCount = waybillInfo.value?.assembleCount ?: ""
|
||||||
@@ -179,6 +170,12 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
|
|
||||||
// 刷新列表
|
// 刷新列表
|
||||||
waybillList.value = list
|
waybillList.value = list
|
||||||
|
|
||||||
|
// 清除防抖标记,强制重新查询组装信息列表
|
||||||
|
lastQueriedAssembledParams = ""
|
||||||
|
|
||||||
|
// 触发组装信息列表查询
|
||||||
|
loadAssembledList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -226,14 +223,11 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
if (currentWaybillNo.isNotEmpty()) {
|
if (currentWaybillNo.isNotEmpty()) {
|
||||||
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 = waybillInfo.value?.operator ?: ""
|
||||||
waybillInfo.value = WaybillInfoBean().apply {
|
waybillInfo.value = WaybillInfoBean().apply {
|
||||||
operator = previousOperator
|
operator = previousOperator
|
||||||
}
|
}
|
||||||
if (editMode != null) {
|
|
||||||
editMode = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,14 +272,11 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
if (currentWaybillNo.isNotEmpty()) {
|
if (currentWaybillNo.isNotEmpty()) {
|
||||||
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 = waybillInfo.value?.operator ?: ""
|
||||||
waybillInfo.value = WaybillInfoBean().apply {
|
waybillInfo.value = WaybillInfoBean().apply {
|
||||||
operator = previousOperator
|
operator = previousOperator
|
||||||
}
|
}
|
||||||
if (editMode != null) {
|
|
||||||
editMode = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,35 +420,18 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. 获取或构建运单Bean
|
// 2. 获取或构建运单Bean
|
||||||
val selectedWaybill: AssembleWaybillBean = if (editMode != null) {
|
// 从运单列表中获取选中的运单
|
||||||
// 编辑模式:从本地存储中获取运单数据
|
|
||||||
val uldNoInEdit = editMode!!.first
|
|
||||||
val waybillNoInEdit = editMode!!.second
|
|
||||||
val storedList = assembledCargoMap[uldNoInEdit]
|
|
||||||
val storedWaybill = storedList?.firstOrNull { it.waybillNo == waybillNoInEdit }
|
|
||||||
|
|
||||||
if (storedWaybill == null) {
|
|
||||||
showToast("未找到运单数据")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用存储的运单数据(包含原始件数/重量和其他字段)
|
|
||||||
storedWaybill
|
|
||||||
} else {
|
|
||||||
// 新增模式:从运单列表中获取选中的运单
|
|
||||||
val currentWaybillList = waybillList.value
|
val currentWaybillList = waybillList.value
|
||||||
if (currentWaybillList == null) {
|
if (currentWaybillList == null) {
|
||||||
showToast("运单列表为空")
|
showToast("运单列表为空")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val selected = currentWaybillList.firstOrNull { it.isSelected.get() }
|
val selectedWaybill = currentWaybillList.firstOrNull { it.isSelected.get() }
|
||||||
if (selected == null) {
|
if (selectedWaybill == null) {
|
||||||
showToast("请选择运单")
|
showToast("请选择运单")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
selected
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 构建useInfo(ULD信息)
|
// 3. 构建useInfo(ULD信息)
|
||||||
val useInfo = mapOf(
|
val useInfo = mapOf(
|
||||||
@@ -472,13 +446,13 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 4. 构建wbInfo(运单信息)
|
// 4. 构建wbInfo(运单信息)
|
||||||
// 如果是编辑模式,使用原始运单件数/重量;否则使用当前件数/重量
|
// 使用原始运单件数/重量(如果有),否则使用当前件数/重量
|
||||||
val waybillPc = if (editMode != null && selectedWaybill.originalPieces.isNotEmpty()) {
|
val waybillPc = if (selectedWaybill.originalPieces.isNotEmpty()) {
|
||||||
selectedWaybill.originalPieces.toLongOrNull()
|
selectedWaybill.originalPieces.toLongOrNull()
|
||||||
} else {
|
} else {
|
||||||
selectedWaybill.pieces.toLongOrNull()
|
selectedWaybill.pieces.toLongOrNull()
|
||||||
}
|
}
|
||||||
val waybillWeight = if (editMode != null && selectedWaybill.originalWeight.isNotEmpty()) {
|
val waybillWeight = if (selectedWaybill.originalWeight.isNotEmpty()) {
|
||||||
selectedWaybill.originalWeight.toDoubleOrNull()
|
selectedWaybill.originalWeight.toDoubleOrNull()
|
||||||
} else {
|
} else {
|
||||||
selectedWaybill.weight.toDoubleOrNull()
|
selectedWaybill.weight.toDoubleOrNull()
|
||||||
@@ -505,12 +479,9 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
"userId" to SharedPreferenceUtil.getString(Constant.Share.account)
|
"userId" to SharedPreferenceUtil.getString(Constant.Share.account)
|
||||||
).toRequestBody()
|
).toRequestBody()
|
||||||
|
|
||||||
// 6. 立即同步到组装信息列表(不等接口成功)
|
// 6. 调用接口(带Loading,等待接口返回)
|
||||||
val operationName = if (isLoad) "装货" else "卸货"
|
val operationName = if (isLoad) "装货" else "卸货"
|
||||||
handleOperationSuccess(operationName, isLoad, uldNo, selectedWaybill, assembleCount, assembleWeight)
|
launchLoadingCollect({
|
||||||
|
|
||||||
// 7. 调用接口(后台执行,不阻塞UI)
|
|
||||||
launchCollect({
|
|
||||||
if (isLoad) {
|
if (isLoad) {
|
||||||
NetApply.api.assembleLoadCargo(params)
|
NetApply.api.assembleLoadCargo(params)
|
||||||
} else {
|
} else {
|
||||||
@@ -518,10 +489,11 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
}
|
}
|
||||||
}) {
|
}) {
|
||||||
onSuccess = { result ->
|
onSuccess = { result ->
|
||||||
// 接口成功,无需额外操作(已经同步到本地)
|
// 接口成功后才显示成功提示并刷新列表
|
||||||
|
handleOperationSuccess(operationName, isLoad, uldNo, selectedWaybill, assembleCount, assembleWeight)
|
||||||
}
|
}
|
||||||
onFailed = { code, message ->
|
onFailed = { code, message ->
|
||||||
showToast("${operationName}接口调用失败: $message(数据已保存到本地)")
|
showToast("${operationName}失败: $message")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -539,37 +511,8 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
) {
|
) {
|
||||||
showToast("${operationName}成功")
|
showToast("${operationName}成功")
|
||||||
|
|
||||||
// 创建一个包含本次操作件数和重量的运单Bean
|
// 重新查询组装信息列表(刷新数据)
|
||||||
val assembleWaybill = AssembleWaybillBean()
|
loadAssembledList()
|
||||||
assembleWaybill.waybillNo = selectedWaybill.waybillNo
|
|
||||||
assembleWaybill.pieces = assembleCount // 本次操作的件数
|
|
||||||
assembleWaybill.weight = assembleWeight // 本次操作的重量
|
|
||||||
assembleWaybill.flight = selectedWaybill.flight
|
|
||||||
assembleWaybill.fno = selectedWaybill.fno
|
|
||||||
assembleWaybill.fdate = selectedWaybill.fdate
|
|
||||||
assembleWaybill.whId = selectedWaybill.whId
|
|
||||||
assembleWaybill.isMarked = selectedWaybill.isMarked
|
|
||||||
|
|
||||||
// 保存原始运单件数/重量(用于编辑模式回显)
|
|
||||||
assembleWaybill.originalPieces = selectedWaybill.originalPieces.ifEmpty { selectedWaybill.pieces }
|
|
||||||
assembleWaybill.originalWeight = selectedWaybill.originalWeight.ifEmpty { selectedWaybill.weight }
|
|
||||||
|
|
||||||
// 判断是新增还是编辑模式
|
|
||||||
if (editMode != null) {
|
|
||||||
// 编辑模式:更新本地存储中的对应运单
|
|
||||||
updateAssembledCargoInLocal(
|
|
||||||
uldNo = editMode!!.first,
|
|
||||||
oldWaybillNo = editMode!!.second,
|
|
||||||
newWaybillBean = assembleWaybill,
|
|
||||||
isLoad = isLoad
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
// 新增模式:添加到本地存储
|
|
||||||
addAssembledCargoToLocal(uldNo, assembleWaybill, isLoad)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 同步刷新组装信息列表
|
|
||||||
syncAssembleInfoListFromLocal()
|
|
||||||
|
|
||||||
// 刷新运单列表
|
// 刷新运单列表
|
||||||
loadInitialWaitingAssemble()
|
loadInitialWaitingAssemble()
|
||||||
@@ -578,84 +521,13 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
clearForm()
|
clearForm()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 从本地存储同步组装信息列表
|
|
||||||
* 1. 遍历 assembledCargoMap,为每个 ULD 生成一级行
|
|
||||||
* 2. 计算总件数/总重量(求和子运单)
|
|
||||||
* 3. 根据展开状态决定是否添加二级运单行
|
|
||||||
* 4. 更新 LiveData 触发 UI 刷新
|
|
||||||
*/
|
|
||||||
private fun syncAssembleInfoListFromLocal() {
|
|
||||||
// 记录当前展开状态(避免刷新后展开状态丢失)
|
|
||||||
val expandedUlds = flatAssembleInfoList
|
|
||||||
.filter { it.itemType == AssembleInfoBean.ItemType.ULD_HEADER && it.isExpanded.get() }
|
|
||||||
.map { it.uldNo }
|
|
||||||
.toSet()
|
|
||||||
|
|
||||||
flatAssembleInfoList.clear()
|
|
||||||
|
|
||||||
// 遍历每个 ULD(带序号)
|
|
||||||
var uldIndex = 1
|
|
||||||
assembledCargoMap.forEach { (uldNo, waybillList) ->
|
|
||||||
// 计算总件数和总重量
|
|
||||||
var totalPieces = 0
|
|
||||||
var totalWeight = 0.0
|
|
||||||
waybillList.forEach { waybill ->
|
|
||||||
totalPieces += waybill.pieces.toIntOrNull() ?: 0
|
|
||||||
totalWeight += waybill.weight.toDoubleOrNull() ?: 0.0
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建一级 ULD 行
|
|
||||||
val uldHeader = AssembleInfoBean().apply {
|
|
||||||
itemType = AssembleInfoBean.ItemType.ULD_HEADER
|
|
||||||
this.uldNo = uldNo
|
|
||||||
this.uldIndex = uldIndex
|
|
||||||
this.totalPieces = totalPieces
|
|
||||||
this.totalWeight = totalWeight
|
|
||||||
hasArrow = true
|
|
||||||
showIndex = true // 显示序号
|
|
||||||
|
|
||||||
// 恢复展开状态
|
|
||||||
isExpanded.set(expandedUlds.contains(uldNo))
|
|
||||||
|
|
||||||
// 保存子运单(用于展开/折叠)
|
|
||||||
waybillChildren = waybillList.map { waybill ->
|
|
||||||
AssembleInfoBean().apply {
|
|
||||||
itemType = AssembleInfoBean.ItemType.WAYBILL_DETAIL
|
|
||||||
parentUldNo = uldNo
|
|
||||||
wbNo = waybill.waybillNo
|
|
||||||
waybillPieces = waybill.pieces.toIntOrNull() ?: 0
|
|
||||||
waybillWeight = waybill.weight.toDoubleOrNull() ?: 0.0
|
|
||||||
waybillData = waybill
|
|
||||||
showIndent = true
|
|
||||||
showIndex = false
|
|
||||||
}
|
|
||||||
}.toMutableList()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加一级行
|
|
||||||
flatAssembleInfoList.add(uldHeader)
|
|
||||||
|
|
||||||
// 如果展开,添加二级运单行
|
|
||||||
if (uldHeader.isExpanded.get()) {
|
|
||||||
flatAssembleInfoList.addAll(uldHeader.waybillChildren)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 递增序号
|
|
||||||
uldIndex++
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新 LiveData
|
|
||||||
assembleInfoList.value = flatAssembleInfoList.toMutableList()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 组装信息列表点击事件
|
* 组装信息列表点击事件
|
||||||
* 1. 点击一级 ULD 行:切换展开/折叠状态
|
* 1. 点击一级ULD行:展开/折叠(按需加载运单列表)
|
||||||
* 2. 点击二级运单行:进入编辑模式,填充表单
|
* 2. 点击二级运单行:填充表单(编辑模式)
|
||||||
*/
|
*/
|
||||||
fun onAssembleInfoItemClick(position: Int) {
|
fun onAssembleInfoItemClick(position: Int) {
|
||||||
val list = flatAssembleInfoList
|
val list = assembleInfoList.value ?: return
|
||||||
if (position !in list.indices) return
|
if (position !in list.indices) return
|
||||||
|
|
||||||
val clickedItem = list[position]
|
val clickedItem = list[position]
|
||||||
@@ -666,8 +538,13 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
val newExpandState = !clickedItem.isExpanded.get()
|
val newExpandState = !clickedItem.isExpanded.get()
|
||||||
clickedItem.isExpanded.set(newExpandState)
|
clickedItem.isExpanded.set(newExpandState)
|
||||||
|
|
||||||
// 重新生成扁平化列表
|
if (newExpandState) {
|
||||||
syncAssembleInfoListFromLocal()
|
// 展开:查询该ULD的运单列表
|
||||||
|
loadWaybillsByUld(position, clickedItem)
|
||||||
|
} else {
|
||||||
|
// 折叠:移除二级运单行
|
||||||
|
removeWaybillRows(position)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AssembleInfoBean.ItemType.WAYBILL_DETAIL -> {
|
AssembleInfoBean.ItemType.WAYBILL_DETAIL -> {
|
||||||
@@ -677,12 +554,103 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载指定ULD的运单列表
|
||||||
|
*/
|
||||||
|
private fun loadWaybillsByUld(uldPosition: Int, uldItem: AssembleInfoBean) {
|
||||||
|
val uldBean = uldItem.tag as? GjcUldUseBean ?: return
|
||||||
|
|
||||||
|
// 检查是否已缓存
|
||||||
|
if (uldBean.waybillDetails != null) {
|
||||||
|
// 已缓存,直接展开
|
||||||
|
insertWaybillRows(uldPosition, uldBean.waybillDetails!!)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 未缓存,调用接口查询
|
||||||
|
val params = uldBean.toRequestBody()
|
||||||
|
|
||||||
|
launchLoadingCollect({ NetApply.api.getAssembledWaybillsByUld(params) }) {
|
||||||
|
onSuccess = { result ->
|
||||||
|
val waybillList = result.data ?: emptyList()
|
||||||
|
|
||||||
|
if (waybillList.isEmpty()) {
|
||||||
|
showToast("该ULD暂无运单记录")
|
||||||
|
// 折叠回去
|
||||||
|
uldItem.isExpanded.set(false)
|
||||||
|
} else {
|
||||||
|
// 缓存到GjcUldUseBean
|
||||||
|
uldBean.waybillDetails = waybillList.toMutableList()
|
||||||
|
|
||||||
|
// 插入二级运单行
|
||||||
|
insertWaybillRows(uldPosition, waybillList)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onFailed = { code, message ->
|
||||||
|
showToast("查询失败: $message")
|
||||||
|
// 折叠回去
|
||||||
|
uldItem.isExpanded.set(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在指定位置后插入二级运单行
|
||||||
|
*/
|
||||||
|
private fun insertWaybillRows(uldPosition: Int, waybillList: List<GjcWarehouse>) {
|
||||||
|
val list = assembleInfoList.value?.toMutableList() ?: return
|
||||||
|
val uldItem = list[uldPosition]
|
||||||
|
|
||||||
|
// 生成二级运单行
|
||||||
|
val waybillRows = waybillList.map { warehouse ->
|
||||||
|
AssembleInfoBean().apply {
|
||||||
|
itemType = AssembleInfoBean.ItemType.WAYBILL_DETAIL
|
||||||
|
parentUldNo = uldItem.uldNo
|
||||||
|
wbNo = warehouse.wbNo
|
||||||
|
waybillPieces = warehouse.pc.toInt()
|
||||||
|
waybillWeight = warehouse.weight
|
||||||
|
showIndent = true
|
||||||
|
showIndex = false
|
||||||
|
|
||||||
|
// 转换为AssembleWaybillBean(用于填充表单)
|
||||||
|
waybillData = 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 插入到ULD行后面
|
||||||
|
list.addAll(uldPosition + 1, waybillRows)
|
||||||
|
assembleInfoList.value = list
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除指定ULD后的二级运单行
|
||||||
|
*/
|
||||||
|
private fun removeWaybillRows(uldPosition: Int) {
|
||||||
|
val list = assembleInfoList.value?.toMutableList() ?: return
|
||||||
|
val uldItem = list[uldPosition]
|
||||||
|
|
||||||
|
// 移除该ULD的所有二级行
|
||||||
|
list.removeAll {
|
||||||
|
it.itemType == AssembleInfoBean.ItemType.WAYBILL_DETAIL &&
|
||||||
|
it.parentUldNo == uldItem.uldNo
|
||||||
|
}
|
||||||
|
|
||||||
|
assembleInfoList.value = list
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从二级运单行填充表单(编辑模式)
|
* 从二级运单行填充表单(编辑模式)
|
||||||
* 1. 填充ULD信息(并锁定ULD编号)
|
* 1. 填充ULD信息(并锁定ULD编号)
|
||||||
* 2. 填充运单信息(使用原始运单件数/重量,只读)
|
* 2. 填充运单信息(使用原始运单件数/重量,只读)
|
||||||
* 3. 保留组装件数、组装重量、组装人为可编辑
|
* 3. 保留组装件数、组装重量、组装人为可编辑
|
||||||
* 4. 标记编辑模式
|
|
||||||
*/
|
*/
|
||||||
private fun fillFormFromWaybillDetail(item: AssembleInfoBean) {
|
private fun fillFormFromWaybillDetail(item: AssembleInfoBean) {
|
||||||
val waybill = item.waybillData ?: return
|
val waybill = item.waybillData ?: return
|
||||||
@@ -710,106 +678,118 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
// 3. 锁定ULD编号
|
// 3. 锁定ULD编号
|
||||||
isUldNoLocked.value = true
|
isUldNoLocked.value = true
|
||||||
|
|
||||||
// 4. 标记编辑模式(存储原始 ULD 编号和运单号)
|
// 4. 查询ULD信息(如果需要)
|
||||||
editMode = Pair(item.parentUldNo, waybill.waybillNo)
|
|
||||||
|
|
||||||
// 5. 查询 ULD 信息(如果需要)
|
|
||||||
if (item.parentUldNo != lastQueriedUldNo) {
|
if (item.parentUldNo != lastQueriedUldNo) {
|
||||||
lastQueriedUldNo = item.parentUldNo
|
lastQueriedUldNo = item.parentUldNo
|
||||||
queryUldInfo(item.parentUldNo)
|
queryUldInfo(item.parentUldNo)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增模式:添加已组装货物到本地存储
|
* 查询已组装的ULD列表
|
||||||
* @param isLoad true-装货(加),false-卸货(减)
|
* 参数来源:
|
||||||
|
* - fno/fdate:从当前选中的运单自动提取
|
||||||
|
* - loadArea:从当前选中的组装位置获取
|
||||||
|
* - uld:从ULD搜索框获取(可选)
|
||||||
*/
|
*/
|
||||||
private fun addAssembledCargoToLocal(uldNo: String, waybill: AssembleWaybillBean, isLoad: Boolean) {
|
fun loadAssembledList() {
|
||||||
val list = assembledCargoMap.getOrPut(uldNo) { mutableListOf() }
|
// 1. 参数验证
|
||||||
|
val fno = assembleFlightNo.value ?: ""
|
||||||
|
val fdate = assembleFlightDate.value ?: ""
|
||||||
|
val loadArea = selectedPosition.value?.positionName ?: ""
|
||||||
|
val uldSearch = uldSearchText.value ?: ""
|
||||||
|
|
||||||
// 检查是否已存在
|
// 必填参数检查
|
||||||
val existingIndex = list.indexOfFirst { it.waybillNo == waybill.waybillNo }
|
if (fno.isEmpty() || fdate.isEmpty() || loadArea.isEmpty()) {
|
||||||
if (existingIndex >= 0) {
|
// 参数缺失,清空列表(静默处理)
|
||||||
// 已存在:累加或减去件数和重量
|
assembleInfoList.value = mutableListOf()
|
||||||
val existing = list[existingIndex]
|
return
|
||||||
val existingPieces = existing.pieces.toIntOrNull() ?: 0
|
|
||||||
val existingWeight = existing.weight.toDoubleOrNull() ?: 0.0
|
|
||||||
val newPieces = waybill.pieces.toIntOrNull() ?: 0
|
|
||||||
val newWeight = waybill.weight.toDoubleOrNull() ?: 0.0
|
|
||||||
|
|
||||||
if (isLoad) {
|
|
||||||
// 装货:累加
|
|
||||||
existing.pieces = (existingPieces + newPieces).toString()
|
|
||||||
existing.weight = String.format("%.1f", existingWeight + newWeight)
|
|
||||||
} else {
|
|
||||||
// 卸货:减去
|
|
||||||
val resultPieces = existingPieces - newPieces
|
|
||||||
val resultWeight = existingWeight - newWeight
|
|
||||||
|
|
||||||
if (resultPieces <= 0 || resultWeight <= 0) {
|
|
||||||
// 减到0或负数,从列表中移除
|
|
||||||
list.removeAt(existingIndex)
|
|
||||||
// 如果该ULD下没有运单了,删除整个ULD
|
|
||||||
if (list.isEmpty()) {
|
|
||||||
assembledCargoMap.remove(uldNo)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 2. 防抖检查(避免重复查询)
|
||||||
|
val currentParams = "$fno|$fdate|$loadArea|$uldSearch"
|
||||||
|
if (currentParams == lastQueriedAssembledParams) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lastQueriedAssembledParams = currentParams
|
||||||
|
|
||||||
|
// 3. 构建请求参数
|
||||||
|
val params = mapOf(
|
||||||
|
"fno" to fno,
|
||||||
|
"fdate" to fdate,
|
||||||
|
"loadArea" to loadArea,
|
||||||
|
"uld" to uldSearch.ifEmpty { null } // 空值时传null
|
||||||
|
).toRequestBody()
|
||||||
|
|
||||||
|
// 4. 调用接口
|
||||||
|
launchLoadingCollect({ NetApply.api.getAssembledList(params) }) {
|
||||||
|
onSuccess = { result ->
|
||||||
|
val uldList = result.data ?: emptyList()
|
||||||
|
|
||||||
|
if (uldList.isEmpty()) {
|
||||||
|
showToast("暂无已组装记录")
|
||||||
|
assembleInfoList.value = mutableListOf()
|
||||||
} else {
|
} else {
|
||||||
existing.pieces = resultPieces.toString()
|
// 转换为AssembleInfoBean列表
|
||||||
existing.weight = String.format("%.1f", resultWeight)
|
convertToAssembleInfoBeans(uldList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
onFailed = { code, message ->
|
||||||
// 不存在:直接新增(只有装货时才会走到这里)
|
showToast("查询失败: $message")
|
||||||
if (isLoad) {
|
assembleInfoList.value = mutableListOf()
|
||||||
list.add(waybill)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编辑模式:更新本地存储中的运单数据
|
* 数据转换: List<GjcAssembled> → List<AssembleInfoBean>
|
||||||
* @param isLoad true-装货(加),false-卸货(减)
|
* 只生成一级ULD行,不包含二级运单行
|
||||||
|
* 同时将运单列表缓存到uldBean.waybillDetails
|
||||||
*/
|
*/
|
||||||
private fun updateAssembledCargoInLocal(
|
private fun convertToAssembleInfoBeans(assembledList: List<GjcAssembled>) {
|
||||||
uldNo: String,
|
val infoList = assembledList.mapIndexed { index, assembled ->
|
||||||
oldWaybillNo: String,
|
val uldBean = assembled.uldUse
|
||||||
newWaybillBean: AssembleWaybillBean,
|
val warehouseList = assembled.warehouseList
|
||||||
isLoad: Boolean
|
|
||||||
) {
|
|
||||||
val list = assembledCargoMap[uldNo] ?: return
|
|
||||||
|
|
||||||
// 查找并更新
|
if (uldBean == null) {
|
||||||
val index = list.indexOfFirst { it.waybillNo == oldWaybillNo }
|
return@mapIndexed null
|
||||||
if (index >= 0) {
|
}
|
||||||
val existing = list[index]
|
|
||||||
val existingPieces = existing.pieces.toIntOrNull() ?: 0
|
|
||||||
val existingWeight = existing.weight.toDoubleOrNull() ?: 0.0
|
|
||||||
val newPieces = newWaybillBean.pieces.toIntOrNull() ?: 0
|
|
||||||
val newWeight = newWaybillBean.weight.toDoubleOrNull() ?: 0.0
|
|
||||||
|
|
||||||
if (isLoad) {
|
// 缓存运单列表到uldBean(展开时不需要再次查询)
|
||||||
// 装货:累加
|
if (warehouseList != null && warehouseList.isNotEmpty()) {
|
||||||
existing.pieces = (existingPieces + newPieces).toString()
|
uldBean.waybillDetails = warehouseList
|
||||||
existing.weight = String.format("%.1f", existingWeight + newWeight)
|
}
|
||||||
} else {
|
|
||||||
// 卸货:减去
|
|
||||||
val resultPieces = existingPieces - newPieces
|
|
||||||
val resultWeight = existingWeight - newWeight
|
|
||||||
|
|
||||||
if (resultPieces <= 0 || resultWeight <= 0) {
|
// 计算总件数和总重量(从运单列表求和)
|
||||||
// 减到0或负数,从列表中移除
|
val calculatedPieces = warehouseList?.sumOf { it.pc.toInt() } ?: 0
|
||||||
list.removeAt(index)
|
val calculatedWeight = warehouseList?.sumOf { it.weight } ?: 0.0
|
||||||
// 如果该ULD下没有运单了,删除整个ULD
|
|
||||||
if (list.isEmpty()) {
|
AssembleInfoBean().apply {
|
||||||
assembledCargoMap.remove(uldNo)
|
itemType = AssembleInfoBean.ItemType.ULD_HEADER
|
||||||
}
|
uldNo = uldBean.uld
|
||||||
} else {
|
uldIndex = index + 1
|
||||||
existing.pieces = resultPieces.toString()
|
|
||||||
existing.weight = String.format("%.1f", resultWeight)
|
// 使用计算的总件数和总重量
|
||||||
}
|
totalPieces = calculatedPieces
|
||||||
|
totalWeight = calculatedWeight
|
||||||
|
|
||||||
|
hasArrow = true
|
||||||
|
showIndex = true
|
||||||
|
isExpanded.set(false) // 默认折叠
|
||||||
|
|
||||||
|
// 关联原始ULD数据(用于点击展开时查询)
|
||||||
|
tag = uldBean // 使用tag存储GjcUldUseBean对象
|
||||||
}
|
}
|
||||||
|
}.filterNotNull().toMutableList()
|
||||||
|
|
||||||
|
assembleInfoList.value = infoList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ULD搜索框输入完成回调
|
||||||
|
*/
|
||||||
|
fun onUldSearchInputComplete() {
|
||||||
|
loadAssembledList()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -823,6 +803,5 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
|||||||
operator = previousOperator // 恢复组装人
|
operator = previousOperator // 恢复组装人
|
||||||
}
|
}
|
||||||
isUldNoLocked.value = false
|
isUldNoLocked.value = false
|
||||||
editMode = null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,11 +46,13 @@
|
|||||||
android:layout_weight="3"
|
android:layout_weight="3"
|
||||||
android:background="@drawable/bg_white_radius_8"
|
android:background="@drawable/bg_white_radius_8"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
<!-- 搜索框 -->
|
<!-- ULD搜索框 -->
|
||||||
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayoutNew
|
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayoutNew
|
||||||
hint='@{"请输入ULD编码"}'
|
hint='@{"请输入ULD编号"}'
|
||||||
|
icon="@{@drawable/img_search}"
|
||||||
|
setRefreshCallBack="@{viewModel::onUldSearchInputComplete}"
|
||||||
type="@{SearchLayoutType.INPUT}"
|
type="@{SearchLayoutType.INPUT}"
|
||||||
value="@={viewModel.searchText}"
|
value="@={viewModel.uldSearchText}"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="4dp" />
|
android:layout_margin="4dp" />
|
||||||
|
|||||||
Reference in New Issue
Block a user