fix: 进港移库归属更正——删除误建IntImpMove,重新适配到国内进港DomImpMove

设计稿11「进港移库」经确认归属国内进港移库(DomImpMove后端8接口齐全),
此前误判为国际进港并预接了不存在的IntImpMove模块(问题清单#31作废)。

- 删除module_gjj的IntImpMove全套实现(3页面+Bean+Api+菜单+路由+权限串)
- GnjMoveStashListActivity双形态适配:待移库/已移库Tab走search/searchMoved
  双端点,Tab角标、筛选弹层4项、全选/批量移库复用平板既有链路
- 新增手机专属页:运单详情(Intent传bean零请求)+拍照上传(detail回填
  已有照片,modify最小体三字段提交,与平板移交编辑页同链路)
- 手机首页入口改挂国内Tab(GnViewModel补通用route跳转,权限串AppDomImpMove)
- 内网真实数据双端验证通过;Proxyman A/B:wbNo/awbType生效,
  fdate/fno/spCode被后端静默忽略(#32)、opId/opDate恒null(#33)
- 问题清单更正#31+新增#32~#34,CLAUDE.md/CHANGELOG/api-doc.md同步

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-03 12:17:10 +08:00
parent eb0655d3fc
commit 49f11ef8e6
35 changed files with 1341 additions and 1545 deletions

View File

@@ -158,9 +158,21 @@
android:exported="true"
tools:replace="android:exported" />
<!-- 进港移库(手机版适配验证页,后端模块未交付,直启验证 UI -->
<!-- 进港移库(国内进港,手机版适配验证页) -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpMoveActivity"
android:name="com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListActivity"
android:exported="true"
tools:replace="android:exported" />
<!-- 进港移库-运单详情(手机版专属页) -->
<activity
android:name="com.lukouguoji.aerologic.page.gnj.move.stash.detail.GnjMoveStashDetailActivity"
android:exported="true"
tools:replace="android:exported" />
<!-- 进港移库-拍照上传(手机版专属页) -->
<activity
android:name="com.lukouguoji.aerologic.page.gnj.move.stash.photo.GnjMoveStashPhotoActivity"
android:exported="true"
tools:replace="android:exported" />

View File

@@ -375,6 +375,20 @@
android:name=".page.gnj.move.stash.list.GnjMoveStashListActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="unspecified" />
<!-- 国内进港移库-运单详情5.5寸手机版专属) -->
<activity
android:name=".page.gnj.move.stash.detail.GnjMoveStashDetailActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="unspecified" />
<!-- 国内进港移库-拍照上传5.5寸手机版专属) -->
<activity
android:name=".page.gnj.move.stash.photo.GnjMoveStashPhotoActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="unspecified" />
<activity
android:name=".page.gnj.stash.list.GnjStashListActivity"
android:configChanges="orientation|keyboardHidden"
@@ -565,27 +579,6 @@
android:exported="false"
android:screenOrientation="unspecified" />
<!-- 国际进港-进港移库5.5寸手机版专属) -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpMoveActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="unspecified" />
<!-- 国际进港-进港移库-运单详情5.5寸手机版专属) -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpMoveDetailActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="unspecified" />
<!-- 国际进港-进港移库-拍照上传5.5寸手机版专属) -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpMovePhotoActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="unspecified" />
<!-- 国际进港-进港查询 -->
<activity
android:name="com.lukouguoji.gjj.activity.IntImpQueryActivity"

View File

@@ -0,0 +1,49 @@
package com.lukouguoji.aerologic.page.gnj.move.stash.detail
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.google.gson.Gson
import com.lukouguoji.aerologic.R
import com.lukouguoji.aerologic.databinding.ActivityGnjMoveStashDetailBinding
import com.lukouguoji.aerologic.page.gnj.move.stash.photo.GnjMoveStashPhotoActivity
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.bean.MoveStashBean
import com.lukouguoji.module_base.common.Constant
/**
* 国内进港移库「运单详情」5.5 寸手持端专属页面,无平板变体)
*
* 由列表卡片的「查看详情」进入;「异常照片」卡片的加号槽位跳拍照上传页。
* 展示字段全部由列表项带入Gson JSON零新增请求。
*/
class GnjMoveStashDetailActivity :
BaseBindingActivity<ActivityGnjMoveStashDetailBinding, GnjMoveStashDetailViewModel>() {
override fun layoutId() = R.layout.activity_gnj_move_stash_detail
override fun viewModelClass() = GnjMoveStashDetailViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("运单详情")
binding.viewModel = viewModel
binding.activity = this
viewModel.initOnCreated(intent)
}
/** 「异常照片」加号槽位 → 拍照上传页 */
fun openPhoto() {
viewModel.dataBean.value?.let {
GnjMoveStashPhotoActivity.start(this, it.mawbId, it.wbNo)
}
}
companion object {
@JvmStatic
fun start(context: Context, bean: MoveStashBean) {
context.startActivity(
Intent(context, GnjMoveStashDetailActivity::class.java)
.putExtra(Constant.Key.DATA, Gson().toJson(bean))
)
}
}
}

View File

@@ -0,0 +1,25 @@
package com.lukouguoji.aerologic.page.gnj.move.stash.detail
import android.content.Intent
import androidx.lifecycle.MutableLiveData
import com.google.gson.Gson
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.MoveStashBean
import com.lukouguoji.module_base.common.Constant
/**
* 国内进港移库「运单详情」ViewModel5.5 寸手持端专属页面)
*
* 列表项数据已包含详情页所需全部字段(含 isMoved 端点打标),直接由列表带入,不额外请求。
*/
class GnjMoveStashDetailViewModel : BaseViewModel() {
val dataBean = MutableLiveData(MoveStashBean())
fun initOnCreated(intent: Intent) {
val json = intent.getStringExtra(Constant.Key.DATA).orEmpty()
if (json.isNotEmpty()) {
dataBean.value = Gson().fromJson(json, MoveStashBean::class.java)
}
}
}

View File

@@ -1,36 +1,104 @@
package com.lukouguoji.aerologic.page.gnj.move.stash.list
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.lukouguoji.aerologic.R
import com.lukouguoji.aerologic.databinding.ActivityGnjMoveStashListBinding
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.ktx.getLifecycleOwner
class GnjMoveStashListActivity :
BaseBindingActivity<ActivityGnjMoveStashListBinding, GnjMoveStashListViewModel>() {
override fun layoutId() = R.layout.activity_gnj_move_stash_list
override fun viewModelClass() = GnjMoveStashListViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("国内进港移库")
binding.viewModel = viewModel
viewModel.pageModel
.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, getLifecycleOwner())
viewModel.refresh()
}
companion object {
@JvmStatic
fun start(context: Context) {
val starter = Intent(context, GnjMoveStashListActivity::class.java)
context.startActivity(starter)
}
}
}
package com.lukouguoji.aerologic.page.gnj.move.stash.list
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.databinding.ObservableBoolean
import com.alibaba.android.arouter.facade.annotation.Route
import com.lukouguoji.aerologic.R
import com.lukouguoji.aerologic.databinding.ActivityGnjMoveStashListBinding
import com.lukouguoji.aerologic.page.gnj.move.stash.photo.GnjMoveStashPhotoActivity
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.bean.MoveStashBean
import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.impl.observe
import com.lukouguoji.module_base.ktx.getLifecycleOwner
import com.lukouguoji.module_base.router.ARouterConstants
import com.lukouguoji.module_base.util.DeviceUtil
@Route(path = ARouterConstants.ACTIVITY_URL_GNJ_MOVE_STASH_LIST)
class GnjMoveStashListActivity :
BaseBindingActivity<ActivityGnjMoveStashListBinding, GnjMoveStashListViewModel>() {
override fun layoutId() = R.layout.activity_gnj_move_stash_list
override fun viewModelClass() = GnjMoveStashListViewModel::class.java
/** 筛选弹层显隐(仅手机 UI 状态,平板布局不绑定) */
val filterPanelVisible = ObservableBoolean(false)
override fun initOnCreate(savedInstanceState: Bundle?) {
// 设计稿手机端标题为「进港移库」,平板保持原标题
setBackArrow(if (DeviceUtil.isPhone()) "进港移库" else "国内进港移库")
binding.viewModel = viewModel
binding.activity = this
viewModel.pageModel
.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, getLifecycleOwner())
if (DeviceUtil.isPhone()) {
// 手机专属Tab 角标 + 特码字典等额外请求
viewModel.initPhoneExtras()
// 卡片勾选变化 → 更新全选状态与已选计数
FlowBus.with<String>(ConstantEvent.EVENT_CHECK_CHANGED).observe(this) {
viewModel.updateCheckAllStatus()
}
}
// 拍照上传等子页面完成后刷新列表(平板无发射方,观察无副作用)
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).observe(this) {
viewModel.refresh()
}
viewModel.refresh()
}
// ==================== 筛选弹层(仅手机) ====================
fun toggleFilterPanel() {
filterPanelVisible.set(!filterPanelVisible.get())
}
/** 筛选:重置(只清空弹层内条件,不影响 Tab 与顶部搜索框) */
fun resetFilter() {
viewModel.flightDate.value = ""
viewModel.flightNo.value = ""
viewModel.spCode.value = ""
viewModel.businessType.value = ""
}
fun confirmFilter() {
filterPanelVisible.set(false)
viewModel.refresh()
}
// ==================== 卡片长按「拍照」浮层(仅手机) ====================
/** 卡片长按展开操作浮层View.OnLongClickListener 要求返回 Boolean */
fun showCardActionPhone(bean: MoveStashBean): Boolean {
bean.actionMenuVisible.set(true)
return true
}
/** 点浮层空白处关闭 */
fun hideCardActionPhone(bean: MoveStashBean) {
bean.actionMenuVisible.set(false)
}
/** 浮层「拍照」→ 拍照上传页 */
fun openPhoto(bean: MoveStashBean) {
bean.actionMenuVisible.set(false)
GnjMoveStashPhotoActivity.start(this, bean.mawbId, bean.wbNo)
}
companion object {
@JvmStatic
fun start(context: Context) {
val starter = Intent(context, GnjMoveStashListActivity::class.java)
context.startActivity(starter)
}
}
}

View File

@@ -3,34 +3,64 @@ package com.lukouguoji.aerologic.page.gnj.move.stash.list
import android.view.View
import android.widget.Toast
import com.lukouguoji.aerologic.databinding.ItemGnjMoveStashListBinding
import com.lukouguoji.aerologic.page.gnj.move.stash.detail.GnjMoveStashDetailActivity
import com.lukouguoji.gnj.page.yiku.handover.GnjYiKuHandoverActivity
import com.lukouguoji.module_base.base.BaseViewHolder
import com.lukouguoji.module_base.bean.MoveStashBean
import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.impl.FlowBus
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
/**
* 国内进港移库列表项 ViewHolder双形态共用
*
* 平板/手机布局差异较大,单侧独有的控件 id 在 Binding 基类中为 @Nullable
* 全部走判空调用平板swipe_menu/btn_edit/ll手机ll_detail
*/
class GnjMoveStashListViewHolder(view: View) :
BaseViewHolder<MoveStashBean, ItemGnjMoveStashListBinding>(view) {
override fun onBind(item: Any?, position: Int) {
val bean = getItemBean(item)!!
binding.bean = bean
binding.position = position
binding.activity = itemView.context as? GnjMoveStashListActivity
// 勾选框(双形态共有):切换选中;手机端另行广播刷新全选/已选计数
binding.ivIcon.setOnClickListener {
bean.checked.set(!bean.checked.get())
binding.executePendingBindings()
GlobalScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_CHECK_CHANGED).emit("check_changed")
}
}
// ===== 平板独有交互 =====
// 点击列表项进入移交详情
binding.ll.setOnClickListener {
binding.ll?.setOnClickListener {
GnjYiKuHandoverActivity.startForDetails(itemView.context, bean.mawbId)
}
// 侧滑菜单 - 编辑按钮
binding.btnEdit.setOnClickListener {
binding.swipeMenu.quickClose()
binding.btnEdit?.setOnClickListener {
binding.swipeMenu?.quickClose()
if (bean.pickFlag == "1") {
Toast.makeText(itemView.context, "已出库,不可编辑", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
GnjYiKuHandoverActivity.startForEdit(itemView.context, bean.mawbId)
}
// ===== 手机独有交互 =====
// 「查看详情」→ 手机版运单详情页
binding.llDetail?.setOnClickListener {
GnjMoveStashDetailActivity.start(itemView.context, bean)
}
binding.executePendingBindings()
}
}

View File

@@ -49,6 +49,41 @@ class GnjMoveStashListViewModel : BasePageViewModel() {
val number = MutableLiveData("0")
val weight = MutableLiveData("0")
// ========== 5.5 寸手持端专属字段(平板布局不绑定,默认值保证平板行为零变化) ==========
/** 移库状态 Tab"0" 待移库DomImpMove/search/ "1" 已移库DomImpMove/searchMoved */
val moveState = MutableLiveData("0")
/** 手机筛选弹层:航班日期 / 航班号 / 特码(默认空 → 不进请求) */
val flightDate = MutableLiveData("")
val flightNo = MutableLiveData("")
val spCode = MutableLiveData("")
val spCodeList = MutableLiveData<List<KeyValue>>(emptyList())
val moveStateTabs = MutableLiveData(
listOf(KeyValue("待移库", "0"), KeyValue("已移库", "1"))
)
/** 状态 Tab 角标(与 [moveStateTabs] 等长,取两端点分页 total */
val moveStateCounts = MutableLiveData(listOf("", ""))
/** 底部操作条「已选 N 项」 */
val selectedCount = MutableLiveData("0")
/** 全选状态(手机 PhoneBottomBar 勾选图标) */
val isAllChecked = MutableLiveData(false)
/** 手机专属的额外请求Tab 角标、特码字典)开关,仅手机形态在 Activity 中开启 */
private var phoneExtrasEnabled = false
fun initPhoneExtras() {
phoneExtrasEnabled = true
// 特码字典flag=0 国内、ieFlag=I 进港(是否生效待实测,见问题清单)
DictUtils.getSpecialCodeList(addAll = false, flag = 0, ieFlag = "I") { list ->
spCodeList.postValue(listOf(KeyValue("全部", "")) + list)
}
}
///////////////////////////////////////////////////////////////////////////
// 方法区
///////////////////////////////////////////////////////////////////////////
@@ -95,25 +130,73 @@ class GnjMoveStashListViewModel : BasePageViewModel() {
}
/** 查询条件分页参数除外search / searchMoved / searchTotal 三处共用同一套入参 */
private fun buildFilterParams(): Map<String, Any?> = mapOf(
"awbType" to businessType.value!!.ifEmpty { null },
"wbNo" to waybill.value!!.ifEmpty { null },
"carrier" to carrier.value!!.ifEmpty { null },
// 以下为手机筛选弹层字段,平板恒为空串 → 恒传 null行为不变
"fdate" to flightDate.value?.ifEmpty { null },
"fno" to flightNo.value?.ifEmpty { null },
"spCode" to spCode.value?.ifEmpty { null },
)
override fun getData() {
val body = mapOf(
val body = (buildFilterParams() + mapOf(
"page" to pageModel.page,
"limit" to pageModel.limit,
"awbType" to businessType.value!!.ifEmpty { null },
"wbNo" to waybill.value!!.ifEmpty { null },
"carrier" to carrier.value!!.ifEmpty { null },
).toRequestBody()
)).toRequestBody()
val moved = moveState.value == "1"
launchLoadingCollect({
NetApply.api.getGnjMoveStashList(
body
)
// 平板 moveState 恒为 "0" → 恒走 search原行为已移库 Tab 走 searchMoved
if (moved) NetApply.api.getGnjMoveStashMovedList(body)
else NetApply.api.getGnjMoveStashList(body)
}) {
onSuccess = {
pageModel.handleListBean(it)
// searchMoved 出参无移库标识,按端点打标(卡片形态/详情移库信息卡依赖)
it.list?.forEach { bean -> bean.isMoved = moved }
pageModel.handleListBean(it) { updateCheckAllStatus() }
count.value = it.total
}
}
getCountData(body)
if (phoneExtrasEnabled) loadTabCounts()
}
/** Tab 角标search / searchMoved 各以 limit=1 查一次取分页 total仅手机形态发起 */
private fun loadTabCounts() {
val body = (buildFilterParams() + mapOf("page" to 1, "limit" to 1)).toRequestBody()
launchCollect({ NetApply.api.getGnjMoveStashList(body) }) {
onSuccess = { updateTabCount(0, it.total) }
}
launchCollect({ NetApply.api.getGnjMoveStashMovedList(body) }) {
onSuccess = { updateTabCount(1, it.total) }
}
}
private fun updateTabCount(index: Int, total: Int?) {
val current = moveStateCounts.value?.toMutableList() ?: mutableListOf("", "")
if (index < current.size) {
current[index] = (total ?: 0).toString()
moveStateCounts.value = current
}
}
// ========== 手机端全选 / 已选计数 ==========
fun toggleSelectAll() {
val list = pageModel.rv?.commonAdapter()?.items
?.filterIsInstance<MoveStashBean>() ?: return
CheckUtil.handleAllCheck(list)
updateCheckAllStatus()
pageModel.rv?.commonAdapter()?.notifyDataSetChanged()
}
fun updateCheckAllStatus() {
val list = pageModel.rv?.commonAdapter()?.items
?.filterIsInstance<MoveStashBean>() ?: return
isAllChecked.value = list.isNotEmpty() && list.all { it.checked.get() }
selectedCount.value = list.count { it.checked.get() }.toString()
}
private fun getCountData(body: RequestBody) {

View File

@@ -0,0 +1,45 @@
package com.lukouguoji.aerologic.page.gnj.move.stash.photo
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.lukouguoji.aerologic.R
import com.lukouguoji.aerologic.databinding.ActivityGnjMoveStashPhotoBinding
import com.lukouguoji.module_base.base.BaseBindingActivity
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.ktx.addOnItemClickListener
/**
* 国内进港移库「拍照上传」5.5 寸手持端专属页面,无平板变体)
*
* 由列表卡片长按浮层「拍照」或运单详情「异常照片」加号槽位进入。
* 已有照片经 DomImpMove/detail 回填,提交走 DomImpMove/modify
* mawbId + pic/originalPic/picNumber 三字段规范,与平板移交编辑页同一链路)。
*/
class GnjMoveStashPhotoActivity :
BaseBindingActivity<ActivityGnjMoveStashPhotoBinding, GnjMoveStashPhotoViewModel>() {
override fun layoutId() = R.layout.activity_gnj_move_stash_photo
override fun viewModelClass() = GnjMoveStashPhotoViewModel::class.java
override fun initOnCreate(savedInstanceState: Bundle?) {
setBackArrow("拍照上传")
binding.viewModel = viewModel
viewModel.rv = binding.rv
binding.rv.addOnItemClickListener(viewModel)
viewModel.initOnCreated(intent)
}
companion object {
@JvmStatic
fun start(context: Context, mawbId: String, wbNo: String) {
context.startActivity(
Intent(context, GnjMoveStashPhotoActivity::class.java)
.putExtra(Constant.Key.ID, mawbId)
.putExtra(Constant.Key.CODE, wbNo)
)
}
}
}

View File

@@ -0,0 +1,174 @@
package com.lukouguoji.aerologic.page.gnj.move.stash.photo
import android.content.Intent
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import androidx.recyclerview.widget.RecyclerView
import com.lukouguoji.module_base.base.BaseViewModel
import com.lukouguoji.module_base.bean.FileBean
import com.lukouguoji.module_base.bean.GnjYiKuBean
import com.lukouguoji.module_base.common.Constant
import com.lukouguoji.module_base.common.ConstantEvent
import com.lukouguoji.module_base.http.net.NetApply
import com.lukouguoji.module_base.impl.FlowBus
import com.lukouguoji.module_base.impl.ImageSelectNewViewHolder
import com.lukouguoji.module_base.interfaces.IOnItemClickListener
import com.lukouguoji.module_base.ktx.commonAdapter
import com.lukouguoji.module_base.ktx.launchCollect
import com.lukouguoji.module_base.ktx.launchLoadingCollect
import com.lukouguoji.module_base.ktx.noNull
import com.lukouguoji.module_base.ktx.showToast
import com.lukouguoji.module_base.ktx.toRequestBody
import com.lukouguoji.module_base.util.MediaUtil
import com.lukouguoji.module_base.util.UploadUtil
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
/**
* 国内进港移库「拍照上传」ViewModel5.5 寸手持端专属页面)
*
* 图片选择/预览/删除复用 module_base 的 ImageSelectNewViewHolder末位加号槽位
* 已有照片经 DomImpMove/detail 回填;提交走 DomImpMove/modify 最小体
* mawbId/remark/picNumber/pic/originalPic与平板移交编辑页同一链路。
*/
class GnjMoveStashPhotoViewModel : BaseViewModel(), IOnItemClickListener {
var mawbId = ""
/** 运单号(副标题展示,由列表带入) */
val wbNo = MutableLiveData("")
/** detail 回填的完整 bean提交时保留 remark 等原值) */
private var detailBean = GnjYiKuBean()
// 图片网格适配器配置(复用公共图片选择组件)
val itemViewHolder = ImageSelectNewViewHolder::class.java
val itemLayoutId = com.lukouguoji.module_base.R.layout.item_image_select_new
var rv: RecyclerView? = null
fun initOnCreated(intent: Intent) {
mawbId = intent.getStringExtra(Constant.Key.ID).orEmpty()
wbNo.value = intent.getStringExtra(Constant.Key.CODE).orEmpty()
// 已有照片回填pic 缩略图 + originalPic 原图),末位补加号槽位
launchCollect({ NetApply.api.getGnjMoveStashDetail(mawbId) }) {
onSuccess = {
detailBean = it.data ?: GnjYiKuBean()
val picList = detailBean.pic.split(",").filter { p -> p.isNotEmpty() }
val originalList = detailBean.originalPic.split(",").filter { p -> p.isNotEmpty() }
val images = picList.mapIndexed { index, picUrl ->
FileBean(
path = MediaUtil.fillUrl(picUrl),
url = picUrl,
originalPic = MediaUtil.fillUrl(originalList.getOrElse(index) { picUrl })
)
}
rv?.post {
rv?.commonAdapter()?.refresh(images + FileBean())
}
}
onFailed = { _, _ ->
// 详情取不到也允许直接新增照片
rv?.post { rv?.commonAdapter()?.refresh(listOf(FileBean())) }
}
}
}
/**
* 确认提交:先补传未上传的本地图片,再按三字段规范提交 modify
*/
fun submitClick() {
(rv?.commonAdapter()?.items ?: emptyList())
.asFlow()
.map { it as FileBean }
.filter { it.path.isNotEmpty() && it.url.isEmpty() }
.onEach {
val data = UploadUtil.upload(it.path).data
// UploadUtil 返回newName=原图(较大)zipFileName=缩略图(较小)
it.url = data?.zipFileName ?: ""
it.originalPic = data?.newName ?: ""
}
.flowOn(Dispatchers.IO)
.onStart { showLoading() }
.catch {
showToast(it.message.noNull("上传图片失败"))
dismissLoading()
}
.onCompletion {
launchLoadingCollect({
val list = (rv?.commonAdapter()?.items ?: emptyList())
.filterIsInstance<FileBean>()
.filter { it.path.isNotEmpty() }
// 最小体提交只更新图片三字段remark 保留 detail 原值),与平板移交编辑页一致
val params = mapOf(
"mawbId" to mawbId,
"remark" to detailBean.remark,
"picNumber" to list.size.toString(),
"pic" to list.joinToString(",") { MediaUtil.removeUrl(it.url) },
"originalPic" to list.joinToString(",") { MediaUtil.removeUrl(it.originalPic) },
).toRequestBody(removeEmptyOrNull = true)
NetApply.api.modifyGnjMoveStash(params)
}) {
onSuccess = {
showToast("提交成功")
viewModelScope.launch {
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
}
getTopActivity().finish()
}
onFailed = { _, msg ->
showToast(msg.noNull("提交失败"))
}
}
}
.launchIn(viewModelScope)
}
/**
* 「拍照/上传」按钮:直接唤起图片选择(含拍照入口)
*/
fun pickClick() {
MediaUtil.pickImage(getTopActivity(), maxNum = 9) { results ->
val adapter = rv?.commonAdapter() ?: return@pickImage
results.forEach { result ->
// 在加号槽位(最后一项)之前插入
val insertPos = (adapter.items.size - 1).coerceAtLeast(0)
adapter.items.add(insertPos, FileBean(path = result.realPath))
adapter.notifyItemInserted(insertPos)
}
}
}
/**
* 图片网格点击回调(长按出删除角标 / 点删除角标移除)
*/
override fun onItemClick(position: Int, type: Int) {
val adapter = rv?.commonAdapter() ?: return
val bean = adapter.getItem(position) as? FileBean ?: return
when (type) {
com.lukouguoji.module_base.R.id.rl -> {
if (bean.path.isNotEmpty()) {
bean.canDelete.set(!bean.canDelete.get())
}
}
com.lukouguoji.module_base.R.id.iv_delete -> {
adapter.removeItem(position)
}
else -> {}
}
}
}

View File

@@ -0,0 +1,153 @@
<?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"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType" />
<variable
name="viewModel"
type="com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListViewModel" />
<!-- 平板不使用,仅为与手机变体保持 <variable> 一致DataBinding 双变体强制约束) -->
<variable
name="activity"
type="com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListActivity" />
</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" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:gravity="center_vertical">
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请选择业务类型"}'
list="@{viewModel.businessTypeList}"
type="@{SearchLayoutType.SPINNER}"
value="@={viewModel.businessType}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请输入运单号"}'
icon="@{@drawable/img_scan}"
setInputWaybill="@{true}"
setOnIconClickListener="@{()-> viewModel.waybillScanClick()}"
setRefreshCallBack="@{viewModel::refresh}"
setSearchListRefresh="@{viewModel::getWayBillList}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.waybill}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请输入承运人"}'
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.carrier}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<ImageView
style="@style/iv_search_action"
android:onClick="@{()-> viewModel.refresh()}"
android:src="@drawable/img_search" />
</LinearLayout>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:onClick="@{()->viewModel.checkAllClick()}"
android:text="全选" />
<ImageView
android:id="@+id/checkIcon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="5dp"
android:onClick="@{()->viewModel.checkAllClick()}"
android:src="@drawable/img_check_all" />
</androidx.appcompat.widget.LinearLayoutCompat>
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/srl"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_gnj_move_stash_list" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/color_bottom_layout"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text='@{"合计:"+viewModel.count+"条,总件数:"+viewModel.number+",总重量:"+viewModel.weight+"KG"}'
android:textColor="@color/white"
android:textSize="18sp"
android:textStyle="bold"
tools:text="合计3条总件数212总重量342KG" />
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()-> viewModel.moveStashClick()}"
android:text="移库" />
</LinearLayout>
</LinearLayout>
</layout>

View File

@@ -0,0 +1,296 @@
<?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"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="bean"
type="com.lukouguoji.module_base.bean.MoveStashBean" />
<!-- 以下两个变量平板不使用,仅为与手机变体保持 <variable> 一致DataBinding 双变体强制约束) -->
<variable
name="position"
type="Integer" />
<variable
name="activity"
type="com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListActivity" />
</data>
<!-- 外层容器承载间距 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="5dp"
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
android:id="@+id/ll"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_item"
android:orientation="horizontal"
android:padding="10dp">
<ImageView
android:id="@+id/iv_icon"
loadImage="@{bean.checked ? @drawable/img_plane_s : @drawable/img_plane}"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:src="@drawable/img_plane" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:orientation="vertical">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单号:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.wbNo}"
android:textColor="@color/colorPrimary"
tools:text="789165431" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="件数:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.pc}' />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="重量:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.weight}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="代理人:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.agentCode}' />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单类型:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.awbType}' />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="航班:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.flight}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="始发港:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.origin}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="起始站:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.dep}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="目的港:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.dest}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="品名:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.goods}" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</LinearLayout>
<!-- 右侧箭头 -->
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_gravity="center"
android:layout_marginLeft="10dp"
android:src="@drawable/img_pda_right" />
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 侧滑菜单区域 -->
<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>
</layout>

View File

@@ -0,0 +1,332 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
国内进港移库「运单详情」—— 5.5 寸手持端专属页面(无平板变体)
对应设计稿 11_进港移库 的「运单详情」页:
· 卡片一:蓝色表头(运单号 + 绿点 + 操作时间)+ 类型标签行(红「运单类型」+ 货物类型)
+ 品名大字 + 两列字段网格(件数/重量/特码/代理/出运路径/承运人)
· 卡片二:绿色表头「移库信息」+ 移库人 / 移库时间(仅已移库显示)
· 卡片三:橙色表头「异常照片」+ 三个虚线加号槽位(点击跳拍照上传页)
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<variable
name="viewModel"
type="com.lukouguoji.aerologic.page.gnj.move.stash.detail.GnjMoveStashDetailViewModel" />
<variable
name="activity"
type="com.lukouguoji.aerologic.page.gnj.move.stash.detail.GnjMoveStashDetailActivity" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/phone_page_bg"
android:orientation="vertical">
<include layout="@layout/title_tool_bar" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- ==================== 卡片一:运单基本信息 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_phone_card"
android:orientation="vertical">
<!-- 蓝色表头:运单号 + 绿点 + 操作时间 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_phone_card_header_blue"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="16dp"
android:paddingVertical="12dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{viewModel.dataBean.wbNo}"
android:textColor="@color/white"
android:textSize="17sp"
android:textStyle="bold" />
<View
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginEnd="6dp"
android:background="@drawable/bg_phone_dot_green" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.dataBean.orDash(viewModel.dataBean.opDate)}"
android:textColor="@color/white"
android:textSize="14sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<!-- 类型标签行:运单类型(红标签) + 货物类型 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="22dp"
android:background="@drawable/bg_phone_tag_red"
android:gravity="center"
android:paddingHorizontal="8dp"
android:text="@{viewModel.dataBean.orDash(viewModel.dataBean.awbType)}"
android:textColor="@color/phone_tag_red_text"
android:textSize="12sp"
android:textStyle="bold" />
<View
android:layout_width="1dp"
android:layout_height="14dp"
android:layout_marginHorizontal="10dp"
android:background="@color/phone_divider" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{viewModel.dataBean.orDash(viewModel.dataBean.cargoType)}"
android:textColor="@color/phone_text_body"
android:textSize="14sp" />
</LinearLayout>
<!-- 品名(主字段大字) -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:text="@{viewModel.dataBean.orDash(viewModel.dataBean.goods)}"
android:textColor="@color/phone_text_strong"
android:textSize="22sp"
android:textStyle="bold" />
<!-- 第 1 行:件数 / 重量 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"件数"}'
value="@{viewModel.dataBean.orDash(viewModel.dataBean.pc)}" />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_weight="1"
title='@{"重量"}'
value='@{viewModel.dataBean.orDash(viewModel.dataBean.weight) + " kg"}' />
</LinearLayout>
<!-- 第 2 行:特码 / 代理 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"特码"}'
value="@{viewModel.dataBean.spCode}" />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_weight="1"
title='@{"代理"}'
value="@{viewModel.dataBean.agentDisplay}" />
</LinearLayout>
<!-- 第 3 行:出运路径 / 承运人 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"出运路径"}'
value="@{viewModel.dataBean.range}" />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_weight="1"
title='@{"承运人"}'
value="@{viewModel.dataBean.by1}" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- ==================== 卡片二:移库信息(仅已移库显示) ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/bg_phone_card"
android:orientation="vertical"
android:visibility="@{viewModel.dataBean.isMoved ? View.VISIBLE : View.GONE}">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_phone_card_header_green"
android:paddingHorizontal="16dp"
android:paddingVertical="10dp"
android:text="移库信息"
android:textColor="@color/white"
android:textSize="15sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingHorizontal="16dp"
android:paddingVertical="12dp">
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
title='@{"移库人"}'
value="@{viewModel.dataBean.opId}" />
<com.lukouguoji.module_base.ui.weight.phone.PhoneKvItem
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_weight="1"
title='@{"移库时间"}'
value="@{viewModel.dataBean.opDate}" />
</LinearLayout>
</LinearLayout>
<!-- ==================== 卡片三:异常照片 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:background="@drawable/bg_phone_card"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_phone_card_header_orange"
android:paddingHorizontal="16dp"
android:paddingVertical="10dp"
android:text="异常照片"
android:textColor="@color/white"
android:textSize="15sp"
android:textStyle="bold" />
<!-- 三个虚线加号槽位(等宽正方形由 weight + 固定高实现),点击进拍照上传页 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="16dp">
<TextView
android:layout_width="0dp"
android:layout_height="96dp"
android:layout_weight="1"
android:background="@drawable/bg_phone_photo_add"
android:gravity="center"
android:onClick="@{()-> activity.openPhoto()}"
android:text="+"
android:textColor="@color/phone_text_hint"
android:textSize="24sp" />
<TextView
android:layout_width="0dp"
android:layout_height="96dp"
android:layout_marginStart="12dp"
android:layout_weight="1"
android:background="@drawable/bg_phone_photo_add"
android:gravity="center"
android:onClick="@{()-> activity.openPhoto()}"
android:text="+"
android:textColor="@color/phone_text_hint"
android:textSize="24sp" />
<TextView
android:layout_width="0dp"
android:layout_height="96dp"
android:layout_marginStart="12dp"
android:layout_weight="1"
android:background="@drawable/bg_phone_photo_add"
android:gravity="center"
android:onClick="@{()-> activity.openPhoto()}"
android:text="+"
android:textColor="@color/phone_text_hint"
android:textSize="24sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
</layout>

View File

@@ -1,148 +1,166 @@
<?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"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="com.lukouguoji.module_base.ui.weight.search.layout.SearchLayoutType" />
<variable
name="viewModel"
type="com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListViewModel" />
</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" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
android:gravity="center_vertical">
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请选择业务类型"}'
list="@{viewModel.businessTypeList}"
type="@{SearchLayoutType.SPINNER}"
value="@={viewModel.businessType}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请输入运单号"}'
icon="@{@drawable/img_scan}"
setInputWaybill="@{true}"
setOnIconClickListener="@{()-> viewModel.waybillScanClick()}"
setRefreshCallBack="@{viewModel::refresh}"
setSearchListRefresh="@{viewModel::getWayBillList}"
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.waybill}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
hint='@{"请输入承运人"}'
type="@{SearchLayoutType.INPUT}"
value="@={viewModel.carrier}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<ImageView
style="@style/iv_search_action"
android:onClick="@{()-> viewModel.refresh()}"
android:src="@drawable/img_search" />
</LinearLayout>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingTop="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:onClick="@{()->viewModel.checkAllClick()}"
android:text="全选" />
<ImageView
android:id="@+id/checkIcon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="5dp"
android:onClick="@{()->viewModel.checkAllClick()}"
android:src="@drawable/img_check_all" />
</androidx.appcompat.widget.LinearLayoutCompat>
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/srl"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_gnj_move_stash_list" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/color_bottom_layout"
android:gravity="center_vertical"
android:paddingHorizontal="15dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text='@{"合计:"+viewModel.count+"条,总件数:"+viewModel.number+",总重量:"+viewModel.weight+"KG"}'
android:textColor="@color/white"
android:textSize="18sp"
android:textStyle="bold"
tools:text="合计3条总件数212总重量342KG" />
<TextView
style="@style/tv_bottom_btn"
android:onClick="@{()-> viewModel.moveStashClick()}"
android:text="移库" />
</LinearLayout>
</LinearLayout>
</layout>
<?xml version="1.0" encoding="utf-8"?>
<!--
国内进港移库 —— 5.5 寸手持端布局(平板变体见 layout-sw600dp/ 同名文件)
对应设计稿 documents/5.5寸手持端设计文件/11_进港移库/进港移库.html
· 顶部搜索框(运单号,含扫码)+ 筛选弹层(航班日期 / 航班号 / 特码 / 运单类型)
· 「待移库 / 已移库」Tab 绑定 viewModel.moveState"0"/"1"
分别走 DomImpMove/search 与 DomImpMove/searchMoved 两个端点
· 已移库 Tab 下隐藏底部操作条(与设计稿一致)
· 卡片长按出「拍照」浮层(见 item_gnj_move_stash_list.xml
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<import type="com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayoutType" />
<variable
name="viewModel"
type="com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListViewModel" />
<variable
name="activity"
type="com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListActivity" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/phone_page_bg">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/title_tool_bar" />
<!-- ==================== 搜索行 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="vertical"
android:paddingHorizontal="16dp"
android:paddingTop="16dp"
android:paddingBottom="12dp">
<com.lukouguoji.module_base.ui.weight.phone.PhoneSearchBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"搜索运单号"}'
setOnFilterClickListener="@{(v)-> activity.toggleFilterPanel()}"
setOnScanClickListener="@{(v)-> viewModel.waybillScanClick()}"
setRefreshCallBack="@{viewModel::refresh}"
upperCase="@{true}"
value="@={viewModel.waybill}" />
</LinearLayout>
<!-- ==================== 待移库 / 已移库 Tab ==================== -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneStatusTab
android:layout_width="match_parent"
android:layout_height="wrap_content"
counts="@{viewModel.moveStateCounts}"
setOnTabChanged="@{viewModel::refresh}"
tabs="@{viewModel.moveStateTabs}"
value="@={viewModel.moveState}" />
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/phone_divider" />
<!-- ==================== 列表 ==================== -->
<com.scwang.smart.refresh.layout.SmartRefreshLayout
android:id="@+id/srl"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:overScrollMode="never"
android:paddingBottom="12dp"
itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="3"
tools:listitem="@layout/item_gnj_move_stash_list" />
</com.scwang.smart.refresh.layout.SmartRefreshLayout>
<!-- ==================== 底部操作条(已移库 Tab 下隐藏) ==================== -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneBottomBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
actionText='@{"移库"}'
allChecked="@{viewModel.isAllChecked}"
countText='@{"已选 " + viewModel.selectedCount + " 项"}'
setOnActionClick="@{(v)-> viewModel.moveStashClick()}"
setOnAllCheckClick="@{(v)-> viewModel.toggleSelectAll()}"
android:visibility="@{`1`.equals(viewModel.moveState) ? View.GONE : View.VISIBLE}" />
</LinearLayout>
<!-- ==================== 筛选弹层 ==================== -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneFilterPanel
android:layout_width="match_parent"
android:layout_height="match_parent"
panelVisible="@{activity.filterPanelVisible}"
setOnConfirmClick="@{(v)-> activity.confirmFilter()}"
setOnDismissClick="@{(v)-> activity.toggleFilterPanel()}"
setOnResetClick="@{(v)-> activity.resetFilter()}"
title='@{"筛选条件"}'>
<!-- 航班日期(入参 fdate -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"请选择航班日期"}'
title='@{"航班日期"}'
type="@{PhoneDataLayoutType.DATE}"
value="@={viewModel.flightDate}" />
<!-- 航班号(入参 fno -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"请输入航班号"}'
title='@{"航班号"}'
type="@{PhoneDataLayoutType.INPUT}"
value="@={viewModel.flightNo}" />
<!-- 特码(入参 spCode -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"请选择特码"}'
list="@{viewModel.spCodeList}"
title='@{"特码"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.spCode}" />
<!-- 运单类型(入参 awbType复用平板既有 businessType 字段与字典) -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneDataLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
hint='@{"请选择运单类型"}'
list="@{viewModel.businessTypeList}"
title='@{"运单类型"}'
type="@{PhoneDataLayoutType.SPINNER}"
value="@={viewModel.businessType}" />
</com.lukouguoji.module_base.ui.weight.phone.PhoneFilterPanel>
</FrameLayout>
</layout>

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
国内进港移库「拍照上传」—— 5.5 寸手持端专属页面(无平板变体)
对应设计稿 11_进港移库/photo.html
· 白卡「运单照片上传」+ 图片预览网格(复用公共 ImageSelectNewViewHolder末位加号槽位
· 底部两个按钮:拍照/上传(蓝) + 确认提交(绿)
提交走 DomImpMove/modifypic/originalPic/picNumber 三字段规范)。
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.lukouguoji.aerologic.page.gnj.move.stash.photo.GnjMoveStashPhotoViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/phone_page_bg"
android:orientation="vertical">
<include layout="@layout/title_tool_bar" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_phone_card"
android:orientation="vertical"
android:padding="16dp">
<!-- 标题:运单照片上传(副行展示运单号) -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单照片上传"
android:textColor="@color/phone_text_strong"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="@{viewModel.wbNo}"
android:textColor="@color/phone_text_body"
android:textSize="13sp"
tools:text="78133363573" />
<!-- 图片预览网格(末位加号槽位,长按出删除角标) -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:overScrollMode="never"
itemLayoutId="@{viewModel.itemLayoutId}"
viewHolder="@{viewModel.itemViewHolder}"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="3"
tools:itemCount="3" />
<!-- 底部按钮:拍照/上传(蓝) + 确认提交(绿) -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="44dp"
android:layout_weight="1"
android:background="@drawable/bg_phone_btn_primary"
android:gravity="center"
android:onClick="@{()-> viewModel.pickClick()}"
android:text="拍照/上传"
android:textColor="@color/white"
android:textSize="15sp"
android:textStyle="bold" />
<TextView
android:layout_width="0dp"
android:layout_height="44dp"
android:layout_marginStart="12dp"
android:layout_weight="1"
android:background="@drawable/bg_phone_btn_green"
android:gravity="center"
android:onClick="@{()-> viewModel.submitClick()}"
android:text="确认提交"
android:textColor="@color/white"
android:textSize="15sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
</layout>

View File

@@ -1,287 +1,227 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
国内进港移库 —— 列表项 5.5 寸手持端布局(平板变体见 layout-sw600dp/ 同名文件)
一套布局覆盖设计稿两种卡片形态,按 bean.isMoved 切换(载入时按端点打标):
· 待移库:圆形勾选框 + 蓝色运单号 + 橙色「待移库」标签
· 已移库:无勾选框 + 深色运单号 + 绿色对勾「已移库」
长按卡片出「拍照」浮层(跳拍照上传页),点浮层空白处收起。
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable
name="bean"
type="com.lukouguoji.module_base.bean.MoveStashBean" />
<variable
name="position"
type="Integer" />
<variable
name="activity"
type="com.lukouguoji.aerologic.page.gnj.move.stash.list.GnjMoveStashListActivity" />
</data>
<!-- 外层容器承载间距 -->
<LinearLayout
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="5dp"
android:orientation="vertical">
android:layout_marginHorizontal="12dp"
android:layout_marginTop="12dp">
<!-- 侧滑布局 -->
<com.mcxtzhang.swipemenulib.SwipeMenuLayout
android:id="@+id/swipe_menu"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:background="@drawable/bg_phone_card"
android:onLongClick="@{()-> activity.showCardActionPhone(bean)}"
android:orientation="vertical"
android:padding="16dp">
<!-- 主列表项容器 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:id="@+id/ll"
<!-- ==================== 卡片头部:勾选框 + 运单号 + 状态 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/bg_item"
android:orientation="horizontal"
android:padding="10dp">
android:gravity="center_vertical"
android:orientation="horizontal">
<!-- 圆形勾选框(已移库的记录不可勾选,隐藏) -->
<ImageView
android:id="@+id/iv_icon"
loadImage="@{bean.checked ? @drawable/img_plane_s : @drawable/img_plane}"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:src="@drawable/img_plane" />
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginEnd="8dp"
android:src="@drawable/ic_phone_check_round_unchecked"
android:visibility="@{bean.isMoved ? View.GONE : View.VISIBLE}"
loadImage="@{bean.checked.get() ? @drawable/ic_phone_check_round_checked : @drawable/ic_phone_check_round_unchecked}" />
<LinearLayout
<!-- 运单号 -->
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:orientation="vertical">
android:text="@{bean.wbNo}"
android:textColor="@{bean.isMoved ? @color/phone_text_title : @color/phone_primary}"
android:textSize="15sp"
android:textStyle="bold" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 待移库:橙色状态标签 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="20dp"
android:layout_marginStart="8dp"
android:background="@drawable/bg_phone_tag_orange"
android:gravity="center"
android:paddingHorizontal="8dp"
android:text="待移库"
android:textColor="@color/phone_tag_orange_text"
android:textSize="11sp"
android:visibility="@{bean.isMoved ? View.GONE : View.VISIBLE}" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<!-- 已移库:对勾 + 状态文字 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="@{bean.isMoved ? View.VISIBLE : View.GONE}">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单号:" />
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_phone_check_circle" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.wbNo}"
android:textColor="@color/colorPrimary"
tools:text="789165431" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="件数:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.pc}' />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.7"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="重量:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.weight}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="代理人:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.agentCode}' />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="运单类型:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text='@{bean.awbType}' />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="航班:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.flight}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="始发港:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.origin}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="起始站:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.dep}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:gravity="center_vertical">
<TextView
completeSpace="@{4}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="目的港:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.dest}" />
</androidx.appcompat.widget.LinearLayoutCompat>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.1"
android:gravity="center_vertical">
<TextView
completeSpace="@{5}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="品名:" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{bean.goods}" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
android:layout_marginStart="4dp"
android:text="已移库"
android:textColor="@color/phone_text_title"
android:textSize="13sp" />
</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>
</androidx.appcompat.widget.LinearLayoutCompat>
<!-- 侧滑菜单区域 -->
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="wrap_content"
android:layout_height="match_parent"
<!-- ==================== 航班信息行 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginBottom="12dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<!-- 编辑按钮 -->
<ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:src="@drawable/ic_phone_airplane" />
<TextView
android:id="@+id/btn_edit"
style="@style/tv_item_action"
android:background="@color/colorPrimary"
android:text="编辑" />
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_weight="1"
android:text='@{"航班信息:" + bean.orDash(bean.flight)}'
android:textColor="@color/phone_text_body"
android:textSize="13sp"
tools:text="航班信息20260709/MU2311" />
</androidx.appcompat.widget.LinearLayoutCompat>
</LinearLayout>
</com.mcxtzhang.swipemenulib.SwipeMenuLayout>
<!-- ==================== 统计框:特码 / 件数 / 重量 ==================== -->
<com.lukouguoji.module_base.ui.weight.phone.PhoneStatBox
android:layout_width="match_parent"
android:layout_height="wrap_content"
label1='@{"特码"}'
label2='@{"件数"}'
label3='@{"重量"}'
value1="@{bean.orDash(bean.spCode)}"
value2='@{bean.orDash(bean.pc) + "件"}'
value3='@{bean.orDash(bean.weight) + "kg"}' />
</LinearLayout>
<!-- ==================== 出运路径 ==================== -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:layout_width="14dp"
android:layout_height="14dp"
android:src="@drawable/ic_phone_location" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_weight="1"
android:text='@{"出运路径:" + bean.orDash(bean.range)}'
android:textColor="@color/phone_text_body"
android:textSize="13sp" />
</LinearLayout>
<!-- ==================== 查看详情 ==================== -->
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginTop="16dp"
android:background="@color/phone_stat_bg" />
<LinearLayout
android:id="@+id/ll_detail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|end"
android:orientation="horizontal"
android:paddingTop="12dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查看详情"
android:textColor="@color/phone_primary"
android:textSize="14sp" />
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_phone_chevron_right" />
</LinearLayout>
</LinearLayout>
<!-- ==================== 长按操作浮层:拍照 ==================== -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#66000000"
android:clickable="true"
android:onClick="@{()-> activity.hideCardActionPhone(bean)}"
android:visibility="@{bean.actionMenuVisible ? View.VISIBLE : View.GONE}">
<TextView
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_gravity="center"
android:background="@drawable/bg_phone_fab_purple"
android:gravity="center"
android:onClick="@{()-> activity.openPhoto(bean)}"
android:text="拍照"
android:textColor="@color/white"
android:textSize="12sp"
android:textStyle="bold" />
</FrameLayout>
</FrameLayout>
</layout>