fix: 修复了一些问题
This commit is contained in:
@@ -152,7 +152,7 @@ const passApplication = () => {
|
|||||||
// 新标签跳转到 exportWesternMedicineApi
|
// 新标签跳转到 exportWesternMedicineApi
|
||||||
exportOrderApi().then((res) => {
|
exportOrderApi().then((res) => {
|
||||||
// 创建新的URL表示指定的File对象或者Blob对象。
|
// 创建新的URL表示指定的File对象或者Blob对象。
|
||||||
downloadByData(res.data, '萧康云医-西药导出.xlsx');
|
downloadByData(res.data, `萧康云医-商品订单导出${new Date()}.xlsx`);
|
||||||
message.success('导出成功!');
|
message.success('导出成功!');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,61 +3,97 @@ import { ref } from 'vue';
|
|||||||
|
|
||||||
import { useVbenModal } from '@vben/common-ui';
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
import { message, UploadDragger } from 'ant-design-vue';
|
import { message, UploadDragger, type UploadFile } from 'ant-design-vue';
|
||||||
|
|
||||||
import { importChinaMedicineApi } from '../api';
|
import { importChinaMedicineApi } from '../api';
|
||||||
|
|
||||||
const gridApi = ref();
|
const gridApi = ref();
|
||||||
const fileList = ref([]);
|
const fileList = ref<UploadFile[]>([]);
|
||||||
|
const selectedFile = ref<File | null>(null); // 新增:存储选中的文件
|
||||||
const importChinaMedicine = (file) => {
|
const isFileSelected = ref(false); // 新增:标记是否有文件被选中
|
||||||
const submitApi = importChinaMedicineApi;
|
|
||||||
submitApi({
|
|
||||||
file: file.file,
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
message.success('导入成功');
|
|
||||||
gridApi.value?.reload();
|
|
||||||
modalApi.close();
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
fullscreenButton: false,
|
fullscreenButton: false,
|
||||||
draggable: true,
|
draggable: true,
|
||||||
onCancel() {
|
onCancel() {
|
||||||
|
// 重置文件状态
|
||||||
|
selectedFile.value = null;
|
||||||
|
isFileSelected.value = false;
|
||||||
|
fileList.value = [];
|
||||||
modalApi.close();
|
modalApi.close();
|
||||||
},
|
},
|
||||||
onConfirm: async () => {
|
onConfirm: async () => {
|
||||||
|
// 检查是否有选中文件
|
||||||
|
if (!selectedFile.value) {
|
||||||
|
message.warning('请先选择要上传的文件');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
modalApi.setState({ loading: true, confirmLoading: true });
|
modalApi.setState({ loading: true, confirmLoading: true });
|
||||||
const submitApi = importChinaMedicineApi;
|
|
||||||
submitApi({
|
try {
|
||||||
file: fileList.value,
|
await importChinaMedicineApi({
|
||||||
})
|
file: selectedFile.value,
|
||||||
.then(() => {
|
|
||||||
message.success('导入成功');
|
|
||||||
gridApi.value?.reload();
|
|
||||||
modalApi.close();
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
modalApi.setState({ loading: false, confirmLoading: false });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
message.success('导入成功');
|
||||||
|
gridApi.value?.reload();
|
||||||
|
|
||||||
|
// 重置文件状态
|
||||||
|
selectedFile.value = null;
|
||||||
|
isFileSelected.value = false;
|
||||||
|
fileList.value = [];
|
||||||
|
|
||||||
|
modalApi.close();
|
||||||
|
} catch (error) {
|
||||||
|
message.error('导入失败');
|
||||||
|
} finally {
|
||||||
|
modalApi.setState({ loading: false, confirmLoading: false });
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onOpenChange(isOpen: boolean) {
|
onOpenChange(isOpen: boolean) {
|
||||||
gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
|
gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
|
||||||
|
// 重置文件状态
|
||||||
|
selectedFile.value = null;
|
||||||
|
isFileSelected.value = false;
|
||||||
|
fileList.value = [];
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 处理文件选择变化,只存储文件不上传
|
||||||
|
const handleChange = (info: { file: UploadFile }) => {
|
||||||
|
const { file } = info;
|
||||||
|
|
||||||
|
if (file.status === 'removed') {
|
||||||
|
// 文件被移除
|
||||||
|
selectedFile.value = null;
|
||||||
|
isFileSelected.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
// 存储选中的文件
|
||||||
|
selectedFile.value = file;
|
||||||
|
isFileSelected.value = true;
|
||||||
|
message.success('文件已选择,请点击确认按钮上传');
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Modal class="w-[30%]" title="上传Excel">
|
<Modal class="w-[30%]" title="上传Excel">
|
||||||
|
<!-- 新增:显示文件选择状态 -->
|
||||||
|
<div v-if="isFileSelected" class="mb-4 p-3 bg-green-50 border border-green-200 rounded">
|
||||||
|
<p class="text-green-700 text-sm">已选择文件:{{ selectedFile?.name }}</p>
|
||||||
|
<p class="text-green-600 text-xs mt-1">文件已准备就绪,点击确认按钮开始上传</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<UploadDragger
|
<UploadDragger
|
||||||
v-model:file-list="fileList"
|
v-model:file-list="fileList"
|
||||||
:custom-request="importChinaMedicine"
|
:before-upload="() => false"
|
||||||
:max-count="1"
|
:max-count="1"
|
||||||
|
:on-change="handleChange"
|
||||||
name="file"
|
name="file"
|
||||||
|
accept=".xlsx,.xls"
|
||||||
>
|
>
|
||||||
<p class="flex justify-center">
|
<p class="flex justify-center">
|
||||||
<svg
|
<svg
|
||||||
@@ -121,11 +157,10 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
<path d="M19.581 16H30v6.5H19.581Z" fill="#107c41" />
|
<path d="M19.581 16H30v6.5H19.581Z" fill="#107c41" />
|
||||||
</svg>
|
</svg>
|
||||||
</p>
|
</p>
|
||||||
<p class="ant-upload-text">点击或拖动文件到此区域进行上传</p>
|
<p class="ant-upload-text">点击或拖动文件到此区域进行选择</p>
|
||||||
<p class="ant-upload-hint">
|
<p class="ant-upload-hint">
|
||||||
支持单个上传,xlsx格式文件。严禁上传公司数据或其他带格式文件。
|
支持单个上传,xlsx格式文件。选择文件后需要点击确认按钮进行上传。
|
||||||
</p>
|
</p>
|
||||||
</UploadDragger>
|
</UploadDragger>
|
||||||
<!-- <Form />-->
|
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -3,60 +3,101 @@ import { ref } from 'vue';
|
|||||||
|
|
||||||
import { useVbenModal } from '@vben/common-ui';
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
import { message, UploadDragger } from 'ant-design-vue';
|
import { message, UploadDragger, type UploadFile } from 'ant-design-vue';
|
||||||
|
|
||||||
import { importWesternMedicineApi } from '../api';
|
import { importWesternMedicineApi } from '../api';
|
||||||
|
|
||||||
const gridApi = ref();
|
const gridApi = ref();
|
||||||
const fileList = ref([]);
|
const fileList = ref<UploadFile[]>([]);
|
||||||
|
const selectedFile = ref<File | null>(null); // 新增:存储选中的文件
|
||||||
const importWesternMedicine = (file) => {
|
const isFileSelected = ref(false); // 新增:标记是否有文件被选中
|
||||||
const submitApi = importWesternMedicineApi;
|
|
||||||
submitApi({
|
|
||||||
file: file.file,
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
message.success('导入成功');
|
|
||||||
gridApi.value?.reload();
|
|
||||||
modalApi.close();
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
fullscreenButton: false,
|
fullscreenButton: false,
|
||||||
draggable: true,
|
draggable: true,
|
||||||
onCancel() {
|
onCancel() {
|
||||||
|
// 重置文件状态
|
||||||
|
selectedFile.value = null;
|
||||||
|
isFileSelected.value = false;
|
||||||
|
fileList.value = [];
|
||||||
modalApi.close();
|
modalApi.close();
|
||||||
},
|
},
|
||||||
onConfirm: async () => {
|
onConfirm: async () => {
|
||||||
|
// 检查是否有选中文件
|
||||||
|
if (!selectedFile.value) {
|
||||||
|
message.warning('请先选择要上传的文件');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
modalApi.setState({ loading: true, confirmLoading: true });
|
modalApi.setState({ loading: true, confirmLoading: true });
|
||||||
const submitApi = importWesternMedicineApi;
|
|
||||||
submitApi({
|
try {
|
||||||
file: fileList.value,
|
await importWesternMedicineApi({
|
||||||
})
|
file: selectedFile.value,
|
||||||
.then(() => {
|
|
||||||
message.success('导入成功');
|
|
||||||
gridApi.value?.reload();
|
|
||||||
modalApi.close();
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
modalApi.setState({ loading: false, confirmLoading: false });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
message.success('导入成功');
|
||||||
|
gridApi.value?.reload();
|
||||||
|
|
||||||
|
// 重置文件状态
|
||||||
|
selectedFile.value = null;
|
||||||
|
isFileSelected.value = false;
|
||||||
|
fileList.value = [];
|
||||||
|
|
||||||
|
modalApi.close();
|
||||||
|
} catch {
|
||||||
|
message.error('导入失败');
|
||||||
|
} finally {
|
||||||
|
modalApi.setState({ loading: false, confirmLoading: false });
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onOpenChange(isOpen: boolean) {
|
onOpenChange(isOpen: boolean) {
|
||||||
gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
|
gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
|
||||||
|
// 重置文件状态
|
||||||
|
selectedFile.value = null;
|
||||||
|
isFileSelected.value = false;
|
||||||
|
fileList.value = [];
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 处理文件选择变化,只存储文件不上传
|
||||||
|
const handleChange = (info: { file: UploadFile }) => {
|
||||||
|
const { file } = info;
|
||||||
|
|
||||||
|
if (file.status === 'removed') {
|
||||||
|
// 文件被移除
|
||||||
|
selectedFile.value = null;
|
||||||
|
isFileSelected.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
// 存储选中的文件
|
||||||
|
selectedFile.value = file;
|
||||||
|
isFileSelected.value = true;
|
||||||
|
message.success('文件已选择,请点击确认按钮上传');
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Modal class="w-[30%]" title="上传Excel">
|
<Modal class="w-[30%]" title="上传Excel">
|
||||||
|
<!-- 新增:显示文件选择状态 -->
|
||||||
|
<div
|
||||||
|
v-if="isFileSelected"
|
||||||
|
class="mb-4 rounded border border-green-200 bg-green-50 p-3"
|
||||||
|
>
|
||||||
|
<p class="text-sm text-green-700">已选择文件:{{ selectedFile?.name }}</p>
|
||||||
|
<p class="mt-1 text-xs text-green-600">
|
||||||
|
文件已准备就绪,点击确认按钮开始上传
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<UploadDragger
|
<UploadDragger
|
||||||
v-model:file-list="fileList"
|
v-model:file-list="fileList"
|
||||||
:custom-request="importWesternMedicine"
|
:before-upload="() => false"
|
||||||
:max-count="1"
|
:max-count="1"
|
||||||
|
:on-change="handleChange"
|
||||||
|
accept=".xlsx,.xls"
|
||||||
name="file"
|
name="file"
|
||||||
>
|
>
|
||||||
<p class="flex justify-center">
|
<p class="flex justify-center">
|
||||||
@@ -121,11 +162,10 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
<path d="M19.581 16H30v6.5H19.581Z" fill="#107c41" />
|
<path d="M19.581 16H30v6.5H19.581Z" fill="#107c41" />
|
||||||
</svg>
|
</svg>
|
||||||
</p>
|
</p>
|
||||||
<p class="ant-upload-text">点击或拖动文件到此区域进行上传</p>
|
<p class="ant-upload-text">点击或拖动文件到此区域进行选择</p>
|
||||||
<p class="ant-upload-hint">
|
<p class="ant-upload-hint">
|
||||||
支持单个上传,xlsx格式文件。严禁上传公司数据或其他带格式文件。
|
支持单个上传,xlsx格式文件。选择文件后需要点击确认按钮进行上传。
|
||||||
</p>
|
</p>
|
||||||
</UploadDragger>
|
</UploadDragger>
|
||||||
<!-- <Form />-->
|
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
message,
|
message,
|
||||||
type UploadChangeParam,
|
type UploadChangeParam,
|
||||||
UploadDragger,
|
UploadDragger,
|
||||||
|
type UploadFile,
|
||||||
} from 'ant-design-vue';
|
} from 'ant-design-vue';
|
||||||
|
|
||||||
import { downloadByData } from '#/util/tool';
|
import { downloadByData } from '#/util/tool';
|
||||||
@@ -20,62 +21,108 @@ import {
|
|||||||
|
|
||||||
const gridApi = ref();
|
const gridApi = ref();
|
||||||
const passApplication = ref();
|
const passApplication = ref();
|
||||||
|
const titles = ref('批量修改药品价格');
|
||||||
const importType = ref(1);
|
const importType = ref(1);
|
||||||
const fileList = ref([]);
|
const uploadType = ref(1);
|
||||||
|
const fileList = ref<UploadFile[]>([]);
|
||||||
|
const selectedFile = ref<File | null>(null); // 新增:存储选中的文件
|
||||||
|
const isFileSelected = ref(false); // 新增:标记是否有文件被选中
|
||||||
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
fullscreenButton: false,
|
fullscreenButton: false,
|
||||||
draggable: true,
|
draggable: true,
|
||||||
onCancel() {
|
onCancel() {
|
||||||
|
// 重置文件状态
|
||||||
|
selectedFile.value = null;
|
||||||
|
isFileSelected.value = false;
|
||||||
|
fileList.value = [];
|
||||||
modalApi.close();
|
modalApi.close();
|
||||||
},
|
},
|
||||||
onConfirm: async () => {
|
onConfirm: async () => {
|
||||||
// modalApi.setState({ loading: true, confirmLoading: true });
|
// 检查是否有选中文件
|
||||||
gridApi.value?.reload();
|
if (!selectedFile.value) {
|
||||||
modalApi.close();
|
message.warning('请先选择要上传的文件');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
modalApi.setState({ loading: true, confirmLoading: true });
|
||||||
|
|
||||||
|
try {
|
||||||
|
const submitApi =
|
||||||
|
importType.value === 1
|
||||||
|
? importWarehouseDrugManagementApi
|
||||||
|
: importUpdatePriceApi;
|
||||||
|
|
||||||
|
await submitApi({
|
||||||
|
file: selectedFile.value,
|
||||||
|
upload_type: uploadType.value,
|
||||||
|
});
|
||||||
|
|
||||||
|
message.success('上传成功');
|
||||||
|
gridApi.value?.reload();
|
||||||
|
|
||||||
|
// 重置文件状态
|
||||||
|
selectedFile.value = null;
|
||||||
|
isFileSelected.value = false;
|
||||||
|
fileList.value = [];
|
||||||
|
|
||||||
|
modalApi.close();
|
||||||
|
} catch {
|
||||||
|
message.error('上传失败');
|
||||||
|
} finally {
|
||||||
|
modalApi.setState({ loading: false, confirmLoading: false });
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onOpenChange(isOpen: boolean) {
|
onOpenChange(isOpen: boolean) {
|
||||||
gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
|
gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
|
||||||
passApplication.value = isOpen ? modalApi.getData()?.passApplication : null;
|
passApplication.value = isOpen ? modalApi.getData()?.passApplication : null;
|
||||||
importType.value = isOpen ? modalApi.getData()?.type : 1;
|
importType.value = isOpen ? modalApi.getData()?.type : 1;
|
||||||
|
uploadType.value = isOpen ? modalApi.getData()?.uploadType : 1;
|
||||||
fileList.value = [];
|
fileList.value = [];
|
||||||
|
selectedFile.value = null; // 重置选中的文件
|
||||||
|
isFileSelected.value = false; // 重置文件选择状态
|
||||||
|
|
||||||
|
switch (uploadType.value) {
|
||||||
|
case 1: {
|
||||||
|
titles.value = '批量修改中药价格(库里不存在的自动添加)';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
titles.value = '批量修改西(中成)药价格(库里不存在的自动添加)';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5: {
|
||||||
|
titles.value = '批量修产品服务包药价格(库里不存在的自动添加)';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// No default
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const importWarehouseDrugManagement = ({ file, onSuccess }) => {
|
// 修改:处理文件选择变化,只存储文件不上传
|
||||||
modalApi.setState({ loading: true, confirmLoading: true });
|
|
||||||
const submitApi =
|
|
||||||
importType.value === 1
|
|
||||||
? importWarehouseDrugManagementApi
|
|
||||||
: importUpdatePriceApi;
|
|
||||||
submitApi({
|
|
||||||
file,
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
onSuccess('ok', { status: 'done' });
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
onSuccess('error', { status: 'error' });
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
modalApi.setState({ loading: false, confirmLoading: false });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const handleChange = (info: UploadChangeParam) => {
|
const handleChange = (info: UploadChangeParam) => {
|
||||||
if (info.file.status === 'uploading') {
|
const { file } = info;
|
||||||
|
|
||||||
|
if (file.status === 'removed') {
|
||||||
|
// 文件被移除
|
||||||
|
selectedFile.value = null;
|
||||||
|
isFileSelected.value = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (info.file.status === 'done') {
|
|
||||||
message.success('上传成功');
|
if (file) {
|
||||||
}
|
// 存储选中的文件
|
||||||
if (info.file.status === 'error') {
|
selectedFile.value = file;
|
||||||
message.error('upload error');
|
isFileSelected.value = true;
|
||||||
|
message.success('文件已选择,请点击确认按钮上传');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 修改:移除原来的上传函数,因为现在在onConfirm中处理上传
|
||||||
|
|
||||||
const exportWarehouseDrugManagementTemplate = () => {
|
const exportWarehouseDrugManagementTemplate = () => {
|
||||||
exportWarehouseDrugManagementTemplateApi().then((res) => {
|
exportWarehouseDrugManagementTemplateApi().then((res) => {
|
||||||
// 创建新的URL表示指定的File对象或者Blob对象。
|
|
||||||
downloadByData(
|
downloadByData(
|
||||||
res.data,
|
res.data,
|
||||||
'萧康云医-仓库商品导入模板结果导出(只包含未导入的药品).xlsx',
|
'萧康云医-仓库商品导入模板结果导出(只包含未导入的药品).xlsx',
|
||||||
@@ -85,19 +132,36 @@ const exportWarehouseDrugManagementTemplate = () => {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Modal class="w-[30%]" :title="importType === 1 ? '上传Excel' : '批量修改价格'">
|
<Modal :title="importType === 1 ? '上传Excel' : titles" class="w-[30%]">
|
||||||
<Button v-if="importType === 1" type="link" @click="exportWarehouseDrugManagementTemplate">
|
<Button
|
||||||
|
v-if="importType === 1"
|
||||||
|
type="link"
|
||||||
|
@click="exportWarehouseDrugManagementTemplate"
|
||||||
|
>
|
||||||
下载位同步到仓库药品的导入模板
|
下载位同步到仓库药品的导入模板
|
||||||
</Button>
|
</Button>
|
||||||
<Button v-if="importType === 2" type="link" @click="passApplication">
|
<Button v-if="importType === 2" type="link" @click="passApplication">
|
||||||
下载修改价格模板
|
下载修改价格模板
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
<!-- 新增:显示文件选择状态 -->
|
||||||
|
<div
|
||||||
|
v-if="isFileSelected"
|
||||||
|
class="mt-4 rounded border border-green-200 bg-green-50 p-3"
|
||||||
|
>
|
||||||
|
<p class="text-sm text-green-700">已选择文件:{{ selectedFile?.name }}</p>
|
||||||
|
<p class="mt-1 text-xs text-green-600">
|
||||||
|
文件已准备就绪,点击确认按钮开始上传
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<UploadDragger
|
<UploadDragger
|
||||||
class="mt-6"
|
|
||||||
v-model:file-list="fileList"
|
v-model:file-list="fileList"
|
||||||
:custom-request="importWarehouseDrugManagement"
|
:before-upload="() => false"
|
||||||
:max-count="1"
|
:max-count="1"
|
||||||
:on-change="handleChange"
|
:on-change="handleChange"
|
||||||
|
accept=".xlsx,.xls"
|
||||||
|
class="mt-6"
|
||||||
name="file"
|
name="file"
|
||||||
>
|
>
|
||||||
<p class="flex justify-center">
|
<p class="flex justify-center">
|
||||||
@@ -162,11 +226,10 @@ const exportWarehouseDrugManagementTemplate = () => {
|
|||||||
<path d="M19.581 16H30v6.5H19.581Z" fill="#107c41" />
|
<path d="M19.581 16H30v6.5H19.581Z" fill="#107c41" />
|
||||||
</svg>
|
</svg>
|
||||||
</p>
|
</p>
|
||||||
<p class="ant-upload-text">点击或拖动文件到此区域进行上传</p>
|
<p class="ant-upload-text">点击或拖动文件到此区域进行选择</p>
|
||||||
<p class="ant-upload-hint">
|
<p class="ant-upload-hint">
|
||||||
支持单个上传,xlsx格式文件。严禁上传公司数据或其他带格式文件。
|
支持单个上传,xlsx格式文件。选择文件后需要点击确认按钮进行上传。
|
||||||
</p>
|
</p>
|
||||||
</UploadDragger>
|
</UploadDragger>
|
||||||
<!-- <Form />-->
|
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -85,9 +85,12 @@ const passApplication = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const openExcelUploadModal = (type = 1) => {
|
const openExcelUploadModal = (type = 1) => {
|
||||||
|
const uploadType = gridApi.formApi.latestSubmissionValues.type;
|
||||||
|
|
||||||
ExcelUploadModalApi.setData({
|
ExcelUploadModalApi.setData({
|
||||||
gridApi,
|
gridApi,
|
||||||
type,
|
type,
|
||||||
|
uploadType,
|
||||||
passApplication,
|
passApplication,
|
||||||
});
|
});
|
||||||
ExcelUploadModalApi.open();
|
ExcelUploadModalApi.open();
|
||||||
@@ -150,6 +153,7 @@ const updateStatus = (id: number) => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
|
:flex="false"
|
||||||
>
|
>
|
||||||
<template #more>
|
<template #more>
|
||||||
<Button style="margin-left: 16px">
|
<Button style="margin-left: 16px">
|
||||||
|
|||||||
@@ -34,6 +34,14 @@ export async function updateWarehouseDrugManagementStoreStatusApi(id: number) {
|
|||||||
return requestClient.get<any>(`${prefix}update-status`, { params: { id } });
|
return requestClient.get<any>(`${prefix}update-status`, { params: { id } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上架/下架
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
export async function updateWarehouseDrugManagementShopUpdateStatusApi(id: number) {
|
||||||
|
return requestClient.get<any>(`${prefix}shop-update-status`, { params: { id } });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出仓库药品药品
|
* 导出仓库药品药品
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
message,
|
message,
|
||||||
type UploadChangeParam,
|
type UploadChangeParam,
|
||||||
UploadDragger,
|
UploadDragger,
|
||||||
|
type UploadFile,
|
||||||
} from 'ant-design-vue';
|
} from 'ant-design-vue';
|
||||||
|
|
||||||
import { downloadByData } from '#/util/tool';
|
import { downloadByData } from '#/util/tool';
|
||||||
@@ -21,61 +22,85 @@ import {
|
|||||||
const gridApi = ref();
|
const gridApi = ref();
|
||||||
const passApplication = ref();
|
const passApplication = ref();
|
||||||
const importType = ref(1);
|
const importType = ref(1);
|
||||||
const fileList = ref([]);
|
const fileList = ref<UploadFile[]>([]);
|
||||||
|
const selectedFile = ref<File | null>(null); // 新增:存储选中的文件
|
||||||
|
const isFileSelected = ref(false); // 新增:标记是否有文件被选中
|
||||||
|
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
fullscreenButton: false,
|
fullscreenButton: false,
|
||||||
draggable: true,
|
draggable: true,
|
||||||
onCancel() {
|
onCancel() {
|
||||||
|
// 重置文件状态
|
||||||
|
selectedFile.value = null;
|
||||||
|
isFileSelected.value = false;
|
||||||
|
fileList.value = [];
|
||||||
modalApi.close();
|
modalApi.close();
|
||||||
},
|
},
|
||||||
onConfirm: async () => {
|
onConfirm: async () => {
|
||||||
// modalApi.setState({ loading: true, confirmLoading: true });
|
// 检查是否有选中文件
|
||||||
gridApi.value?.reload();
|
if (!selectedFile.value) {
|
||||||
modalApi.close();
|
message.warning('请先选择要上传的文件');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
modalApi.setState({ loading: true, confirmLoading: true });
|
||||||
|
|
||||||
|
try {
|
||||||
|
const submitApi =
|
||||||
|
importType.value === 1
|
||||||
|
? importWarehouseDrugManagementStoreApi
|
||||||
|
: importUpdatePriceApi;
|
||||||
|
|
||||||
|
await submitApi({
|
||||||
|
file: selectedFile.value,
|
||||||
|
});
|
||||||
|
|
||||||
|
message.success('上传成功');
|
||||||
|
gridApi.value?.reload();
|
||||||
|
|
||||||
|
// 重置文件状态
|
||||||
|
selectedFile.value = null;
|
||||||
|
isFileSelected.value = false;
|
||||||
|
fileList.value = [];
|
||||||
|
|
||||||
|
modalApi.close();
|
||||||
|
} catch {
|
||||||
|
message.error('上传失败');
|
||||||
|
} finally {
|
||||||
|
modalApi.setState({ loading: false, confirmLoading: false });
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onOpenChange(isOpen: boolean) {
|
onOpenChange(isOpen: boolean) {
|
||||||
gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
|
gridApi.value = isOpen ? modalApi.getData()?.gridApi : null;
|
||||||
passApplication.value = isOpen ? modalApi.getData()?.passApplication : null;
|
passApplication.value = isOpen ? modalApi.getData()?.passApplication : null;
|
||||||
importType.value = isOpen ? modalApi.getData()?.type : 1;
|
importType.value = isOpen ? modalApi.getData()?.type : 1;
|
||||||
fileList.value = [];
|
fileList.value = [];
|
||||||
|
selectedFile.value = null; // 重置选中的文件
|
||||||
|
isFileSelected.value = false; // 重置文件选择状态
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const importWarehouseDrugManagementStore = ({ file, onSuccess }) => {
|
// 修改:处理文件选择变化,只存储文件不上传
|
||||||
modalApi.setState({ loading: true, confirmLoading: true });
|
|
||||||
const submitApi =
|
|
||||||
importType.value === 1
|
|
||||||
? importWarehouseDrugManagementStoreApi
|
|
||||||
: importUpdatePriceApi;
|
|
||||||
submitApi({
|
|
||||||
file,
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
onSuccess('ok', { status: 'done' });
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
onSuccess('error', { status: 'error' });
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
modalApi.setState({ loading: false, confirmLoading: false });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const handleChange = (info: UploadChangeParam) => {
|
const handleChange = (info: UploadChangeParam) => {
|
||||||
if (info.file.status === 'uploading') {
|
const { file } = info;
|
||||||
|
|
||||||
|
if (file.status === 'removed') {
|
||||||
|
// 文件被移除
|
||||||
|
selectedFile.value = null;
|
||||||
|
isFileSelected.value = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (info.file.status === 'done') {
|
|
||||||
message.success('上传成功');
|
if (file) {
|
||||||
}
|
// 存储选中的文件
|
||||||
if (info.file.status === 'error') {
|
selectedFile.value = file;
|
||||||
message.error('upload error');
|
isFileSelected.value = true;
|
||||||
|
message.success('文件已选择,请点击确认按钮上传');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const exportWarehouseDrugManagementStoreTemplate = () => {
|
const exportWarehouseDrugManagementStoreTemplate = () => {
|
||||||
exportWarehouseDrugManagementStoreTemplateApi().then((res) => {
|
exportWarehouseDrugManagementStoreTemplateApi().then((res) => {
|
||||||
// 创建新的URL表示指定的File对象或者Blob对象。
|
|
||||||
downloadByData(
|
downloadByData(
|
||||||
res.data,
|
res.data,
|
||||||
'萧康云医-仓库商品导入模板结果导出(只包含未导入的药品).xlsx',
|
'萧康云医-仓库商品导入模板结果导出(只包含未导入的药品).xlsx',
|
||||||
@@ -85,19 +110,39 @@ const exportWarehouseDrugManagementStoreTemplate = () => {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Modal class="w-[30%]" :title="importType === 1 ? '上传Excel' : '批量修改价格'">
|
<Modal
|
||||||
<Button v-if="importType === 1" type="link" @click="exportWarehouseDrugManagementStoreTemplate">
|
:title="importType === 1 ? '上传Excel' : '批量修改价格'"
|
||||||
|
class="w-[30%]"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
v-if="importType === 1"
|
||||||
|
type="link"
|
||||||
|
@click="exportWarehouseDrugManagementStoreTemplate"
|
||||||
|
>
|
||||||
下载位同步到仓库药品的导入模板
|
下载位同步到仓库药品的导入模板
|
||||||
</Button>
|
</Button>
|
||||||
<Button v-if="importType === 2" type="link" @click="passApplication">
|
<Button v-if="importType === 2" type="link" @click="passApplication">
|
||||||
下载修改价格模板
|
下载修改价格模板
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
|
<!-- 新增:显示文件选择状态 -->
|
||||||
|
<div
|
||||||
|
v-if="isFileSelected"
|
||||||
|
class="mt-4 rounded border border-green-200 bg-green-50 p-3"
|
||||||
|
>
|
||||||
|
<p class="text-sm text-green-700">已选择文件:{{ selectedFile?.name }}</p>
|
||||||
|
<p class="mt-1 text-xs text-green-600">
|
||||||
|
文件已准备就绪,点击确认按钮开始上传
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<UploadDragger
|
<UploadDragger
|
||||||
class="mt-6"
|
|
||||||
v-model:file-list="fileList"
|
v-model:file-list="fileList"
|
||||||
:custom-request="importWarehouseDrugManagementStore"
|
:before-upload="() => false"
|
||||||
:max-count="1"
|
:max-count="1"
|
||||||
:on-change="handleChange"
|
:on-change="handleChange"
|
||||||
|
accept=".xlsx,.xls"
|
||||||
|
class="mt-6"
|
||||||
name="file"
|
name="file"
|
||||||
>
|
>
|
||||||
<p class="flex justify-center">
|
<p class="flex justify-center">
|
||||||
@@ -162,11 +207,10 @@ const exportWarehouseDrugManagementStoreTemplate = () => {
|
|||||||
<path d="M19.581 16H30v6.5H19.581Z" fill="#107c41" />
|
<path d="M19.581 16H30v6.5H19.581Z" fill="#107c41" />
|
||||||
</svg>
|
</svg>
|
||||||
</p>
|
</p>
|
||||||
<p class="ant-upload-text">点击或拖动文件到此区域进行上传</p>
|
<p class="ant-upload-text">点击或拖动文件到此区域进行选择</p>
|
||||||
<p class="ant-upload-hint">
|
<p class="ant-upload-hint">
|
||||||
支持单个上传,xlsx格式文件。严禁上传公司数据或其他带格式文件。
|
支持单个上传,xlsx格式文件。选择文件后需要点击确认按钮进行上传。
|
||||||
</p>
|
</p>
|
||||||
</UploadDragger>
|
</UploadDragger>
|
||||||
<!-- <Form />-->
|
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ export const gridOptions: VxeGridProps<RowType> = {
|
|||||||
{ field: 'drug.drug_store_drug.price', title: '建议售价' },
|
{ field: 'drug.drug_store_drug.price', title: '建议售价' },
|
||||||
{ field: 'price', title: '售价' },
|
{ field: 'price', title: '售价' },
|
||||||
{ field: 'status', title: '状态', slots: { default: 'status' } },
|
{ field: 'status', title: '状态', slots: { default: 'status' } },
|
||||||
|
{ field: 'is_shop', title: '是否上架商城', slots: { default: 'is_shop' } },
|
||||||
{ type: 'html', align: 'right', title: '操作', slots: { default: 'action' }, width: 300, },
|
{ type: 'html', align: 'right', title: '操作', slots: { default: 'action' }, width: 300, },
|
||||||
],
|
],
|
||||||
keepSource: true,
|
keepSource: true,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { ref } from 'vue';
|
|||||||
|
|
||||||
import { Page, useVbenModal } from '@vben/common-ui';
|
import { Page, useVbenModal } from '@vben/common-ui';
|
||||||
|
|
||||||
import { Button, Image, message, Tag } from 'ant-design-vue';
|
import { Button, Image, message, Switch, Tag } from 'ant-design-vue';
|
||||||
|
|
||||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { TableAction } from '#/components/table-action';
|
import { TableAction } from '#/components/table-action';
|
||||||
@@ -14,11 +14,15 @@ import { downloadByData } from '#/util/tool';
|
|||||||
import {
|
import {
|
||||||
checkSubscribeApi,
|
checkSubscribeApi,
|
||||||
deleteWarehouseDrugManagementStore,
|
deleteWarehouseDrugManagementStore,
|
||||||
exportWarehouseDrugManagementStoreApi, subscribeApi, syncDrugApi, syncDrugPriceApi,
|
exportWarehouseDrugManagementStoreApi,
|
||||||
updateWarehouseDrugManagementStoreStatusApi
|
subscribeApi,
|
||||||
|
syncDrugApi,
|
||||||
|
syncDrugPriceApi,
|
||||||
|
updateWarehouseDrugManagementShopUpdateStatusApi,
|
||||||
|
updateWarehouseDrugManagementStoreStatusApi,
|
||||||
} from './api';
|
} from './api';
|
||||||
import FormModalDemo from './components/modal.vue';
|
|
||||||
import ExcelUpload from './components/ExcelUpload.vue';
|
import ExcelUpload from './components/ExcelUpload.vue';
|
||||||
|
import FormModalDemo from './components/modal.vue';
|
||||||
import { formOptions } from './config/search';
|
import { formOptions } from './config/search';
|
||||||
import { gridOptions } from './config/table';
|
import { gridOptions } from './config/table';
|
||||||
|
|
||||||
@@ -98,15 +102,22 @@ const syncDrugs = () => {
|
|||||||
syncDrugApi().then((res) => {
|
syncDrugApi().then((res) => {
|
||||||
message.success('同步成功!');
|
message.success('同步成功!');
|
||||||
gridApi.reload();
|
gridApi.reload();
|
||||||
})
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateStatus = (id) => {
|
const updateStatus = (id) => {
|
||||||
updateWarehouseDrugManagementStoreStatusApi(id).then(() => {
|
updateWarehouseDrugManagementStoreStatusApi(id).then(() => {
|
||||||
message.success('修改成功!');
|
message.success('修改成功!');
|
||||||
gridApi.reload();
|
gridApi.query();
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
|
const updateWarehouseDrugManagementShopUpdateStatus = (id) => {
|
||||||
|
updateWarehouseDrugManagementShopUpdateStatusApi(id).then(() => {
|
||||||
|
message.success('修改成功!');
|
||||||
|
gridApi.query();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const syncDrugPrice = () => {
|
const syncDrugPrice = () => {
|
||||||
gridApi.setLoading(true);
|
gridApi.setLoading(true);
|
||||||
@@ -116,20 +127,20 @@ const syncDrugPrice = () => {
|
|||||||
gridApi.setLoading(false);
|
gridApi.setLoading(false);
|
||||||
gridApi.reload();
|
gridApi.reload();
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
const isSubscribe = ref(true);
|
const isSubscribe = ref(true);
|
||||||
|
|
||||||
const checkSubscribe = () =>{
|
const checkSubscribe = () => {
|
||||||
checkSubscribeApi().then((res) => {
|
checkSubscribeApi().then((res) => {
|
||||||
isSubscribe.value = res;
|
isSubscribe.value = res;
|
||||||
})
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const subscribe = () =>{
|
const subscribe = () => {
|
||||||
subscribeApi().then(() => {
|
subscribeApi().then(() => {
|
||||||
message.success('操作成功!');
|
message.success('操作成功!');
|
||||||
})
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
checkSubscribe();
|
checkSubscribe();
|
||||||
@@ -142,7 +153,6 @@ checkSubscribe();
|
|||||||
<Grid>
|
<Grid>
|
||||||
<template #toolbar-buttons>
|
<template #toolbar-buttons>
|
||||||
<TableAction
|
<TableAction
|
||||||
:flex="false"
|
|
||||||
:actions="[
|
:actions="[
|
||||||
{
|
{
|
||||||
label: '批量修改价格',
|
label: '批量修改价格',
|
||||||
@@ -186,6 +196,7 @@ checkSubscribe();
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
|
:flex="false"
|
||||||
>
|
>
|
||||||
<template #more>
|
<template #more>
|
||||||
<Button style="margin-left: 16px">
|
<Button style="margin-left: 16px">
|
||||||
@@ -196,7 +207,14 @@ checkSubscribe();
|
|||||||
</TableAction>
|
</TableAction>
|
||||||
</template>
|
</template>
|
||||||
<template #image="{ row }">
|
<template #image="{ row }">
|
||||||
<Image :src="row.drug?.image || 'https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk_upload_20250510/cd470ebf97e31c4048ba502ba71b66a3.jpg'" height="30" width="30" />
|
<Image
|
||||||
|
:src="
|
||||||
|
row.drug?.image ||
|
||||||
|
'https://xiaokang88.oss-cn-hangzhou.aliyuncs.com/xk_upload_20250510/cd470ebf97e31c4048ba502ba71b66a3.jpg'
|
||||||
|
"
|
||||||
|
height="30"
|
||||||
|
width="30"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #instruction="{ row }">
|
<template #instruction="{ row }">
|
||||||
<div class="div" style="width: 120px; height: 120px; overflow: scroll">
|
<div class="div" style="width: 120px; height: 120px; overflow: scroll">
|
||||||
@@ -204,22 +222,51 @@ checkSubscribe();
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #status="{ row }">
|
<template #status="{ row }">
|
||||||
<Tag :color="row.status === 2 ? 'green' : 'red'">{{
|
<!-- <Tag :color="row.status === 2 ? 'green' : 'red'">-->
|
||||||
row.status === 2 ? '上架' : '下架'
|
<!-- {{ row.status === 2 ? '上架' : '下架' }}-->
|
||||||
}}</Tag>
|
<!-- </Tag>-->
|
||||||
|
<Switch
|
||||||
|
:checked="row.status"
|
||||||
|
:checked-value="2"
|
||||||
|
:un-checked-value="1"
|
||||||
|
checked-children="上架"
|
||||||
|
un-checked-children="下架"
|
||||||
|
@click="updateStatus(row.id)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #is_shop="{ row }">
|
||||||
|
<Switch
|
||||||
|
:checked="row.is_shop"
|
||||||
|
:checked-value="2"
|
||||||
|
:un-checked-value="1"
|
||||||
|
checked-children="上架"
|
||||||
|
un-checked-children="下架"
|
||||||
|
@click="updateWarehouseDrugManagementShopUpdateStatus(row.id)"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #toolbar-tools></template>
|
<template #toolbar-tools></template>
|
||||||
<template #action="{ row }">
|
<template #action="{ row }">
|
||||||
<TableAction
|
<TableAction
|
||||||
:actions="[
|
:actions="[
|
||||||
{
|
// {
|
||||||
label: '上架/下架',
|
// label: '上架/下架(仓库)',
|
||||||
type: 'link',
|
// type: 'link',
|
||||||
icon: 'uil:edit',
|
// icon: 'uil:edit',
|
||||||
size: 'small',
|
// size: 'small',
|
||||||
// auth: ['western-medicine', 'sys:role:detail'],
|
// // auth: ['western-medicine', 'sys:role:detail'],
|
||||||
onClick: updateStatus.bind(null, row.id),
|
// onClick: updateStatus.bind(null, row.id),
|
||||||
},
|
// },
|
||||||
|
// {
|
||||||
|
// label: '上架/下架(商城)',
|
||||||
|
// type: 'link',
|
||||||
|
// icon: 'uil:edit',
|
||||||
|
// size: 'small',
|
||||||
|
// // auth: ['western-medicine', 'sys:role:detail'],
|
||||||
|
// onClick: updateWarehouseDrugManagementShopUpdateStatus.bind(
|
||||||
|
// null,
|
||||||
|
// row.id,
|
||||||
|
// ),
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
label: '编辑',
|
label: '编辑',
|
||||||
type: 'link',
|
type: 'link',
|
||||||
@@ -229,8 +276,7 @@ checkSubscribe();
|
|||||||
onClick: showModal.bind(null, row, true),
|
onClick: showModal.bind(null, row, true),
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
:drop-down-actions="[
|
:drop-down-actions="[]"
|
||||||
]"
|
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class RequestClient {
|
|||||||
'Content-Type': 'application/json;charset=utf-8',
|
'Content-Type': 'application/json;charset=utf-8',
|
||||||
},
|
},
|
||||||
// 默认超时时间
|
// 默认超时时间
|
||||||
timeout: 10_000,
|
timeout: 100_000,
|
||||||
};
|
};
|
||||||
const { ...axiosConfig } = options;
|
const { ...axiosConfig } = options;
|
||||||
const requestConfig = merge(axiosConfig, defaultConfig);
|
const requestConfig = merge(axiosConfig, defaultConfig);
|
||||||
|
|||||||
Reference in New Issue
Block a user