fix: 店铺拉单弹窗按 TikTok 状态筛选,并避免表格刷新打断弹窗
All checks were successful
Build and Deploy Front / deploy (push) Successful in 6m16s
All checks were successful
Build and Deploy Front / deploy (push) Successful in 6m16s
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
e5175e6cc1
commit
108083d332
@ -1475,6 +1475,9 @@
|
|||||||
manualColumnResize: true,
|
manualColumnResize: true,
|
||||||
manualColumnMove: props.enableColumnReorder,
|
manualColumnMove: props.enableColumnReorder,
|
||||||
stretchH: props.stretchColumns ? 'all' : 'none',
|
stretchH: props.stretchColumns ? 'all' : 'none',
|
||||||
|
// 列宽由列定义给出。开启后 loadData 会走 GhostTable 测量,
|
||||||
|
// 单元格节点缺失时抛 getBoundingClientRect,并中断外层页面更新。
|
||||||
|
autoColumnSize: false,
|
||||||
// stretch 时锁定操作/序号/复选框列,避免被均分拉宽
|
// stretch 时锁定操作/序号/复选框列,避免被均分拉宽
|
||||||
beforeStretchingColumnWidth: lockFixedColumnStretchWidth,
|
beforeStretchingColumnWidth: lockFixedColumnStretchWidth,
|
||||||
...(props.rowHeight != null && props.rowHeight > 0
|
...(props.rowHeight != null && props.rowHeight > 0
|
||||||
@ -2362,6 +2365,8 @@
|
|||||||
hotInstance.loadData([]);
|
hotInstance.loadData([]);
|
||||||
hotInstance.render();
|
hotInstance.render();
|
||||||
publishSelection([], new Set());
|
publishSelection([], new Set());
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('[HandsontablePro] clear failed', error);
|
||||||
} finally {
|
} finally {
|
||||||
selectionLock -= 1;
|
selectionLock -= 1;
|
||||||
}
|
}
|
||||||
@ -2393,6 +2398,8 @@
|
|||||||
} else {
|
} else {
|
||||||
applySelectedRowStyles();
|
applySelectedRowStyles();
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('[HandsontablePro] refresh failed', error);
|
||||||
} finally {
|
} finally {
|
||||||
selectionLock -= 1;
|
selectionLock -= 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1079,9 +1079,25 @@ export default {
|
|||||||
'order.platformStoreOrder.createFulfillWms.success': 'Created {count} fulfill order(s)',
|
'order.platformStoreOrder.createFulfillWms.success': 'Created {count} fulfill order(s)',
|
||||||
'order.platformStoreOrder.pull.store': 'Store',
|
'order.platformStoreOrder.pull.store': 'Store',
|
||||||
'order.platformStoreOrder.pull.storePlaceholder': 'Select stores',
|
'order.platformStoreOrder.pull.storePlaceholder': 'Select stores',
|
||||||
|
'order.platformStoreOrder.pull.storeAll': 'All stores',
|
||||||
'order.platformStoreOrder.pull.status': 'Status',
|
'order.platformStoreOrder.pull.status': 'Status',
|
||||||
|
'order.platformStoreOrder.pull.statusAll': 'All',
|
||||||
|
'order.platformStoreOrder.pull.statusClear': 'Clear',
|
||||||
|
'order.platformStoreOrder.pull.statusCount': '{count} selected',
|
||||||
'order.platformStoreOrder.pull.time': 'Time',
|
'order.platformStoreOrder.pull.time': 'Time',
|
||||||
'order.platformStoreOrder.pull.timeHint': 'Defaults to today',
|
'order.platformStoreOrder.pull.timeHint': 'Filter by order created time. Defaults to today.',
|
||||||
|
'order.platformStoreOrder.pull.today': 'Today',
|
||||||
|
'order.platformStoreOrder.pull.last7': '7 days',
|
||||||
|
'order.platformStoreOrder.pull.last15': '15 days',
|
||||||
|
'order.platformStoreOrder.pull.status.UNPAID': 'Unpaid',
|
||||||
|
'order.platformStoreOrder.pull.status.ON_HOLD': 'On hold',
|
||||||
|
'order.platformStoreOrder.pull.status.PARTIALLY_SHIPPING': 'Partially shipping',
|
||||||
|
'order.platformStoreOrder.pull.status.AWAITING_SHIPMENT': 'Awaiting shipment',
|
||||||
|
'order.platformStoreOrder.pull.status.AWAITING_COLLECTION': 'Awaiting collection',
|
||||||
|
'order.platformStoreOrder.pull.status.IN_TRANSIT': 'In transit',
|
||||||
|
'order.platformStoreOrder.pull.status.DELIVERED': 'Delivered',
|
||||||
|
'order.platformStoreOrder.pull.status.COMPLETED': 'Completed',
|
||||||
|
'order.platformStoreOrder.pull.status.CANCELLED': 'Cancelled',
|
||||||
'order.platformStoreOrder.message.loadFailed': 'Failed to load orders',
|
'order.platformStoreOrder.message.loadFailed': 'Failed to load orders',
|
||||||
'order.platformStoreOrder.message.detailFailed': 'Failed to load detail',
|
'order.platformStoreOrder.message.detailFailed': 'Failed to load detail',
|
||||||
'order.platformStoreOrder.message.matchSuccess': 'Inventory matched',
|
'order.platformStoreOrder.message.matchSuccess': 'Inventory matched',
|
||||||
|
|||||||
@ -1070,9 +1070,25 @@ export default {
|
|||||||
'order.platformStoreOrder.createFulfillWms.success': '成功创建 {count} 张代发订单',
|
'order.platformStoreOrder.createFulfillWms.success': '成功创建 {count} 张代发订单',
|
||||||
'order.platformStoreOrder.pull.store': '店铺',
|
'order.platformStoreOrder.pull.store': '店铺',
|
||||||
'order.platformStoreOrder.pull.storePlaceholder': '请选择店铺',
|
'order.platformStoreOrder.pull.storePlaceholder': '请选择店铺',
|
||||||
'order.platformStoreOrder.pull.status': '类型',
|
'order.platformStoreOrder.pull.storeAll': '全选店铺',
|
||||||
|
'order.platformStoreOrder.pull.status': '状态',
|
||||||
|
'order.platformStoreOrder.pull.statusAll': '全选',
|
||||||
|
'order.platformStoreOrder.pull.statusClear': '清空',
|
||||||
|
'order.platformStoreOrder.pull.statusCount': '已选 {count} 个',
|
||||||
'order.platformStoreOrder.pull.time': '时间',
|
'order.platformStoreOrder.pull.time': '时间',
|
||||||
'order.platformStoreOrder.pull.timeHint': '默认时间为当天',
|
'order.platformStoreOrder.pull.timeHint': '按订单创建时间拉取,默认当天',
|
||||||
|
'order.platformStoreOrder.pull.today': '今天',
|
||||||
|
'order.platformStoreOrder.pull.last7': '近7天',
|
||||||
|
'order.platformStoreOrder.pull.last15': '近15天',
|
||||||
|
'order.platformStoreOrder.pull.status.UNPAID': '未付款',
|
||||||
|
'order.platformStoreOrder.pull.status.ON_HOLD': '待处理',
|
||||||
|
'order.platformStoreOrder.pull.status.PARTIALLY_SHIPPING': '部分发货',
|
||||||
|
'order.platformStoreOrder.pull.status.AWAITING_SHIPMENT': '待发货',
|
||||||
|
'order.platformStoreOrder.pull.status.AWAITING_COLLECTION': '待揽收',
|
||||||
|
'order.platformStoreOrder.pull.status.IN_TRANSIT': '运输中',
|
||||||
|
'order.platformStoreOrder.pull.status.DELIVERED': '已送达',
|
||||||
|
'order.platformStoreOrder.pull.status.COMPLETED': '已完成',
|
||||||
|
'order.platformStoreOrder.pull.status.CANCELLED': '已取消',
|
||||||
'order.platformStoreOrder.message.loadFailed': '加载订单失败',
|
'order.platformStoreOrder.message.loadFailed': '加载订单失败',
|
||||||
'order.platformStoreOrder.message.detailFailed': '加载详情失败',
|
'order.platformStoreOrder.message.detailFailed': '加载详情失败',
|
||||||
'order.platformStoreOrder.message.matchSuccess': '库存匹配成功',
|
'order.platformStoreOrder.message.matchSuccess': '库存匹配成功',
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import { pickField } from '@/utils/warehouseListMapper'
|
|||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
visible: boolean
|
visible: boolean
|
||||||
customerId?: number
|
customerId?: number
|
||||||
|
platformCode?: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@ -16,51 +17,77 @@ const emit = defineEmits<{
|
|||||||
success: []
|
success: []
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
/** TikTok 订单搜索状态,与平台 order_status 一致 */
|
||||||
|
const TIKTOK_PULL_STATUSES = [
|
||||||
|
'UNPAID',
|
||||||
|
'ON_HOLD',
|
||||||
|
'PARTIALLY_SHIPPING',
|
||||||
|
'AWAITING_SHIPMENT',
|
||||||
|
'AWAITING_COLLECTION',
|
||||||
|
'IN_TRANSIT',
|
||||||
|
'DELIVERED',
|
||||||
|
'COMPLETED',
|
||||||
|
'CANCELLED',
|
||||||
|
] as const
|
||||||
|
|
||||||
|
type StoreOption = { label: string; value: number; platform: string }
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const storeLoading = ref(false)
|
const storeLoading = ref(false)
|
||||||
const storeOptions = ref<Array<{ label: string; value: number }>>([])
|
const storeOptions = ref<StoreOption[]>([])
|
||||||
const storeIds = ref<number[]>([])
|
const storeIds = ref<number[]>([])
|
||||||
const orderStatuses = ref<string[]>([
|
const orderStatuses = ref<string[]>([...TIKTOK_PULL_STATUSES])
|
||||||
'unpaid',
|
const dateRange = ref<[string, string]>(todayRange())
|
||||||
'pending',
|
|
||||||
'canceled',
|
|
||||||
'ready_to_ship',
|
|
||||||
'delivered',
|
|
||||||
'returned',
|
|
||||||
'shipped',
|
|
||||||
'failed',
|
|
||||||
'topack',
|
|
||||||
'toship',
|
|
||||||
'shipping',
|
|
||||||
'lost',
|
|
||||||
])
|
|
||||||
const dateRange = ref<[string, string] | undefined>()
|
|
||||||
|
|
||||||
const statusOptions = computed(() =>
|
|
||||||
[
|
|
||||||
'unpaid',
|
|
||||||
'pending',
|
|
||||||
'canceled',
|
|
||||||
'ready_to_ship',
|
|
||||||
'delivered',
|
|
||||||
'returned',
|
|
||||||
'shipped',
|
|
||||||
'failed',
|
|
||||||
'topack',
|
|
||||||
'toship',
|
|
||||||
'shipping',
|
|
||||||
'lost',
|
|
||||||
].map((value) => ({ label: value, value })),
|
|
||||||
)
|
|
||||||
|
|
||||||
const modalVisible = computed({
|
const modalVisible = computed({
|
||||||
get: () => props.visible,
|
get: () => props.visible,
|
||||||
set: (v: boolean) => emit('update:visible', v),
|
set: (v: boolean) => emit('update:visible', v),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const visibleStoreOptions = computed(() => {
|
||||||
|
const platform = (props.platformCode || '').trim().toLowerCase()
|
||||||
|
if (!platform || platform === 'all') return storeOptions.value
|
||||||
|
return storeOptions.value.filter((item) => item.platform === platform)
|
||||||
|
})
|
||||||
|
|
||||||
|
const allStatusesChecked = computed(
|
||||||
|
() => orderStatuses.value.length === TIKTOK_PULL_STATUSES.length,
|
||||||
|
)
|
||||||
|
const allStoresChecked = computed(
|
||||||
|
() =>
|
||||||
|
visibleStoreOptions.value.length > 0
|
||||||
|
&& storeIds.value.length === visibleStoreOptions.value.length,
|
||||||
|
)
|
||||||
|
const canSubmit = computed(
|
||||||
|
() => storeIds.value.length > 0 && orderStatuses.value.length > 0 && !storeLoading.value,
|
||||||
|
)
|
||||||
|
|
||||||
|
function todayRange(): [string, string] {
|
||||||
|
return [dayjs().format('YYYY-MM-DD'), dayjs().format('YYYY-MM-DD')]
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyRange(days: number) {
|
||||||
|
dateRange.value = [
|
||||||
|
dayjs().subtract(days - 1, 'day').format('YYYY-MM-DD'),
|
||||||
|
dayjs().format('YYYY-MM-DD'),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleAllStatuses() {
|
||||||
|
orderStatuses.value = allStatusesChecked.value ? [] : [...TIKTOK_PULL_STATUSES]
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleAllStores() {
|
||||||
|
storeIds.value = allStoresChecked.value
|
||||||
|
? []
|
||||||
|
: visibleStoreOptions.value.map((item) => item.value)
|
||||||
|
}
|
||||||
|
|
||||||
async function loadStoreOptions() {
|
async function loadStoreOptions() {
|
||||||
storeIds.value = []
|
storeIds.value = []
|
||||||
|
orderStatuses.value = [...TIKTOK_PULL_STATUSES]
|
||||||
|
dateRange.value = todayRange()
|
||||||
storeLoading.value = true
|
storeLoading.value = true
|
||||||
try {
|
try {
|
||||||
const { items } = await getPlatformStoreList({
|
const { items } = await getPlatformStoreList({
|
||||||
@ -72,12 +99,12 @@ async function loadStoreOptions() {
|
|||||||
.map((raw: Record<string, unknown>) => {
|
.map((raw: Record<string, unknown>) => {
|
||||||
const id = Number(pickField(raw, 'id', 'Id'))
|
const id = Number(pickField(raw, 'id', 'Id'))
|
||||||
const name = String(pickField(raw, 'storeNickname', 'StoreNickname') ?? `#${id}`)
|
const name = String(pickField(raw, 'storeNickname', 'StoreNickname') ?? `#${id}`)
|
||||||
const platform = String(pickField(raw, 'platformCode', 'PlatformCode') ?? '')
|
const platform = String(pickField(raw, 'platformCode', 'PlatformCode') ?? '').toLowerCase()
|
||||||
return { label: platform ? `${name} (${platform})` : name, value: id }
|
return { label: platform ? `${name} (${platform})` : name, value: id, platform }
|
||||||
})
|
})
|
||||||
.filter((x) => x.value > 0)
|
.filter((item) => item.value > 0)
|
||||||
if (!storeOptions.value.length) {
|
if (visibleStoreOptions.value.length === 1) {
|
||||||
$baseMessage(t('order.platformStoreOrder.message.noStore'), 'warning')
|
storeIds.value = [visibleStoreOptions.value[0].value]
|
||||||
}
|
}
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
storeOptions.value = []
|
storeOptions.value = []
|
||||||
@ -145,38 +172,152 @@ async function handleSubmit(): Promise<boolean> {
|
|||||||
<a-modal
|
<a-modal
|
||||||
v-model:visible="modalVisible"
|
v-model:visible="modalVisible"
|
||||||
:title="t('order.platformStoreOrder.actions.pullOrders')"
|
:title="t('order.platformStoreOrder.actions.pullOrders')"
|
||||||
|
:width="720"
|
||||||
:ok-loading="loading"
|
:ok-loading="loading"
|
||||||
:ok-text="t('order.platformStoreOrder.actions.startPull')"
|
:ok-text="t('order.platformStoreOrder.actions.startPull')"
|
||||||
|
:ok-button-props="{ disabled: !canSubmit }"
|
||||||
unmount-on-close
|
unmount-on-close
|
||||||
:on-before-ok="handleSubmit"
|
:on-before-ok="handleSubmit"
|
||||||
>
|
>
|
||||||
<a-form :label-col-props="{ span: 6 }" :wrapper-col-props="{ span: 16 }">
|
<a-form class="pull-form" :label-col-props="{ span: 6 }" :wrapper-col-props="{ span: 16 }">
|
||||||
<a-form-item :label="t('order.platformStoreOrder.pull.store')" required>
|
<a-form-item :label="t('order.platformStoreOrder.pull.store')" required>
|
||||||
<a-select
|
<div class="pull-block">
|
||||||
v-model="storeIds"
|
<div class="pull-row">
|
||||||
multiple
|
<a-select
|
||||||
allow-clear
|
v-model="storeIds"
|
||||||
:loading="storeLoading"
|
class="pull-grow"
|
||||||
:options="storeOptions"
|
multiple
|
||||||
:placeholder="t('order.platformStoreOrder.pull.storePlaceholder')"
|
allow-clear
|
||||||
:max-tag-count="3"
|
:loading="storeLoading"
|
||||||
/>
|
:options="visibleStoreOptions"
|
||||||
|
:placeholder="t('order.platformStoreOrder.pull.storePlaceholder')"
|
||||||
|
:max-tag-count="2"
|
||||||
|
/>
|
||||||
|
<a-button
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
:disabled="!visibleStoreOptions.length"
|
||||||
|
@click="toggleAllStores"
|
||||||
|
>
|
||||||
|
{{ allStoresChecked ? t('order.platformStoreOrder.pull.statusClear') : t('order.platformStoreOrder.pull.storeAll') }}
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
<div v-if="!storeLoading && !visibleStoreOptions.length" class="hint">
|
||||||
|
{{ t('order.platformStoreOrder.message.noStore') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item :label="t('order.platformStoreOrder.pull.status')" required>
|
<a-form-item :label="t('order.platformStoreOrder.pull.status')" required>
|
||||||
<a-checkbox-group v-model="orderStatuses" :options="statusOptions" />
|
<div class="pull-block">
|
||||||
|
<div class="pull-row pull-row--between">
|
||||||
|
<span class="hint">
|
||||||
|
{{ t('order.platformStoreOrder.pull.statusCount', { count: orderStatuses.length }) }}
|
||||||
|
</span>
|
||||||
|
<a-button type="text" size="small" @click="toggleAllStatuses">
|
||||||
|
{{ allStatusesChecked ? t('order.platformStoreOrder.pull.statusClear') : t('order.platformStoreOrder.pull.statusAll') }}
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
<a-checkbox-group v-model="orderStatuses" class="status-grid">
|
||||||
|
<a-checkbox v-for="status in TIKTOK_PULL_STATUSES" :key="status" :value="status">
|
||||||
|
<span class="status-name">{{ t(`order.platformStoreOrder.pull.status.${status}`) }}</span>
|
||||||
|
<span class="status-code">{{ status }}</span>
|
||||||
|
</a-checkbox>
|
||||||
|
</a-checkbox-group>
|
||||||
|
</div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item :label="t('order.platformStoreOrder.pull.time')">
|
<a-form-item :label="t('order.platformStoreOrder.pull.time')">
|
||||||
<a-range-picker v-model="dateRange" style="width: 100%" />
|
<div class="pull-block">
|
||||||
<div class="hint">{{ t('order.platformStoreOrder.pull.timeHint') }}</div>
|
<a-range-picker
|
||||||
|
v-model="dateRange"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
value-format="YYYY-MM-DD"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
<div class="pull-row">
|
||||||
|
<a-button type="text" size="small" @click="applyRange(1)">
|
||||||
|
{{ t('order.platformStoreOrder.pull.today') }}
|
||||||
|
</a-button>
|
||||||
|
<a-button type="text" size="small" @click="applyRange(7)">
|
||||||
|
{{ t('order.platformStoreOrder.pull.last7') }}
|
||||||
|
</a-button>
|
||||||
|
<a-button type="text" size="small" @click="applyRange(15)">
|
||||||
|
{{ t('order.platformStoreOrder.pull.last15') }}
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
<div class="hint">{{ t('order.platformStoreOrder.pull.timeHint') }}</div>
|
||||||
|
</div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.hint {
|
.pull-form {
|
||||||
margin-top: 8px;
|
:deep(.arco-form-item) {
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-form-item-label-col) {
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.arco-form-item-content) {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.pull-block {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
gap: 8px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pull-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pull-row--between {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pull-grow {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-grid {
|
||||||
|
display: grid !important;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 10px 12px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
:deep(.arco-checkbox) {
|
||||||
|
margin: 0;
|
||||||
|
align-items: center;
|
||||||
|
line-height: 22px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-name {
|
||||||
|
color: var(--color-text-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-code {
|
||||||
|
margin-left: 6px;
|
||||||
color: var(--color-text-3);
|
color: var(--color-text-3);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hint {
|
||||||
|
color: var(--color-text-3);
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -860,6 +860,7 @@ watch(
|
|||||||
v-if="pullVisible"
|
v-if="pullVisible"
|
||||||
v-model:visible="pullVisible"
|
v-model:visible="pullVisible"
|
||||||
:customer-id="withCustomerId({}).customerId"
|
:customer-id="withCustomerId({}).customerId"
|
||||||
|
:platform-code="platformCode"
|
||||||
@success="() => { loadSummary(); loadList() }"
|
@success="() => { loadSummary(); loadList() }"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user