feat: 同步数据/批量同步
This commit is contained in:
@ -332,4 +332,17 @@ export const postPlacementAccountsSync = (id: string) => {
|
|||||||
return Http.post(`/v1/placement-accounts/${id}/sync-data`);
|
return Http.post(`/v1/placement-accounts/${id}/sync-data`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 媒体账号-同步数据
|
||||||
|
export const postSyncMediaAccountData = (id: string) => {
|
||||||
|
return Http.post(`/v1/media-accounts/${id}/sync-data`);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 媒体账号-批量同步数据
|
||||||
|
export const postBatchSyncMediaAccountData = (params: {}) => {
|
||||||
|
return Http.post(`/v1/media-accounts/batch-sync-data`, params);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 媒体账号-查询同步状态
|
||||||
|
export const getMediaAccountSyncStatus = (params = {}) => {
|
||||||
|
return Http.get('/v1/media-accounts/sync-status', params);
|
||||||
|
};
|
||||||
|
|||||||
@ -70,6 +70,9 @@
|
|||||||
</a-button>
|
</a-button>
|
||||||
<template #content>
|
<template #content>
|
||||||
<a-doption class="color-#211F24" @click="openEdit(item)">编辑</a-doption>
|
<a-doption class="color-#211F24" @click="openEdit(item)">编辑</a-doption>
|
||||||
|
<a-doption v-if="item.status === EnumStatus.NORMAL" class="color-#211F24" @click="handleReauthorize(item)"
|
||||||
|
>重新授权</a-doption
|
||||||
|
>
|
||||||
<a-doption v-if="showPauseButton(item.status)" class="color-#211F24" @click="handlePause(item)"
|
<a-doption v-if="showPauseButton(item.status)" class="color-#211F24" @click="handlePause(item)"
|
||||||
>暂停同步</a-doption
|
>暂停同步</a-doption
|
||||||
>
|
>
|
||||||
@ -113,7 +116,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineProps, ref, computed } from 'vue';
|
import { defineProps, ref, computed, inject } from 'vue';
|
||||||
import { STATUS_LIST, EnumStatus } from '@/views/property-marketing/media-account/components/status-select/constants';
|
import { STATUS_LIST, EnumStatus } from '@/views/property-marketing/media-account/components/status-select/constants';
|
||||||
|
|
||||||
import PauseAccountPatchModal from './pause-account-patch';
|
import PauseAccountPatchModal from './pause-account-patch';
|
||||||
@ -183,6 +186,9 @@ const handlePause = (item) => {
|
|||||||
const showPauseButton = (status) => {
|
const showPauseButton = (status) => {
|
||||||
return ![EnumStatus.PAUSE, EnumStatus.UNAUTHORIZED].includes(status);
|
return ![EnumStatus.PAUSE, EnumStatus.UNAUTHORIZED].includes(status);
|
||||||
};
|
};
|
||||||
|
const showSyncDataButton = (status) => {
|
||||||
|
return [EnumStatus.NORMAL, EnumStatus.ABNORMAL_MISSING].includes(status);
|
||||||
|
};
|
||||||
const isUnauthorizedStatus = (status) => {
|
const isUnauthorizedStatus = (status) => {
|
||||||
return [EnumStatus.UNAUTHORIZED].includes(status);
|
return [EnumStatus.UNAUTHORIZED].includes(status);
|
||||||
};
|
};
|
||||||
@ -201,13 +207,19 @@ const getTooltipText = (status) => {
|
|||||||
return STATUS_LIST.find((v) => v.value === status)?.tooltip ?? '-';
|
return STATUS_LIST.find((v) => v.value === status)?.tooltip ?? '-';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSyncData = inject('handleSyncData');
|
||||||
|
|
||||||
const onBtnClick = (item) => {
|
const onBtnClick = (item) => {
|
||||||
|
if (showSyncDataButton(item.status)) {
|
||||||
|
handleSyncData && handleSyncData(item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (isUnauthorizedStatus(item.status)) {
|
if (isUnauthorizedStatus(item.status)) {
|
||||||
handleReauthorize(item);
|
handleReauthorize(item);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([EnumStatus.PAUSE, EnumStatus.NORMAL].includes(item.status) || isAbnormalStatus(item.status)) {
|
if ([EnumStatus.PAUSE].includes(item.status) || isAbnormalStatus(item.status)) {
|
||||||
handleReauthorize(item);
|
handleReauthorize(item);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -216,11 +228,15 @@ const onBtnClick = (item) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getBtnText = (item) => {
|
const getBtnText = (item) => {
|
||||||
|
if (showSyncDataButton(item.status)) {
|
||||||
|
return '更新数据';
|
||||||
|
}
|
||||||
|
|
||||||
if (isUnauthorizedStatus(item.status)) {
|
if (isUnauthorizedStatus(item.status)) {
|
||||||
return '去授权';
|
return '去授权';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([EnumStatus.PAUSE, EnumStatus.NORMAL].includes(item.status) || isAbnormalStatus(item.status)) {
|
if ([EnumStatus.PAUSE].includes(item.status) || isAbnormalStatus(item.status)) {
|
||||||
return '重新授权';
|
return '重新授权';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -162,6 +162,8 @@
|
|||||||
<AuthorizedAccountModal ref="authorizedAccountModalRef" @update="emits('update')" />
|
<AuthorizedAccountModal ref="authorizedAccountModalRef" @update="emits('update')" />
|
||||||
<ImportPromptModal ref="importPromptModalRef" />
|
<ImportPromptModal ref="importPromptModalRef" />
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
|
||||||
|
<SyncDataModal ref="syncDataModalRef" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@ -171,6 +173,7 @@ import GroupSelect from '@/views/property-marketing/media-account/components/gro
|
|||||||
import AuthorizedAccountModal from '../authorized-account-modal';
|
import AuthorizedAccountModal from '../authorized-account-modal';
|
||||||
import ImportPromptModal from '../import-prompt-modal';
|
import ImportPromptModal from '../import-prompt-modal';
|
||||||
import StatusBox from '../status-box';
|
import StatusBox from '../status-box';
|
||||||
|
import SyncDataModal from '../sync-data-modal';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
fetchAccountTags,
|
fetchAccountTags,
|
||||||
@ -220,6 +223,7 @@ const importPromptModalRef = ref(null);
|
|||||||
const uploadRef = ref(null);
|
const uploadRef = ref(null);
|
||||||
const isCustomCookie = ref(false);
|
const isCustomCookie = ref(false);
|
||||||
const form = ref(cloneDeep(INITIAL_FORM));
|
const form = ref(cloneDeep(INITIAL_FORM));
|
||||||
|
const syncDataModalRef = ref(null);
|
||||||
|
|
||||||
const rules = {
|
const rules = {
|
||||||
mobile: [
|
mobile: [
|
||||||
@ -245,8 +249,13 @@ const rules = {
|
|||||||
|
|
||||||
const isBatchImport = computed(() => uploadType.value === 'batch');
|
const isBatchImport = computed(() => uploadType.value === 'batch');
|
||||||
const confirmBtnText = computed(() => {
|
const confirmBtnText = computed(() => {
|
||||||
if (isBatchImport.value) return '确定导入';
|
if (isBatchImport.value) {
|
||||||
return isEdit.value ? '确定' : '生成授权码';
|
return '确定导入';
|
||||||
|
} else if (isEdit.value) {
|
||||||
|
return '确定';
|
||||||
|
} else {
|
||||||
|
return isCustomCookie.value ? '确认添加' : '生成授权码';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 获取分组数据
|
// 获取分组数据
|
||||||
@ -354,7 +363,11 @@ const handleAddAccount = async () => {
|
|||||||
onClose();
|
onClose();
|
||||||
|
|
||||||
const { id, platform } = data;
|
const { id, platform } = data;
|
||||||
!_isCustomCookie && startAuthorized(id, platform);
|
if (_isCustomCookie) {
|
||||||
|
syncDataModalRef.value.open(id);
|
||||||
|
} else {
|
||||||
|
startAuthorized(id, platform);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -375,6 +388,11 @@ async function onSubmit() {
|
|||||||
|
|
||||||
formRef.value.validate(async (errors) => {
|
formRef.value.validate(async (errors) => {
|
||||||
if (!errors) {
|
if (!errors) {
|
||||||
|
if (isCustomCookie.value && !form.value.cookie) {
|
||||||
|
AMessage.warning('请填写Cookie值');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
isEdit.value ? handleEditAccount() : handleAddAccount();
|
isEdit.value ? handleEditAccount() : handleAddAccount();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<!-- 完成状态 -->
|
<!-- 完成状态 -->
|
||||||
<template v-if="modalState === MODAL_STATE.SUCCESS || modalState === MODAL_STATE.FAILED">
|
<template v-if="[MODAL_STATE.SUCCESS, MODAL_STATE.FAILED].includes(modalState)">
|
||||||
<img :src="modalState === MODAL_STATE.SUCCESS ? icon2 : icon3" width="80" height="80" class="mb-16px" />
|
<img :src="modalState === MODAL_STATE.SUCCESS ? icon2 : icon3" width="80" height="80" class="mb-16px" />
|
||||||
<p class="s2">{{ `数据初始化${modalState === MODAL_STATE.SUCCESS ? '成功' : '失败'}。` }}</p>
|
<p class="s2">{{ `数据初始化${modalState === MODAL_STATE.SUCCESS ? '成功' : '失败'}。` }}</p>
|
||||||
<p v-if="modalState === MODAL_STATE.FAILED" class="red-text">失败原因:{{ failReason || '-' }}</p>
|
<p v-if="modalState === MODAL_STATE.FAILED" class="red-text">失败原因:{{ failReason || '-' }}</p>
|
||||||
@ -61,10 +61,8 @@
|
|||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- 正常二维码 -->
|
<!-- 正常二维码 -->
|
||||||
<a-image v-else :src="qrCodeUrl" width="160" height="160" />
|
<a-image v-else :src="qrCodeUrl" width="160" height="160" />
|
||||||
|
|
||||||
<!-- 二维码失效遮罩 -->
|
<!-- 二维码失效遮罩 -->
|
||||||
<div v-if="modalState === MODAL_STATE.QR_EXPIRED" class="mask cursor-pointer" @click="handleRefreshQrCode">
|
<div v-if="modalState === MODAL_STATE.QR_EXPIRED" class="mask cursor-pointer" @click="handleRefreshQrCode">
|
||||||
<icon-refresh size="24" class="mb-13px" />
|
<icon-refresh size="24" class="mb-13px" />
|
||||||
@ -82,7 +80,7 @@
|
|||||||
重新生成
|
重新生成
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button
|
<a-button
|
||||||
v-if="modalState === MODAL_STATE.SUCCESS || modalState === MODAL_STATE.FAILED"
|
v-if="[MODAL_STATE.SUCCESS, MODAL_STATE.FAILED].includes(modalState)"
|
||||||
size="large"
|
size="large"
|
||||||
class="cancel-btn"
|
class="cancel-btn"
|
||||||
@click="close"
|
@click="close"
|
||||||
@ -94,12 +92,15 @@
|
|||||||
</a-button>
|
</a-button>
|
||||||
</template>
|
</template>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
|
||||||
|
<SyncDataModal ref="syncDataModalRef" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineExpose, ref, computed } from 'vue';
|
import { defineExpose, ref, computed } from 'vue';
|
||||||
import { Message as AMessage } from '@arco-design/web-vue';
|
import { Message as AMessage } from '@arco-design/web-vue';
|
||||||
import { getAuthorizedImage, getMediaAccountsAuthorizedStatus } from '@/api/all/propertyMarketing';
|
import { getAuthorizedImage, getMediaAccountsAuthorizedStatus } from '@/api/all/propertyMarketing';
|
||||||
|
import SyncDataModal from '../sync-data-modal';
|
||||||
|
|
||||||
import icon1 from '@/assets/img/media-account/icon-default-qrcode.png';
|
import icon1 from '@/assets/img/media-account/icon-default-qrcode.png';
|
||||||
import icon2 from '@/assets/img/media-account/icon-feedback-success.png';
|
import icon2 from '@/assets/img/media-account/icon-feedback-success.png';
|
||||||
@ -127,6 +128,7 @@ const progress = ref(0);
|
|||||||
const id = ref('');
|
const id = ref('');
|
||||||
const platform = ref('');
|
const platform = ref('');
|
||||||
const qrCodeUrl = ref('');
|
const qrCodeUrl = ref('');
|
||||||
|
const syncDataModalRef = ref(null);
|
||||||
|
|
||||||
let progressTimer = null;
|
let progressTimer = null;
|
||||||
let overdueTimer = null;
|
let overdueTimer = null;
|
||||||
@ -140,7 +142,7 @@ const confirmBtnText = computed(() => {
|
|||||||
[MODAL_STATE.QR_READY]: '完成扫码',
|
[MODAL_STATE.QR_READY]: '完成扫码',
|
||||||
[MODAL_STATE.QR_EXPIRED]: '重新生成',
|
[MODAL_STATE.QR_EXPIRED]: '重新生成',
|
||||||
[MODAL_STATE.LOADING]: '处理中...',
|
[MODAL_STATE.LOADING]: '处理中...',
|
||||||
[MODAL_STATE.SUCCESS]: '继续添加',
|
[MODAL_STATE.SUCCESS]: '确认添加',
|
||||||
[MODAL_STATE.FAILED]: '重新扫码',
|
[MODAL_STATE.FAILED]: '重新扫码',
|
||||||
};
|
};
|
||||||
return btnTextMap[modalState.value] || '确定';
|
return btnTextMap[modalState.value] || '确定';
|
||||||
@ -299,6 +301,7 @@ const handleOk = () => {
|
|||||||
|
|
||||||
// 授权成功,关闭弹窗
|
// 授权成功,关闭弹窗
|
||||||
if (modalState.value === MODAL_STATE.SUCCESS) {
|
if (modalState.value === MODAL_STATE.SUCCESS) {
|
||||||
|
syncDataModalRef.value.open(id.value);
|
||||||
close();
|
close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -108,12 +108,15 @@
|
|||||||
</a-button>
|
</a-button>
|
||||||
</template>
|
</template>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
|
||||||
|
<SyncDataModal ref="syncDataModalRef" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineExpose, ref, computed } from 'vue';
|
import { defineExpose, ref, computed } from 'vue';
|
||||||
import { Message as AMessage } from '@arco-design/web-vue';
|
import { Message as AMessage } from '@arco-design/web-vue';
|
||||||
import { getMediaAccountsAuthorizedStatus, getAuthorizedImage } from '@/api/all/propertyMarketing';
|
import { getMediaAccountsAuthorizedStatus, getAuthorizedImage } from '@/api/all/propertyMarketing';
|
||||||
|
import SyncDataModal from '../sync-data-modal';
|
||||||
|
|
||||||
import icon1 from '@/assets/img/media-account/icon-default-qrcode.png';
|
import icon1 from '@/assets/img/media-account/icon-default-qrcode.png';
|
||||||
import icon2 from '@/assets/img/media-account/icon-feedback-success.png';
|
import icon2 from '@/assets/img/media-account/icon-feedback-success.png';
|
||||||
@ -142,6 +145,7 @@ const id = ref('');
|
|||||||
const platform = ref('');
|
const platform = ref('');
|
||||||
const qrCodeUrl = ref('');
|
const qrCodeUrl = ref('');
|
||||||
const isNicknameChanged = ref(false); // 昵称发生变化
|
const isNicknameChanged = ref(false); // 昵称发生变化
|
||||||
|
const syncDataModalRef = ref(null);
|
||||||
|
|
||||||
let progressTimer = null;
|
let progressTimer = null;
|
||||||
let overdueTimer = null;
|
let overdueTimer = null;
|
||||||
@ -155,7 +159,7 @@ const confirmBtnText = computed(() => {
|
|||||||
[MODAL_STATE.QR_READY]: '完成扫码',
|
[MODAL_STATE.QR_READY]: '完成扫码',
|
||||||
[MODAL_STATE.QR_EXPIRED]: '重新生成',
|
[MODAL_STATE.QR_EXPIRED]: '重新生成',
|
||||||
[MODAL_STATE.LOADING]: '处理中...',
|
[MODAL_STATE.LOADING]: '处理中...',
|
||||||
[MODAL_STATE.SUCCESS]: isNicknameChanged.value ? '确定覆盖' : '继续添加',
|
[MODAL_STATE.SUCCESS]: isNicknameChanged.value ? '确定覆盖' : '确认添加',
|
||||||
[MODAL_STATE.FAILED]: '重新扫码',
|
[MODAL_STATE.FAILED]: '重新扫码',
|
||||||
};
|
};
|
||||||
return btnTextMap[modalState.value] || '确定';
|
return btnTextMap[modalState.value] || '确定';
|
||||||
@ -318,6 +322,7 @@ const handleOk = () => {
|
|||||||
console.log('确定覆盖');
|
console.log('确定覆盖');
|
||||||
// 这里可以添加覆盖逻辑
|
// 这里可以添加覆盖逻辑
|
||||||
} else {
|
} else {
|
||||||
|
syncDataModalRef.value.open(id.value);
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -0,0 +1,58 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: RenXiaoDong
|
||||||
|
* @Date: 2025-06-25 17:51:46
|
||||||
|
-->
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
v-model:visible="visible"
|
||||||
|
width="480px"
|
||||||
|
title="更新数据"
|
||||||
|
modal-class="sync-data-modal"
|
||||||
|
:mask-closable="false"
|
||||||
|
@close="close"
|
||||||
|
>
|
||||||
|
<div class="flex flex-col items-center">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<img :src="icon1" width="20" height="20" class="mr-12px" />
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<p class="tip">为确保数据准确,建议立即同步账号数据。您也可以在账号管理列表中手动触发更新。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<template #footer>
|
||||||
|
<a-button size="large" class="cancel-btn" @click="close">稍后再说</a-button>
|
||||||
|
<a-button type="primary" size="large" @click="handleOk"> 更新数据 </a-button>
|
||||||
|
</template>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { defineExpose } from 'vue';
|
||||||
|
|
||||||
|
import icon1 from '@/assets/img/media-account/icon-warn-1.png';
|
||||||
|
|
||||||
|
const handleSyncData = inject('handleSyncData');
|
||||||
|
|
||||||
|
const id = ref('');
|
||||||
|
|
||||||
|
const visible = ref(false);
|
||||||
|
const open = (accountId) => {
|
||||||
|
id.value = accountId;
|
||||||
|
visible.value = true;
|
||||||
|
};
|
||||||
|
const close = () => {
|
||||||
|
id.value = '';
|
||||||
|
visible.value = false;
|
||||||
|
};
|
||||||
|
const handleOk = () => {
|
||||||
|
handleSyncData({ id: id.value });
|
||||||
|
close();
|
||||||
|
};
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import './style.scss';
|
||||||
|
</style>
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
@import "@/views/property-marketing/component.scss";
|
||||||
|
.sync-data-modal {
|
||||||
|
border-radius: 8px;
|
||||||
|
.arco-modal-body {
|
||||||
|
.tip {
|
||||||
|
color: var(--Text-1, #211f24);
|
||||||
|
font-family: $font-family-regular;
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 22px; /* 157.143% */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -51,6 +51,9 @@
|
|||||||
个账号
|
个账号
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
<span class="operation-btn" :class="{ disabled: isDisabledBatchSyncData }" @click="handleBatchSyncData"
|
||||||
|
>批量更新数据</span
|
||||||
|
>
|
||||||
<span class="operation-btn" @click="handleBatchTag">批量标签</span>
|
<span class="operation-btn" @click="handleBatchTag">批量标签</span>
|
||||||
<span class="operation-btn" @click="handleBatchGroup">批量分组</span>
|
<span class="operation-btn" @click="handleBatchGroup">批量分组</span>
|
||||||
<span class="operation-btn red" @click="handleBatchDelete"> 批量删除 </span>
|
<span class="operation-btn red" @click="handleBatchDelete"> 批量删除 </span>
|
||||||
@ -111,7 +114,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
import { ref, provide } from 'vue';
|
||||||
|
|
||||||
import FilterBlock from './components/filter-block';
|
import FilterBlock from './components/filter-block';
|
||||||
import AccountTable from './components/account-table';
|
import AccountTable from './components/account-table';
|
||||||
@ -121,9 +124,17 @@ import AddAccountModal from './components/add-account-modal';
|
|||||||
import DeleteAccountModal from './components/account-table/delete-account';
|
import DeleteAccountModal from './components/account-table/delete-account';
|
||||||
import BatchTagModal from './components/batch-tag-modal';
|
import BatchTagModal from './components/batch-tag-modal';
|
||||||
import BatchGroupModal from './components/batch-group-modal';
|
import BatchGroupModal from './components/batch-group-modal';
|
||||||
|
import { Notification } from '@arco-design/web-vue';
|
||||||
|
|
||||||
import { INITIAL_QUERY, INITIAL_PAGE_INFO } from './constants';
|
import { INITIAL_QUERY, INITIAL_PAGE_INFO } from './constants';
|
||||||
import { getMediaAccounts, getMediaAccountsHealth } from '@/api/all/propertyMarketing';
|
import { EnumStatus } from '@/views/property-marketing/media-account/components/status-select/constants';
|
||||||
|
import {
|
||||||
|
getMediaAccounts,
|
||||||
|
getMediaAccountsHealth,
|
||||||
|
postSyncMediaAccountData,
|
||||||
|
postBatchSyncMediaAccountData,
|
||||||
|
getMediaAccountSyncStatus,
|
||||||
|
} from '@/api/all/propertyMarketing';
|
||||||
|
|
||||||
import icon1 from '@/assets/img/media-account/icon-add.png';
|
import icon1 from '@/assets/img/media-account/icon-add.png';
|
||||||
import icon2 from '@/assets/img/media-account/icon-group.png';
|
import icon2 from '@/assets/img/media-account/icon-group.png';
|
||||||
@ -132,6 +143,8 @@ import icon4 from '@/assets/img/media-account/icon-success.png';
|
|||||||
import icon5 from '@/assets/img/media-account/icon-warn.png';
|
import icon5 from '@/assets/img/media-account/icon-warn.png';
|
||||||
import icon6 from '@/assets/img/media-account/icon-close.png';
|
import icon6 from '@/assets/img/media-account/icon-close.png';
|
||||||
|
|
||||||
|
let syncDataTimer = null;
|
||||||
|
|
||||||
const groupManageModalRef = ref(null);
|
const groupManageModalRef = ref(null);
|
||||||
const tagsManageModalRef = ref(null);
|
const tagsManageModalRef = ref(null);
|
||||||
const addAccountModalRef = ref(null);
|
const addAccountModalRef = ref(null);
|
||||||
@ -145,8 +158,10 @@ const query = ref(cloneDeep(INITIAL_QUERY));
|
|||||||
const dataSource = ref([]);
|
const dataSource = ref([]);
|
||||||
const selectedItems = ref([]);
|
const selectedItems = ref([]);
|
||||||
const healthData = ref({});
|
const healthData = ref({});
|
||||||
|
const startSyncData = ref(false);
|
||||||
|
|
||||||
const isAbNormalStatus = computed(() => healthData.value?.total_abnormal_number > 0);
|
const isAbNormalStatus = computed(() => healthData.value?.total_abnormal_number > 0);
|
||||||
|
const isDisabledBatchSyncData = computed(() => selectedItems.value.some((item) => item.status !== EnumStatus.NORMAL));
|
||||||
|
|
||||||
const checkedAll = computed(() => selectedItems.value.length === dataSource.value.length);
|
const checkedAll = computed(() => selectedItems.value.length === dataSource.value.length);
|
||||||
const indeterminate = computed(
|
const indeterminate = computed(
|
||||||
@ -180,10 +195,6 @@ const tipLabel = computed(() => {
|
|||||||
return `共有 ${total_abnormal_number} 个账号存在授权异常,其中:${abnormalLabels.join(',')}。`;
|
return `共有 ${total_abnormal_number} 个账号存在授权异常,其中:${abnormalLabels.join(',')}。`;
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
getData();
|
|
||||||
});
|
|
||||||
|
|
||||||
const getData = () => {
|
const getData = () => {
|
||||||
getHealthData();
|
getHealthData();
|
||||||
getAccountData();
|
getAccountData();
|
||||||
@ -262,10 +273,54 @@ const handleDelete = (item) => {
|
|||||||
const handleCloseTip = () => {
|
const handleCloseTip = () => {
|
||||||
selectedItems.value = [];
|
selectedItems.value = [];
|
||||||
};
|
};
|
||||||
|
const startSyncDataPolling = () => {
|
||||||
|
startSyncData.value = true;
|
||||||
|
clearSyncDataTimer();
|
||||||
|
|
||||||
|
syncDataTimer = setInterval(async () => {
|
||||||
|
const { code, data } = await getMediaAccountSyncStatus();
|
||||||
|
if (code === 200) {
|
||||||
|
// 所有任务都结束了,才停止轮询,刷新页面
|
||||||
|
const isEnd = data.every((item) => item.status !== 0);
|
||||||
|
if (isEnd) {
|
||||||
|
clearSyncDataTimer();
|
||||||
|
startSyncData.value = false;
|
||||||
|
|
||||||
|
getData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSyncData = async (item) => {
|
||||||
|
Notification.info({
|
||||||
|
title: '账号正在同步数据。',
|
||||||
|
});
|
||||||
|
|
||||||
|
const { code } = await postSyncMediaAccountData(item.id);
|
||||||
|
if (code === 200) {
|
||||||
|
if (!startSyncData.value) {
|
||||||
|
startSyncDataPolling();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleBatchTag = () => {
|
const handleBatchTag = () => {
|
||||||
batchTagModalRef.value?.open(selectedItems.value);
|
batchTagModalRef.value?.open(selectedItems.value);
|
||||||
};
|
};
|
||||||
|
const handleBatchSyncData = async () => {
|
||||||
|
if (isDisabledBatchSyncData.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ids = selectedItems.value.map((item) => item.id);
|
||||||
|
const { code } = await postBatchSyncMediaAccountData({ ids });
|
||||||
|
if (code === 200) {
|
||||||
|
if (!startSyncData.value) {
|
||||||
|
startSyncDataPolling();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
const handleBatchGroup = () => {
|
const handleBatchGroup = () => {
|
||||||
batchGroupModalRef.value?.open(selectedItems.value);
|
batchGroupModalRef.value?.open(selectedItems.value);
|
||||||
};
|
};
|
||||||
@ -277,6 +332,21 @@ const handleOpenAbnormalAccount = () => {
|
|||||||
query.value.status = 2;
|
query.value.status = 2;
|
||||||
reload();
|
reload();
|
||||||
};
|
};
|
||||||
|
const clearSyncDataTimer = () => {
|
||||||
|
if (syncDataTimer) {
|
||||||
|
clearInterval(syncDataTimer);
|
||||||
|
syncDataTimer = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getData();
|
||||||
|
});
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearSyncDataTimer();
|
||||||
|
});
|
||||||
|
|
||||||
|
provide('handleSyncData', handleSyncData);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@ -60,7 +60,7 @@
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
color: var(--Brand-Brand-6, #6d4cfe);
|
color: var(--Brand-Brand-6, #6d4cfe);
|
||||||
font-family: $font-family-medium;
|
font-family: $font-family-regular;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
@ -71,6 +71,10 @@
|
|||||||
&.red {
|
&.red {
|
||||||
color: #F64B31;
|
color: #F64B31;
|
||||||
}
|
}
|
||||||
|
&.disabled {
|
||||||
|
color: #C5B7FF;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.card-wrap {
|
.card-wrap {
|
||||||
|
|||||||
Reference in New Issue
Block a user