fix(wms): 解决仓储管理中数据删除和导出状态处理问题
This commit is contained in:
parent
178cc058e1
commit
bd8a73a4e1
@ -184,7 +184,7 @@ public interface ErrorCodeConstants {
|
|||||||
|
|
||||||
ErrorCode WMS_STORAGE_NOT_EXISTS = new ErrorCode(1_015_001, "当前数据不存在");
|
ErrorCode WMS_STORAGE_NOT_EXISTS = new ErrorCode(1_015_001, "当前数据不存在");
|
||||||
ErrorCode WMS_STORAGE_IS_EXPORT = new ErrorCode(1_015_002, "当前数据已导出,请刷新界面。");
|
ErrorCode WMS_STORAGE_IS_EXPORT = new ErrorCode(1_015_002, "当前数据已导出,请刷新界面。");
|
||||||
ErrorCode WMS_STORAGE_NOT_DELETE = new ErrorCode(1_015_003, "存在已导出的数据,请刷新界面。!");
|
ErrorCode WMS_STORAGE_DELETE = new ErrorCode(1_015_003, "存在已删除的数据,请刷新界面。!");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -105,13 +105,18 @@ public class WmsStorageController {
|
|||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public CommonResult<List<WmsStorageRespVO>> exportCheck(@RequestParam("ids") String ids) {
|
public CommonResult<List<WmsStorageRespVO>> exportCheck(@RequestParam("ids") String ids) {
|
||||||
// 处理数据,更新导出状态
|
// 处理数据,更新导出状态
|
||||||
Tuple2<Boolean, List<WmsStorageDO>> objects = wmsStorageService.processWsmStorage(false, ids);
|
Tuple2<Integer, List<WmsStorageDO>> objects = wmsStorageService.processWsmStorage(false, ids);
|
||||||
List<WmsStorageDO> list = objects.getT2();
|
List<WmsStorageDO> list = objects.getT2();
|
||||||
if (!objects.getT1()) {
|
if (objects.getT1() == 1) {
|
||||||
// list 统计ID,用,分割
|
// list 统计ID,用,分割
|
||||||
String idList = list.stream().map(WmsStorageDO::getId).map(String::valueOf).collect(Collectors.joining(","));
|
String idList = list.stream().map(WmsStorageDO::getId).map(String::valueOf).collect(Collectors.joining(","));
|
||||||
return CommonResult.error(10010, idList);
|
return CommonResult.error(10010, idList);
|
||||||
}
|
}
|
||||||
|
if (objects.getT1() == 2) {
|
||||||
|
// list 统计ID,用,分割
|
||||||
|
String idList = list.stream().map(WmsStorageDO::getId).map(String::valueOf).collect(Collectors.joining(","));
|
||||||
|
return CommonResult.error(10011, idList);
|
||||||
|
}
|
||||||
return CommonResult.success(null);
|
return CommonResult.success(null);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -125,14 +130,18 @@ public class WmsStorageController {
|
|||||||
@RequestParam("ids") String ids,
|
@RequestParam("ids") String ids,
|
||||||
HttpServletResponse response) throws IOException {
|
HttpServletResponse response) throws IOException {
|
||||||
// 处理数据,更新导出状态
|
// 处理数据,更新导出状态
|
||||||
Tuple2<Boolean, List<WmsStorageDO>> objects = wmsStorageService.processWsmStorage(true, ids);
|
Tuple2<Integer, List<WmsStorageDO>> objects = wmsStorageService.processWsmStorage(true, ids);
|
||||||
List<WmsStorageDO> list = objects.getT2();
|
List<WmsStorageDO> list = objects.getT2();
|
||||||
if (!objects.getT1()) {
|
if (objects.getT1() == 1) {
|
||||||
// list 统计单据编号,用,分割
|
// list 统计单据编号,用,分割
|
||||||
String stockNoList = list.stream().map(WmsStorageDO::getStockNo).collect(Collectors.joining(","));
|
String stockNoList = list.stream().map(WmsStorageDO::getStockNo).collect(Collectors.joining(","));
|
||||||
throw new ServiceException(1010, "单据编号{" + stockNoList + "}存在已导出的数据,请刷新界面。");
|
throw new ServiceException(10010, "单据编号{" + stockNoList + "}存在已删除的数据,请刷新界面。");
|
||||||
|
}
|
||||||
|
if (objects.getT1() == 2) {
|
||||||
|
// list 统计单据编号,用,分割
|
||||||
|
String stockNoList = list.stream().map(WmsStorageDO::getStockNo).collect(Collectors.joining(","));
|
||||||
|
throw new ServiceException(10011, "单据编号{" + stockNoList + "}存在已导出的数据,请刷新界面。");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断入库还是出库
|
// 判断入库还是出库
|
||||||
boolean isInbound = stockType == 1;
|
boolean isInbound = stockType == 1;
|
||||||
String typeName = isInbound ? "入库" : "出库";
|
String typeName = isInbound ? "入库" : "出库";
|
||||||
@ -236,7 +245,7 @@ public class WmsStorageController {
|
|||||||
public void exportWmsStorageExcel(@RequestParam("stockType") Integer stockType,
|
public void exportWmsStorageExcel(@RequestParam("stockType") Integer stockType,
|
||||||
@RequestParam("ids") String ids,
|
@RequestParam("ids") String ids,
|
||||||
HttpServletResponse response) throws IOException {
|
HttpServletResponse response) throws IOException {
|
||||||
Tuple2<Boolean, List<WmsStorageDO>> objects = wmsStorageService.processWsmStorage(true, ids);
|
Tuple2<Integer, List<WmsStorageDO>> objects = wmsStorageService.processWsmStorage(true, ids);
|
||||||
List<WmsStorageDO> list = objects.getT2();
|
List<WmsStorageDO> list = objects.getT2();
|
||||||
|
|
||||||
// 导出 Excel - 两个sheet
|
// 导出 Excel - 两个sheet
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
package com.chanko.yunxi.mes.module.heli.dal.dataobject.storagelog;
|
package com.chanko.yunxi.mes.module.heli.dal.dataobject.storagelog;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import com.chanko.yunxi.mes.framework.mybatis.core.dataobject.BaseDO;
|
import com.chanko.yunxi.mes.framework.mybatis.core.dataobject.BaseDO;
|
||||||
import com.chanko.yunxi.mes.module.heli.dal.dataobject.material.MaterialDO;
|
import com.chanko.yunxi.mes.module.heli.dal.dataobject.material.MaterialDO;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
@ -97,8 +94,14 @@ public class StorageLogDO extends BaseDO {
|
|||||||
@TableField(exist = false)
|
@TableField(exist = false)
|
||||||
private List<MaterialDO> materialDOList;
|
private List<MaterialDO> materialDOList;
|
||||||
|
|
||||||
|
// 允许设置为null
|
||||||
|
@TableField(updateStrategy = FieldStrategy.IGNORED)
|
||||||
private Long xzdStockId;
|
private Long xzdStockId;
|
||||||
|
|
||||||
|
@TableField(updateStrategy = FieldStrategy.IGNORED)
|
||||||
private String xzdStockNo;
|
private String xzdStockNo;
|
||||||
|
|
||||||
|
@TableField(updateStrategy = FieldStrategy.IGNORED)
|
||||||
private String incoiceCode;
|
private String incoiceCode;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import com.chanko.yunxi.mes.framework.mybatis.core.mapper.BaseMapperX;
|
|||||||
import com.chanko.yunxi.mes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import com.chanko.yunxi.mes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import com.chanko.yunxi.mes.module.heli.controller.admin.wmsstorage.vo.WmsStoragePageReqVO;
|
import com.chanko.yunxi.mes.module.heli.controller.admin.wmsstorage.vo.WmsStoragePageReqVO;
|
||||||
import com.chanko.yunxi.mes.module.heli.dal.dataobject.wmsstorage.WmsStorageDO;
|
import com.chanko.yunxi.mes.module.heli.dal.dataobject.wmsstorage.WmsStorageDO;
|
||||||
|
import org.apache.ibatis.annotations.Delete;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,4 +24,7 @@ public interface WmsStorageMapper extends BaseMapperX<WmsStorageDO> {
|
|||||||
.eqIfPresent(WmsStorageDO::getStockType, reqVO.getStockType())
|
.eqIfPresent(WmsStorageDO::getStockType, reqVO.getStockType())
|
||||||
.orderByDesc(WmsStorageDO::getId));
|
.orderByDesc(WmsStorageDO::getId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Delete("DELETE FROM xzd_wms_storage WHERE id = #{id}")
|
||||||
|
int deleteByIdPhysical(Long id);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import com.chanko.yunxi.mes.framework.mybatis.core.mapper.BaseMapperX;
|
|||||||
import com.chanko.yunxi.mes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import com.chanko.yunxi.mes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import com.chanko.yunxi.mes.module.heli.controller.admin.wmsstoragedetail.vo.WmsStorageDetailPageReqVO;
|
import com.chanko.yunxi.mes.module.heli.controller.admin.wmsstoragedetail.vo.WmsStorageDetailPageReqVO;
|
||||||
import com.chanko.yunxi.mes.module.heli.dal.dataobject.wmsstoragedetail.WmsStorageDetailDO;
|
import com.chanko.yunxi.mes.module.heli.dal.dataobject.wmsstoragedetail.WmsStorageDetailDO;
|
||||||
|
import org.apache.ibatis.annotations.Delete;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,4 +29,6 @@ public interface WmsStorageDetailMapper extends BaseMapperX<WmsStorageDetailDO>
|
|||||||
.orderByDesc(WmsStorageDetailDO::getId));
|
.orderByDesc(WmsStorageDetailDO::getId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Delete("DELETE FROM xzd_wms_storage_detail WHERE xzd_wms_id = #{xzdWmsId}")
|
||||||
|
int deleteByXzdWmsIdPhysical(Long xzdWmsId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,6 +54,12 @@ public interface WmsStorageService {
|
|||||||
*/
|
*/
|
||||||
PageResult<WmsStorageDO> getWmsStoragePage(WmsStoragePageReqVO pageReqVO);
|
PageResult<WmsStorageDO> getWmsStoragePage(WmsStoragePageReqVO pageReqVO);
|
||||||
|
|
||||||
Tuple2<Boolean, List<WmsStorageDO>> processWsmStorage(Boolean isExport, String ids);
|
/**
|
||||||
|
* 处理新中大入/出库主
|
||||||
|
* @param isExport 是否导出
|
||||||
|
* @param ids 新中大入/出库主编号
|
||||||
|
* @return 处理结果
|
||||||
|
*/
|
||||||
|
Tuple2<Integer, List<WmsStorageDO>> processWsmStorage(Boolean isExport, String ids);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,8 +26,7 @@ import java.util.List;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static com.chanko.yunxi.mes.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static com.chanko.yunxi.mes.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static com.chanko.yunxi.mes.module.heli.enums.ErrorCodeConstants.WMS_STORAGE_IS_EXPORT;
|
import static com.chanko.yunxi.mes.module.heli.enums.ErrorCodeConstants.*;
|
||||||
import static com.chanko.yunxi.mes.module.heli.enums.ErrorCodeConstants.WMS_STORAGE_NOT_EXISTS;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新中大入/出库主 Service 实现类
|
* 新中大入/出库主 Service 实现类
|
||||||
@ -72,9 +71,11 @@ public class WmsStorageServiceImpl implements WmsStorageService {
|
|||||||
if (wmsStorage.getStatus() == 2) {
|
if (wmsStorage.getStatus() == 2) {
|
||||||
throw exception(WMS_STORAGE_IS_EXPORT);
|
throw exception(WMS_STORAGE_IS_EXPORT);
|
||||||
}
|
}
|
||||||
// 删除
|
// 物理删除
|
||||||
wmsStorageMapper.deleteById(id);
|
wmsStorageMapper.deleteByIdPhysical(id);
|
||||||
wmsStorageDetailMapper.delete(WmsStorageDetailDO::getXzdWmsId, id);
|
wmsStorageDetailMapper.deleteByXzdWmsIdPhysical(id);
|
||||||
|
// wmsStorageMapper.deleteById(id);
|
||||||
|
// wmsStorageDetailMapper.delete(WmsStorageDetailDO::getXzdWmsId, id);
|
||||||
|
|
||||||
// storageLogService
|
// storageLogService
|
||||||
StorageLogDO storageLogDO = storageLogMapper.selectOne(StorageLogDO::getXzdStockId, wmsStorage.getId());
|
StorageLogDO storageLogDO = storageLogMapper.selectOne(StorageLogDO::getXzdStockId, wmsStorage.getId());
|
||||||
@ -113,20 +114,34 @@ public class WmsStorageServiceImpl implements WmsStorageService {
|
|||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public Tuple2<Boolean, List<WmsStorageDO>> processWsmStorage(Boolean isExport, String ids) {
|
public Tuple2<Integer, List<WmsStorageDO>> processWsmStorage(Boolean isExport, String ids) {
|
||||||
// 分割并转换为 Long 类型
|
// 分割并转换为 Long 类型
|
||||||
List<Long> idList = Arrays.stream(ids.split(",")).map(Long::valueOf).collect(Collectors.toList());
|
List<Long> idList = Arrays.stream(ids.split(",")).map(Long::valueOf).collect(Collectors.toList());
|
||||||
|
// YYDS hhhhh
|
||||||
if (!idList.isEmpty()) {
|
if (!idList.isEmpty()) {
|
||||||
// 根据ID查询出所有数据,批量更新导出人,导出状态
|
|
||||||
List<WmsStorageDO> wmsStorageDOS = wmsStorageMapper.selectList(WmsStorageDO::getId, idList);
|
|
||||||
List<WmsStorageDO> errWmsStorageDOS = new ArrayList<>();
|
List<WmsStorageDO> errWmsStorageDOS = new ArrayList<>();
|
||||||
|
List<WmsStorageDO> wmsStorageDOS = new ArrayList<>();
|
||||||
|
// 根据ID查询出所有数据,批量更新导出人,导出状态
|
||||||
|
for (Long l : idList) {
|
||||||
|
WmsStorageDO wmsStorageDO = wmsStorageMapper.selectById(l);
|
||||||
|
if (wmsStorageDO == null) {
|
||||||
|
WmsStorageDO wmsStorageDO1 = new WmsStorageDO();
|
||||||
|
wmsStorageDO1.setId(l);
|
||||||
|
errWmsStorageDOS.add(wmsStorageDO1);
|
||||||
|
}
|
||||||
|
wmsStorageDOS.add(wmsStorageDO);
|
||||||
|
}
|
||||||
|
if (!errWmsStorageDOS.isEmpty()) {
|
||||||
|
return Tuples.of(1, errWmsStorageDOS);
|
||||||
|
}
|
||||||
for (WmsStorageDO wmsStorageDO : wmsStorageDOS) {
|
for (WmsStorageDO wmsStorageDO : wmsStorageDOS) {
|
||||||
if (wmsStorageDO.getStatus() == 2) {
|
if (wmsStorageDO.getStatus() == 2) {
|
||||||
errWmsStorageDOS.add(wmsStorageDO);
|
errWmsStorageDOS.add(wmsStorageDO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!errWmsStorageDOS.isEmpty()) {
|
if (!errWmsStorageDOS.isEmpty()) {
|
||||||
return Tuples.of(false, errWmsStorageDOS);
|
// 已经导出的ID
|
||||||
|
return Tuples.of(2, errWmsStorageDOS);
|
||||||
}
|
}
|
||||||
if (isExport) {
|
if (isExport) {
|
||||||
for (WmsStorageDO wmsStorageDO : wmsStorageDOS) {
|
for (WmsStorageDO wmsStorageDO : wmsStorageDOS) {
|
||||||
@ -140,8 +155,8 @@ public class WmsStorageServiceImpl implements WmsStorageService {
|
|||||||
wmsStorageDO.setDetailList(wmsStorageDetailDOS);
|
wmsStorageDO.setDetailList(wmsStorageDetailDOS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Tuples.of(true, wmsStorageDOS);
|
return Tuples.of(0, wmsStorageDOS);
|
||||||
}
|
}
|
||||||
return Tuples.of(false, Collections.emptyList());
|
return Tuples.of(0, Collections.emptyList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -168,7 +168,7 @@ service.interceptors.response.use(
|
|||||||
} else if (code === 500) {
|
} else if (code === 500) {
|
||||||
ElMessage.error(t('sys.api.errMsg500'))
|
ElMessage.error(t('sys.api.errMsg500'))
|
||||||
return Promise.reject(new Error(msg))
|
return Promise.reject(new Error(msg))
|
||||||
} else if (code === 10010) {
|
} else if (code === 10010 || code === 10011) {
|
||||||
// 导出校验失败,不显示错误提示,直接返回完整数据
|
// 导出校验失败,不显示错误提示,直接返回完整数据
|
||||||
return Promise.reject(data)
|
return Promise.reject(data)
|
||||||
} else if (code === 901) {
|
} else if (code === 901) {
|
||||||
|
|||||||
@ -73,6 +73,7 @@
|
|||||||
:data="list"
|
:data="list"
|
||||||
class="hl-table"
|
class="hl-table"
|
||||||
ref="multipleTableRef"
|
ref="multipleTableRef"
|
||||||
|
height="510"
|
||||||
@selection-change="handleSelectionChange"
|
@selection-change="handleSelectionChange"
|
||||||
:row-class-name="tableRowClassName"
|
:row-class-name="tableRowClassName"
|
||||||
>
|
>
|
||||||
@ -89,7 +90,7 @@
|
|||||||
{{ getHeliStockTypeLabel(scope.row.stockType) }}
|
{{ getHeliStockTypeLabel(scope.row.stockType) }}
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column fixed="left" label="单据状态" min-width="120" align="center" prop="status">
|
<el-table-column fixed="left" label="单据状态" min-width="140" align="center" prop="status">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag v-if="scope.row.status === 1" type="success">
|
<el-tag v-if="scope.row.status === 1" type="success">
|
||||||
<Icon icon="ep:check" class="mr-5px" />
|
<Icon icon="ep:check" class="mr-5px" />
|
||||||
@ -104,7 +105,7 @@
|
|||||||
<el-table-column
|
<el-table-column
|
||||||
label="单据编号"
|
label="单据编号"
|
||||||
fixed="left"
|
fixed="left"
|
||||||
min-width="180"
|
min-width="190"
|
||||||
align="center"
|
align="center"
|
||||||
prop="stockNo"
|
prop="stockNo"
|
||||||
/>
|
/>
|
||||||
@ -268,14 +269,17 @@ const handleExportSelected = async () => {
|
|||||||
try {
|
try {
|
||||||
const checkData = await WmsStorageApi.exportCheck(ids)
|
const checkData = await WmsStorageApi.exportCheck(ids)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
// 获取错误信息中的 ID 列表
|
// 获取错误码和错误信息中的 ID 列表
|
||||||
|
let code = 0
|
||||||
let idStr = ''
|
let idStr = ''
|
||||||
if (typeof e === 'string') {
|
if (typeof e === 'string') {
|
||||||
idStr = e
|
idStr = e
|
||||||
} else if (e.msg) {
|
} else if (e.code) {
|
||||||
idStr = e.msg
|
code = e.code
|
||||||
} else if (e.response?.data?.msg) {
|
idStr = e.msg || ''
|
||||||
idStr = e.response.data.msg
|
} else if (e.response?.data) {
|
||||||
|
code = e.response.data.code
|
||||||
|
idStr = e.response.data.msg || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
// 移除 msg 中可能存在的中文后缀
|
// 移除 msg 中可能存在的中文后缀
|
||||||
@ -283,17 +287,27 @@ const handleExportSelected = async () => {
|
|||||||
|
|
||||||
// 分割msg,获取ID数组
|
// 分割msg,获取ID数组
|
||||||
const msg = idStr.split(',')
|
const msg = idStr.split(',')
|
||||||
// 在selectedRows中找到对应ID的序号集合
|
// 在list中找到对应ID的序号集合(表格显示的序号)
|
||||||
const errorIndices = msg
|
const errorIndices = msg
|
||||||
.map((id) => {
|
.map((id) => {
|
||||||
const index = selectedRows.value.findIndex((row) => row.id === parseInt(id))
|
const index = list.value.findIndex((row) => row.id === parseInt(id))
|
||||||
return index + 1 // 序号从1开始
|
if (index === -1) return 0 // 未找到返回0
|
||||||
|
// 计算表格显示的序号:(当前页-1) * 每页条数 + 当前页索引 + 1
|
||||||
|
return (queryParams.pageNo - 1) * queryParams.pageSize + index + 1
|
||||||
})
|
})
|
||||||
.filter((index) => index > 0) // 过滤掉未找到的
|
.filter((index) => index > 0) // 过滤掉未找到的
|
||||||
// 转换为字符串用逗号分割 errorIndices从小到大排序,是数字
|
// 转换为字符串用逗号分割,errorIndices从小到大排序
|
||||||
errorIndices.sort((a, b) => a - b)
|
errorIndices.sort((a, b) => a - b)
|
||||||
const errorIndicesStr = errorIndices.join(',')
|
const errorIndicesStr = errorIndices.join(',')
|
||||||
message.error(`行 (${errorIndicesStr} )存在已导出的数据,请刷新界面。`)
|
|
||||||
|
// 根据不同的错误码显示不同的提示
|
||||||
|
if (code === 10010) {
|
||||||
|
message.error(`行 (${errorIndicesStr} )存在已删除的数据,请刷新界面!`)
|
||||||
|
} else if (code === 10011) {
|
||||||
|
message.error(`行 (${errorIndicesStr} )存在已导出的数据,请刷新界面!`)
|
||||||
|
} else {
|
||||||
|
message.error(`行 (${errorIndicesStr} )存在异常数据,请刷新界面。`)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user