feat:新增转移到公共池
This commit is contained in:
parent
de468c1acb
commit
a300cb4760
@ -1,37 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="transfer-container">
|
<view class="transfer-container">
|
||||||
<view class="content">
|
<view class="content">
|
||||||
<view class="section-title">选择新负责团队</view>
|
<view class="tips">处理中...</view>
|
||||||
<view class="selector-item" @click="selectTeam">
|
|
||||||
<text :class="team ? '' : 'placeholder'">{{ team ? team.name : '请选择团队' }}</text>
|
|
||||||
<uni-icons type="arrowdown" size="16" color="#999" />
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<template v-if="team">
|
|
||||||
<view class="section-title">选择责任人</view>
|
|
||||||
<view class="selector-item" @click="selectUser">
|
|
||||||
<text :class="userId ? '' : 'placeholder'">{{ userLabel || '请选择责任人' }}</text>
|
|
||||||
<uni-icons type="arrowdown" size="16" color="#999" />
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<view class="tips">客户将与本团队解除服务关系,本团队成员将没有权限查询到客户档案。</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="footer">
|
|
||||||
<button class="btn plain" @click="cancel">取消</button>
|
|
||||||
<button class="btn primary" @click="save">保存</button>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { onLoad } from '@dcloudio/uni-app';
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import api from '@/utils/api';
|
import api from '@/utils/api';
|
||||||
import useAccountStore from '@/store/account';
|
import useAccountStore from '@/store/account';
|
||||||
import { hideLoading, loading, toast } from '@/utils/widget';
|
import { confirm as uniConfirm, hideLoading, loading as showLoading, toast } from '@/utils/widget';
|
||||||
|
|
||||||
const CURRENT_TEAM_STORAGE_KEY = 'ykt_case_current_team';
|
const CURRENT_TEAM_STORAGE_KEY = 'ykt_case_current_team';
|
||||||
const NEED_RELOAD_STORAGE_KEY = 'ykt_case_need_reload';
|
const NEED_RELOAD_STORAGE_KEY = 'ykt_case_need_reload';
|
||||||
@ -44,15 +25,6 @@ const { getDoctorInfo } = accountStore;
|
|||||||
const customerIds = ref([]);
|
const customerIds = ref([]);
|
||||||
const currentTeam = ref(null);
|
const currentTeam = ref(null);
|
||||||
const teams = ref([]);
|
const teams = ref([]);
|
||||||
const team = ref(null);
|
|
||||||
const teamMembers = ref([]);
|
|
||||||
const userId = ref('');
|
|
||||||
|
|
||||||
const userLabel = computed(() => {
|
|
||||||
const list = Array.isArray(teamMembers.value) ? teamMembers.value : [];
|
|
||||||
const found = list.find((m) => String(m?.userid || '') === String(userId.value));
|
|
||||||
return found ? String(found.anotherName || found.name || found.userid || '') : '';
|
|
||||||
});
|
|
||||||
|
|
||||||
function getUserId() {
|
function getUserId() {
|
||||||
const d = doctorInfo.value || {};
|
const d = doctorInfo.value || {};
|
||||||
@ -71,6 +43,21 @@ function getCurrentTeamId() {
|
|||||||
return String(currentTeam.value?.teamId || '') || '';
|
return String(currentTeam.value?.teamId || '') || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showActionSheet(itemList = [], title = '') {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!Array.isArray(itemList) || itemList.length === 0) {
|
||||||
|
reject(new Error('empty'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uni.showActionSheet({
|
||||||
|
title,
|
||||||
|
itemList,
|
||||||
|
success: ({ tapIndex }) => resolve(tapIndex),
|
||||||
|
fail: () => reject(new Error('cancel')),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function normalizeTeam(raw) {
|
function normalizeTeam(raw) {
|
||||||
if (!raw || typeof raw !== 'object') return null;
|
if (!raw || typeof raw !== 'object') return null;
|
||||||
const teamId = raw.teamId || raw.id || raw._id || '';
|
const teamId = raw.teamId || raw.id || raw._id || '';
|
||||||
@ -94,114 +81,174 @@ async function loadTeams() {
|
|||||||
await ensureDoctor();
|
await ensureDoctor();
|
||||||
const corpId = getCorpId();
|
const corpId = getCorpId();
|
||||||
const userId = getUserId();
|
const userId = getUserId();
|
||||||
if (!corpId || !userId) return;
|
if (!corpId || !userId) return [];
|
||||||
const res = await api('getTeamBymember', { corpId, corpUserId: userId });
|
const res = await api('getTeamBymember', { corpId, corpUserId: userId });
|
||||||
if (!res?.success) {
|
if (!res?.success) {
|
||||||
toast(res?.message || '获取团队失败');
|
toast(res?.message || '获取团队失败');
|
||||||
return;
|
return [];
|
||||||
}
|
}
|
||||||
const list = Array.isArray(res?.data) ? res.data : Array.isArray(res?.data?.data) ? res.data.data : [];
|
const list = Array.isArray(res?.data) ? res.data : Array.isArray(res?.data?.data) ? res.data.data : [];
|
||||||
teams.value = list.map(normalizeTeam).filter(Boolean);
|
teams.value = list.map(normalizeTeam).filter(Boolean);
|
||||||
|
return teams.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadTeamMembers(teamId) {
|
async function fetchTeamMembers(teamId) {
|
||||||
const corpId = getCorpId();
|
const corpId = getCorpId();
|
||||||
if (!teamId) return;
|
if (!teamId) return [];
|
||||||
const res = await api('getTeamData', { corpId, teamId });
|
const res = await api('getTeamData', { corpId, teamId });
|
||||||
if (!res?.success) {
|
if (!res?.success) {
|
||||||
toast(res?.message || '获取团队成员失败');
|
toast(res?.message || '获取团队成员失败');
|
||||||
teamMembers.value = [];
|
return [];
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
const t = res?.data && typeof res.data === 'object' ? res.data : {};
|
const t = res?.data && typeof res.data === 'object' ? res.data : {};
|
||||||
teamMembers.value = Array.isArray(t.memberList) ? t.memberList : [];
|
return Array.isArray(t.memberList) ? t.memberList : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectTeam = async () => {
|
async function transferToCustomerPool() {
|
||||||
if (!teams.value.length) await loadTeams();
|
try {
|
||||||
const currentId = getCurrentTeamId();
|
await uniConfirm('客户将与本团队解除服务关系,本团队成员将没有权限查询到客户档案。');
|
||||||
const candidates = teams.value.filter((t) => t.teamId !== currentId);
|
} catch (e) {
|
||||||
if (!candidates.length) {
|
return false;
|
||||||
toast('暂无可选团队');
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
uni.showActionSheet({
|
|
||||||
itemList: candidates.map((t) => t.name),
|
|
||||||
success: async (res) => {
|
|
||||||
team.value = candidates[res.tapIndex] || null;
|
|
||||||
userId.value = '';
|
|
||||||
teamMembers.value = [];
|
|
||||||
if (team.value) await loadTeamMembers(team.value.teamId);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const selectUser = () => {
|
|
||||||
const list = Array.isArray(teamMembers.value) ? teamMembers.value : [];
|
|
||||||
if (!list.length) {
|
|
||||||
toast('当前团队暂无可选成员');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const labels = list.map((m) => String(m?.anotherName || m?.name || m?.userid || ''));
|
|
||||||
uni.showActionSheet({
|
|
||||||
itemList: labels,
|
|
||||||
success: (res) => {
|
|
||||||
const picked = list[res.tapIndex];
|
|
||||||
userId.value = picked?.userid ? String(picked.userid) : '';
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const cancel = () => {
|
|
||||||
uni.navigateBack();
|
|
||||||
};
|
|
||||||
|
|
||||||
const save = async () => {
|
|
||||||
if (!team.value) return toast('请选择团队');
|
|
||||||
if (!userId.value) return toast('请选择负责人');
|
|
||||||
|
|
||||||
const corpId = getCorpId();
|
const corpId = getCorpId();
|
||||||
const currentTeamId = getCurrentTeamId();
|
const currentTeamId = getCurrentTeamId();
|
||||||
const creatorUserId = getUserId();
|
const creatorUserId = getUserId();
|
||||||
if (!corpId || !currentTeamId || !creatorUserId) return toast('缺少用户/团队信息');
|
if (!corpId || !currentTeamId || !creatorUserId) {
|
||||||
|
toast('缺少用户/团队信息');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
loading('保存中...');
|
showLoading('保存中...');
|
||||||
try {
|
try {
|
||||||
const res = await api('transferCustomers', {
|
const res = await api('transferCustomers', {
|
||||||
corpId,
|
corpId,
|
||||||
customerIds: customerIds.value,
|
customerIds: customerIds.value,
|
||||||
currentTeamId,
|
currentTeamId,
|
||||||
targetTeamId: team.value.teamId,
|
operationType: 'transferToCustomerPool',
|
||||||
targetUserId: userId.value,
|
creatorUserId,
|
||||||
|
});
|
||||||
|
if (!res?.success) {
|
||||||
|
toast(res?.message || '操作失败');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
toast('操作成功');
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
toast('操作失败');
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
hideLoading();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function transferToOtherTeam() {
|
||||||
|
const corpId = getCorpId();
|
||||||
|
const currentTeamId = getCurrentTeamId();
|
||||||
|
const creatorUserId = getUserId();
|
||||||
|
if (!corpId || !currentTeamId || !creatorUserId) {
|
||||||
|
toast('缺少用户/团队信息');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!teams.value.length) await loadTeams();
|
||||||
|
const candidates = teams.value.filter((t) => String(t?.teamId || '') !== String(currentTeamId));
|
||||||
|
if (!candidates.length) {
|
||||||
|
toast('暂无可选团队');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let teamIndex;
|
||||||
|
try {
|
||||||
|
teamIndex = await showActionSheet(candidates.map((t) => t.name || ''), '选择新负责团队');
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const pickedTeam = candidates[teamIndex];
|
||||||
|
if (!pickedTeam?.teamId) {
|
||||||
|
toast('团队信息异常');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const members = await fetchTeamMembers(pickedTeam.teamId);
|
||||||
|
if (!members.length) {
|
||||||
|
toast('当前团队暂无可选成员');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let userIndex;
|
||||||
|
try {
|
||||||
|
userIndex = await showActionSheet(
|
||||||
|
members.map((m) => String(m?.anotherName || m?.name || m?.userid || '')),
|
||||||
|
'选择责任人'
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetUserId = String(members[userIndex]?.userid || '') || '';
|
||||||
|
if (!targetUserId) {
|
||||||
|
toast('责任人信息异常');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
showLoading('保存中...');
|
||||||
|
try {
|
||||||
|
const res = await api('transferCustomers', {
|
||||||
|
corpId,
|
||||||
|
customerIds: customerIds.value,
|
||||||
|
currentTeamId,
|
||||||
|
targetTeamId: String(pickedTeam.teamId),
|
||||||
|
targetUserId,
|
||||||
operationType: 'transferToOtherTeam',
|
operationType: 'transferToOtherTeam',
|
||||||
creatorUserId,
|
creatorUserId,
|
||||||
});
|
});
|
||||||
if (!res?.success) {
|
if (!res?.success) {
|
||||||
toast(res?.message || '操作失败');
|
toast(res?.message || '操作失败');
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
toast('操作成功');
|
toast('操作成功');
|
||||||
uni.removeStorageSync(BATCH_CUSTOMER_IDS_KEY);
|
return true;
|
||||||
uni.setStorageSync(NEED_RELOAD_STORAGE_KEY, 1);
|
|
||||||
uni.navigateBack();
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast('操作失败');
|
toast('操作失败');
|
||||||
|
return false;
|
||||||
} finally {
|
} finally {
|
||||||
hideLoading();
|
hideLoading();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
onLoad(async () => {
|
async function runFlow(options = {}) {
|
||||||
|
let mode = options?.mode === 'pool' ? 'pool' : options?.mode === 'team' ? 'team' : '';
|
||||||
|
if (!mode) {
|
||||||
|
let pick;
|
||||||
|
try {
|
||||||
|
pick = await showActionSheet(['转移给其他团队', '转移至客户公共池']);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mode = pick === 0 ? 'team' : 'pool';
|
||||||
|
}
|
||||||
|
return mode === 'team' ? await transferToOtherTeam() : await transferToCustomerPool();
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoad(async (options = {}) => {
|
||||||
customerIds.value = Array.isArray(uni.getStorageSync(BATCH_CUSTOMER_IDS_KEY))
|
customerIds.value = Array.isArray(uni.getStorageSync(BATCH_CUSTOMER_IDS_KEY))
|
||||||
? uni.getStorageSync(BATCH_CUSTOMER_IDS_KEY).map(String).filter(Boolean)
|
? uni.getStorageSync(BATCH_CUSTOMER_IDS_KEY).map(String).filter(Boolean)
|
||||||
: [];
|
: [];
|
||||||
currentTeam.value = uni.getStorageSync(CURRENT_TEAM_STORAGE_KEY) || null;
|
currentTeam.value = uni.getStorageSync(CURRENT_TEAM_STORAGE_KEY) || null;
|
||||||
|
|
||||||
if (!customerIds.value.length) {
|
if (!customerIds.value.length) {
|
||||||
toast('未选择客户');
|
toast('未选择客户');
|
||||||
setTimeout(() => uni.navigateBack(), 200);
|
setTimeout(() => uni.navigateBack(), 200);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await loadTeams();
|
|
||||||
|
const ok = await runFlow(options);
|
||||||
|
if (ok) {
|
||||||
|
uni.removeStorageSync(BATCH_CUSTOMER_IDS_KEY);
|
||||||
|
uni.setStorageSync(NEED_RELOAD_STORAGE_KEY, 1);
|
||||||
|
}
|
||||||
|
setTimeout(() => uni.navigateBack(), 50);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@ -131,7 +131,7 @@ import dayjs from 'dayjs';
|
|||||||
|
|
||||||
import api from '@/utils/api';
|
import api from '@/utils/api';
|
||||||
import useAccountStore from '@/store/account';
|
import useAccountStore from '@/store/account';
|
||||||
import { toast } from '@/utils/widget';
|
import { confirm as uniConfirm, hideLoading, loading as showLoading, toast } from '@/utils/widget';
|
||||||
|
|
||||||
// State
|
// State
|
||||||
const teams = ref([]);
|
const teams = ref([]);
|
||||||
@ -767,14 +767,149 @@ const cancelBatch = () => {
|
|||||||
selectedItems.value = [];
|
selectedItems.value = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTransfer = () => {
|
function showActionSheet(itemList = [], title = '') {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!Array.isArray(itemList) || itemList.length === 0) {
|
||||||
|
reject(new Error('empty'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uni.showActionSheet({
|
||||||
|
title,
|
||||||
|
itemList,
|
||||||
|
success: ({ tapIndex }) => resolve(tapIndex),
|
||||||
|
fail: () => reject(new Error('cancel')),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchTeamMembersByTeamId(teamId) {
|
||||||
|
const corpId = getCorpId();
|
||||||
|
if (!corpId || !teamId) return [];
|
||||||
|
const res = await api('getTeamData', { corpId, teamId });
|
||||||
|
if (!res?.success) return [];
|
||||||
|
const t = res?.data && typeof res.data === 'object' ? res.data : {};
|
||||||
|
return Array.isArray(t.memberList) ? t.memberList : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function transferToCustomerPool(customerIds) {
|
||||||
|
try {
|
||||||
|
await uniConfirm('客户将与本团队解除服务关系,本团队成员将没有权限查询到客户档案。');
|
||||||
|
} catch (e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const corpId = getCorpId();
|
||||||
|
const currentTeamId = getTeamId();
|
||||||
|
const creatorUserId = getUserId();
|
||||||
|
if (!corpId || !currentTeamId || !creatorUserId) return toast('缺少用户/团队信息');
|
||||||
|
|
||||||
|
showLoading('保存中...');
|
||||||
|
try {
|
||||||
|
const res = await api('transferCustomers', {
|
||||||
|
corpId,
|
||||||
|
customerIds,
|
||||||
|
currentTeamId,
|
||||||
|
operationType: 'transferToCustomerPool',
|
||||||
|
creatorUserId,
|
||||||
|
});
|
||||||
|
if (!res?.success) {
|
||||||
|
toast(res?.message || '操作失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
toast('操作成功');
|
||||||
|
cancelBatch();
|
||||||
|
await reload(true);
|
||||||
|
} catch (e) {
|
||||||
|
toast('操作失败');
|
||||||
|
} finally {
|
||||||
|
hideLoading();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function transferToOtherTeam(customerIds) {
|
||||||
|
const corpId = getCorpId();
|
||||||
|
const currentTeamId = getTeamId();
|
||||||
|
const creatorUserId = getUserId();
|
||||||
|
if (!corpId || !currentTeamId || !creatorUserId) return toast('缺少用户/团队信息');
|
||||||
|
|
||||||
|
if (!teams.value.length) await loadTeams();
|
||||||
|
const candidates = teams.value.filter((t) => String(t?.teamId || '') !== String(currentTeamId));
|
||||||
|
if (!candidates.length) return toast('暂无可选团队');
|
||||||
|
|
||||||
|
let teamIndex;
|
||||||
|
try {
|
||||||
|
teamIndex = await showActionSheet(candidates.map((t) => t.name || ''), '选择新负责团队');
|
||||||
|
} catch (e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const pickedTeam = candidates[teamIndex];
|
||||||
|
if (!pickedTeam?.teamId) return toast('团队信息异常');
|
||||||
|
|
||||||
|
let members = [];
|
||||||
|
try {
|
||||||
|
members = await fetchTeamMembersByTeamId(pickedTeam.teamId);
|
||||||
|
} catch (e) {
|
||||||
|
members = [];
|
||||||
|
}
|
||||||
|
if (!members.length) return toast('当前团队暂无可选成员');
|
||||||
|
|
||||||
|
const labels = members.map((m) => String(m?.anotherName || m?.name || m?.userid || ''));
|
||||||
|
let userIndex;
|
||||||
|
try {
|
||||||
|
userIndex = await showActionSheet(labels, '选择责任人');
|
||||||
|
} catch (e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const pickedUser = members[userIndex] || null;
|
||||||
|
const targetUserId = String(pickedUser?.userid || '') || '';
|
||||||
|
if (!targetUserId) return toast('责任人信息异常');
|
||||||
|
|
||||||
|
showLoading('保存中...');
|
||||||
|
try {
|
||||||
|
const res = await api('transferCustomers', {
|
||||||
|
corpId,
|
||||||
|
customerIds,
|
||||||
|
currentTeamId,
|
||||||
|
targetTeamId: String(pickedTeam.teamId),
|
||||||
|
targetUserId,
|
||||||
|
operationType: 'transferToOtherTeam',
|
||||||
|
creatorUserId,
|
||||||
|
});
|
||||||
|
if (!res?.success) {
|
||||||
|
toast(res?.message || '操作失败');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
toast('操作成功');
|
||||||
|
cancelBatch();
|
||||||
|
await reload(true);
|
||||||
|
} catch (e) {
|
||||||
|
toast('操作失败');
|
||||||
|
} finally {
|
||||||
|
hideLoading();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleTransfer = async () => {
|
||||||
if (selectedItems.value.length === 0) {
|
if (selectedItems.value.length === 0) {
|
||||||
uni.showToast({ title: '请选择患者', icon: 'none' });
|
uni.showToast({ title: '请选择患者', icon: 'none' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uni.setStorageSync(BATCH_CUSTOMER_IDS_KEY, selectedItems.value.slice());
|
|
||||||
// Navigate to Transfer Page
|
let tapIndex;
|
||||||
uni.navigateTo({ url: '/pages/case/batch-transfer' });
|
try {
|
||||||
|
tapIndex = await showActionSheet(['转移给其他团队', '转移至客户公共池']);
|
||||||
|
} catch (e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const customerIds = selectedItems.value.slice().map(String).filter(Boolean);
|
||||||
|
if (!customerIds.length) return toast('请选择患者');
|
||||||
|
|
||||||
|
if (tapIndex === 0) {
|
||||||
|
await transferToOtherTeam(customerIds);
|
||||||
|
} else if (tapIndex === 1) {
|
||||||
|
await transferToCustomerPool(customerIds);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleShare = () => {
|
const handleShare = () => {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user