feat: 国际进港装机单添加航班级联查询和入库/修改库位功能
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,13 +6,18 @@ import android.os.Bundle
|
|||||||
import com.alibaba.android.arouter.facade.annotation.Route
|
import com.alibaba.android.arouter.facade.annotation.Route
|
||||||
import com.lukouguoji.gjj.R
|
import com.lukouguoji.gjj.R
|
||||||
import com.lukouguoji.gjj.databinding.ActivityIntImpLoadingListBinding
|
import com.lukouguoji.gjj.databinding.ActivityIntImpLoadingListBinding
|
||||||
|
import com.lukouguoji.gjj.dialog.IntImpInStorageDialogModel
|
||||||
|
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.router.ARouterConstants
|
import com.lukouguoji.module_base.router.ARouterConstants
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,6 +33,7 @@ class IntImpLoadingListActivity :
|
|||||||
override fun initOnCreate(savedInstanceState: Bundle?) {
|
override fun initOnCreate(savedInstanceState: Bundle?) {
|
||||||
setBackArrow("国际进港装机单")
|
setBackArrow("国际进港装机单")
|
||||||
binding.viewModel = viewModel
|
binding.viewModel = viewModel
|
||||||
|
binding.activity = this
|
||||||
|
|
||||||
// 观察全选状态,更新图标透明度
|
// 观察全选状态,更新图标透明度
|
||||||
viewModel.isAllChecked.observe(this) { isAllChecked ->
|
viewModel.isAllChecked.observe(this) { isAllChecked ->
|
||||||
@@ -45,10 +51,61 @@ class IntImpLoadingListActivity :
|
|||||||
viewModel.refresh()
|
viewModel.refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 接收从进港舱单传递的参数
|
||||||
|
intent.getStringExtra("fdate")?.let { if (it.isNotEmpty()) viewModel.flightDate.value = it }
|
||||||
|
intent.getStringExtra("fno")?.let { if (it.isNotEmpty()) viewModel.flightNo.value = it }
|
||||||
|
intent.getStringExtra("sendAddress")?.let { if (it.isNotEmpty()) viewModel.sendAddress.value = it }
|
||||||
|
intent.getStringExtra("fdest")?.let { if (it.isNotEmpty()) viewModel.fdest.value = it }
|
||||||
|
|
||||||
|
// 如果收到了航班号和日期参数,触发航班查询来构建始发站下拉列表
|
||||||
|
val fdate = intent.getStringExtra("fdate")
|
||||||
|
val fno = intent.getStringExtra("fno")
|
||||||
|
if (!fdate.isNullOrEmpty() && !fno.isNullOrEmpty()) {
|
||||||
|
viewModel.onFlightNoInputComplete()
|
||||||
|
}
|
||||||
|
|
||||||
// 初始加载数据
|
// 初始加载数据
|
||||||
viewModel.refresh()
|
viewModel.refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示入库操作对话框
|
||||||
|
*/
|
||||||
|
fun showInStorageDialog() {
|
||||||
|
val list = viewModel.pageModel.rv?.commonAdapter()?.items as? List<*> ?: return
|
||||||
|
val selectedItems = list.filterIsInstance<GjjManifest>().filter { it.isSelected }
|
||||||
|
|
||||||
|
if (selectedItems.isEmpty()) {
|
||||||
|
showToast("请选择要入库的记录")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
IntImpInStorageDialogModel { dialog ->
|
||||||
|
val locationName = dialog.locationName
|
||||||
|
val locationId = dialog.locationId
|
||||||
|
viewModel.performInStorage(locationName, locationId, selectedItems)
|
||||||
|
}.show(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示修改库位对话框
|
||||||
|
*/
|
||||||
|
fun showModifyStorageDialog() {
|
||||||
|
val list = viewModel.pageModel.rv?.commonAdapter()?.items as? List<*> ?: return
|
||||||
|
val selectedItems = list.filterIsInstance<GjjManifest>().filter { it.isSelected }
|
||||||
|
|
||||||
|
if (selectedItems.isEmpty()) {
|
||||||
|
showToast("请选择要修改库位的记录")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
IntImpModifyStorageDialogModel { dialog ->
|
||||||
|
val locationName = dialog.locationName
|
||||||
|
val locationId = dialog.locationId
|
||||||
|
viewModel.performModifyStorage(locationName, locationId, selectedItems)
|
||||||
|
}.show(this)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
if (requestCode == Constant.RequestCode.WAYBILL && resultCode == Activity.RESULT_OK) {
|
if (requestCode == Constant.RequestCode.WAYBILL && resultCode == Activity.RESULT_OK) {
|
||||||
|
|||||||
@@ -1,18 +1,24 @@
|
|||||||
package com.lukouguoji.gjj.viewModel
|
package com.lukouguoji.gjj.viewModel
|
||||||
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
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.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.http.net.NetApply
|
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.commonAdapter
|
||||||
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.showToast
|
import com.lukouguoji.module_base.ktx.showToast
|
||||||
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 dev.utils.app.info.KeyValue
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 国际进港装机单 ViewModel
|
* 国际进港装机单 ViewModel
|
||||||
@@ -22,10 +28,75 @@ class IntImpLoadingListViewModel : BasePageViewModel() {
|
|||||||
// ========== 搜索条件 ==========
|
// ========== 搜索条件 ==========
|
||||||
val flightDate = MutableLiveData("") // 航班日期
|
val flightDate = MutableLiveData("") // 航班日期
|
||||||
val flightNo = MutableLiveData("") // 航班号
|
val flightNo = MutableLiveData("") // 航班号
|
||||||
val fdep = MutableLiveData("") // 始发站
|
val sendAddress = MutableLiveData("") // 始发站(选中值)
|
||||||
|
val sendAddressList = MutableLiveData<List<KeyValue>>(emptyList()) // 始发站下拉列表
|
||||||
val fdest = MutableLiveData("") // 目的站
|
val fdest = MutableLiveData("") // 目的站
|
||||||
val waybillNo = MutableLiveData("") // 运单号
|
val waybillNo = MutableLiveData("") // 运单号
|
||||||
|
|
||||||
|
// ========== 航班级联查询 ==========
|
||||||
|
private var lastQueriedFlight = ""
|
||||||
|
private var fid = ""
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
// 构建始发站下拉列表:fdep + jtz(经停港)
|
||||||
|
val list = mutableListOf(
|
||||||
|
KeyValue(flight.fdep.noNull(), flight.fdep.noNull()),
|
||||||
|
)
|
||||||
|
if (!flight.jtz.isNullOrEmpty()) {
|
||||||
|
list.add(KeyValue(flight.jtz.noNull(), flight.jtz.noNull()))
|
||||||
|
}
|
||||||
|
sendAddressList.value = list
|
||||||
|
sendAddress.value = flight.fdep.noNull()
|
||||||
|
} else {
|
||||||
|
fid = ""
|
||||||
|
fdest.value = ""
|
||||||
|
sendAddressList.value = emptyList()
|
||||||
|
sendAddress.value = ""
|
||||||
|
showToast(it.msg.noNull("获取航班信息失败"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onFailed = { _, _ ->
|
||||||
|
fid = ""
|
||||||
|
fdest.value = ""
|
||||||
|
sendAddressList.value = emptyList()
|
||||||
|
sendAddress.value = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ========== 统计信息 ==========
|
// ========== 统计信息 ==========
|
||||||
val totalCount = MutableLiveData("0") // 合计票数
|
val totalCount = MutableLiveData("0") // 合计票数
|
||||||
val totalPc = MutableLiveData("0") // 总件数
|
val totalPc = MutableLiveData("0") // 总件数
|
||||||
@@ -76,33 +147,74 @@ class IntImpLoadingListViewModel : BasePageViewModel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改库位按钮点击
|
* 修改库位(由 Activity 调用 Dialog 后回调)
|
||||||
*/
|
*/
|
||||||
fun modifyLocationClick() {
|
fun performModifyStorage(
|
||||||
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjManifest> ?: return
|
locationName: String,
|
||||||
val selectedItems = list.filter { it.isSelected }
|
locationId: String,
|
||||||
|
selectedItems: List<GjjManifest>
|
||||||
if (selectedItems.isEmpty()) {
|
) {
|
||||||
showToast("请选择要修改库位的记录")
|
if (locationName.isEmpty() || locationId.isEmpty()) {
|
||||||
|
showToast("请选择库位")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
showToast("修改库位功能开发中")
|
val params = mapOf(
|
||||||
|
"location" to locationName,
|
||||||
|
"locationId" to locationId.toLongOrNull(),
|
||||||
|
"manifestList" to selectedItems
|
||||||
|
).toRequestBody()
|
||||||
|
|
||||||
|
launchLoadingCollect({ NetApply.api.modifyIntImpStorage(params) }) {
|
||||||
|
onSuccess = {
|
||||||
|
showToast("修改库位成功")
|
||||||
|
viewModelScope.launch {
|
||||||
|
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
|
||||||
|
}
|
||||||
|
refresh()
|
||||||
|
}
|
||||||
|
onFailed = { _, msg ->
|
||||||
|
showToast(msg ?: "修改库位失败")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 入库按钮点击
|
* 入库(由 Activity 调用 Dialog 后回调)
|
||||||
*/
|
*/
|
||||||
fun inboundClick() {
|
fun performInStorage(
|
||||||
val list = pageModel.rv?.commonAdapter()?.items as? List<GjjManifest> ?: return
|
locationName: String,
|
||||||
val selectedItems = list.filter { it.isSelected }
|
locationId: String,
|
||||||
|
selectedItems: List<GjjManifest>
|
||||||
|
) {
|
||||||
if (selectedItems.isEmpty()) {
|
if (selectedItems.isEmpty()) {
|
||||||
showToast("请选择要入库的记录")
|
showToast("请至少选择一个单据")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
showToast("入库功能开发中")
|
if (locationName.isEmpty() || locationId.isEmpty()) {
|
||||||
|
showToast("请选择库位")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val params = mapOf(
|
||||||
|
"location" to locationName,
|
||||||
|
"locationId" to locationId.toLongOrNull(),
|
||||||
|
"manifestList" to selectedItems
|
||||||
|
).toRequestBody()
|
||||||
|
|
||||||
|
launchLoadingCollect({ NetApply.api.inIntImpStorage(params) }) {
|
||||||
|
onSuccess = {
|
||||||
|
showToast("入库成功")
|
||||||
|
viewModelScope.launch {
|
||||||
|
FlowBus.with<String>(ConstantEvent.EVENT_REFRESH).emit("refresh")
|
||||||
|
}
|
||||||
|
refresh()
|
||||||
|
}
|
||||||
|
onFailed = { _, msg ->
|
||||||
|
showToast(msg ?: "入库失败")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,7 +225,7 @@ class IntImpLoadingListViewModel : BasePageViewModel() {
|
|||||||
val filterParams = mapOf(
|
val filterParams = mapOf(
|
||||||
"fdate" to flightDate.value?.ifEmpty { null },
|
"fdate" to flightDate.value?.ifEmpty { null },
|
||||||
"fno" to flightNo.value?.ifEmpty { null },
|
"fno" to flightNo.value?.ifEmpty { null },
|
||||||
"fdep" to fdep.value?.ifEmpty { null },
|
"sendAddress" to sendAddress.value?.ifEmpty { null },
|
||||||
"fdest" to fdest.value?.ifEmpty { null },
|
"fdest" to fdest.value?.ifEmpty { null },
|
||||||
"wbNo" to waybillNo.value?.ifEmpty { null }
|
"wbNo" to waybillNo.value?.ifEmpty { null }
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -258,6 +258,10 @@ class IntImpManifestViewModel : BasePageViewModel() {
|
|||||||
fun sortingTallyClick() {
|
fun sortingTallyClick() {
|
||||||
com.alibaba.android.arouter.launcher.ARouter.getInstance()
|
com.alibaba.android.arouter.launcher.ARouter.getInstance()
|
||||||
.build(com.lukouguoji.module_base.router.ARouterConstants.ACTIVITY_URL_INT_IMP_LOADING_LIST)
|
.build(com.lukouguoji.module_base.router.ARouterConstants.ACTIVITY_URL_INT_IMP_LOADING_LIST)
|
||||||
|
.withString("fdate", flightDate.value ?: "")
|
||||||
|
.withString("fno", flightNo.value ?: "")
|
||||||
|
.withString("sendAddress", sendAddress.value ?: "")
|
||||||
|
.withString("fdest", fdep.value ?: "")
|
||||||
.navigation()
|
.navigation()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,10 @@
|
|||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
type="com.lukouguoji.gjj.viewModel.IntImpLoadingListViewModel" />
|
type="com.lukouguoji.gjj.viewModel.IntImpLoadingListViewModel" />
|
||||||
|
|
||||||
|
<variable
|
||||||
|
name="activity"
|
||||||
|
type="com.lukouguoji.gjj.activity.IntImpLoadingListActivity" />
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@@ -33,6 +37,7 @@
|
|||||||
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
|
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
|
||||||
hint='@{"请选择航班日期"}'
|
hint='@{"请选择航班日期"}'
|
||||||
icon="@{@drawable/img_date}"
|
icon="@{@drawable/img_date}"
|
||||||
|
setRefreshCallBack="@{viewModel::onFlightDateInputComplete}"
|
||||||
type="@{SearchLayoutType.DATE}"
|
type="@{SearchLayoutType.DATE}"
|
||||||
value="@={viewModel.flightDate}"
|
value="@={viewModel.flightDate}"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
@@ -42,24 +47,28 @@
|
|||||||
<!-- 航班号 -->
|
<!-- 航班号 -->
|
||||||
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
|
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
|
||||||
hint='@{"请输入航班号"}'
|
hint='@{"请输入航班号"}'
|
||||||
|
setRefreshCallBack="@{viewModel::onFlightNoInputComplete}"
|
||||||
|
setUpperCaseAlphanumeric="@{true}"
|
||||||
type="@{SearchLayoutType.INPUT}"
|
type="@{SearchLayoutType.INPUT}"
|
||||||
value="@={viewModel.flightNo}"
|
value="@={viewModel.flightNo}"
|
||||||
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="1" />
|
||||||
|
|
||||||
<!-- 始发站 -->
|
<!-- 始发站(下拉列表) -->
|
||||||
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
|
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
|
||||||
hint='@{"请选择始发站"}'
|
hint='@{"请选择始发站"}'
|
||||||
type="@{SearchLayoutType.INPUT}"
|
list="@{viewModel.sendAddressList}"
|
||||||
value="@={viewModel.fdep}"
|
type="@{SearchLayoutType.SPINNER}"
|
||||||
|
value="@={viewModel.sendAddress}"
|
||||||
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="1" />
|
||||||
|
|
||||||
<!-- 目的站 -->
|
<!-- 目的站(只读) -->
|
||||||
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
|
<com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout
|
||||||
hint='@{"HFE"}'
|
enable="@{false}"
|
||||||
|
hint='@{"目的站"}'
|
||||||
type="@{SearchLayoutType.INPUT}"
|
type="@{SearchLayoutType.INPUT}"
|
||||||
value="@={viewModel.fdest}"
|
value="@={viewModel.fdest}"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
@@ -198,7 +207,7 @@
|
|||||||
android:layout_marginEnd="10dp"
|
android:layout_marginEnd="10dp"
|
||||||
android:background="@drawable/bg_btn_bottom"
|
android:background="@drawable/bg_btn_bottom"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:onClick="@{()-> viewModel.modifyLocationClick()}"
|
android:onClick="@{()-> activity.showModifyStorageDialog()}"
|
||||||
android:text="修改库位"
|
android:text="修改库位"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="18sp" />
|
android:textSize="18sp" />
|
||||||
@@ -210,7 +219,7 @@
|
|||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:background="@drawable/bg_btn_bottom"
|
android:background="@drawable/bg_btn_bottom"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:onClick="@{()-> viewModel.inboundClick()}"
|
android:onClick="@{()-> activity.showInStorageDialog()}"
|
||||||
android:text="入库"
|
android:text="入库"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="18sp" />
|
android:textSize="18sp" />
|
||||||
|
|||||||
Reference in New Issue
Block a user