Compare commits

...

8 Commits

Author SHA1 Message Date
2ba70d1a09 feat: 国际出港开始组装新增 IMP代码、板型、BUP 输入项
- ULD 信息卡新增第二行:IMP代码(大写过滤)、板型(手输 + 下拉选择,箭头与 Spinner 同源)、BUP(否/是,默认否)
- 装货/卸货提交时 dgrCode、boardType、bupFlag 同时写入顶层参数与 useInfo,输入 ULD 后从 getUld 回填
- 板型选项走通用字典接口,字典 code 暂定 BOARDTYPE,测试环境返回为空时提示手动输入

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-09 10:40:43 +08:00
ea83361102 feat: 国际进出港 5 个列表页侧滑新增海关回执查看
原始舱单、进港理货、出港运抵、出港装载、出港理货主单卡片
新增侧滑「回执」按钮,调用各模块 getResponse 接口后跳转
module_base 共用的只读回执页。请求同时传 prefix、no 与
wbNo,回执优先取 data、为空再取 msg,兼容后端实际返回;
回执为空时提示「暂无海关回执」不跳转。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-09 10:12:52 +08:00
7a09bbbeab feat: 国际出港开始组装运单列表首次装货后显示剩余/总数
首次装货成功前件数、重量列显示总数;成功后表头切换为
「剩余件数/总件数」「剩余重量/总重量」,剩余值由 pc 减
checkInPc、weight 减 checkInWeight 得出。三处接口数据转
Bean 的重复代码合并为扩展函数。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-08 20:43:55 +08:00
6b2006fdb7 feat: 国际出港出库交接新增装机状态显示与允许装机操作
列表项新增「装机状态」列,依据分页接口 allowLoad 字段展示,
允许装机绿色、不允许红色,并重新分配列权重避免长字段换行。
底部新增「允许装机」按钮,支持多选后批量调用允许装机接口。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-08 20:17:31 +08:00
b368efa827 fix: 国际进港仓库列表件数改取 pcLabel 字段
分页接口新增 pcLabel 字段(如 0/8),用于展示已入库/总件数,
列表项件数由 pc 改为优先显示 pcLabel,缺失时回退 pc。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-08 20:04:01 +08:00
fcb247c3f5 feat: 国际出港理货新增分单全选功能
底部栏新增「分单全选」按钮,与主单全选相互独立。
依据分页接口新增的 allTally 字段判断:主单存在分批申报(allTally=0)时跳过其分单,
只有主单全部申报完毕(allTally=1)才允许全选该主单下的分单,跳过时 toast 提示。
分单单个勾选后同步刷新分单全选状态。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-08 19:55:44 +08:00
5edb1bea06 feat: 国际进港装机单列表改为 ULD 主单与运单子单结构
适配装机单查询接口按 ULD 分组的新返回结构,主单展示 ULD 编号、
总件数、总重量、航班信息,展开后显示关联运单的运单号、件数、重量、品名,
样式与展开交互与其他主子单列表一致;点击子单行进入装机单编辑。
右下角“修改库位”“入库”按钮暂时隐藏。同步修正进港舱单页修改库位时
从新分组结构中取运单记录。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-08 19:43:26 +08:00
51c5ac6e96 feat: 国际出港移库新增详情查看与侧滑编辑
列表项右侧增加箭头,点击进入详情页;左滑显示“编辑”按钮进入编辑页。
详情与编辑复用同一表单页,编辑模式仅支持修改备注与交接图片上传/删除,
表单结构参考国内进港移交编辑。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-09-08 16:00:48 +08:00
53 changed files with 1711 additions and 313 deletions

View File

@@ -222,6 +222,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.page.move.IntExpMoveEditActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="userLandscape" />
<activity <activity
android:name=".MineActivity" android:name=".MineActivity"
android:configChanges="orientation|keyboardHidden" android:configChanges="orientation|keyboardHidden"

View File

@@ -19,6 +19,27 @@ class AssembleWaybillBean {
var originalPieces: String = "" // 原始运单件数 var originalPieces: String = "" // 原始运单件数
var originalWeight: String = "" // 原始运单重量 var originalWeight: String = "" // 原始运单重量
// ========== 剩余/总数显示(开始组装页首次装货成功后切换) ==========
var checkInPieces: Long = 0 // 已组装件数(接口 checkInPc
var checkInWeight: Double = 0.0 // 已组装重量(接口 checkInWeight
var showRemaining: Boolean = false // 是否以“剩余/总数”形式显示
/** 件数列显示:首次装货成功前为总件数,之后为“剩余件数/总件数”(剩余 = pc checkInPc */
val piecesDisplay: String
get() {
if (!showRemaining) return pieces
val total = pieces.toLongOrNull() ?: return pieces
return "${total - checkInPieces}/$pieces"
}
/** 重量列显示:首次装货成功前为总重量,之后为“剩余重量/总重量”(剩余 = weight checkInWeight */
val weightDisplay: String
get() {
if (!showRemaining) return weight
val total = weight.toDoubleOrNull() ?: return weight
return String.format("%.1f", total - checkInWeight) + "/" + weight
}
val fLightInfo: String val fLightInfo: String
get() = "$fno/${fdate.replace("-", "")}" get() = "$fno/${fdate.replace("-", "")}"

View File

@@ -44,6 +44,7 @@ data class GjcMaWb(
// ==================== 货物信息 ==================== // ==================== 货物信息 ====================
var pc: Long? = null, // 预配件数 var pc: Long? = null, // 预配件数
var pcLabel: String? = null, // 件数展示文本(国际进港仓库分页返回,如 0/8、44
var weight: Double? = null, // 预配重量KG var weight: Double? = null, // 预配重量KG
var volume: Double? = null, // 预配体积CBM var volume: Double? = null, // 预配体积CBM
var goods: String? = null, // 品名(英) var goods: String? = null, // 品名(英)
@@ -85,6 +86,7 @@ data class GjcMaWb(
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, // 清仓正常01 var clearNormal: String? = null, // 清仓正常01
var allTally: String? = null, // 运单理货申报全部通过01为 1 时才允许全选该主单下的分单
// ==================== 操作信息 ==================== // ==================== 操作信息 ====================
var opDate: String? = null, // 操作时间(入库时间) var opDate: String? = null, // 操作时间(入库时间)
@@ -94,6 +96,9 @@ data class GjcMaWb(
// ==================== 备注与其他 ==================== // ==================== 备注与其他 ====================
var remark: String? = null, // 备注 var remark: String? = null, // 备注
var pic: String? = null, // 交接图片缩略图路径(逗号分隔)
var originalPic: String? = null, // 交接图片原图路径(逗号分隔)
var picNumber: String? = null, // 交接图片数量
var ffmMemo: String? = null, // ffm备注 var ffmMemo: String? = null, // ffm备注
var mftMemo: String? = null, // mft备注 var mftMemo: String? = null, // mft备注
var unNumber: String? = null, // UN编号 var unNumber: String? = null, // UN编号
@@ -129,6 +134,13 @@ data class GjcMaWb(
get() = checked.get() get() = checked.get()
set(value) = checked.set(value) set(value) = checked.set(value)
/**
* 是否允许全选该主单下的分单
* 主单存在分批申报(未全部申报完毕)时接口返回 allTally=0此时不允许全选其分单
*/
val canCheckAllHaWb: Boolean
get() = allTally == "1"
// ==================== 状态转换扩展属性 ==================== // ==================== 状态转换扩展属性 ====================
/** /**
* 计重状态中文 * 计重状态中文

View File

@@ -51,6 +51,7 @@ class GjcUldUseBean : Serializable {
var uldFlag: String = "" // uld分类 var uldFlag: String = "" // uld分类
var status: String = "" // uld状态0正常1故障 var status: String = "" // uld状态0正常1故障
var dgrCode: String = "" // IMP代码 var dgrCode: String = "" // IMP代码
var bupFlag: String = "" // BUP选项01
var height: String = "" // 高度 var height: String = "" // 高度
var passageway: String = "" // 通道号 var passageway: String = "" // 通道号
var passagewayId: String = "" var passagewayId: String = ""
@@ -65,6 +66,19 @@ class GjcUldUseBean : Serializable {
var loadArea: String = "" // 组装区 var loadArea: String = "" // 组装区
var pc: Long = 0 // 组装件数 var pc: Long = 0 // 组装件数
var allowLoad: String = "" // 允许装机0不允许1允许
// 是否允许装机
val isAllowLoad: Boolean
get() = allowLoad == "1"
// 装机状态文本
val allowLoadText: String
get() = when (allowLoad) {
"1" -> "允许装机"
"0" -> "不允许装机"
else -> ""
}
var fillWeightFlag: String = "" // 回填状态0-未回填1-部分回填2-已回填 var fillWeightFlag: String = "" // 回填状态0-未回填1-部分回填2-已回填
// 回填状态文本 // 回填状态文本

View File

@@ -0,0 +1,36 @@
package com.lukouguoji.module_base.bean
import androidx.databinding.ObservableBoolean
import com.lukouguoji.module_base.interfaces.ICheck
import java.io.Serializable
/**
* 国际进港装机单 ULD 主单 Bean
* 对应接口:/IntImpManifest/pageQueryAir 返回的列表项(按 ULD 分组manifestList 为关联运单)
*/
data class GjjLoadingUld(
var uld: String? = null, // ULD 编号
var flight: String? = null, // 航班信息
var totalPc: Long? = null, // 总件数
var totalWeight: Double? = null, // 总重量
var manifestList: List<GjjManifest>? = null, // 关联运单列表
// 展开/收起状态
@Transient
val showMore: ObservableBoolean = ObservableBoolean(false),
// 选中状态
@Transient
val checked: ObservableBoolean = ObservableBoolean(false)
) : Serializable, ICheck {
override fun getCheckObservable(): ObservableBoolean = checked
var isSelected: Boolean
get() = checked.get()
set(value) = checked.set(value)
/** 总重量显示(取整) */
val totalWeightText: String
get() = ((totalWeight ?: 0.0).toInt()).toString()
}

View File

@@ -13,4 +13,7 @@ class UldInfoBean {
var totalWeight: String = "" // 总重量 var totalWeight: String = "" // 总重量
var status: String = "" // 状态(旧字段,保留兼容) var status: String = "" // 状态(旧字段,保留兼容)
var useId: Long? = null // ULD使用ID来自getUld接口 var useId: Long? = null // ULD使用ID来自getUld接口
var dgrCode: String = "" // IMP代码
var boardType: String = "" // 板型(可下拉选择,也可手动输入)
var bupFlag: String = "0" // BUP选项01默认否
} }

View File

@@ -346,6 +346,9 @@ interface Constant {
// 数据 // 数据
const val DATA = "data" const val DATA = "data"
// 页面标题
const val TITLE = "title"
const val POSITION = "position" const val POSITION = "position"
// 单号 // 单号

View File

@@ -56,6 +56,7 @@ import com.lukouguoji.module_base.bean.IntImpAccidentVisaBean
import com.lukouguoji.module_base.bean.IntImpPickUpDLVBean import com.lukouguoji.module_base.bean.IntImpPickUpDLVBean
import com.lukouguoji.module_base.bean.IntImpPickUpRecordBean import com.lukouguoji.module_base.bean.IntImpPickUpRecordBean
import com.lukouguoji.module_base.bean.IntImpQueryBean import com.lukouguoji.module_base.bean.IntImpQueryBean
import com.lukouguoji.module_base.bean.GjjLoadingUld
import com.lukouguoji.module_base.bean.GjjManifest import com.lukouguoji.module_base.bean.GjjManifest
import com.lukouguoji.module_base.bean.GjjManifestBean import com.lukouguoji.module_base.bean.GjjManifestBean
import com.lukouguoji.module_base.bean.GjjPackTypeBean import com.lukouguoji.module_base.bean.GjjPackTypeBean
@@ -147,6 +148,14 @@ interface Api {
@POST @POST
suspend fun singleStringPost(@Url url: String): BaseResultBean<String> suspend fun singleStringPost(@Url url: String): BaseResultBean<String>
/**
* 获取海关回执(国际进港原始舱单/进港理货/出港运抵/出港装载/出港理货 共用)
* urlXXX/getResponsebody 传 prefix、no 与拼接的 wbNo后端实测按 prefix + no 匹配),
* 回执文本实测在 msg 字段、data 为 null取值见 CustomsResponseKtx.showCustomsResponse
*/
@POST
suspend fun getCustomsResponse(@Url url: String, @Body data: RequestBody): BaseResultBean<String>
@GET @GET
suspend fun anyGetForId(@Url url: String, @Query("id") id: String): BaseResultBean<Any> suspend fun anyGetForId(@Url url: String, @Query("id") id: String): BaseResultBean<Any>
@@ -657,7 +666,8 @@ interface Api {
* 国际出港组装 - 根据全ULD查询ULD状态和耗材重量 * 国际出港组装 - 根据全ULD查询ULD状态和耗材重量
* 接口路径: /IntExpAssemble/getUld * 接口路径: /IntExpAssemble/getUld
* @param uld ULD编号 * @param uld ULD编号
* @return ULD信息包含status0正常1故障consumeWeight耗材重量 * @return ULD信息包含status0正常1故障consumeWeight耗材重量
* dgrCodeIMP代码、boardType板型、bupFlagBUP选项 01
*/ */
@GET("IntExpAssemble/getUld") @GET("IntExpAssemble/getUld")
suspend fun getUldWithConsumeWeight(@Query("uld") uld: String): BaseResultBean<GjcUldUseBean> suspend fun getUldWithConsumeWeight(@Query("uld") uld: String): BaseResultBean<GjcUldUseBean>
@@ -666,7 +676,8 @@ interface Api {
* 国际出港组装 - 卸货 * 国际出港组装 - 卸货
* 接口路径: /IntExpAssemble/drop * 接口路径: /IntExpAssemble/drop
* @param data 请求参数abPc组装件数、abWeight组装重量、consumeWeight耗材重量 * @param data 请求参数abPc组装件数、abWeight组装重量、consumeWeight耗材重量
* ldId组装人、loadArea组装区、useInfoULD信息、wbInfo运单信息、userId用户ID * ldId组装人、loadArea组装区、useInfoULD信息、wbInfo运单信息、userId用户ID
* dgrCodeIMP代码、boardType板型、bupFlagBUP选项 01
*/ */
@POST("IntExpAssemble/drop") @POST("IntExpAssemble/drop")
suspend fun assembleDropCargo(@Body data: RequestBody): BaseResultBean<GjcWarehouse> suspend fun assembleDropCargo(@Body data: RequestBody): BaseResultBean<GjcWarehouse>
@@ -675,7 +686,8 @@ interface Api {
* 国际出港组装 - 装货 * 国际出港组装 - 装货
* 接口路径: /IntExpAssemble/assemble * 接口路径: /IntExpAssemble/assemble
* @param data 请求参数abPc组装件数、abWeight组装重量、consumeWeight耗材重量 * @param data 请求参数abPc组装件数、abWeight组装重量、consumeWeight耗材重量
* ldId组装人、loadArea组装区、useInfoULD信息、wbInfo运单信息、userId用户ID * ldId组装人、loadArea组装区、useInfoULD信息、wbInfo运单信息、userId用户ID
* dgrCodeIMP代码、boardType板型、bupFlagBUP选项 01
*/ */
@POST("IntExpAssemble/assemble") @POST("IntExpAssemble/assemble")
suspend fun assembleLoadCargo(@Body data: RequestBody): BaseResultBean<GjcWarehouse> suspend fun assembleLoadCargo(@Body data: RequestBody): BaseResultBean<GjcWarehouse>
@@ -737,6 +749,14 @@ interface Api {
@POST("IntExpOutHandover/waitingTrans") @POST("IntExpOutHandover/waitingTrans")
suspend fun waitingTrans(@Body data: RequestBody): BaseResultBean<String> suspend fun waitingTrans(@Body data: RequestBody): BaseResultBean<String>
/**
* 国际出港出库交接-允许装机
* 接口路径: /IntExpOutHandover/allow
* @param data 请求参数选中的ULD列表GjcUldUseBean 数组)
*/
@POST("IntExpOutHandover/allow")
suspend fun allowLoading(@Body data: RequestBody): BaseResultBean<Boolean>
/** /**
* 国际出港-出港装载 分页查询 * 国际出港-出港装载 分页查询
* 接口路径: /IntExpLoad/pageQuery * 接口路径: /IntExpLoad/pageQuery
@@ -872,6 +892,20 @@ interface Api {
@POST("IntExpMove/move") @POST("IntExpMove/move")
suspend fun submitIntExpMove(@Body data: RequestBody): BaseResultBean<SimpleResultBean> suspend fun submitIntExpMove(@Body data: RequestBody): BaseResultBean<SimpleResultBean>
/**
* 国际出港移库-详情
* 接口路径: /IntExpMove/detail
*/
@POST("IntExpMove/detail")
suspend fun getIntExpMoveDetail(@Query("maWbId") maWbId: Long): BaseResultBean<GjcMaWb>
/**
* 国际出港移库-编辑(仅更新备注与交接图片)
* 接口路径: /IntExpMove/update
*/
@POST("IntExpMove/update")
suspend fun updateIntExpMove(@Body data: RequestBody): BaseResultBean<String>
/** /**
* 国际出港库位操作-清仓 * 国际出港库位操作-清仓
* 接口路径: /IntExpStorageUse/updateClear * 接口路径: /IntExpStorageUse/updateClear
@@ -1942,10 +1976,10 @@ interface Api {
suspend fun getMaWbMinusHaWb(@Body data: RequestBody): BaseResultBean<GjjHaWb> suspend fun getMaWbMinusHaWb(@Body data: RequestBody): BaseResultBean<GjjHaWb>
/** /**
* 国际进港舱单-分拣理货(装机单)-分页查询 * 国际进港舱单-分拣理货(装机单)-分页查询(按 ULD 分组manifestList 为关联运单)
*/ */
@POST("IntImpManifest/pageQueryAir") @POST("IntImpManifest/pageQueryAir")
suspend fun getIntImpLoadingList(@Body data: RequestBody): PageInfo<GjjManifest> suspend fun getIntImpLoadingList(@Body data: RequestBody): PageInfo<GjjLoadingUld>
/** /**
* 国际进港舱单-分拣理货(装机单)-分页合计 * 国际进港舱单-分拣理货(装机单)-分页合计

View File

@@ -0,0 +1,53 @@
package com.lukouguoji.module_base.ktx
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.ui.page.customs.CustomsResponseActivity
/**
* 海关回执接口地址(各页面对应各自模块的 getResponse
*/
object CustomsResponseUrl {
const val INT_IMP_AIR_MANIFEST = "IntImpAirManifest/getResponse" // 国际进港原始舱单
const val INT_IMP_TALLY = "IntImpTally/getResponse" // 国际进港理货
const val INT_EXP_ARRIVE = "IntExpArrive/getResponse" // 国际出港运抵
const val INT_EXP_LOAD = "IntExpLoad/getResponse" // 国际出港装载
const val INT_EXP_TALLY = "IntExpTally/getResponse" // 国际出港理货
}
/**
* 列表项侧滑「回执」按钮的 onItemClick type
* 现有取值为 0/1/2、101~103、1000~3000 及 view id9001 与之均不冲突
*/
const val ITEM_CLICK_TYPE_CUSTOMS_RESPONSE = 9001
/**
* 查询海关回执并跳转只读详情页
* - 带 Loading 调用 [url],本期只查主单,不传 hno
* - 请求体同时传 prefix、no 与拼接后的 wbNo测试环境实测后端按 prefix + no 匹配,
* 只传 wbNo 会查不到(与文档「运单号必填」描述不一致)
* - 回执文本实测放在 msg 字段data 恒为 null这里优先取 data、为空再取 msg兼容两种返回
* - 回执为空时提示「暂无海关回执」,不跳转
* - 接口失败由 launchLoadingCollect 默认 Toast 错误信息
*/
fun BaseViewModel.showCustomsResponse(url: String, prefix: String?, no: String?, title: String) {
if (prefix.isNullOrEmpty() || no.isNullOrEmpty()) {
showToast("运单号为空")
return
}
val params = mapOf(
"wbNo" to prefix + no,
"prefix" to prefix,
"no" to no
).toRequestBody()
launchLoadingCollect({ NetApply.api.getCustomsResponse(url, params) }) {
onSuccess = { result ->
val content = result.data?.ifEmpty { null } ?: result.msg ?: ""
if (content.isEmpty()) {
showToast("暂无海关回执")
} else {
CustomsResponseActivity.start(getTopActivity(), title, content)
}
}
}
}

View File

@@ -142,6 +142,7 @@ object ARouterConstants {
const val ACTIVITY_URL_INT_EXP_ASSEMBLE = "/gjc/IntExpAssembleActivity" //国际出港 出港组装 const val ACTIVITY_URL_INT_EXP_ASSEMBLE = "/gjc/IntExpAssembleActivity" //国际出港 出港组装
const val ACTIVITY_URL_INT_EXP_ASSEMBLE_START = "/gjc/IntExpAssembleStartActivity" //国际出港 开始组装 const val ACTIVITY_URL_INT_EXP_ASSEMBLE_START = "/gjc/IntExpAssembleStartActivity" //国际出港 开始组装
const val ACTIVITY_URL_INT_EXP_MOVE = "/gjc/IntExpMoveActivity" //国际出港 出港移库 const val ACTIVITY_URL_INT_EXP_MOVE = "/gjc/IntExpMoveActivity" //国际出港 出港移库
const val ACTIVITY_URL_INT_EXP_MOVE_EDIT = "/gjc/IntExpMoveEditActivity" //国际出港 出港移库编辑/详情
const val ACTIVITY_URL_GJC_ASSEMBLE_ALLOCATE = "/gjc/GjcAssembleAllocateActivity" //国际出港 组装分配 const val ACTIVITY_URL_GJC_ASSEMBLE_ALLOCATE = "/gjc/GjcAssembleAllocateActivity" //国际出港 组装分配
const val ACTIVITY_URL_INT_EXP_OUT_HANDOVER = "/gjc/IntExpOutHandoverActivity" //国际出港 出库交接 const val ACTIVITY_URL_INT_EXP_OUT_HANDOVER = "/gjc/IntExpOutHandoverActivity" //国际出港 出库交接
const val ACTIVITY_URL_INT_EXP_LOAD = "/gjc/IntExpLoadActivity" //国际出港 出港装载 const val ACTIVITY_URL_INT_EXP_LOAD = "/gjc/IntExpLoadActivity" //国际出港 出港装载

View File

@@ -0,0 +1,46 @@
package com.lukouguoji.module_base.ui.page.customs
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.lukouguoji.module_base.R
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.databinding.ActivityCustomsResponseBinding
import com.lukouguoji.module_base.impl.EmptyViewModel
/**
* 海关回执详情页(只读)
* 回执文本由 Intent 传入页面内不调接口UI 参照国际进港电报详情页
*/
class CustomsResponseActivity :
BaseBindingActivity<ActivityCustomsResponseBinding, EmptyViewModel>() {
override fun layoutId() = R.layout.activity_customs_response
override fun viewModelClass() = EmptyViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow(intent.getStringExtra(Constant.Key.TITLE) ?: "海关回执")
binding.etContent.apply {
setText(intent.getStringExtra(Constant.Key.DATA) ?: "")
// 只读:不可输入、无光标,但仍可长按选择复制
keyListener = null
isFocusable = false
isFocusableInTouchMode = false
isCursorVisible = false
}
}
companion object {
@JvmStatic
fun start(context: Context, title: String, content: String) {
context.startActivity(
Intent(context, CustomsResponseActivity::class.java)
.putExtra(Constant.Key.TITLE, title)
.putExtra(Constant.Key.DATA, content)
)
}
}
}

View File

@@ -625,6 +625,21 @@ object DictUtils {
} }
} }
/**
* 板型列表(国际出港组装-开始组装)
* 字典 codeBOARDTYPE显示与提交均使用 value 字段
*/
fun getBoardTypeList(callBack: (List<KeyValue>) -> Unit) {
launchCollect({
NetApply.api
.getDictList("BOARDTYPE")
}) {
onSuccess = {
callBack((it.data ?: emptyList()).map { b -> KeyValue(b.value, b.value) })
}
}
}
// 报文类型 // 报文类型
fun getTelegramTypeList(callBack: (List<KeyValue>) -> Unit) { fun getTelegramTypeList(callBack: (List<KeyValue>) -> Unit) {
launchCollect({ launchCollect({

View File

@@ -34,6 +34,13 @@
android:exported="false" android:exported="false"
android:screenOrientation="userLandscape" /> android:screenOrientation="userLandscape" />
<!-- 海关回执(只读) -->
<activity
android:name=".ui.page.customs.CustomsResponseActivity"
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"

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 输入框边框 + 与 Spinnerbg_spinner_pda_new完全一致的下拉箭头用于“手动输入 + 下拉选择”组合输入框 -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bg_data_layout_new" />
<item
android:width="8.7dp"
android:height="6dp"
android:drawable="@drawable/img_sp_down"
android:gravity="center_vertical|right"
android:right="10dp" />
</layer-list>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_f2"
android:orientation="vertical">
<!-- 标题栏 -->
<include layout="@layout/title_tool_bar" />
<!-- 回执内容区域(只读,可滚动、可长按复制) -->
<EditText
android:id="@+id/etContent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:layout_margin="20dp"
android:background="@color/white"
android:gravity="top|start"
android:inputType="textMultiLine"
android:lineSpacingExtra="4dp"
android:overScrollMode="always"
android:padding="20dp"
android:scrollbars="vertical"
android:textColor="@color/black"
android:textSize="16sp" />
</LinearLayout>
</layout>

View File

@@ -9,6 +9,7 @@ import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.impl.FlowBus import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.bean.GjcMaWb import com.lukouguoji.module_base.bean.GjcMaWb
import com.lukouguoji.module_base.ktx.refresh import com.lukouguoji.module_base.ktx.refresh
import com.lukouguoji.module_base.ktx.ITEM_CLICK_TYPE_CUSTOMS_RESPONSE
/** /**
* 国际出港-出港运抵 列表项ViewHolder * 国际出港-出港运抵 列表项ViewHolder
@@ -22,6 +23,12 @@ class IntExpArriveViewHolder(view: View) :
binding.position = position binding.position = position
binding.executePendingBindings() binding.executePendingBindings()
// 侧滑菜单 - 回执按钮(关闭侧滑后分发到 ViewModel
binding.btnResponse.setOnClickListener {
binding.swipeMenu.quickClose()
clickListener?.onItemClick(position, ITEM_CLICK_TYPE_CUSTOMS_RESPONSE)
}
// 添加图标点击事件 - 切换选择状态 // 添加图标点击事件 - 切换选择状态
binding.ivIcon.setOnClickListener { binding.ivIcon.setOnClickListener {
bean.checked.set(!bean.checked.get()) bean.checked.set(!bean.checked.get())

View File

@@ -6,6 +6,7 @@ import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.common.ConstantEvent import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.impl.FlowBus import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.bean.GjcExportLoad import com.lukouguoji.module_base.bean.GjcExportLoad
import com.lukouguoji.module_base.ktx.ITEM_CLICK_TYPE_CUSTOMS_RESPONSE
/** /**
* 国际出港-出港装载 列表项ViewHolder * 国际出港-出港装载 列表项ViewHolder
@@ -19,6 +20,12 @@ class IntExpLoadViewHolder(view: View) :
binding.position = position binding.position = position
binding.executePendingBindings() binding.executePendingBindings()
// 侧滑菜单 - 回执按钮(关闭侧滑后分发到 ViewModel
binding.btnResponse.setOnClickListener {
binding.swipeMenu.quickClose()
clickListener?.onItemClick(position, ITEM_CLICK_TYPE_CUSTOMS_RESPONSE)
}
// 添加图标点击事件 - 切换选择状态 // 添加图标点击事件 - 切换选择状态
binding.ivIcon.setOnClickListener { binding.ivIcon.setOnClickListener {
// 反转checked状态 // 反转checked状态

View File

@@ -2,6 +2,7 @@ package com.lukouguoji.gjc.holder
import android.view.View import android.view.View
import com.lukouguoji.gjc.databinding.ItemIntExpMoveBinding import com.lukouguoji.gjc.databinding.ItemIntExpMoveBinding
import com.lukouguoji.gjc.page.move.IntExpMoveEditActivity
import com.lukouguoji.module_base.base.BaseViewHolder import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjcMove import com.lukouguoji.module_base.bean.GjcMove
import com.lukouguoji.module_base.common.ConstantEvent import com.lukouguoji.module_base.common.ConstantEvent
@@ -31,6 +32,17 @@ class IntExpMoveViewHolder(view: View) :
} }
} }
// 点击列表项进入移库详情
binding.ll.setOnClickListener {
IntExpMoveEditActivity.startForDetails(itemView.context, bean.maWbId)
}
// 侧滑菜单 - 编辑按钮
binding.btnEdit.setOnClickListener {
binding.swipeMenu.quickClose()
IntExpMoveEditActivity.startForEdit(itemView.context, bean.maWbId)
}
binding.executePendingBindings() binding.executePendingBindings()
} }
} }

View File

@@ -4,6 +4,8 @@ import android.view.View
import com.lukouguoji.gjc.databinding.ItemIntExpTallySubBinding import com.lukouguoji.gjc.databinding.ItemIntExpTallySubBinding
import com.lukouguoji.module_base.base.BaseViewHolder import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjcHaWb import com.lukouguoji.module_base.bean.GjcHaWb
import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.impl.FlowBus
/** /**
* 国际出港-出港理货 子订单(分单) ViewHolder * 国际出港-出港理货 子订单(分单) ViewHolder
@@ -20,6 +22,8 @@ class IntExpTallySubViewHolder(view: View) :
// checkbox点击切换选择状态 // checkbox点击切换选择状态
binding.ivCheckbox.setOnClickListener { binding.ivCheckbox.setOnClickListener {
bean.checked.set(!bean.checked.get()) bean.checked.set(!bean.checked.get())
// 通知页面刷新分单全选状态
FlowBus.with<String>(ConstantEvent.EVENT_CHECK_CHANGED).tryEmit("check_changed")
binding.executePendingBindings() binding.executePendingBindings()
} }
} }

View File

@@ -9,6 +9,7 @@ import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.impl.FlowBus import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.bean.GjcMaWb import com.lukouguoji.module_base.bean.GjcMaWb
import com.lukouguoji.module_base.ktx.refresh import com.lukouguoji.module_base.ktx.refresh
import com.lukouguoji.module_base.ktx.ITEM_CLICK_TYPE_CUSTOMS_RESPONSE
/** /**
* 国际出港-出港理货 ViewHolder * 国际出港-出港理货 ViewHolder
@@ -22,6 +23,12 @@ class IntExpTallyViewHolder(view: View) :
binding.position = position binding.position = position
binding.executePendingBindings() binding.executePendingBindings()
// 侧滑菜单 - 回执按钮(关闭侧滑后分发到 ViewModel
binding.btnResponse.setOnClickListener {
binding.swipeMenu.quickClose()
clickListener?.onItemClick(position, ITEM_CLICK_TYPE_CUSTOMS_RESPONSE)
}
// 图标点击切换选择状态(主单和分单独立,互不干扰) // 图标点击切换选择状态(主单和分单独立,互不干扰)
binding.ivIcon.setOnClickListener { binding.ivIcon.setOnClickListener {
bean.checked.set(!bean.checked.get()) bean.checked.set(!bean.checked.get())

View File

@@ -4,6 +4,7 @@ import android.app.Activity
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.alibaba.android.arouter.facade.annotation.Route import com.alibaba.android.arouter.facade.annotation.Route
import com.lukouguoji.gjc.R import com.lukouguoji.gjc.R
@@ -66,8 +67,17 @@ class IntExpAssembleStartActivity :
setBackArrow("国际出港开始组装") setBackArrow("国际出港开始组装")
binding.viewModel = viewModel binding.viewModel = viewModel
// 为ULD编号添加大写字母和数字的输入限制 // 为ULD编号、IMP代码添加大写字母和数字的输入限制
binding.uldNoInput.et.setUpperCaseAlphanumericFilter() binding.uldNoInput.et.setUpperCaseAlphanumericFilter()
binding.impCodeInput.et.setUpperCaseAlphanumericFilter()
// 板型:手动输入 + 下拉选择组合框。箭头复用 Spinner 同款背景绘制(同资源、同尺寸、同边距),
// 图标位不放图片,仅作为覆盖在箭头上的透明点击区域(点击事件由布局 setOnIconClickListener 绑定)
binding.boardTypeInput.apply {
ll.setBackgroundResource(com.lukouguoji.module_base.R.drawable.bg_data_layout_new_dropdown)
iv.setImageDrawable(null)
iv.visibility = View.VISIBLE
}
// 初始化列表 // 初始化列表
initRecyclerViews() initRecyclerViews()
@@ -81,6 +91,9 @@ class IntExpAssembleStartActivity :
// 加载组装人列表 // 加载组装人列表
viewModel.loadAssemblerList() viewModel.loadAssemblerList()
// 加载板型选项列表
viewModel.loadBoardTypeList()
// 监听登出事件,清空缓存 // 监听登出事件,清空缓存
FlowBus.with<Any>(ConstantEvent.LOGOUT).observe(this) { FlowBus.with<Any>(ConstantEvent.LOGOUT).observe(this) {
viewModel.clearCachedOperator() viewModel.clearCachedOperator()

View File

@@ -0,0 +1,68 @@
package com.lukouguoji.gjc.page.move
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.alibaba.android.arouter.facade.annotation.Route
import com.lukouguoji.gjc.R
import com.lukouguoji.gjc.databinding.ActivityIntExpMoveEditBinding
import com.lukouguoji.gjc.viewModel.IntExpMoveEditViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.DetailsPageType
import com.lukouguoji.module_base.ktx.addOnItemClickListener
import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.router.ARouterConstants
/**
* 国际出港移库编辑/详情页
* 编辑模式仅支持拍照上传与备注修改
*/
@Route(path = ARouterConstants.ACTIVITY_URL_INT_EXP_MOVE_EDIT)
class IntExpMoveEditActivity :
BaseBindingActivity<ActivityIntExpMoveEditBinding, IntExpMoveEditViewModel>() {
override fun layoutId() = R.layout.activity_int_exp_move_edit
override fun viewModelClass() = IntExpMoveEditViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
viewModel.initOnCreated(intent)
when (viewModel.pageType.value) {
DetailsPageType.Modify -> setBackArrow("国际出港移库编辑")
else -> setBackArrow("国际出港移库详情")
}
binding.viewModel = viewModel
// 绑定图片 RecyclerView 引用
viewModel.rvImages = binding.rvImages
// 绑定图片列表点击事件(编辑模式下可删除图片)
binding.rvImages.addOnItemClickListener(viewModel)
// 监听图片列表变化并更新 adapter
viewModel.imageList.observe(this) { images ->
binding.rvImages.commonAdapter()?.refresh(images)
}
}
companion object {
@JvmStatic
fun startForEdit(context: Context, maWbId: Long?) {
val starter = Intent(context, IntExpMoveEditActivity::class.java)
.putExtra(Constant.Key.PAGE_TYPE, DetailsPageType.Modify.name)
.putExtra(Constant.Key.ID, maWbId?.toString() ?: "")
context.startActivity(starter)
}
@JvmStatic
fun startForDetails(context: Context, maWbId: Long?) {
val starter = Intent(context, IntExpMoveEditActivity::class.java)
.putExtra(Constant.Key.PAGE_TYPE, DetailsPageType.Details.name)
.putExtra(Constant.Key.ID, maWbId?.toString() ?: "")
context.startActivity(starter)
}
}
}

View File

@@ -15,6 +15,9 @@ 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.commonAdapter import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.CustomsResponseUrl
import com.lukouguoji.module_base.ktx.ITEM_CLICK_TYPE_CUSTOMS_RESPONSE
import com.lukouguoji.module_base.ktx.showCustomsResponse
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
@@ -344,4 +347,14 @@ class IntExpArriveViewModel : BasePageViewModel() {
} }
} }
} }
/**
* 列表项点击分发:侧滑「回执」按钮 → 查询海关回执并跳转只读详情页
*/
override fun onItemClick(position: Int, type: Int) {
val bean = pageModel.rv?.commonAdapter()?.getItem(position) as? GjcMaWb ?: return
if (type == ITEM_CLICK_TYPE_CUSTOMS_RESPONSE) {
showCustomsResponse(CustomsResponseUrl.INT_EXP_ARRIVE, bean.prefix, bean.no, "出港运抵回执")
}
}
} }

View File

@@ -2,6 +2,7 @@ package com.lukouguoji.gjc.viewModel
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.alibaba.fastjson.JSONArray
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
@@ -16,8 +17,11 @@ 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.toJson
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.Common
import com.lukouguoji.module_base.util.DictUtils
import dev.utils.app.info.KeyValue import dev.utils.app.info.KeyValue
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -75,6 +79,12 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
// ========== 组装人列表 ========== // ========== 组装人列表 ==========
val assemblerList = MutableLiveData<List<KeyValue>>(emptyList()) val assemblerList = MutableLiveData<List<KeyValue>>(emptyList())
// ========== BUP选项01默认否 ==========
val bupFlagList = listOf(KeyValue("", "0"), KeyValue("", "1"))
// ========== 板型选项(字典;支持下拉选择,也支持手动输入)==========
val boardTypeList = MutableLiveData<List<KeyValue>>(emptyList())
// ========== 标记位,避免重复查询 ========== // ========== 标记位,避免重复查询 ==========
private var lastQueriedUldNo = "" private var lastQueriedUldNo = ""
@@ -107,6 +117,12 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
*/ */
val isLoadEnabled = MutableLiveData(true) val isLoadEnabled = MutableLiveData(true)
/**
* 本页面是否已至少一次装货成功
* 首次装货成功前,运单列表件数/重量列显示总数;成功后显示“剩余/总数”
*/
val hasLoadedOnce = MutableLiveData(false)
/** /**
* 卸货按钮启用状态(编辑模式时启用) * 卸货按钮启用状态(编辑模式时启用)
*/ */
@@ -274,6 +290,27 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
ScanModel.startScan(getTopActivity(), Constant.RequestCode.WAYBILL) ScanModel.startScan(getTopActivity(), Constant.RequestCode.WAYBILL)
} }
/**
* 待组装运单接口数据转右侧运单列表 Bean
* 同时带上已组装件数/重量与“剩余/总数”显示开关(首次装货成功后生效)
*/
private fun GjcWarehouse.toAssembleWaybillBean(): AssembleWaybillBean {
val warehouse = this
return 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 // 运单ID用于接口调用
isMarked = false
checkInPieces = warehouse.checkInPc
checkInWeight = warehouse.checkInWeight
showRemaining = hasLoadedOnce.value == true
}
}
/** /**
* 加载待组装运单列表 * 加载待组装运单列表
*/ */
@@ -285,18 +322,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
onSuccess = { result -> onSuccess = { result ->
// 数据转换: GjcWarehouse -> AssembleWaybillBean // 数据转换: GjcWarehouse -> AssembleWaybillBean
val warehouseList = result.data ?: mutableListOf() val warehouseList = result.data ?: mutableListOf()
val waybillBeanList = warehouseList.map { warehouse -> val waybillBeanList = warehouseList.map { it.toAssembleWaybillBean() }.toMutableList()
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 // 添加运单ID
isMarked = false
}
}.toMutableList()
// 更新列表 // 更新列表
waybillList.value = waybillBeanList waybillList.value = waybillBeanList
@@ -335,18 +361,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
launchLoadingCollect({ NetApply.api.queryWaitingAssemble("") }) { launchLoadingCollect({ NetApply.api.queryWaitingAssemble("") }) {
onSuccess = { result -> onSuccess = { result ->
val warehouseList = result.data ?: mutableListOf() val warehouseList = result.data ?: mutableListOf()
val waybillBeanList = warehouseList.map { warehouse -> val waybillBeanList = warehouseList.map { it.toAssembleWaybillBean() }.toMutableList()
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 // 添加运单ID
isMarked = false
}
}.toMutableList()
waybillList.value = waybillBeanList waybillList.value = waybillBeanList
@@ -399,6 +414,37 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
} }
/**
* 加载板型选项列表(字典)
*/
fun loadBoardTypeList() {
DictUtils.getBoardTypeList { boardTypeList.value = it }
}
/**
* 板型下拉图标点击:弹出选项列表,选中后回填到板型输入框(回填后仍可手动修改)
*/
fun onBoardTypeSelectClick() {
val list = boardTypeList.value ?: emptyList()
if (list.isEmpty()) {
showToast("暂无板型选项,请手动输入")
return
}
val jsonArray = JSONArray.parseArray(
list.map { mapOf("name" to it.key, "code" to it.value) }.toJson(false)
)
Common.singleSelect(
getTopActivity(),
"选择板型",
jsonArray,
uldInfo.value?.boardType
) { position, _ ->
uldInfo.value = uldInfo.value?.apply {
boardType = list.getOrNull(position)?.value ?: ""
}
}
}
/** /**
* ULD编号输入完成时调用 * ULD编号输入完成时调用
*/ */
@@ -433,6 +479,10 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
} }
// 保存useId用于装货/卸货接口) // 保存useId用于装货/卸货接口)
useId = uldBean.useId useId = uldBean.useId
// 回填 IMP代码 / 板型 / BUP服务端有值时覆盖修改模式回显为空时保留当前输入
if (!uldBean.dgrCode.isNullOrEmpty()) dgrCode = uldBean.dgrCode
if (!uldBean.boardType.isNullOrEmpty()) boardType = uldBean.boardType
if (!uldBean.bupFlag.isNullOrEmpty()) bupFlag = uldBean.bupFlag
} }
// 【新增】从ULD信息提取航班信息 // 【新增】从ULD信息提取航班信息
@@ -601,9 +651,17 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
val loadAreaId = selectedPosition.value?.positionCode?.trim() ?: "" val loadAreaId = selectedPosition.value?.positionCode?.trim() ?: ""
// IMP代码 / 板型 / BUP接口新增字段useInfo 与顶层参数均需携带)
val dgrCode = uldInfo.value?.dgrCode?.trim() ?: ""
val boardType = uldInfo.value?.boardType?.trim() ?: ""
val bupFlag = uldInfo.value?.bupFlag?.ifEmpty { "0" } ?: "0"
// 2. 构建useInfoULD信息 // 2. 构建useInfoULD信息
val useInfo = mapOf( val useInfo = mapOf(
"uld" to uldNo, "uld" to uldNo,
"dgrCode" to dgrCode.ifEmpty { null },
"boardType" to boardType.ifEmpty { null },
"bupFlag" to bupFlag,
"consumeWeight" to materialWeight.toDoubleOrNull(), "consumeWeight" to materialWeight.toDoubleOrNull(),
"status" to when (uldInfo.value?.uldStatus) { "status" to when (uldInfo.value?.uldStatus) {
"正常" -> "0" "正常" -> "0"
@@ -688,6 +746,9 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
"ldId" to operatorValue, "ldId" to operatorValue,
"loadArea" to loadArea, "loadArea" to loadArea,
"loadAreaId" to loadAreaId.ifEmpty { null }, // 组装位置ID "loadAreaId" to loadAreaId.ifEmpty { null }, // 组装位置ID
"dgrCode" to dgrCode.ifEmpty { null }, // IMP代码
"boardType" to boardType.ifEmpty { null }, // 板型
"bupFlag" to bupFlag, // BUP选项01
"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)
@@ -724,6 +785,11 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
) { ) {
showToast("${operationName}成功") showToast("${operationName}成功")
// 首次装货成功后,运单列表件数/重量列切换为“剩余/总数”显示
if (isLoad) {
hasLoadedOnce.value = true
}
// 发送刷新事件,通知出港组装列表页面更新数据 // 发送刷新事件,通知出港组装列表页面更新数据
viewModelScope.launch { viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh") FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
@@ -780,18 +846,7 @@ class IntExpAssembleStartViewModel : BaseViewModel() {
launchLoadingCollect({ NetApply.api.queryWaitingAssemble(wbNo) }) { launchLoadingCollect({ NetApply.api.queryWaitingAssemble(wbNo) }) {
onSuccess = { result -> onSuccess = { result ->
val warehouseList = result.data ?: mutableListOf() val warehouseList = result.data ?: mutableListOf()
val waybillBeanList = warehouseList.map { warehouse -> val waybillBeanList = warehouseList.map { it.toAssembleWaybillBean() }.toMutableList()
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 waybillList.value = waybillBeanList
} }

View File

@@ -15,6 +15,9 @@ 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.commonAdapter import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.CustomsResponseUrl
import com.lukouguoji.module_base.ktx.ITEM_CLICK_TYPE_CUSTOMS_RESPONSE
import com.lukouguoji.module_base.ktx.showCustomsResponse
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.noNull import com.lukouguoji.module_base.ktx.noNull
@@ -310,4 +313,14 @@ class IntExpLoadViewModel : BasePageViewModel() {
} }
} }
} }
/**
* 列表项点击分发:侧滑「回执」按钮 → 查询海关回执并跳转只读详情页
*/
override fun onItemClick(position: Int, type: Int) {
val bean = pageModel.rv?.commonAdapter()?.getItem(position) as? GjcExportLoad ?: return
if (type == ITEM_CLICK_TYPE_CUSTOMS_RESPONSE) {
showCustomsResponse(CustomsResponseUrl.INT_EXP_LOAD, bean.prefix, bean.no, "出港装载回执")
}
}
} }

View File

@@ -0,0 +1,164 @@
package com.lukouguoji.gjc.viewModel
import android.content.Intent
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import androidx.recyclerview.widget.RecyclerView
import com.lukouguoji.gjc.R
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.FileBean
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.common.DetailsPageType
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.impl.ImageSelectNewViewHolder
import com.lukouguoji.module_base.interfaces.IOnItemClickListener
import com.lukouguoji.module_base.ktx.commonAdapter
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.util.MediaUtil
import com.lukouguoji.module_base.util.UploadUtil
import kotlinx.coroutines.launch
/**
* 国际出港移库编辑/详情 ViewModel
* 编辑模式仅支持修改备注与交接图片
*/
class IntExpMoveEditViewModel : BaseViewModel(), IOnItemClickListener {
val pageType = MutableLiveData(DetailsPageType.Details)
private var maWbId: Long = 0L
val dataBean = MutableLiveData(GjcMaWb())
// 备注单独用 LiveData 双向绑定,避免修改 data class 属性后需重新赋值
val remark = MutableLiveData("")
// 图片列表
val imageList = MutableLiveData<MutableList<FileBean>>(mutableListOf())
// 图片适配器配置
val imageItemLayoutId = R.layout.item_image_select_new
val imageItemViewHolder = ImageSelectNewViewHolder::class.java
// 详情模式下无图片时显示占位提示
val showNoImage = MutableLiveData(false)
// 图片 RecyclerView 引用(用于从 adapter 实时获取图片)
var rvImages: RecyclerView? = null
fun initOnCreated(intent: Intent) {
pageType.value = DetailsPageType.valueOf(
intent.getStringExtra(Constant.Key.PAGE_TYPE) ?: DetailsPageType.Details.name
)
maWbId = intent.getStringExtra(Constant.Key.ID)?.toLongOrNull() ?: 0L
loadData()
}
private fun loadData() {
launchLoadingCollect({ NetApply.api.getIntExpMoveDetail(maWbId) }) {
onSuccess = {
val bean = it.data ?: GjcMaWb()
// 详情接口 wbNo 可能为空,回退为 前缀 + 运单号
if (bean.wbNo.isNullOrEmpty()) {
bean.wbNo = (bean.prefix ?: "") + (bean.no ?: "")
}
dataBean.value = bean
remark.value = bean.remark ?: ""
// 处理图片列表(同时保留缩略图和原图信息,确保二次编辑时不丢失)
val picList = (bean.pic ?: "").split(",").filter { p -> p.isNotEmpty() }
val originalPicList = (bean.originalPic ?: "").split(",").filter { p -> p.isNotEmpty() }
val images = if (picList.isNotEmpty()) {
picList.mapIndexed { index, picUrl ->
val originalUrl = originalPicList.getOrElse(index) { picUrl }
FileBean(
path = MediaUtil.fillUrl(originalUrl),
url = picUrl,
originalPic = originalUrl
)
}.toMutableList()
} else {
originalPicList.map { url ->
FileBean(path = MediaUtil.fillUrl(url), url = url, originalPic = url)
}.toMutableList()
}
// 编辑模式添加空 FileBean 用于显示“添加照片”按钮
if (pageType.value == DetailsPageType.Modify) {
images.add(FileBean())
}
imageList.value = images
// 详情模式下无图片时显示占位提示
showNoImage.value = pageType.value == DetailsPageType.Details && images.isEmpty()
}
}
}
/**
* 提交保存(只保存备注和图片)
*/
fun submit() {
// 从 adapter 实时获取所有非空图片ViewHolder 新增图片直接操作 adapter items
val allItems = (rvImages?.commonAdapter()?.items as? List<*>)
?.filterIsInstance<FileBean>() ?: imageList.value!!
val images = allItems.filter { it.path.isNotEmpty() }
if (images.size > 7) {
showToast("最多上传7张图片")
return
}
launchLoadingCollect({
// 上传本地新图片;已上传的图片保持原有 url 与 originalPic
images.forEach { fileBean ->
if (fileBean.url.isEmpty()) {
// UploadUtil 返回newName=原图(较大)zipFileName=缩略图(较小)
// FileBean.url 用作缩略图标识FileBean.originalPic 用作原图标识
val data = UploadUtil.upload(fileBean.path).data
fileBean.url = data?.zipFileName ?: ""
fileBean.originalPic = data?.newName ?: ""
}
}
val params = mapOf(
"maWbId" to maWbId,
"remark" to (remark.value ?: ""),
"picNumber" to images.size.toString(),
"pic" to images.joinToString(",") { MediaUtil.removeUrl(it.url) },
"originalPic" to images.joinToString(",") { MediaUtil.removeUrl(it.originalPic) },
).toRequestBody(removeEmptyOrNull = true)
NetApply.api.updateIntExpMove(params)
}) {
onSuccess = {
showToast("保存成功")
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
getTopActivity().finish()
}
}
}
fun cancel() {
getTopActivity().finish()
}
/**
* 处理图片删除点击事件
*/
override fun onItemClick(position: Int, type: Int) {
if (type == R.id.iv_delete) {
val adapter = rvImages?.commonAdapter() ?: return
if (position < adapter.items.size) {
adapter.removeItem(position)
}
}
}
}

View File

@@ -106,6 +106,36 @@ class IntExpOutHandoverViewModel : BasePageViewModel() {
} }
} }
/**
* 允许装机(多选,批量操作)
*/
fun allowLoadClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcUldUseBean> ?: return
val selectedItems = list.filter { it.isSelected }
if (selectedItems.isEmpty()) {
showToast("请选择要允许装机的ULD")
return
}
if (selectedItems.all { it.isAllowLoad }) {
showToast("所选ULD均已允许装机")
return
}
val requestData = selectedItems.toRequestBody()
launchLoadingCollect({ NetApply.api.allowLoading(requestData) }) {
onSuccess = {
showToast("允许装机成功")
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
refresh()
}
}
}
/** /**
* 待配运按钮点击 * 待配运按钮点击
*/ */

View File

@@ -16,6 +16,9 @@ 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.commonAdapter import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.CustomsResponseUrl
import com.lukouguoji.module_base.ktx.ITEM_CLICK_TYPE_CUSTOMS_RESPONSE
import com.lukouguoji.module_base.ktx.showCustomsResponse
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
@@ -42,7 +45,8 @@ class IntExpTallyViewModel : BasePageViewModel() {
val totalWeight = MutableLiveData("0") // 总重量 val totalWeight = MutableLiveData("0") // 总重量
// ========== 全选状态 ========== // ========== 全选状态 ==========
val isAllChecked = MutableLiveData(false) val isAllChecked = MutableLiveData(false) // 主单全选状态
val isAllHaWbChecked = MutableLiveData(false) // 分单全选状态(仅统计允许全选的主单下的分单)
fun onItemCheckChanged() { fun onItemCheckChanged() {
updateCheckAllStatus() updateCheckAllStatus()
@@ -51,6 +55,10 @@ class IntExpTallyViewModel : BasePageViewModel() {
fun updateCheckAllStatus() { fun updateCheckAllStatus() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return
isAllChecked.value = list.isNotEmpty() && list.all { it.checked.get() } isAllChecked.value = list.isNotEmpty() && list.all { it.checked.get() }
// 分单全选状态:只看允许全选的主单下的分单
val eligibleHaWbList = list.filter { it.canCheckAllHaWb }.flatMap { it.haWbList ?: emptyList() }
isAllHaWbChecked.value = eligibleHaWbList.isNotEmpty() && eligibleHaWbList.all { it.checked.get() }
} }
// ========== 全局展开状态 ========== // ========== 全局展开状态 ==========
@@ -86,6 +94,43 @@ class IntExpTallyViewModel : BasePageViewModel() {
pageModel.rv?.commonAdapter()?.notifyDataSetChanged() pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
} }
/**
* 分单全选按钮点击 (只切换分单的选中状态,主单选择独立)
* 规则:主单存在分批申报(接口 allTally=0不允许选中该主单下的分单
* 只有主单全部申报完毕allTally=1才允许全选其分单。
*/
fun checkAllHaWbClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjcMaWb> ?: return
val shouldCheckAll = !isAllHaWbChecked.value!!
var eligibleCount = 0 // 允许全选的分单数
var skippedMaWbCount = 0 // 因未全部申报而跳过的主单数
list.forEach { maWb ->
val haWbList = maWb.haWbList
if (haWbList.isNullOrEmpty()) return@forEach
if (maWb.canCheckAllHaWb) {
eligibleCount += haWbList.size
haWbList.forEach { it.checked.set(shouldCheckAll) }
} else if (shouldCheckAll) {
// 主单未全部申报完毕,跳过其分单(保持原有选中状态不变)
skippedMaWbCount++
}
}
isAllHaWbChecked.value = shouldCheckAll && eligibleCount > 0
if (shouldCheckAll) {
if (eligibleCount == 0) {
showToast("暂无可全选的分单,主单需全部申报完毕后才可全选其分单")
} else if (skippedMaWbCount > 0) {
showToast("${skippedMaWbCount}票主单未全部申报完毕,其分单未选中")
}
}
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
}
/** /**
* 切换全局展开/收起状态 * 切换全局展开/收起状态
*/ */
@@ -344,4 +389,14 @@ class IntExpTallyViewModel : BasePageViewModel() {
} }
} }
} }
/**
* 列表项点击分发:侧滑「回执」按钮 → 查询海关回执并跳转只读详情页
*/
override fun onItemClick(position: Int, type: Int) {
val bean = pageModel.rv?.commonAdapter()?.getItem(position) as? GjcMaWb ?: return
if (type == ITEM_CLICK_TYPE_CUSTOMS_RESPONSE) {
showCustomsResponse(CustomsResponseUrl.INT_EXP_TALLY, bean.prefix, bean.no, "出港理货回执")
}
}
} }

View File

@@ -190,7 +190,7 @@
android:layout_width="120dp" android:layout_width="120dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:text="件数" android:text='@{viewModel.hasLoadedOnce ? "剩余件数/总件数" : "件数"}'
android:textColor="@color/text_normal" android:textColor="@color/text_normal"
android:textSize="13sp" /> android:textSize="13sp" />
@@ -199,7 +199,7 @@
android:layout_width="120dp" android:layout_width="120dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:text="重量" android:text='@{viewModel.hasLoadedOnce ? "剩余重量/总重量" : "重量"}'
android:textColor="@color/text_normal" android:textColor="@color/text_normal"
android:textSize="13sp" /> android:textSize="13sp" />
@@ -293,6 +293,54 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" /> android:layout_weight="1" />
</LinearLayout> </LinearLayout>
<!-- 第二行IMP代码、板型下拉选择 + 手动输入、BUP -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:id="@+id/impCodeInput"
enable="@{true}"
hint='@{"请输入IMP代码"}'
required="@{false}"
title='@{"IMP代码"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value="@={viewModel.uldInfo.dgrCode}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:id="@+id/boardTypeInput"
enable="@{true}"
hint='@{"请输入或选择"}'
required="@{false}"
setOnIconClickListener="@{(v) -> viewModel.onBoardTypeSelectClick()}"
setTextAllCaps="@{true}"
title='@{"板型:"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value="@={viewModel.uldInfo.boardType}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
enable="@{true}"
list="@{viewModel.bupFlagList}"
required="@{false}"
title='@{"BUP"}'
titleLength="@{5}"
type="@{DataLayoutType.SPINNER}"
value="@={viewModel.uldInfo.bupFlag}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout> </LinearLayout>
<!-- 运单信息卡片 --> <!-- 运单信息卡片 -->

View File

@@ -0,0 +1,259 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="com.lukouguoji.module_base.ui.weight.data.layout.DataLayoutType" />
<import type="com.lukouguoji.module_base.common.DetailsPageType" />
<import type="android.view.View" />
<variable
name="viewModel"
type="com.lukouguoji.gjc.viewModel.IntExpMoveEditViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_f2"
android:orientation="vertical">
<include layout="@layout/title_tool_bar" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="15dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_8"
android:orientation="vertical"
android:padding="15dp">
<!-- 第一行:运单号、件数、重量(均只读) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"运单号"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.wbNo}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"件数"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.pc == null ? "" : String.valueOf(viewModel.dataBean.pc)}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"重量"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.weight == null ? "" : String.valueOf(viewModel.dataBean.weight)}' />
</LinearLayout>
<!-- 第二行:特码、代理人、品名(均只读) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"特码"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.spCode}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"代理人"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.agentCode}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"品名"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.goodsCn == null || viewModel.dataBean.goodsCn.isEmpty() ? viewModel.dataBean.goods : viewModel.dataBean.goodsCn}' />
</LinearLayout>
<!-- 第三行:出港航班、出运路径、运单类型(均只读) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"出港航班"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.flightInfo}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"出运路径"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.rangeText}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"运单类型"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.awbName}' />
</LinearLayout>
<!-- 第四行:承运人(只读)、备注(编辑模式可编辑) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
enable="@{false}"
title='@{"承运人"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@{viewModel.dataBean.by1}' />
<com.lukouguoji.module_base.ui.weight.data.layout.PadDataLayoutNew
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
enable="@{viewModel.pageType != DetailsPageType.Details}"
hint='@{"请输入备注"}'
title='@{"备注"}'
titleLength="@{5}"
type="@{DataLayoutType.INPUT}"
value='@={viewModel.remark}' />
</LinearLayout>
<!-- 交接图片区域label 在左,图片在右 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="交接图片"
android:textColor="@color/text_gray"
completeSpace="@{5}" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_images"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:overScrollMode="never"
itemLayoutId="@{viewModel.imageItemLayoutId}"
viewHolder="@{viewModel.imageItemViewHolder}"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="9" />
</LinearLayout>
<!-- 详情模式下无图片时的占位提示 -->
<TextView
android:id="@+id/tv_no_image"
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="center"
android:text="暂无图片"
android:textColor="@color/text_gray"
android:textSize="14sp"
android:visibility="@{viewModel.showNoImage ? View.VISIBLE : View.GONE}" />
</LinearLayout>
<!-- 底部按钮(详情模式不显示) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginBottom="15dp"
android:gravity="center"
android:orientation="horizontal"
android:visibility="@{viewModel.pageType != DetailsPageType.Details ? View.VISIBLE : View.GONE}">
<TextView
style="@style/tv_bottom_btn"
android:layout_width="120dp"
android:onClick="@{()-> viewModel.cancel()}"
android:text="取消" />
<TextView
style="@style/tv_bottom_btn"
android:layout_width="120dp"
android:onClick="@{()-> viewModel.submit()}"
android:text="保存" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
</layout>

View File

@@ -173,6 +173,12 @@
</LinearLayout> </LinearLayout>
<!-- 允许装机按钮(多选) -->
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()-> viewModel.allowLoadClick()}"
android:text="允许装机" />
<!-- 待配运按钮 --> <!-- 待配运按钮 -->
<TextView <TextView
style="@style/tv_bottom_btn" style="@style/tv_bottom_btn"

View File

@@ -167,6 +167,32 @@
</LinearLayout> </LinearLayout>
<!-- 分单全选按钮(仅选中已全部申报完毕的主单下的分单) -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginEnd="5dp"
android:gravity="center_vertical"
android:onClick="@{()-> viewModel.checkAllHaWbClick()}"
android:orientation="horizontal">
<ImageView
setIVCheckAllImage="@{viewModel.isAllHaWbChecked}"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginEnd="5dp"
android:src="@drawable/img_check_all_unchecked" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="分单全选"
android:textColor="@color/color_66"
android:textSize="18sp" />
</LinearLayout>
<!-- 统计信息 --> <!-- 统计信息 -->
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"

View File

@@ -55,7 +55,7 @@
android:layout_width="120dp" android:layout_width="120dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:text="@{bean.pieces}" android:text="@{bean.piecesDisplay}"
android:textColor="@{bean.isMarked ? @color/text_red : @color/text_normal}" android:textColor="@{bean.isMarked ? @color/text_red : @color/text_normal}"
android:textSize="14sp" /> android:textSize="14sp" />
@@ -64,7 +64,7 @@
android:layout_width="120dp" android:layout_width="120dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:text="@{bean.weight}" android:text="@{bean.weightDisplay}"
android:textColor="@{bean.isMarked ? @color/text_red : @color/text_normal}" android:textColor="@{bean.isMarked ? @color/text_red : @color/text_normal}"
android:textSize="14sp" /> android:textSize="14sp" />

View File

@@ -22,6 +22,12 @@
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:orientation="vertical"> android:orientation="vertical">
<!-- 侧滑布局:白色卡片(含展开按钮)+ 侧滑菜单 -->
<com.mcxtzhang.swipemenulib.SwipeMenuLayout
android:id="@+id/swipe_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 白色卡片 --> <!-- 白色卡片 -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -353,6 +359,23 @@
</LinearLayout> </LinearLayout>
<!-- 侧滑菜单区 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- 回执按钮 -->
<TextView
android:id="@+id/btnResponse"
style="@style/tv_item_action"
android:background="@color/colorPrimary"
android:text="回执" />
</LinearLayout>
</com.mcxtzhang.swipemenulib.SwipeMenuLayout>
<!-- 子订单列表容器(白色圆角卡片,圆角同主单) --> <!-- 子订单列表容器(白色圆角卡片,圆角同主单) -->
<LinearLayout <LinearLayout
visible="@{bean.showMore}" visible="@{bean.showMore}"

View File

@@ -20,6 +20,18 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp" android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:orientation="vertical">
<!-- 侧滑布局:白色卡片 + 侧滑菜单 -->
<com.mcxtzhang.swipemenulib.SwipeMenuLayout
android:id="@+id/swipe_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 白色卡片 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_8" android:background="@drawable/bg_white_radius_8"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal" android:orientation="horizontal"
@@ -300,4 +312,23 @@
</LinearLayout> </LinearLayout>
<!-- 侧滑菜单区 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- 回执按钮 -->
<TextView
android:id="@+id/btnResponse"
style="@style/tv_item_action"
android:background="@color/colorPrimary"
android:text="回执" />
</LinearLayout>
</com.mcxtzhang.swipemenulib.SwipeMenuLayout>
</LinearLayout>
</layout> </layout>

View File

@@ -21,8 +21,15 @@
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:orientation="vertical"> android:orientation="vertical">
<!-- 侧滑布局 -->
<com.mcxtzhang.swipemenulib.SwipeMenuLayout
android:id="@+id/swipe_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 白色卡片 --> <!-- 白色卡片 -->
<LinearLayout <LinearLayout
android:id="@+id/ll"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_8" android:background="@drawable/bg_white_radius_8"
@@ -312,8 +319,33 @@
</LinearLayout> </LinearLayout>
<!-- 右侧箭头 -->
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:src="@drawable/img_pda_right" />
</LinearLayout> </LinearLayout>
<!-- 侧滑菜单区域 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- 编辑按钮 -->
<TextView
android:id="@+id/btn_edit"
style="@style/tv_item_action"
android:background="@color/colorPrimary"
android:text="编辑" />
</androidx.appcompat.widget.LinearLayoutCompat>
</com.mcxtzhang.swipemenulib.SwipeMenuLayout>
</LinearLayout> </LinearLayout>
</layout> </layout>

View File

@@ -54,7 +54,7 @@
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1.1" android:layout_weight="1.0"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
@@ -77,7 +77,7 @@
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="0.8"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
@@ -100,7 +100,7 @@
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0.8" android:layout_weight="0.7"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
@@ -123,7 +123,7 @@
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0.8" android:layout_weight="0.75"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
@@ -146,7 +146,7 @@
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1.2" android:layout_weight="1.3"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
@@ -165,6 +165,30 @@
</LinearLayout> </LinearLayout>
<!-- 装机状态(允许装机绿色,不允许装机红色) -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="装机状态:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.allowLoadText}"
android:textColor="@{bean.isAllowLoad() ? @color/text_green : @color/text_red}"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout> </LinearLayout>
<!-- 第二行目的港、库位号、IMP代码、交接人、交接时间 --> <!-- 第二行目的港、库位号、IMP代码、交接人、交接时间 -->
@@ -179,7 +203,7 @@
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1.1" android:layout_weight="1.0"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
@@ -202,7 +226,7 @@
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="0.8"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
@@ -225,7 +249,7 @@
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0.8" android:layout_weight="0.7"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
@@ -249,7 +273,7 @@
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0.8" android:layout_weight="0.75"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
@@ -272,7 +296,7 @@
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1.2" android:layout_weight="1.3"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
@@ -291,6 +315,12 @@
</LinearLayout> </LinearLayout>
<!-- 占位(与第一行装机状态列等宽,保持列对齐) -->
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_weight="1.0" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View File

@@ -7,6 +7,12 @@
</data> </data>
<!-- 主列表项容器 --> <!-- 主列表项容器 -->
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="10dp" android:layout_marginTop="10dp" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="10dp" android:layout_marginTop="10dp" android:orientation="vertical">
<!-- 侧滑布局:白色卡片(含展开按钮)+ 侧滑菜单 -->
<com.mcxtzhang.swipemenulib.SwipeMenuLayout
android:id="@+id/swipe_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 白色卡片主要内容区域 --> <!-- 白色卡片主要内容区域 -->
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/bg_white_radius_8" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/bg_white_radius_8" android:orientation="vertical">
<!-- 主要内容区域 --> <!-- 主要内容区域 -->
@@ -83,6 +89,23 @@
android:scaleType="center" android:scaleType="center"
android:src="@mipmap/img_down" /> android:src="@mipmap/img_down" />
</LinearLayout> </LinearLayout>
<!-- 侧滑菜单区 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- 回执按钮 -->
<TextView
android:id="@+id/btnResponse"
style="@style/tv_item_action"
android:background="@color/colorPrimary"
android:text="回执" />
</LinearLayout>
</com.mcxtzhang.swipemenulib.SwipeMenuLayout>
<!-- 子订单列表容器(在白色卡片外面) --> <!-- 子订单列表容器(在白色卡片外面) -->
<LinearLayout visible="@{bean.showMore}" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:background="@drawable/bg_white_radius_8" android:orientation="vertical" android:visibility="gone"> <LinearLayout visible="@{bean.showMore}" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:background="@drawable/bg_white_radius_8" android:orientation="vertical" android:visibility="gone">
<!-- 暂无数据提示 --> <!-- 暂无数据提示 -->

View File

@@ -10,13 +10,11 @@ import com.lukouguoji.gjj.dialog.IntImpInStorageDialogModel
import com.lukouguoji.gjj.dialog.IntImpModifyStorageDialogModel import com.lukouguoji.gjj.dialog.IntImpModifyStorageDialogModel
import com.lukouguoji.gjj.viewModel.IntImpLoadingListViewModel import com.lukouguoji.gjj.viewModel.IntImpLoadingListViewModel
import com.lukouguoji.module_base.base.BaseBindingActivity import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.bean.GjjManifest
import com.lukouguoji.module_base.common.Constant import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.impl.FlowBus import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.impl.observe import com.lukouguoji.module_base.impl.observe
import com.lukouguoji.module_base.ktx.addOnItemClickListener import com.lukouguoji.module_base.ktx.addOnItemClickListener
import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.showToast import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.router.ARouterConstants import com.lukouguoji.module_base.router.ARouterConstants
@@ -78,8 +76,7 @@ class IntImpLoadingListActivity :
* 显示入库操作对话框 * 显示入库操作对话框
*/ */
fun showInStorageDialog() { fun showInStorageDialog() {
val list = viewModel.pageModel.rv?.commonAdapter()?.items as? List<*> ?: return val selectedItems = viewModel.getSelectedManifests()
val selectedItems = list.filterIsInstance<GjjManifest>().filter { it.isSelected }
if (selectedItems.isEmpty()) { if (selectedItems.isEmpty()) {
showToast("请选择要入库的记录") showToast("请选择要入库的记录")
@@ -97,8 +94,7 @@ class IntImpLoadingListActivity :
* 显示修改库位对话框 * 显示修改库位对话框
*/ */
fun showModifyStorageDialog() { fun showModifyStorageDialog() {
val list = viewModel.pageModel.rv?.commonAdapter()?.items as? List<*> ?: return val selectedItems = viewModel.getSelectedManifests()
val selectedItems = list.filterIsInstance<GjjManifest>().filter { it.isSelected }
if (selectedItems.isEmpty()) { if (selectedItems.isEmpty()) {
showToast("请选择要修改库位的记录") showToast("请选择要修改库位的记录")

View File

@@ -9,6 +9,7 @@ import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.impl.FlowBus import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.bean.GjjAirManifest import com.lukouguoji.module_base.bean.GjjAirManifest
import com.lukouguoji.module_base.ktx.refresh import com.lukouguoji.module_base.ktx.refresh
import com.lukouguoji.module_base.ktx.ITEM_CLICK_TYPE_CUSTOMS_RESPONSE
/** /**
* 国际进港原始舱单 ViewHolder * 国际进港原始舱单 ViewHolder
@@ -25,6 +26,12 @@ class IntArrAirManifestViewHolder(view: View) :
binding.position = position binding.position = position
binding.executePendingBindings() binding.executePendingBindings()
// 侧滑菜单 - 回执按钮(关闭侧滑后分发到 ViewModel
binding.btnResponse.setOnClickListener {
binding.swipeMenu.quickClose()
clickListener?.onItemClick(position, ITEM_CLICK_TYPE_CUSTOMS_RESPONSE)
}
// 整卡点击 - 跳转详情页 // 整卡点击 - 跳转详情页
notifyItemClick(position, binding.ll) notifyItemClick(position, binding.ll)

View File

@@ -0,0 +1,26 @@
package com.lukouguoji.gjj.holder
import android.view.View
import com.lukouguoji.gjj.activity.IntImpLoadingListEditActivity
import com.lukouguoji.gjj.databinding.ItemIntImpLoadingListSubBinding
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.GjjManifest
/**
* 国际进港装机单 关联运单(子单) ViewHolder
*/
class IntImpLoadingListSubViewHolder(view: View) :
BaseViewHolder<GjjManifest, ItemIntImpLoadingListSubBinding>(view) {
override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item) ?: return
binding.bean = bean
binding.position = position + 1
binding.executePendingBindings()
// 点击运单行进入装机单编辑
binding.llRow.setOnClickListener {
IntImpLoadingListEditActivity.start(itemView.context, bean)
}
}
}

View File

@@ -1,17 +1,20 @@
package com.lukouguoji.gjj.holder package com.lukouguoji.gjj.holder
import android.view.View import android.view.View
import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.databinding.ItemIntImpLoadingListBinding import com.lukouguoji.gjj.databinding.ItemIntImpLoadingListBinding
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.GjjLoadingUld
import com.lukouguoji.module_base.common.ConstantEvent import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.impl.FlowBus import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.bean.GjjManifest import com.lukouguoji.module_base.ktx.refresh
/** /**
* 国际进港装机单 ViewHolder * 国际进港装机单 ULD 主单 ViewHolder
*/ */
class IntImpLoadingListViewHolder(view: View) : class IntImpLoadingListViewHolder(view: View) :
BaseViewHolder<GjjManifest, ItemIntImpLoadingListBinding>(view) { BaseViewHolder<GjjLoadingUld, ItemIntImpLoadingListBinding>(view) {
override fun onBind(item: Any?, position: Int) { override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item) ?: return val bean = getItemBean(item) ?: return
@@ -26,10 +29,35 @@ class IntImpLoadingListViewHolder(view: View) :
binding.executePendingBindings() binding.executePendingBindings()
} }
// 侧滑菜单 - 编辑按钮 // 展开/收起关联运单
binding.btnEdit.setOnClickListener { binding.ivShow.setOnClickListener {
binding.swipeMenu.quickClose() bean.showMore.set(!bean.showMore.get())
clickListener?.onItemClick(position, 2000) }
// 初始化子列表 RecyclerView
setCommonAdapter(
binding.rvSub,
IntImpLoadingListSubViewHolder::class.java,
R.layout.item_int_imp_loading_list_sub
)
// 刷新子列表数据
val subList = bean.manifestList ?: emptyList()
binding.rvSub.refresh(subList)
updateSubListVisibility(subList.isNotEmpty())
}
private fun updateSubListVisibility(hasData: Boolean) {
if (hasData) {
binding.llHeader.visibility = View.VISIBLE
binding.dividerHeader.visibility = View.VISIBLE
binding.rvSub.visibility = View.VISIBLE
binding.tvEmpty.visibility = View.GONE
} else {
binding.llHeader.visibility = View.GONE
binding.dividerHeader.visibility = View.GONE
binding.rvSub.visibility = View.GONE
binding.tvEmpty.visibility = View.VISIBLE
} }
} }
} }

View File

@@ -13,6 +13,7 @@ import com.google.gson.Gson
import com.lukouguoji.module_base.http.net.NetApply import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.ktx.launchCollect import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.refresh import com.lukouguoji.module_base.ktx.refresh
import com.lukouguoji.module_base.ktx.ITEM_CLICK_TYPE_CUSTOMS_RESPONSE
import com.lukouguoji.module_base.ktx.toRequestBody import com.lukouguoji.module_base.ktx.toRequestBody
/** /**
@@ -27,6 +28,12 @@ class IntImpTallyViewHolder(view: View) :
binding.position = position binding.position = position
binding.executePendingBindings() binding.executePendingBindings()
// 侧滑菜单 - 回执按钮(关闭侧滑后分发到 ViewModel
binding.btnResponse.setOnClickListener {
binding.swipeMenu.quickClose()
clickListener?.onItemClick(position, ITEM_CLICK_TYPE_CUSTOMS_RESPONSE)
}
// 选中图标点击 - 切换选择状态(独立选择,不联动分单) // 选中图标点击 - 切换选择状态(独立选择,不联动分单)
binding.ivIcon.setOnClickListener { binding.ivIcon.setOnClickListener {
bean.checked.set(!bean.checked.get()) bean.checked.set(!bean.checked.get())

View File

@@ -16,6 +16,9 @@ import com.lukouguoji.gjj.dialog.IntImpTallyResetDialogModel
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.commonAdapter import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.CustomsResponseUrl
import com.lukouguoji.module_base.ktx.ITEM_CLICK_TYPE_CUSTOMS_RESPONSE
import com.lukouguoji.module_base.ktx.showCustomsResponse
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
@@ -293,10 +296,19 @@ class IntArrAirManifestViewModel : BasePageViewModel() {
// 获取主单数据 // 获取主单数据
val manifest = airManifest.maWb ?: return val manifest = airManifest.maWb ?: return
// 跳转到详情页 when (type) {
com.lukouguoji.gjj.activity.IntArrAirManifestDetailsActivity.start( // 侧滑「回执」按钮:查询海关回执并跳转只读详情页
ITEM_CLICK_TYPE_CUSTOMS_RESPONSE -> showCustomsResponse(
CustomsResponseUrl.INT_IMP_AIR_MANIFEST,
manifest.prefix,
manifest.no,
"原始舱单回执"
)
// 整卡点击type 为 view id跳转到详情页
else -> com.lukouguoji.gjj.activity.IntArrAirManifestDetailsActivity.start(
getTopActivity(), getTopActivity(),
manifest manifest
) )
} }
} }
}

View File

@@ -5,6 +5,7 @@ import androidx.lifecycle.viewModelScope
import com.lukouguoji.gjj.R import com.lukouguoji.gjj.R
import com.lukouguoji.gjj.holder.IntImpLoadingListViewHolder import com.lukouguoji.gjj.holder.IntImpLoadingListViewHolder
import com.lukouguoji.module_base.base.BasePageViewModel import com.lukouguoji.module_base.base.BasePageViewModel
import com.lukouguoji.module_base.bean.GjjLoadingUld
import com.lukouguoji.module_base.bean.GjjManifest import com.lukouguoji.module_base.bean.GjjManifest
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
@@ -115,10 +116,18 @@ class IntImpLoadingListViewModel : BasePageViewModel(), IOnItemClickListener {
} }
fun updateCheckAllStatus() { fun updateCheckAllStatus() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjManifest> ?: return val list = pageModel.rv?.commonAdapter()?.items as? List<GjjLoadingUld> ?: return
isAllChecked.value = list.isNotEmpty() && list.all { it.checked.get() } isAllChecked.value = list.isNotEmpty() && list.all { it.checked.get() }
} }
/**
* 获取选中 ULD 下的全部运单(供修改库位/入库使用)
*/
fun getSelectedManifests(): List<GjjManifest> {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjLoadingUld> ?: return emptyList()
return list.filter { it.checked.get() }.flatMap { it.manifestList ?: emptyList() }
}
// ========== 适配器配置 ========== // ========== 适配器配置 ==========
val itemViewHolder = IntImpLoadingListViewHolder::class.java val itemViewHolder = IntImpLoadingListViewHolder::class.java
val itemLayoutId = R.layout.item_int_imp_loading_list val itemLayoutId = R.layout.item_int_imp_loading_list
@@ -191,7 +200,7 @@ class IntImpLoadingListViewModel : BasePageViewModel(), IOnItemClickListener {
* 全选按钮点击(切换全选状态) * 全选按钮点击(切换全选状态)
*/ */
fun checkAllClick() { fun checkAllClick() {
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjManifest> ?: return val list = pageModel.rv?.commonAdapter()?.items as? List<GjjLoadingUld> ?: return
// 切换全选状态 // 切换全选状态
val shouldCheckAll = !isAllChecked.value!! val shouldCheckAll = !isAllChecked.value!!
@@ -280,17 +289,9 @@ class IntImpLoadingListViewModel : BasePageViewModel(), IOnItemClickListener {
} }
/** /**
* 列表项点击回调(侧滑菜单 * 列表项点击回调(运单编辑已改为在子列表 ViewHolder 中直接跳转
*/ */
override fun onItemClick(position: Int, type: Int) { override fun onItemClick(position: Int, type: Int) {
when (type) {
2000 -> {
// 编辑操作
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjManifest> ?: return
val bean = list.getOrNull(position) ?: return
com.lukouguoji.gjj.activity.IntImpLoadingListEditActivity.start(getTopActivity(), bean)
}
}
} }
/** /**

View File

@@ -509,7 +509,10 @@ class IntImpManifestViewModel : BasePageViewModel() {
launchLoadingCollect({ NetApply.api.getIntImpLoadingList(queryParams) }) { launchLoadingCollect({ NetApply.api.getIntImpLoadingList(queryParams) }) {
onSuccess = { result -> onSuccess = { result ->
val tallyRecord = result.list?.firstOrNull() // 装机单接口已按 ULD 分组,运单记录在 manifestList 中
val tallyRecord = result.list
?.flatMap { it.manifestList ?: emptyList() }
?.let { list -> list.firstOrNull { it.wbNo == selectedItem.wbNo || it.getWaybillNo() == selectedItem.wbNo } ?: list.firstOrNull() }
showModifyStorageDialog( showModifyStorageDialog(
selectedItems = selectedItems, selectedItems = selectedItems,
currentLocationId = tallyRecord?.locationTallyId?.takeIf { it > 0 }?.toString() ?: "", currentLocationId = tallyRecord?.locationTallyId?.takeIf { it > 0 }?.toString() ?: "",

View File

@@ -16,6 +16,9 @@ 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.commonAdapter import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.CustomsResponseUrl
import com.lukouguoji.module_base.ktx.ITEM_CLICK_TYPE_CUSTOMS_RESPONSE
import com.lukouguoji.module_base.ktx.showCustomsResponse
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
@@ -289,4 +292,14 @@ class IntImpTallyViewModel : BasePageViewModel() {
} }
} }
} }
/**
* 列表项点击分发:侧滑「回执」按钮 → 查询海关回执并跳转只读详情页
*/
override fun onItemClick(position: Int, type: Int) {
val bean = pageModel.rv?.commonAdapter()?.getItem(position) as? GjjImportTally ?: return
if (type == ITEM_CLICK_TYPE_CUSTOMS_RESPONSE) {
showCustomsResponse(CustomsResponseUrl.INT_IMP_TALLY, bean.prefix, bean.no, "进港理货回执")
}
}
} }

View File

@@ -207,7 +207,7 @@
</LinearLayout> </LinearLayout>
<!-- 修改库位按钮 (蓝色) --> <!-- 修改库位按钮 (蓝色):暂时隐藏 -->
<TextView <TextView
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="40dp" android:layout_height="40dp"
@@ -218,9 +218,10 @@
android:onClick="@{()-> activity.showModifyStorageDialog()}" android:onClick="@{()-> activity.showModifyStorageDialog()}"
android:text="修改库位" android:text="修改库位"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="18sp"
android:visibility="gone" />
<!-- 入库按钮 (蓝色) --> <!-- 入库按钮 (蓝色):暂时隐藏 -->
<TextView <TextView
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="40dp" android:layout_height="40dp"
@@ -230,7 +231,8 @@
android:onClick="@{()-> activity.showInStorageDialog()}" android:onClick="@{()-> activity.showInStorageDialog()}"
android:text="入库" android:text="入库"
android:textColor="@color/white" android:textColor="@color/white"
android:textSize="18sp" /> android:textSize="18sp"
android:visibility="gone" />
</LinearLayout> </LinearLayout>

View File

@@ -27,6 +27,12 @@
android:layout_marginVertical="5dp" android:layout_marginVertical="5dp"
android:orientation="vertical"> android:orientation="vertical">
<!-- 侧滑布局:白色卡片(含展开按钮)+ 侧滑菜单 -->
<com.mcxtzhang.swipemenulib.SwipeMenuLayout
android:id="@+id/swipe_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 白色卡片(包含内容区域 + 展开按钮,统一圆角) --> <!-- 白色卡片(包含内容区域 + 展开按钮,统一圆角) -->
<androidx.appcompat.widget.LinearLayoutCompat <androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -323,6 +329,23 @@
</androidx.appcompat.widget.LinearLayoutCompat> </androidx.appcompat.widget.LinearLayoutCompat>
<!-- 侧滑菜单区 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- 回执按钮 -->
<TextView
android:id="@+id/btnResponse"
style="@style/tv_item_action"
android:background="@color/colorPrimary"
android:text="回执" />
</LinearLayout>
</com.mcxtzhang.swipemenulib.SwipeMenuLayout>
<!-- 分单子列表容器(淡绿色背景) --> <!-- 分单子列表容器(淡绿色背景) -->
<LinearLayout <LinearLayout
visible="@{bean.showMore}" visible="@{bean.showMore}"

View File

@@ -8,55 +8,56 @@
<variable <variable
name="bean" name="bean"
type="com.lukouguoji.module_base.bean.GjjManifest" /> type="com.lukouguoji.module_base.bean.GjjLoadingUld" />
<variable <variable
name="position" name="position"
type="Integer" /> type="Integer" />
</data> </data>
<com.mcxtzhang.swipemenulib.SwipeMenuLayout <LinearLayout
android:id="@+id/swipe_menu"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp" android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"> android:layout_marginTop="10dp"
android:orientation="vertical">
<!-- 主内容区域 --> <!-- 白色卡片ULD 主单 -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/bg_white_radius_8" android:background="@drawable/bg_white_radius_8"
android:orientation="horizontal" android:orientation="vertical">
android:paddingVertical="20dp"
android:paddingHorizontal="10dp"
android:gravity="center_vertical">
<!-- 选中图标(飞机图标,根据选择状态切换图片) --> <!-- 主要内容区域 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="10dp"
android:paddingVertical="20dp">
<!-- 选中图标 (飞机图标,根据选择状态切换图片) -->
<ImageView <ImageView
android:id="@+id/iv_icon" android:id="@+id/iv_icon"
loadImage="@{bean.checked.get() ? @drawable/img_plane_s : @drawable/img_plane}"
android:layout_width="40dp" android:layout_width="40dp"
android:layout_height="40dp" android:layout_height="40dp"
android:layout_gravity="center" android:layout_gravity="center"
loadImage="@{bean.checked.get() ? @drawable/img_plane_s : @drawable/img_plane}" android:layout_marginTop="0.5px"
android:src="@drawable/img_plane" /> android:src="@drawable/img_plane" />
<!-- 舱单信息区域 --> <!-- ULD 信息区域ULD编号、总件数、总重量、航班信息 -->
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="15dp" android:layout_marginLeft="15dp"
android:layout_weight="1" android:layout_weight="1"
android:orientation="vertical">
<!-- 第一行运单号、始发站、ULD编号、总件数、件数 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
<!-- 运单号 (weight=1.0) --> <!-- ULD编号 -->
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@@ -65,260 +66,207 @@
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <TextView
completeSpace="@{5}"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
completeSpace="@{5}" android:text="ULD编号"
android:text="运单号:" android:textColor="@color/text_normal"
android:textSize="15sp" /> android:textSize="15sp" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@{bean.getWaybillNo()}" android:text="@{bean.uld}"
android:textColor="@color/colorPrimary" android:textColor="@color/colorPrimary"
android:textSize="15sp" android:textSize="15sp"
android:textStyle="bold" /> android:textStyle="bold" />
</LinearLayout> </LinearLayout>
<!-- 始发站 (weight=1) --> <!-- 总件数 -->
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="0.8"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{4}" completeSpace="@{4}"
android:text="始发站:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@{bean.origin}"
android:textSize="15sp" />
</LinearLayout>
<!-- ULD编号 (weight=1.0) -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="ULD编号"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.locationMft}"
android:textSize="15sp" />
</LinearLayout>
<!-- 总件数 (weight=1) -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{4}"
android:text="总件数:" android:text="总件数:"
android:textColor="@color/text_normal"
android:textSize="15sp" /> android:textSize="15sp" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@{String.valueOf(bean.totalPc)}" android:text="@{bean.totalPc == null ? `0` : String.valueOf(bean.totalPc)}"
android:textColor="@color/text_normal"
android:textSize="15sp" /> android:textSize="15sp" />
</LinearLayout> </LinearLayout>
<!-- 件数 (weight=1) --> <!-- 总重量 -->
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="0.8"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <TextView
completeSpace="@{4}"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
completeSpace="@{5}" android:text="总重量:"
android:text="件数:" android:textColor="@color/text_normal"
android:textSize="15sp" /> android:textSize="15sp" />
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@{String.valueOf(bean.pc)}" android:text="@{bean.totalWeightText}"
android:textColor="@color/text_normal"
android:textSize="15sp" />
</LinearLayout>
<!-- 航班信息 -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.2"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="航班信息:"
android:textColor="@color/text_normal"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:text="@{bean.flight}"
android:textColor="@color/text_normal"
android:textSize="15sp" /> android:textSize="15sp" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<!-- 第二行:品名、代理、库位号、重量、计费重量 --> </LinearLayout>
<!-- 展开按钮 -->
<ImageView
android:id="@+id/iv_show"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginTop="-20dp"
android:paddingVertical="2.5dp"
android:rotation="@{bean.showMore.get() ? 180f : 0f}"
android:scaleType="center"
android:src="@mipmap/img_down" />
</LinearLayout>
<!-- 子单列表容器(关联运单,白色圆角卡片) -->
<LinearLayout <LinearLayout
visible="@{bean.showMore}"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:gravity="center_vertical" android:background="@drawable/bg_white_radius_8"
android:orientation="horizontal"> android:orientation="vertical"
android:visibility="gone">
<!-- 品名 (weight=1.0) --> <!-- 暂无数据提示 -->
<TextView
android:id="@+id/tv_empty"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingVertical="15dp"
android:text="暂无运单数据"
android:textColor="@color/text_gray"
android:textSize="14sp"
android:visibility="gone" />
<!-- 表头 -->
<LinearLayout <LinearLayout
android:id="@+id/ll_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_arrive_sub_header"
android:orientation="horizontal"
android:paddingHorizontal="10dp"
android:paddingVertical="10dp">
<TextView
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1.0" android:layout_weight="1.2"
android:gravity="center_vertical" android:gravity="center"
android:orientation="horizontal"> android:text="运单号"
android:textColor="@color/text_normal"
android:textSize="14sp"
android:textStyle="bold" />
<TextView <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="品名(中)"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.goodsCn}"
android:textSize="15sp" />
</LinearLayout>
<!-- 代理 (weight=1) -->
<LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="0.8"
android:gravity="center_vertical" android:gravity="center"
android:orientation="horizontal"> android:text="件数"
android:textColor="@color/text_normal"
android:textSize="14sp"
android:textStyle="bold" />
<TextView <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{4}"
android:text="代理:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.agentCode}"
android:textSize="15sp" />
</LinearLayout>
<!-- 库位号 (weight=1.0) -->
<LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1.0" android:layout_weight="0.8"
android:gravity="center_vertical" android:gravity="center"
android:orientation="horizontal"> android:text="重量"
android:textColor="@color/text_normal"
android:textSize="14sp"
android:textStyle="bold" />
<TextView <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
completeSpace="@{5}"
android:text="库位号:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.locationTally}"
android:textSize="15sp" />
</LinearLayout>
<!-- 重量 (weight=1) -->
<LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:layout_weight="2"
android:gravity="center_vertical" android:gravity="center"
android:orientation="horizontal"> android:text="品名"
android:textColor="@color/text_normal"
<TextView android:textSize="14sp"
android:layout_width="wrap_content" android:textStyle="bold" />
android:layout_height="wrap_content"
completeSpace="@{4}"
android:text="重量:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf((int)bean.weight)}"
android:textSize="15sp" />
</LinearLayout> </LinearLayout>
<!-- 计费重量 (weight=1) --> <com.google.android.material.divider.MaterialDivider
<LinearLayout android:id="@+id/divider_header"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="1px"
android:layout_weight="1" app:dividerColor="@color/sub_list_divider" />
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView <!-- 子列表 RecyclerView -->
android:layout_width="wrap_content" <androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_sub"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
completeSpace="@{5}" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
android:text="计费重量:"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf((int)bean.cashWeight)}"
android:textSize="15sp" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- 侧滑菜单区域 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- 编辑按钮 -->
<TextView
android:id="@+id/btn_edit"
style="@style/tv_item_action"
android:background="@color/colorPrimary"
android:text="编辑" />
</androidx.appcompat.widget.LinearLayoutCompat>
</com.mcxtzhang.swipemenulib.SwipeMenuLayout>
</layout> </layout>

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="bean"
type="com.lukouguoji.module_base.bean.GjjManifest" />
<variable
name="position"
type="Integer" />
</data>
<LinearLayout
android:id="@+id/ll_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="8dp"
android:orientation="horizontal"
android:paddingHorizontal="10dp">
<!-- 运单号 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1.2"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:text="@{bean.getWaybillNo()}"
android:textColor="@color/text_normal"
android:textSize="14sp" />
<!-- 件数 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="0.8"
android:gravity="center"
android:text="@{String.valueOf(bean.pc)}"
android:textColor="@color/text_normal"
android:textSize="14sp" />
<!-- 重量 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="0.8"
android:gravity="center"
android:text="@{String.valueOf((int)bean.weight)}"
android:textColor="@color/text_normal"
android:textSize="14sp" />
<!-- 品名 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="2"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:text="@{bean.goodsCn.isEmpty() ? bean.goods : bean.goodsCn}"
android:textColor="@color/text_normal"
android:textSize="14sp" />
</LinearLayout>
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="1px"
app:dividerColor="@color/sub_list_divider" />
</LinearLayout>
</layout>

View File

@@ -147,7 +147,7 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@{String.valueOf(bean.pc)}" android:text="@{bean.pcLabel ?? String.valueOf(bean.pc)}"
android:textSize="15sp" /> android:textSize="15sp" />
</LinearLayout> </LinearLayout>

View File

@@ -24,6 +24,12 @@
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:orientation="vertical"> android:orientation="vertical">
<!-- 侧滑布局:白色卡片(含展开按钮)+ 侧滑菜单 -->
<com.mcxtzhang.swipemenulib.SwipeMenuLayout
android:id="@+id/swipe_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 白色卡片主要内容区域 --> <!-- 白色卡片主要内容区域 -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -339,6 +345,23 @@
</LinearLayout> </LinearLayout>
<!-- 侧滑菜单区 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<!-- 回执按钮 -->
<TextView
android:id="@+id/btnResponse"
style="@style/tv_item_action"
android:background="@color/colorPrimary"
android:text="回执" />
</LinearLayout>
</com.mcxtzhang.swipemenulib.SwipeMenuLayout>
<!-- 分单子列表容器(在白色卡片外面) --> <!-- 分单子列表容器(在白色卡片外面) -->
<LinearLayout <LinearLayout
visible="@{bean.showMore}" visible="@{bean.showMore}"