feat: opt 开始组装
This commit is contained in:
@@ -39,6 +39,10 @@ class GjcWarehouse : Serializable {
|
||||
var location: String = "" // uld
|
||||
var checkInPc: Long = 0 // 入库件数
|
||||
var checkInWeight: Double = 0.0 // 入库重量
|
||||
set(value) {
|
||||
field = value
|
||||
onDataChanged?.invoke()
|
||||
}
|
||||
var assembleCount: Int = 0 // 已经组装的数量
|
||||
|
||||
// ========== UI扩展字段 ==========
|
||||
|
||||
@@ -126,12 +126,14 @@ class GjcAssembleWeightEditViewModel : BaseViewModel() {
|
||||
|
||||
/**
|
||||
* 计算统计数据:总货重、重量误差
|
||||
* - 总货重:运单列表中所有 checkInWeight(入库重量/组装重量)之和
|
||||
* - 重量误差:(总货重 - ULD货重) / ULD货重 * 100%
|
||||
*/
|
||||
private fun calculateStatistics() {
|
||||
val records = waybillList.value ?: emptyList()
|
||||
|
||||
// 计算总货重(所有运单weight之和)
|
||||
val sumWeight = records.sumOf { it.weight }
|
||||
// 计算总货重(所有运单 checkInWeight 之和,即列表中显示的重量)
|
||||
val sumWeight = records.sumOf { it.checkInWeight }
|
||||
sumCargoWeight.value = String.format("%.2f", sumWeight)
|
||||
|
||||
// 计算重量误差百分比(相对于ULD的货重)
|
||||
|
||||
@@ -83,6 +83,14 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||
*/
|
||||
val isUldNoLocked = MutableLiveData(false)
|
||||
|
||||
/**
|
||||
* 卸货时选中的组装信息子运单数据
|
||||
* 用于:
|
||||
* 1. 卸货校验时对比组装件数/重量
|
||||
* 2. 卸货提交时构建 wbInfo
|
||||
*/
|
||||
private var selectedAssembleWaybill: AssembleInfoBean? = null
|
||||
|
||||
/**
|
||||
* 是否从列表页"修改"模式进入
|
||||
* 与 isUldNoLocked 的区别:
|
||||
@@ -173,6 +181,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||
|
||||
/**
|
||||
* 运单点击(单选切换)
|
||||
* 装货模式:从运单列表选择运单
|
||||
*/
|
||||
fun onWaybillItemClick(position: Int) {
|
||||
val list = waybillList.value ?: return
|
||||
@@ -190,9 +199,10 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||
if (selectedWaybill != null) {
|
||||
selectedWaybill.isSelected.set(true)
|
||||
|
||||
// 自动提取航班号和航班日期
|
||||
assembleFlightNo.value = selectedWaybill.fno
|
||||
assembleFlightDate.value = selectedWaybill.fdate
|
||||
// 【删除】不再从运单提取航班信息(航班信息改为从ULD查询接口获取)
|
||||
|
||||
// 【新增】清空卸货选中的子运单(切换到装货模式)
|
||||
selectedAssembleWaybill = null
|
||||
|
||||
// 保存当前的组装人(始终保留,从operator LiveData读取)
|
||||
val previousOperator = operator.value ?: ""
|
||||
@@ -380,6 +390,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||
|
||||
/**
|
||||
* 查询ULD信息(状态和耗材重量)
|
||||
* 同时从ULD信息提取航班信息,并触发组装信息列表查询
|
||||
*/
|
||||
private fun queryUldInfo(uldNo: String) {
|
||||
launchCollect({ NetApply.api.getUldWithConsumeWeight(uldNo) }) {
|
||||
@@ -401,6 +412,20 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||
// 保存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 ->
|
||||
@@ -426,6 +451,14 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||
/**
|
||||
* 执行组装操作(卸货或装货)
|
||||
* @param isLoad true-装货,false-卸货
|
||||
*
|
||||
* 装货与卸货的区别:
|
||||
* 1. 校验逻辑不同:
|
||||
* - 装货:与运单列表中的件数/重量对比
|
||||
* - 卸货:与组装信息中的组装件数/重量对比
|
||||
* 2. wbInfo 来源不同:
|
||||
* - 装货:从运单列表选中项获取
|
||||
* - 卸货:从组装信息选中的子运单获取
|
||||
*/
|
||||
private fun performAssembleOperation(isLoad: Boolean) {
|
||||
// 1. 验证必填字段
|
||||
@@ -454,36 +487,51 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||
return
|
||||
}
|
||||
|
||||
// 校验件数范围
|
||||
val waybillPieces = waybillInfo.value?.waybillPieces?.trim() ?: ""
|
||||
val assembleCountInt = assembleCount.toLongOrNull() ?: 0L
|
||||
val waybillPiecesInt = waybillPieces.toLongOrNull() ?: 0L
|
||||
|
||||
if (waybillPiecesInt > 0 && assembleCountInt > waybillPiecesInt) {
|
||||
val errorMessage = if (isLoad) {
|
||||
"装货件数不能大于运单件数"
|
||||
} else {
|
||||
"卸货件数不能大于已装货件数"
|
||||
}
|
||||
showToast(errorMessage)
|
||||
return
|
||||
}
|
||||
|
||||
val assembleWeight = waybillInfo.value?.assembleWeight?.trim() ?: ""
|
||||
|
||||
// 校验重量范围(如果填写了组装重量)
|
||||
if (assembleWeight.isNotEmpty()) {
|
||||
val waybillWeight = waybillInfo.value?.waybillWeight?.trim() ?: ""
|
||||
val assembleWeightDouble = assembleWeight.toDoubleOrNull() ?: 0.0
|
||||
val waybillWeightDouble = waybillWeight.toDoubleOrNull() ?: 0.0
|
||||
// 【修改】区分校验逻辑
|
||||
val assembleCountInt = assembleCount.toLongOrNull() ?: 0L
|
||||
val assembleWeightDouble = assembleWeight.toDoubleOrNull() ?: 0.0
|
||||
|
||||
if (waybillWeightDouble > 0 && assembleWeightDouble > waybillWeightDouble) {
|
||||
val errorMessage = if (isLoad) {
|
||||
"装货重量不能大于运单重量"
|
||||
} else {
|
||||
"卸货重量不能大于已装货重量"
|
||||
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
|
||||
}
|
||||
showToast(errorMessage)
|
||||
}
|
||||
} 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
|
||||
}
|
||||
}
|
||||
@@ -500,21 +548,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||
return
|
||||
}
|
||||
|
||||
// 2. 获取或构建运单Bean
|
||||
// 从运单列表中获取选中的运单
|
||||
val currentWaybillList = waybillList.value
|
||||
if (currentWaybillList == null) {
|
||||
showToast("运单列表为空")
|
||||
return
|
||||
}
|
||||
|
||||
val selectedWaybill = currentWaybillList.firstOrNull { it.isSelected.get() }
|
||||
if (selectedWaybill == null) {
|
||||
showToast("请选择运单")
|
||||
return
|
||||
}
|
||||
|
||||
// 3. 构建useInfo(ULD信息)
|
||||
// 2. 构建useInfo(ULD信息)
|
||||
val useInfo = mapOf(
|
||||
"uld" to uldNo,
|
||||
"consumeWeight" to materialWeight.toDoubleOrNull(),
|
||||
@@ -527,29 +561,62 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||
"useId" to if (uldInfo.value?.useId == 0L) null else uldInfo.value?.useId // 添加useId(来自getUld接口)
|
||||
)
|
||||
|
||||
// 4. 构建wbInfo(运单信息)
|
||||
// 使用原始运单件数/重量(如果有),否则使用当前件数/重量
|
||||
val waybillPc = if (selectedWaybill.originalPieces.isNotEmpty()) {
|
||||
selectedWaybill.originalPieces.toLongOrNull()
|
||||
// 3. 【修改】区分 wbInfo 构建
|
||||
val wbInfo: Map<String, Any?>
|
||||
|
||||
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 {
|
||||
selectedWaybill.pieces.toLongOrNull()
|
||||
}
|
||||
val waybillWeight = if (selectedWaybill.originalWeight.isNotEmpty()) {
|
||||
selectedWaybill.originalWeight.toDoubleOrNull()
|
||||
} else {
|
||||
selectedWaybill.weight.toDoubleOrNull()
|
||||
// 卸货:从组装信息子运单获取
|
||||
val assembleWaybill = selectedAssembleWaybill?.waybillData
|
||||
if (assembleWaybill == null) {
|
||||
showToast("请从组装信息列表选择要卸货的运单")
|
||||
return
|
||||
}
|
||||
|
||||
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(
|
||||
"wbNo" to selectedWaybill.waybillNo,
|
||||
"pc" to waybillPc,
|
||||
"weight" to waybillWeight,
|
||||
"fdate" to selectedWaybill.fdate,
|
||||
"fno" to selectedWaybill.fno,
|
||||
"whId" to selectedWaybill.whId
|
||||
)
|
||||
|
||||
// 5. 构建完整请求参数
|
||||
// 4. 构建完整请求参数
|
||||
val params = mapOf(
|
||||
"abPc" to assembleCount.toLongOrNull(),
|
||||
"abWeight" to assembleWeight.toDoubleOrNull(),
|
||||
@@ -561,7 +628,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||
"userId" to SharedPreferenceUtil.getString(Constant.Share.account)
|
||||
).toRequestBody()
|
||||
|
||||
// 6. 调用接口(带Loading,等待接口返回)
|
||||
// 5. 调用接口(带Loading,等待接口返回)
|
||||
val operationName = if (isLoad) "装货" else "卸货"
|
||||
launchLoadingCollect({
|
||||
if (isLoad) {
|
||||
@@ -572,7 +639,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||
}) {
|
||||
onSuccess = { result ->
|
||||
// 接口成功后才显示成功提示并刷新列表
|
||||
handleOperationSuccess(operationName, isLoad, uldNo, selectedWaybill, assembleCount, assembleWeight)
|
||||
handleOperationSuccess(operationName, isLoad, uldNo, assembleCount, assembleWeight)
|
||||
}
|
||||
onFailed = { code, message ->
|
||||
showToast("${operationName}失败: $message")
|
||||
@@ -587,7 +654,6 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||
operationName: String,
|
||||
isLoad: Boolean,
|
||||
uldNo: String,
|
||||
selectedWaybill: AssembleWaybillBean,
|
||||
assembleCount: String,
|
||||
assembleWeight: String
|
||||
) {
|
||||
@@ -598,14 +664,45 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
|
||||
}
|
||||
|
||||
// 重新查询组装信息列表(刷新数据)
|
||||
// 清空表单(在刷新数据前清空,避免刷新时的状态冲突)
|
||||
clearForm()
|
||||
|
||||
// 清除防抖标记,强制刷新组装信息列表
|
||||
lastQueriedAssembledParams = ""
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -737,14 +834,23 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 从二级运单行填充表单(编辑模式)
|
||||
* 1. 填充ULD信息(并锁定ULD编号)
|
||||
* 2. 填充运单信息(使用原始运单件数/重量,只读)
|
||||
* 3. 保留组装件数、组装重量、组装人为可编辑
|
||||
* 从二级运单行填充表单(卸货模式)
|
||||
* 1. 存储选中的组装信息子运单(用于卸货校验和提交)
|
||||
* 2. 填充ULD信息(并锁定ULD编号)
|
||||
* 3. 填充运单信息(字段对调:运单件数/组装件数对调,运单重量/组装重量对调)
|
||||
*
|
||||
* 卸货时字段映射:
|
||||
* - 运单件数 ← pieces (pc,原始运单件数)
|
||||
* - 运单重量 ← weight (weight,原始运单重量)
|
||||
* - 组装件数 ← originalPieces (checkInPc,已组装件数,可编辑卸货数量)
|
||||
* - 组装重量 ← originalWeight (checkInWeight,已组装重量,可编辑卸货数量)
|
||||
*/
|
||||
private fun fillFormFromWaybillDetail(item: AssembleInfoBean) {
|
||||
val waybill = item.waybillData ?: return
|
||||
|
||||
// 【新增】存储选中的组装信息子运单(用于卸货校验和提交)
|
||||
selectedAssembleWaybill = item
|
||||
|
||||
// 1. 填充ULD信息
|
||||
uldInfo.value = uldInfo.value?.apply {
|
||||
uldNo = item.parentUldNo
|
||||
@@ -754,14 +860,13 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||
// 保存当前的组装人(在创建新对象前,从operator LiveData读取)
|
||||
val previousOperator = operator.value ?: ""
|
||||
|
||||
// 2. 填充运单信息
|
||||
// 2. 填充运单信息(【修改】对调字段填充)
|
||||
waybillInfo.value = WaybillInfoBean().apply {
|
||||
waybillNo = waybill.waybillNo
|
||||
waybillPieces = waybill.originalPieces // 使用原始运单件数
|
||||
waybillWeight = waybill.originalWeight // 使用原始运单重量
|
||||
// 填充已累积的组装件数和组装重量(可编辑)
|
||||
assembleCount = waybill.pieces
|
||||
assembleWeight = waybill.weight
|
||||
waybillPieces = waybill.pieces // 【对调】显示运单件数(pc)
|
||||
waybillWeight = waybill.weight // 【对调】显示运单重量(weight)
|
||||
assembleCount = waybill.originalPieces // 【对调】显示组装件数(checkInPc),可编辑卸货数量
|
||||
assembleWeight = waybill.originalWeight // 【对调】显示组装重量(checkInWeight),可编辑卸货数量
|
||||
operator = previousOperator // 保留之前选择的组装人
|
||||
}
|
||||
|
||||
@@ -893,6 +998,9 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
|
||||
operator = previousOperator // 恢复组装人
|
||||
}
|
||||
isUldNoLocked.value = false
|
||||
|
||||
// 【新增】清空卸货选中的子运单
|
||||
selectedAssembleWaybill = null
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user