feat: 国际进出港 5 个列表页侧滑新增海关回执查看

原始舱单、进港理货、出港运抵、出港装载、出港理货主单卡片
新增侧滑「回执」按钮,调用各模块 getResponse 接口后跳转
module_base 共用的只读回执页。请求同时传 prefix、no 与
wbNo,回执优先取 data、为空再取 msg,兼容后端实际返回;
回执为空时提示「暂无海关回执」不跳转。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-09-09 10:12:52 +08:00
parent 7a09bbbeab
commit ea83361102
21 changed files with 384 additions and 10 deletions

View File

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

View File

@@ -148,6 +148,14 @@ interface Api {
@POST
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
suspend fun anyGetForId(@Url url: String, @Query("id") id: String): BaseResultBean<Any>

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

@@ -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

@@ -34,6 +34,13 @@
android:exported="false"
android:screenOrientation="userLandscape" />
<!-- 海关回执(只读) -->
<activity
android:name=".ui.page.customs.CustomsResponseActivity"
android:configChanges="orientation|keyboardHidden"
android:exported="false"
android:screenOrientation="userLandscape" />
<!-- 屏幕适配 -->
<meta-data
android:name="design_width_in_dp"

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>