Merge branch 'main' of http://47.97.125.165:8902/jiangs/lis8.0-vue3
This commit is contained in:
commit
2138f98df2
@ -9,4 +9,31 @@ export function addReportService(LabReportInstr: Object){
|
||||
method: 'post',
|
||||
data: LabReportInstr
|
||||
})
|
||||
}
|
||||
|
||||
//查询数据
|
||||
export function queryReportService(LabReportInstr: Object){
|
||||
return request({
|
||||
url: '/labReportinstr/query',
|
||||
method: 'get',
|
||||
params: LabReportInstr
|
||||
})
|
||||
}
|
||||
|
||||
//修改数据
|
||||
export function updateReportService(LabReportInstr: Object){
|
||||
return request({
|
||||
url: '/labReportinstr/update',
|
||||
method: 'post',
|
||||
data: LabReportInstr
|
||||
})
|
||||
}
|
||||
|
||||
//删除数据
|
||||
export function deleteReportService(LabReportInstr: Object){
|
||||
return request({
|
||||
url: '/labReportinstr/del',
|
||||
method: 'get',
|
||||
params: LabReportInstr
|
||||
})
|
||||
}
|
||||
@ -322,8 +322,8 @@
|
||||
border-color: #aef5ef;
|
||||
}
|
||||
|
||||
// 表格input宽度
|
||||
.full-width-input .el-input__inner {
|
||||
// 表格input宽度,表格select宽度
|
||||
.full-width-input .el-input__inner .el-select__inner {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
@ -339,6 +339,16 @@
|
||||
padding: 0 !important;
|
||||
outline: none;
|
||||
|
||||
&:hover {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
}
|
||||
.el-select__wrapper {
|
||||
box-shadow: none;
|
||||
background: transparent !important;
|
||||
padding: 0 !important;
|
||||
outline: none;
|
||||
|
||||
&:hover {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
87
src/auto-imports.d.ts
vendored
Normal file
87
src/auto-imports.d.ts
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
/* eslint-disable */
|
||||
/* prettier-ignore */
|
||||
// @ts-nocheck
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
// Generated by unplugin-auto-import
|
||||
export {}
|
||||
declare global {
|
||||
const EffectScope: typeof import('vue')['EffectScope']
|
||||
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
|
||||
const computed: typeof import('vue')['computed']
|
||||
const createApp: typeof import('vue')['createApp']
|
||||
const createPinia: typeof import('pinia')['createPinia']
|
||||
const customRef: typeof import('vue')['customRef']
|
||||
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
|
||||
const defineComponent: typeof import('vue')['defineComponent']
|
||||
const defineStore: typeof import('pinia')['defineStore']
|
||||
const effectScope: typeof import('vue')['effectScope']
|
||||
const getActivePinia: typeof import('pinia')['getActivePinia']
|
||||
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
|
||||
const getCurrentScope: typeof import('vue')['getCurrentScope']
|
||||
const h: typeof import('vue')['h']
|
||||
const inject: typeof import('vue')['inject']
|
||||
const isProxy: typeof import('vue')['isProxy']
|
||||
const isReactive: typeof import('vue')['isReactive']
|
||||
const isReadonly: typeof import('vue')['isReadonly']
|
||||
const isRef: typeof import('vue')['isRef']
|
||||
const mapActions: typeof import('pinia')['mapActions']
|
||||
const mapGetters: typeof import('pinia')['mapGetters']
|
||||
const mapState: typeof import('pinia')['mapState']
|
||||
const mapStores: typeof import('pinia')['mapStores']
|
||||
const mapWritableState: typeof import('pinia')['mapWritableState']
|
||||
const markRaw: typeof import('vue')['markRaw']
|
||||
const nextTick: typeof import('vue')['nextTick']
|
||||
const onActivated: typeof import('vue')['onActivated']
|
||||
const onBeforeMount: typeof import('vue')['onBeforeMount']
|
||||
const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
|
||||
const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
|
||||
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
|
||||
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
|
||||
const onDeactivated: typeof import('vue')['onDeactivated']
|
||||
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
|
||||
const onMounted: typeof import('vue')['onMounted']
|
||||
const onRenderTracked: typeof import('vue')['onRenderTracked']
|
||||
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
|
||||
const onScopeDispose: typeof import('vue')['onScopeDispose']
|
||||
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
|
||||
const onUnmounted: typeof import('vue')['onUnmounted']
|
||||
const onUpdated: typeof import('vue')['onUpdated']
|
||||
const onWatcherCleanup: typeof import('vue')['onWatcherCleanup']
|
||||
const provide: typeof import('vue')['provide']
|
||||
const reactive: typeof import('vue')['reactive']
|
||||
const readonly: typeof import('vue')['readonly']
|
||||
const ref: typeof import('vue')['ref']
|
||||
const resolveComponent: typeof import('vue')['resolveComponent']
|
||||
const setActivePinia: typeof import('pinia')['setActivePinia']
|
||||
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
|
||||
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||
const shallowRef: typeof import('vue')['shallowRef']
|
||||
const storeToRefs: typeof import('pinia')['storeToRefs']
|
||||
const toRaw: typeof import('vue')['toRaw']
|
||||
const toRef: typeof import('vue')['toRef']
|
||||
const toRefs: typeof import('vue')['toRefs']
|
||||
const toValue: typeof import('vue')['toValue']
|
||||
const triggerRef: typeof import('vue')['triggerRef']
|
||||
const unref: typeof import('vue')['unref']
|
||||
const useAttrs: typeof import('vue')['useAttrs']
|
||||
const useCssModule: typeof import('vue')['useCssModule']
|
||||
const useCssVars: typeof import('vue')['useCssVars']
|
||||
const useId: typeof import('vue')['useId']
|
||||
const useLink: typeof import('vue-router')['useLink']
|
||||
const useModel: typeof import('vue')['useModel']
|
||||
const useRoute: typeof import('vue-router')['useRoute']
|
||||
const useRouter: typeof import('vue-router')['useRouter']
|
||||
const useSlots: typeof import('vue')['useSlots']
|
||||
const useTemplateRef: typeof import('vue')['useTemplateRef']
|
||||
const watch: typeof import('vue')['watch']
|
||||
const watchEffect: typeof import('vue')['watchEffect']
|
||||
const watchPostEffect: typeof import('vue')['watchPostEffect']
|
||||
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
|
||||
}
|
||||
// for type re-export
|
||||
declare global {
|
||||
// @ts-ignore
|
||||
export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
|
||||
import('vue')
|
||||
}
|
||||
84
src/components/SelectTable/YQSelectTable/index.vue
Normal file
84
src/components/SelectTable/YQSelectTable/index.vue
Normal file
@ -0,0 +1,84 @@
|
||||
<!--仪器组件的封装-->
|
||||
<template>
|
||||
<SelectTable v-model:data="modelValue" :fields="yqFields" :tableData="instrOptions" label="yqmc" size="small"
|
||||
value="yq" objKey="yq" :border="true" :width="props.width" placeholder="请选择仪器" :clearable="false" @getDataValue="getDataValue" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import SelectTable from '@/components/SelectTable/index.vue';
|
||||
import { getGroupInstrdList } from '@/api/liswork/work/LisWork';
|
||||
import { Emits, Props } from '@/types';
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
placeholder: "请选择",
|
||||
size: "default",
|
||||
isHighlight: true,
|
||||
value: undefined,
|
||||
label: undefined,
|
||||
border: false,
|
||||
width: "100%",
|
||||
dictType: '',
|
||||
clearable: true
|
||||
});
|
||||
|
||||
const modelValue = ref('');
|
||||
const yqFields = ref([
|
||||
{ prop: 'yq', label: '代号', width: 80, enablePinyinSearch: true },
|
||||
{ prop: 'yqmc', label: '名称', width: 150, enablePinyinSearch: true },
|
||||
]);
|
||||
const instrOptions = ref<{ yq: string; yqmc: string }[]>([])
|
||||
const emits = defineEmits<Emits>();
|
||||
|
||||
const getYqConfig = () => {
|
||||
getGroupInstrdList()
|
||||
.then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
instrOptions.value = res.data.map((item: any) => ({
|
||||
yq: item.yq.trim(),
|
||||
yqmc: item.yqmc
|
||||
}))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const getDataValue = (val: any) => {
|
||||
emits('getDataValue', val);
|
||||
};
|
||||
|
||||
const handleDataEcho = () => {
|
||||
// if (modelValue.value === null || modelValue.value === undefined) {
|
||||
// modelValue.value = '';
|
||||
// emits('update:data', null);
|
||||
// return;
|
||||
// }
|
||||
// const matchedInstr = instrOptions.value.find(item => item.yq === modelValue.value);
|
||||
// if (matchedInstr) {
|
||||
// emits('update:data', matchedInstr.yq);
|
||||
// } else {
|
||||
// emits('update:data', '');
|
||||
// }
|
||||
emits('update:data', modelValue.value);
|
||||
|
||||
};
|
||||
|
||||
// 监听表格数据和字典类型变化
|
||||
watch(() => instrOptions, (newVal) => {
|
||||
if (newVal) {
|
||||
handleDataEcho();
|
||||
}
|
||||
}, { deep: true });
|
||||
|
||||
// 监听绑定值数据变化,重新处理
|
||||
watch(() => modelValue, (newVal) => {
|
||||
// 数据回显
|
||||
handleDataEcho();
|
||||
}, { deep: true });
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
getYqConfig();
|
||||
});
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
@ -49,29 +49,8 @@ import { getFirstLetter } from '@/utils/pinyin.js';
|
||||
import { ElEmpty } from 'element-plus';
|
||||
// @ts-ignore
|
||||
import { comDict } from '@/utils/dict'
|
||||
interface Field {
|
||||
prop: string;
|
||||
label: string;
|
||||
width?: number;
|
||||
enablePinyinSearch?: boolean; //是否参与拼音搜索
|
||||
}
|
||||
import { Emits, Props } from '@/types';
|
||||
|
||||
interface Props {
|
||||
data: any;
|
||||
fields: Field[];
|
||||
tableData?: object[];
|
||||
label?: string;
|
||||
value?: string;
|
||||
objKey?: string;
|
||||
isHighlight?: boolean;
|
||||
size?: string;
|
||||
placeholder?: string;
|
||||
border?: boolean;
|
||||
width?: string | number;
|
||||
disabled?: boolean;
|
||||
dictType?: string;
|
||||
clearable?: boolean;
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
placeholder: "请选择",
|
||||
size: "default",
|
||||
@ -84,10 +63,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
clearable: true
|
||||
});
|
||||
|
||||
interface Emits {
|
||||
(e: "update:data", val: any): void;
|
||||
(e: "getDataValue", val: any): void;
|
||||
}
|
||||
|
||||
const emits = defineEmits<Emits>();
|
||||
const searchKey = ref('');
|
||||
const tableRef = ref();
|
||||
|
||||
40
src/hooks/lisData/dictData.ts
Normal file
40
src/hooks/lisData/dictData.ts
Normal file
@ -0,0 +1,40 @@
|
||||
//仪器,字典数据自动格式化类
|
||||
import { DictData } from '@/types/index';
|
||||
import { getGroupInstrdList } from '@/api/liswork/work/LisWork';
|
||||
//@ts-ignore
|
||||
import { comDict } from '@/utils/dict'
|
||||
|
||||
const dictData = ref<DictData>({});
|
||||
const instrOptions = ref<{ yq: string; yqmc: string }[]>([])
|
||||
|
||||
export const getYqData = () => {
|
||||
getGroupInstrdList()
|
||||
.then((res: any) => {
|
||||
if (res.code == 0) {
|
||||
instrOptions.value = res.data.map((item: any) => ({
|
||||
yq: item.yq.trim(),
|
||||
yqmc: item.yqmc
|
||||
}))
|
||||
}
|
||||
})
|
||||
}
|
||||
//'XMGL','ITEMCLASS', 'YQDL'
|
||||
export const getDictData = async (...args: string[]) => {
|
||||
const dictRefs = await comDict(...args);
|
||||
// 从 ref 中获取实际数据
|
||||
dictData.value = {
|
||||
XMGL: toRaw(dictRefs.XMGL.value) || [],
|
||||
ITEMCLASS: toRaw(dictRefs.ITEMCLASS.value) || [],
|
||||
YQDL: toRaw(dictRefs.YQDL.value) || []
|
||||
};
|
||||
}
|
||||
|
||||
// 格式化字典数据方法
|
||||
export const formatDict = async (v: string, dictType: string) => {
|
||||
return dictData.value[dictType]?.find((item: any) => item.value == v.trim())?.label;
|
||||
}
|
||||
|
||||
//仪器格式化方法
|
||||
export const formatInstr = (v: string) => {
|
||||
return instrOptions.value.find((item: any) => item.yq == v.trim())?.yqmc;
|
||||
}
|
||||
1
src/hooks/lisData/index.ts
Normal file
1
src/hooks/lisData/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './dictData';
|
||||
10
src/types/Object.d.ts
vendored
10
src/types/Object.d.ts
vendored
@ -1,4 +1,5 @@
|
||||
export interface LabReportInstr {
|
||||
index?: number; //序号
|
||||
yq: string; //仪器
|
||||
xh: number; //序号
|
||||
bgdh: string; //报告单号
|
||||
@ -6,4 +7,13 @@ export interface LabReportInstr {
|
||||
type: string; //使用类型
|
||||
condition: string; //使用条件
|
||||
status?: string; //状态
|
||||
}
|
||||
|
||||
export interface DictData {
|
||||
XMGL?: Array<any>;
|
||||
ITEMCLASS?: Array<any>;
|
||||
YQDL?: Array<any>;
|
||||
xmlbList?: Array<any>;
|
||||
YQ?: Array<any>;
|
||||
[key: string]: any[] | undefined; // 添加索引签名以支持动态访问
|
||||
}
|
||||
29
src/types/SelectTable.d.ts
vendored
Normal file
29
src/types/SelectTable.d.ts
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
export interface Emits {
|
||||
(e: "update:data", val: any): void;
|
||||
(e: "getDataValue", val: any): void;
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
data: any;
|
||||
fields: Field[];
|
||||
tableData?: object[];
|
||||
label?: string;
|
||||
value?: string;
|
||||
objKey?: string;
|
||||
isHighlight?: boolean;
|
||||
size?: string;
|
||||
placeholder?: string;
|
||||
border?: boolean;
|
||||
width?: string | number;
|
||||
disabled?: boolean;
|
||||
dictType?: string;
|
||||
clearable?: boolean;
|
||||
}
|
||||
|
||||
|
||||
export interface Field {
|
||||
prop: string;
|
||||
label: string;
|
||||
width?: number;
|
||||
enablePinyinSearch?: boolean; //是否参与拼音搜索
|
||||
}
|
||||
4
src/types/index.d.ts
vendored
4
src/types/index.d.ts
vendored
@ -1,4 +1,6 @@
|
||||
//聚合文件,导出所有的类型定义
|
||||
|
||||
//对象文件
|
||||
export * from './Object';
|
||||
export * from './Object';
|
||||
|
||||
export * from './SelectTable';
|
||||
@ -1,58 +1,68 @@
|
||||
<template>
|
||||
<!--报告单设定-->
|
||||
<el-form ref="form" :model="formData" :rules="rules" label-width="80px">
|
||||
<el-form ref="form" :model="formData" label-width="80px" size="small">
|
||||
<el-form-item label="仪器" prop="yq">
|
||||
<el-input placeholder="仪器" v-model="formData.yq" style="width: 200px;"></el-input>
|
||||
<YQSelectTable v-model:data="formData.yq" width="200px" @getDataValue="getList"/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handAdd">新增</el-button>
|
||||
<el-button type="primary" @click="handDelete">删除</el-button>
|
||||
<el-button type="primary" @click="handSave">保存</el-button>
|
||||
<el-button type="primary" @click="handAdd" size="default">新增</el-button>
|
||||
<el-button type="primary" @click="handDelete" size="default">删除</el-button>
|
||||
<el-button type="primary" @click="handSave" size="default">保存</el-button>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<el-table :data="tableData" border width="100%" height="700px" @current-change="currentChange">
|
||||
<el-table-column label="仪器" prop="yq" align="center"></el-table-column>
|
||||
<el-table :data="tableData" border width="100%" height="700px" @selection-change="handSelectionChange">
|
||||
<el-table-column label="仪器" prop="yq" align="center">
|
||||
<template #default="scope">
|
||||
{{ formatInstr(scope.row.yq) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="序号" prop="xh" align="center"></el-table-column>
|
||||
<el-table-column label="报告单号" prop="bgdh" align="center"></el-table-column>
|
||||
<el-table-column label="报告单号" prop="bgdh" align="center" >
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.bgdh" placeholder="请输入报告单号" class="full-width-input" @change="handleRowChange(scope.row, scope.$index)"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="医疗机构" prop="yljg" align="center"></el-table-column>
|
||||
<el-table-column label="使用类型" prop="type" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-select v-model="row.type" placeholder="请选择" style="width: 120px;">
|
||||
<el-select v-model="row.type" placeholder="请选择" class="full-width-input">
|
||||
<el-option label="默认" value="1"></el-option>
|
||||
<el-option label="参数" value="2"></el-option>
|
||||
<el-option label="根据项目来判断" value="3"></el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="使用条件" prop="condition" align="center"></el-table-column>
|
||||
<el-table-column label="使用条件" prop="condition" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-input v-model="row.condition" placeholder="请输入使用条件" class="full-width-input"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref} from 'vue';
|
||||
import {addReportService} from '@/api/liswork/xtwh/ReportSetting';
|
||||
import { LabReportInstr } from '@/types/Index';
|
||||
|
||||
import {addReportService,queryReportService,updateReportService,deleteReportService} from '@/api/liswork/xtwh/ReportSetting';
|
||||
import { LabReportInstr } from '@/types/index';
|
||||
import YQSelectTable from '@/components/SelectTable/YQSelectTable/index.vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { formatInstr,getYqData } from '@/hooks/lisData/index';
|
||||
|
||||
|
||||
const formData = ref({
|
||||
yq: ''
|
||||
});
|
||||
|
||||
const rules = ref({
|
||||
// name: [
|
||||
// { required: true, message: '请输入姓名', trigger: 'blur' },
|
||||
// { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
|
||||
// ],
|
||||
// sex: [
|
||||
// { required: true, message: '请选择性别', trigger: 'blur' }
|
||||
// ]
|
||||
});
|
||||
|
||||
const tableData = ref<LabReportInstr[]>([]);
|
||||
|
||||
//选中行的数据
|
||||
const selectedRows = ref<LabReportInstr>();
|
||||
|
||||
//新增数据
|
||||
const handAdd = () => {
|
||||
if(formData.value.yq === ''){
|
||||
ElMessage.warning('请先选择仪器');
|
||||
return;
|
||||
}
|
||||
const newReport: LabReportInstr = {
|
||||
yq: formData.value.yq,
|
||||
xh: tableData.value.length + 1,
|
||||
@ -65,19 +75,50 @@ const handAdd = () => {
|
||||
tableData.value.push(newReport);
|
||||
};
|
||||
|
||||
const handDelete = () => {
|
||||
console.log('删除');
|
||||
//删除数据
|
||||
const handDelete = async () => {
|
||||
const res = await deleteReportService([selectedRows.value?.xh || '']);
|
||||
ElMessage.success('删除成功');
|
||||
};
|
||||
|
||||
const handSave = () => {
|
||||
//保存数据
|
||||
const handSave = async () => {
|
||||
//过滤数据,只需要新增的数据
|
||||
const newReports = tableData.value.filter(item => item.status === 'new');
|
||||
addReportService(newReports);
|
||||
let newReports = tableData.value.filter(item => item.status === 'new');
|
||||
let res = await addReportService(newReports);
|
||||
console.log('res',res);
|
||||
if(res.code !== '0'){
|
||||
ElMessage.error('保存失败:' + res.message);
|
||||
return;
|
||||
}
|
||||
newReports = tableData.value.filter(item => item.status === 'update');
|
||||
res = await updateReportService(newReports);
|
||||
if(res.code !== '0'){
|
||||
ElMessage.error('修改保存失败:' + res.message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//刷新数据
|
||||
const getList = async () => {
|
||||
const res = await queryReportService({ yq: formData.value.yq });
|
||||
tableData.value = res.data;
|
||||
};
|
||||
|
||||
//监听数据是否发生改变
|
||||
const handleRowChange = (row: LabReportInstr, index: number) => {
|
||||
if(row.status !== 'new') {
|
||||
tableData.value[index].status = 'update';
|
||||
}
|
||||
};
|
||||
|
||||
const handSelectionChange = (selection: LabReportInstr[]) => {
|
||||
selectedRows.value = selection[0];
|
||||
};
|
||||
|
||||
|
||||
const currentChange = (currentRow: LabReportInstr, oldCurrentRow: LabReportInstr) => {
|
||||
console.log('当前行数据:', currentRow);
|
||||
};
|
||||
onMounted(() => {
|
||||
getYqData();
|
||||
});
|
||||
|
||||
</script>
|
||||
@ -7,6 +7,7 @@ export default function createAutoImport() {
|
||||
'vue-router',
|
||||
'pinia'
|
||||
],
|
||||
dts: false
|
||||
// 2. 生成类型声明文件(解决TS类型报错)
|
||||
dts: 'src/auto-imports.d.ts', // 生成的.d.ts文件路径(会自动创建)
|
||||
})
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user