feat(property-marketing): 增加媒体账号同步状态展示与操作功能- 在账号管理表格中新增“更新状态”列,用于展示同步状态

This commit is contained in:
rd
2025-09-24 16:28:37 +08:00
parent 822a7df242
commit 9980f41646
3 changed files with 122 additions and 8 deletions

View File

@ -9,6 +9,7 @@
bordered
class="flex-1 w-100%"
rowKey="id"
:rowClassName="(record) => (isSyncing(record) || isSyncFailed(record) ? 'sync' : '')"
>
<template #emptyText>
<NoData />
@ -23,6 +24,7 @@
:minWidth="column.minWidth"
:sorter="column.sortable"
:width="column.width"
:className="column.class"
>
<template #title>
<span class="cts mr-4px">{{ column.title }}</span>
@ -53,7 +55,7 @@
<StatusBox :item="record" />
</template>
<template v-else-if="column.dataIndex === 'platform'" #customRender="{ record }">
<img :src="record.platform === 0 ? icon2 : icon3" height="16" width="16" />
<img :src="record.platform === 0 ? icon2 : icon3" alt="" height="16" width="16" />
</template>
<template v-else-if="column.dataIndex === 'last_synced_at'" #customRender="{ record }">
<span class="cts num">{{ getLastSyncedAt(record) }}</span>
@ -61,6 +63,25 @@
<template v-else-if="column.dataIndex === 'last_authorized_at'" #customRender="{ record }">
<span class="cts num">{{ formatTime(record.last_authorized_at) }}</span>
</template>
<template v-else-if="column.dataIndex === 'sync'" #customRender="{ record }">
<div v-if="isSyncing(record)" class="sync-col">
<Spin tip="更新数据中..." />
</div>
<div v-else-if="isSyncFailed(record)" class="flex items-center">
<div class="flex items-center box mr-16px">
<img :src="icon4" alt="" class="mr-8px" height="16" width="16" />
<span class="name !mb-0">{{ getErrorStatusText(record) }}</span>
</div>
<div class="flex items-center">
<Button class="mr-8px !h-24px !px-12px" ghost size="small" type="primary" @click="handleCancel(record)">
取消
</Button>
<Button v-if="showConfirmBtn(record)" ghost size="small" type="primary" @click="handleConfirm(record)"
>{{ getConfirmBtnText(record) }}
</Button>
</div>
</div>
</template>
<template v-else-if="column.dataIndex === 'operation'" #customRender="{ record }">
<div class="flex items-center">
<FooterBtn
@ -82,12 +103,17 @@
<script setup>
import { ref, computed, inject } from 'vue';
import { Tooltip, Table, Tag } from 'ant-design-vue';
import StatusBox from '@/views/property-marketing/media-account/components/status-select/status-box.tsx';
import { Tooltip, Table, Tag, Spin, Button } from 'ant-design-vue';
import StatusBox, {
EnumErrorStatus,
EnumStatus,
errorStatusMap,
} from '@/views/property-marketing/media-account/components/status-select/status-box.tsx';
const { Column } = Table;
import { formatTableField, exactFormatTime } from '@/utils/tools';
import { deleteSyncStatus } from '@/api/all/propertyMarketing';
import TextOverTips from '@/components/text-over-tips';
import FooterBtn from './footer-btn';
@ -95,6 +121,7 @@ import FooterBtn from './footer-btn';
// import icon1 from '@/assets/img/media-account/icon-delete.png';
import icon2 from '@/assets/img/platform/icon-dy.png';
import icon3 from '@/assets/img/platform/icon-xhs.png';
import icon4 from '@/assets/img/media-account/icon-warn.png';
const emits = defineEmits([
'openEdit',
@ -178,8 +205,89 @@ const rowSelection = {
emits('selectAll', selected);
},
};
const isSyncing = (item) => {
if (!props.syncMediaAccounts.length) return false;
return getSyncMediaAccount(item)?.status === 0;
};
const isSyncFailed = (item) => {
return getSyncMediaAccount(item)?.status === 2;
};
const getErrorStatusText = (item) => {
const error_status = getSyncMediaAccount(item)?.error_status;
return `异常(${errorStatusMap.get(error_status)?.text ?? ''}`;
};
const handleCancel = async (item) => {
const error_status = getSyncMediaAccount(item)?.error_status;
await deleteSyncStatus(item.id);
item.status = EnumStatus.ABNORMAL;
item.error_status = error_status;
emits('updateSyncStatus', item);
};
const handleConfirm = (item) => {
const error_status = getSyncMediaAccount(item)?.error_status;
if (error_status === EnumErrorStatus.MISSING) {
syncData(item);
}
if (error_status === EnumErrorStatus.LOGIN) {
emits('');
handleReauthorize(item);
}
};
const showConfirmBtn = (item) => {
const error_status = getSyncMediaAccount(item)?.error_status;
return [EnumErrorStatus.MISSING, EnumErrorStatus.LOGIN].includes(error_status);
};
const getConfirmBtnText = (item) => {
const error_status = getSyncMediaAccount(item)?.error_status;
if (error_status === EnumErrorStatus.MISSING) {
return '重新更新';
}
if (error_status === EnumErrorStatus.LOGIN) {
return '重新授权';
}
};
</script>
<style lang="scss" scoped>
@import './style.scss';
:deep(.ant-table) {
.ant-table-tbody {
.ant-table-row {
&.sync {
position: relative;
border-bottom: none !important;
.sync-row {
background-color: #fff;
opacity: 0.9;
content: '';
position: absolute;
left: 0;
top: 0;
z-index: 22;
width: 100%;
height: 100%;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
.sync-col {
.ant-spin {
display: flex;
width: fit-content;
.ant-spin-dot {
margin-right: 8px;
}
}
}
}
}
}
}
}
</style>

View File

@ -49,6 +49,11 @@ export const TABLE_COLUMNS = [
width: 200,
fixed: 'left',
},
{
title: '更新状态',
dataIndex: 'sync',
class: 'sync-row',
},
{
title: '状态',
dataIndex: 'status',
@ -94,6 +99,7 @@ export const TABLE_COLUMNS = [
dataIndex: 'tags',
width: 180,
},
{
title: '操作',
dataIndex: 'operation',