From 330b5bc28ae36f66b36b2db7b7656e98f1f12781 Mon Sep 17 00:00:00 2001 From: YANGJIANKUAN Date: Sun, 8 Mar 2026 16:39:03 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=9B=BD=E9=99=85=E8=BF=9B=E6=B8=AF?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BA=8B=E6=95=85=E7=AD=BE=E8=AF=81=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新建事故签证列表页(类型2:多选列表+批量删除) - 搜索区支持航班日期/航班号级联查询始发站和目的站 - 对接 GjAccidentVisa/search 和 GjAccidentVisa/delete 接口 - 国际进港菜单添加"事故签证"入口 Co-Authored-By: Claude Opus 4.6 --- app/src/main/AndroidManifest.xml | 7 + .../aerologic/ui/fragment/HomeFragment.kt | 14 + .../bean/IntImpAccidentVisaBean.kt | 23 ++ .../lukouguoji/module_base/common/Constant.kt | 1 + .../lukouguoji/module_base/http/net/Api.kt | 17 + .../module_base/router/ARouterConstants.kt | 1 + .../activity/IntImpAccidentVisaActivity.kt | 51 +++ .../holder/IntImpAccidentVisaViewHolder.kt | 25 ++ .../viewModel/IntImpAccidentVisaViewModel.kt | 181 +++++++++++ .../layout/activity_int_imp_accident_visa.xml | 198 ++++++++++++ .../res/layout/item_int_imp_accident_visa.xml | 294 ++++++++++++++++++ 11 files changed, 812 insertions(+) create mode 100644 module_base/src/main/java/com/lukouguoji/module_base/bean/IntImpAccidentVisaBean.kt create mode 100644 module_gjj/src/main/java/com/lukouguoji/gjj/activity/IntImpAccidentVisaActivity.kt create mode 100644 module_gjj/src/main/java/com/lukouguoji/gjj/holder/IntImpAccidentVisaViewHolder.kt create mode 100644 module_gjj/src/main/java/com/lukouguoji/gjj/viewModel/IntImpAccidentVisaViewModel.kt create mode 100644 module_gjj/src/main/res/layout/activity_int_imp_accident_visa.xml create mode 100644 module_gjj/src/main/res/layout/item_int_imp_accident_visa.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 739be5d..f1c590a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -454,6 +454,13 @@ android:exported="false" android:screenOrientation="userLandscape" /> + + + diff --git a/app/src/main/java/com/lukouguoji/aerologic/ui/fragment/HomeFragment.kt b/app/src/main/java/com/lukouguoji/aerologic/ui/fragment/HomeFragment.kt index 054eed6..58462f8 100644 --- a/app/src/main/java/com/lukouguoji/aerologic/ui/fragment/HomeFragment.kt +++ b/app/src/main/java/com/lukouguoji/aerologic/ui/fragment/HomeFragment.kt @@ -475,6 +475,13 @@ class HomeFragment : Fragment() { .navigation() } + // 事故签证 + Constant.AuthName.IntImpAccidentVisa -> { + ARouter.getInstance() + .build(ARouterConstants.ACTIVITY_URL_INT_IMP_ACCIDENT_VISA) + .navigation() + } + /** * 航班查询 */ @@ -852,6 +859,13 @@ class HomeFragment : Fragment() { "进港查询" ) ) + list.add( + RightMenu( + Constant.AuthName.IntImpAccidentVisa, + R.mipmap.img_bwjx, + "事故签证" + ) + ) } Constant.AuthName.Flight -> { diff --git a/module_base/src/main/java/com/lukouguoji/module_base/bean/IntImpAccidentVisaBean.kt b/module_base/src/main/java/com/lukouguoji/module_base/bean/IntImpAccidentVisaBean.kt new file mode 100644 index 0000000..9689230 --- /dev/null +++ b/module_base/src/main/java/com/lukouguoji/module_base/bean/IntImpAccidentVisaBean.kt @@ -0,0 +1,23 @@ +package com.lukouguoji.module_base.bean + +import androidx.databinding.ObservableBoolean + +class IntImpAccidentVisaBean { + var id: Long = 0 + var fdate: String = "" // 航班日期 + var fno: String = "" // 航班号 + var fdep: String = "" // 始发站 + var fdest: String = "" // 目的站 + var wbNo: String = "" // 运单号 + var totalPc: Int = 0 // 运单总件数 + var totalWeight: Double = 0.0 // 运单总重量 + var abnPc: Int = 0 // 不正常件数 + var opName: String = "" // 经办人 + var opDate: String = "" // 经办时间 + + val checked: ObservableBoolean = ObservableBoolean(false) + + var isSelected: Boolean + get() = checked.get() + set(value) = checked.set(value) +} diff --git a/module_base/src/main/java/com/lukouguoji/module_base/common/Constant.kt b/module_base/src/main/java/com/lukouguoji/module_base/common/Constant.kt index 62c543d..35e191e 100644 --- a/module_base/src/main/java/com/lukouguoji/module_base/common/Constant.kt +++ b/module_base/src/main/java/com/lukouguoji/module_base/common/Constant.kt @@ -272,6 +272,7 @@ interface Constant { const val IntImpTally = "AppIntImpTally" //理货报告 const val IntImpPickUpRecord = "AppIntImpPickUpRecord" //提取记录 const val IntImpPickUpDLV = "AppIntImpPickUpDLV" //提取出库 + const val IntImpAccidentVisa = "AppIntImpAccidentVisa" //事故签证 const val GjjManifestListActivity = "AppIntExpManifest" //舱单 const val GjjTallyListActivity = "AppIntExpTally" //理货 const val GjjGoodsListActivity = "AppIntExpGjjGoods" //货物交接 diff --git a/module_base/src/main/java/com/lukouguoji/module_base/http/net/Api.kt b/module_base/src/main/java/com/lukouguoji/module_base/http/net/Api.kt index 5a8469b..bbfc9df 100644 --- a/module_base/src/main/java/com/lukouguoji/module_base/http/net/Api.kt +++ b/module_base/src/main/java/com/lukouguoji/module_base/http/net/Api.kt @@ -50,6 +50,7 @@ import com.lukouguoji.module_base.bean.GjjGoodsDetailsBean import com.lukouguoji.module_base.bean.GjjGoodsTypeBean import com.lukouguoji.module_base.bean.GjjHandoverRecordBean import com.lukouguoji.module_base.bean.GjjImportTally +import com.lukouguoji.module_base.bean.IntImpAccidentVisaBean import com.lukouguoji.module_base.bean.IntImpPickUpDLVBean import com.lukouguoji.module_base.bean.IntImpPickUpRecordBean import com.lukouguoji.module_base.bean.IntImpQueryBean @@ -1842,4 +1843,20 @@ interface Api { */ @POST("IntImpTally/pageQueryTotal") suspend fun getIntImpTallyTotal(@Body data: RequestBody): BaseResultBean + + /////////////////////////////////////////////////////////////////////////// + // 国际进港-事故签证 + /////////////////////////////////////////////////////////////////////////// + + /** + * 国际事故签证-分页搜索 + */ + @POST("GjAccidentVisa/search") + suspend fun getIntImpAccidentVisaList(@Body data: RequestBody): PageInfo + + /** + * 国际事故签证-删除(传选中的 Bean 列表) + */ + @POST("GjAccidentVisa/delete") + suspend fun deleteIntImpAccidentVisa(@Body data: RequestBody): BaseResultBean } \ No newline at end of file diff --git a/module_base/src/main/java/com/lukouguoji/module_base/router/ARouterConstants.kt b/module_base/src/main/java/com/lukouguoji/module_base/router/ARouterConstants.kt index 2855742..4ee751c 100644 --- a/module_base/src/main/java/com/lukouguoji/module_base/router/ARouterConstants.kt +++ b/module_base/src/main/java/com/lukouguoji/module_base/router/ARouterConstants.kt @@ -178,6 +178,7 @@ object ARouterConstants { const val ACTIVITY_URL_INT_IMP_LOADING_LIST = "/gjj/IntImpLoadingListActivity" //国际进港 装机单(分拣理货) const val ACTIVITY_URL_INT_IMP_TALLY = "/gjj/IntImpTallyActivity" //国际进港 理货报告 const val ACTIVITY_URL_INT_IMP_PICK_UP_DLV = "/gjj/IntImpPickUpDLVActivity" //国际进港 提取出库 + const val ACTIVITY_URL_INT_IMP_ACCIDENT_VISA = "/gjj/IntImpAccidentVisaActivity" //国际进港 事故签证 ///////////////// 航班查询模块 /** diff --git a/module_gjj/src/main/java/com/lukouguoji/gjj/activity/IntImpAccidentVisaActivity.kt b/module_gjj/src/main/java/com/lukouguoji/gjj/activity/IntImpAccidentVisaActivity.kt new file mode 100644 index 0000000..e2d897e --- /dev/null +++ b/module_gjj/src/main/java/com/lukouguoji/gjj/activity/IntImpAccidentVisaActivity.kt @@ -0,0 +1,51 @@ +package com.lukouguoji.gjj.activity + +import android.app.Activity +import android.content.Intent +import android.os.Bundle +import com.alibaba.android.arouter.facade.annotation.Route +import com.lukouguoji.gjj.R +import com.lukouguoji.gjj.databinding.ActivityIntImpAccidentVisaBinding +import com.lukouguoji.gjj.viewModel.IntImpAccidentVisaViewModel +import com.lukouguoji.module_base.base.BaseBindingActivity +import com.lukouguoji.module_base.common.Constant +import com.lukouguoji.module_base.common.ConstantEvent +import com.lukouguoji.module_base.impl.FlowBus +import com.lukouguoji.module_base.impl.observe +import com.lukouguoji.module_base.router.ARouterConstants + +/** + * 国际进港-事故签证 + */ +@Route(path = ARouterConstants.ACTIVITY_URL_INT_IMP_ACCIDENT_VISA) +class IntImpAccidentVisaActivity : + BaseBindingActivity() { + + override fun layoutId() = R.layout.activity_int_imp_accident_visa + override fun viewModelClass() = IntImpAccidentVisaViewModel::class.java + + override fun initOnCreate(savedInstanceState: Bundle?) { + setBackArrow("国际事故签证") + binding.viewModel = viewModel + + viewModel.isAllChecked.observe(this) { isAllChecked -> + binding.checkIcon.alpha = if (isAllChecked) 1.0f else 0.5f + } + + viewModel.pageModel.bindSmartRefreshLayout(binding.srl, binding.rv, viewModel, this) + + FlowBus.with(ConstantEvent.EVENT_REFRESH).observe(this) { + viewModel.refresh() + } + + viewModel.refresh() + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (requestCode == Constant.RequestCode.WAYBILL && resultCode == Activity.RESULT_OK) { + viewModel.wbNo.value = data?.getStringExtra(Constant.Result.CODED_CONTENT) + viewModel.searchClick() + } + } +} diff --git a/module_gjj/src/main/java/com/lukouguoji/gjj/holder/IntImpAccidentVisaViewHolder.kt b/module_gjj/src/main/java/com/lukouguoji/gjj/holder/IntImpAccidentVisaViewHolder.kt new file mode 100644 index 0000000..7263206 --- /dev/null +++ b/module_gjj/src/main/java/com/lukouguoji/gjj/holder/IntImpAccidentVisaViewHolder.kt @@ -0,0 +1,25 @@ +package com.lukouguoji.gjj.holder + +import android.view.View +import com.lukouguoji.gjj.databinding.ItemIntImpAccidentVisaBinding +import com.lukouguoji.module_base.base.BaseViewHolder +import com.lukouguoji.module_base.bean.IntImpAccidentVisaBean + +/** + * 国际进港-事故签证 列表项ViewHolder + */ +class IntImpAccidentVisaViewHolder(view: View) : + BaseViewHolder(view) { + + override fun onBind(item: Any?, position: Int) { + val bean = getItemBean(item) ?: return + binding.bean = bean + binding.position = position + binding.executePendingBindings() + + binding.ivIcon.setOnClickListener { + bean.checked.set(!bean.checked.get()) + binding.executePendingBindings() + } + } +} diff --git a/module_gjj/src/main/java/com/lukouguoji/gjj/viewModel/IntImpAccidentVisaViewModel.kt b/module_gjj/src/main/java/com/lukouguoji/gjj/viewModel/IntImpAccidentVisaViewModel.kt new file mode 100644 index 0000000..9d150a4 --- /dev/null +++ b/module_gjj/src/main/java/com/lukouguoji/gjj/viewModel/IntImpAccidentVisaViewModel.kt @@ -0,0 +1,181 @@ +package com.lukouguoji.gjj.viewModel + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.viewModelScope +import com.lukouguoji.gjj.R +import com.lukouguoji.gjj.holder.IntImpAccidentVisaViewHolder +import com.lukouguoji.module_base.base.BasePageViewModel +import com.lukouguoji.module_base.bean.IntImpAccidentVisaBean +import com.lukouguoji.module_base.common.Constant +import com.lukouguoji.module_base.common.ConstantEvent +import com.lukouguoji.module_base.http.net.NetApply +import com.lukouguoji.module_base.impl.FlowBus +import com.lukouguoji.module_base.ktx.commonAdapter +import com.lukouguoji.module_base.ktx.formatDate +import com.lukouguoji.module_base.ktx.launchCollect +import com.lukouguoji.module_base.ktx.launchLoadingCollect +import com.lukouguoji.module_base.ktx.noNull +import com.lukouguoji.module_base.ktx.showToast +import com.lukouguoji.module_base.ktx.toRequestBody +import com.lukouguoji.module_base.model.ScanModel +import dev.utils.app.info.KeyValue +import dev.utils.common.DateUtils +import kotlinx.coroutines.launch + +/** + * 国际进港-事故签证 ViewModel + */ +class IntImpAccidentVisaViewModel : BasePageViewModel() { + + // ========== 搜索条件 ========== + val flightDate = MutableLiveData(DateUtils.getCurrentTime().formatDate()) + val flightNo = MutableLiveData("") + val fdep = MutableLiveData("") // 始发站(下拉) + val fdepList = MutableLiveData>(emptyList()) + val fdest = MutableLiveData("") // 目的站(禁止编辑,由航班查询返回) + val wbNo = MutableLiveData("") // 运单号 + + // ========== 航班查询 ========== + private var fid: String = "" + private var lastQueriedFlight = "" + + // ========== 统计信息 ========== + val totalCount = MutableLiveData("0") + + // ========== 全选状态 ========== + val isAllChecked = MutableLiveData(false) + + init { + isAllChecked.observeForever { checked -> + val list = pageModel.rv?.commonAdapter()?.items as? List + ?: return@observeForever + list.forEach { it.checked.set(checked) } + pageModel.rv?.commonAdapter()?.notifyDataSetChanged() + } + } + + // ========== 适配器配置 ========== + val itemViewHolder = IntImpAccidentVisaViewHolder::class.java + val itemLayoutId = R.layout.item_int_imp_accident_visa + + // ========== 航班级联查询 ========== + + fun onFlightDateInputComplete() { + lastQueriedFlight = "" + queryFlightIfReady() + } + + fun onFlightNoInputComplete() { + queryFlightIfReady() + } + + private fun queryFlightIfReady() { + val fdate = flightDate.value + val fno = flightNo.value + if (fdate.isNullOrEmpty() || fno.isNullOrEmpty()) return + + val key = "$fdate-$fno" + if (key == lastQueriedFlight) return + lastQueriedFlight = key + + launchCollect({ + NetApply.api.getGjFlightBean( + mapOf( + "fdate" to fdate, + "fno" to fno, + "ieFlag" to "I", + ).toRequestBody() + ) + }) { + onSuccess = { + if (it.verifySuccess() && it.data != null) { + val flight = it.data!! + fid = flight.fid.noNull() + fdest.value = flight.fdest.noNull() + + val list = mutableListOf( + KeyValue(flight.fdep.noNull(), flight.fdep.noNull()), + ) + if (!flight.jtz.isNullOrEmpty()) { + list.add(KeyValue(flight.jtz.noNull(), flight.jtz.noNull())) + } + fdepList.value = list + fdep.value = flight.fdep.noNull() + } else { + fid = "" + fdest.value = "" + fdepList.value = emptyList() + fdep.value = "" + showToast(it.msg.noNull("获取航班信息失败")) + } + } + + onFailed = { _, _ -> + fid = "" + fdest.value = "" + fdepList.value = emptyList() + fdep.value = "" + } + } + } + + fun scanWbNo() { + ScanModel.startScan(getTopActivity(), Constant.RequestCode.WAYBILL) + } + + fun searchClick() { + refresh() + } + + fun checkAllClick() { + val list = pageModel.rv?.commonAdapter()?.items as? List ?: return + val shouldCheckAll = !isAllChecked.value!! + list.forEach { it.checked.set(shouldCheckAll) } + isAllChecked.value = shouldCheckAll + pageModel.rv?.commonAdapter()?.notifyDataSetChanged() + } + + fun deleteClick() { + val list = pageModel.rv?.commonAdapter()?.items as? List ?: return + val selected = list.filter { it.isSelected } + if (selected.isEmpty()) { + showToast("请选择要删除的数据") + return + } + launchLoadingCollect({ NetApply.api.deleteIntImpAccidentVisa(selected.toRequestBody()) }) { + onSuccess = { + showToast("删除成功") + viewModelScope.launch { + FlowBus.with(ConstantEvent.EVENT_REFRESH).emit("refresh") + } + refresh() + } + } + } + + override fun getData() { + val filterParams = mutableMapOf( + "fdep" to fdep.value?.ifEmpty { null }, + "fdest" to fdest.value?.ifEmpty { null }, + "wbNo" to wbNo.value?.ifEmpty { null } + ) + if (fid.isNotEmpty()) { + filterParams["fid"] = fid + } else { + filterParams["fdate"] = flightDate.value?.ifEmpty { null } + filterParams["fno"] = flightNo.value?.ifEmpty { null } + } + + val listParams = (filterParams + mapOf( + "pageNum" to pageModel.page, + "pageSize" to pageModel.limit + )).toRequestBody() + + launchLoadingCollect({ NetApply.api.getIntImpAccidentVisaList(listParams) }) { + onSuccess = { pageInfo -> + pageModel.handleListBean(pageInfo.toBaseListBean()) + totalCount.value = (pageInfo.total ?: 0).toString() + } + } + } +} diff --git a/module_gjj/src/main/res/layout/activity_int_imp_accident_visa.xml b/module_gjj/src/main/res/layout/activity_int_imp_accident_visa.xml new file mode 100644 index 0000000..fc9f1b1 --- /dev/null +++ b/module_gjj/src/main/res/layout/activity_int_imp_accident_visa.xml @@ -0,0 +1,198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/module_gjj/src/main/res/layout/item_int_imp_accident_visa.xml b/module_gjj/src/main/res/layout/item_int_imp_accident_visa.xml new file mode 100644 index 0000000..b0d015e --- /dev/null +++ b/module_gjj/src/main/res/layout/item_int_imp_accident_visa.xml @@ -0,0 +1,294 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +