Merge remote-tracking branch 'origin/feature/v1.3_营销资产中台' into feature/v1.3_营销资产中台
This commit is contained in:
@ -1,30 +1,30 @@
|
|||||||
@font-face {
|
// @font-face {
|
||||||
font-family: 'PuHuiTi-Regular';
|
// font-family: 'PuHuiTi-Regular';
|
||||||
src: url('@/assets/fonts/Alibaba-PuHuiTi-Regular.woff2') format('woff2');
|
// src: url('@/assets/fonts/Alibaba-PuHuiTi-Regular.woff2') format('woff2');
|
||||||
font-display: swap;
|
// font-display: swap;
|
||||||
}
|
// }
|
||||||
|
|
||||||
@font-face {
|
// @font-face {
|
||||||
font-family: 'PuHuiTi-Medium';
|
// font-family: 'PuHuiTi-Medium';
|
||||||
src: url('@/assets/fonts/Alibaba-PuHuiTi-Medium.woff2') format('woff2');
|
// src: url('@/assets/fonts/Alibaba-PuHuiTi-Medium.woff2') format('woff2');
|
||||||
font-display: swap;
|
// font-display: swap;
|
||||||
}
|
// }
|
||||||
|
|
||||||
@font-face {
|
// @font-face {
|
||||||
font-family: 'PuHuiTi-Bold';
|
// font-family: 'PuHuiTi-Bold';
|
||||||
src: url('@/assets/fonts/Alibaba-PuHuiTi-Bold.woff2') format('woff2');
|
// src: url('@/assets/fonts/Alibaba-PuHuiTi-Bold.woff2') format('woff2');
|
||||||
font-display: swap;
|
// font-display: swap;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// 使用统一的字体族名
|
// // 使用统一的字体族名
|
||||||
.font-family-puhui-regular {
|
// .font-family-puhui-regular {
|
||||||
font-family: 'PuHuiTi-Regular' !important;
|
// font-family: 'PuHuiTi-Regular' !important;
|
||||||
}
|
// }
|
||||||
|
|
||||||
.font-family-puhui-medium {
|
// .font-family-puhui-medium {
|
||||||
font-family: 'PuHuiTi-Medium' !important;
|
// font-family: 'PuHuiTi-Medium' !important;
|
||||||
}
|
// }
|
||||||
|
|
||||||
.font-family-puhui-bold {
|
// .font-family-puhui-bold {
|
||||||
font-family: 'PuHuiTi-Bold' !important;
|
// font-family: 'PuHuiTi-Bold' !important;
|
||||||
}
|
// }
|
||||||
|
|||||||
@ -9,11 +9,12 @@
|
|||||||
title="授权账号"
|
title="授权账号"
|
||||||
modal-class="authorized-account-modal"
|
modal-class="authorized-account-modal"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
:footer="!isLoading"
|
:footer="modalState !== MODAL_STATE.LOADING"
|
||||||
@close="close"
|
@close="close"
|
||||||
>
|
>
|
||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<template v-if="isLoading">
|
<!-- 加载中状态 -->
|
||||||
|
<template v-if="modalState === MODAL_STATE.LOADING">
|
||||||
<a-progress
|
<a-progress
|
||||||
:percent="progress"
|
:percent="progress"
|
||||||
color="#6D4CFE"
|
color="#6D4CFE"
|
||||||
@ -24,32 +25,48 @@
|
|||||||
/>
|
/>
|
||||||
<p class="s2 mt-16px">数据同步和初始化中,请勿关闭窗口。</p>
|
<p class="s2 mt-16px">数据同步和初始化中,请勿关闭窗口。</p>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<template v-if="isCompleted">
|
<!-- 完成状态 -->
|
||||||
<img :src="isSuccess ? icon2 : icon3" width="80" height="80" class="mb-16px" />
|
<template v-if="modalState === MODAL_STATE.SUCCESS || modalState === MODAL_STATE.FAILED">
|
||||||
<p class="s2">{{ `数据初始化${isSuccess ? '成功' : '失败'}。` }}</p>
|
<img :src="modalState === MODAL_STATE.SUCCESS ? icon2 : icon3" width="80" height="80" class="mb-16px" />
|
||||||
<p v-if="!isSuccess" class="red-text">失败原因:{{ failReason || '-' }}</p>
|
<p class="s2">{{ `数据初始化${modalState === MODAL_STATE.SUCCESS ? '成功' : '失败'}。` }}</p>
|
||||||
|
<p v-if="modalState === MODAL_STATE.FAILED" class="red-text">失败原因:{{ failReason || '-' }}</p>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- 二维码状态 -->
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="img-box">
|
<div class="img-box">
|
||||||
<template v-if="qrCodeLoading || isFailLoadQrCode">
|
<!-- 二维码加载中或失败 -->
|
||||||
|
<template v-if="modalState === MODAL_STATE.QR_LOADING || modalState === MODAL_STATE.QR_FAILED">
|
||||||
<div class="relative w-160px h-160px">
|
<div class="relative w-160px h-160px">
|
||||||
<a-image :src="icon1" width="160" height="160" />
|
<a-image :src="icon1" width="160" height="160" />
|
||||||
<div class="absolute top-0 left-0 z-2 w-full h-full flex flex-col items-center justify-center">
|
<div class="absolute top-0 left-0 z-2 w-full h-full flex flex-col items-center justify-center">
|
||||||
<img v-if="isFailLoadQrCode" :src="icon4" width="24" height="24" class="mb-13px" />
|
<img
|
||||||
|
v-if="modalState === MODAL_STATE.QR_FAILED"
|
||||||
|
:src="icon4"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
class="mb-13px"
|
||||||
|
/>
|
||||||
<icon-loading v-else size="24" class="color-#6D4CFE mb-13px" />
|
<icon-loading v-else size="24" class="color-#6D4CFE mb-13px" />
|
||||||
<span :class="isFailLoadQrCode ? '!color-#F64B31' : '!color-#6D4CFE'" class="s2">{{
|
<span
|
||||||
isFailLoadQrCode ? '二维码生成失败' : '二维码生成中...'
|
:class="modalState === MODAL_STATE.QR_FAILED ? '!color-#F64B31' : '!color-#6D4CFE'"
|
||||||
}}</span>
|
class="s2"
|
||||||
|
>{{ modalState === MODAL_STATE.QR_FAILED ? '二维码生成失败' : '二维码生成中...' }}</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="absolute top-0 left-0 w-full h-full flex items-center justify-center opacity-80 bg-#fff"
|
class="absolute top-0 left-0 w-full h-full flex items-center justify-center opacity-80 bg-#fff"
|
||||||
></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="isOverdue" 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" />
|
||||||
<p class="s1">二维码失效</p>
|
<p class="s1">二维码失效</p>
|
||||||
<p class="s1">请点击刷新</p>
|
<p class="s1">请点击刷新</p>
|
||||||
@ -59,15 +76,29 @@
|
|||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<a-button v-if="isCompleted" size="large" class="cancel-btn" @click="close">取消</a-button>
|
<a-button v-if="modalState === MODAL_STATE.QR_READY" size="large" class="cancel-btn" @click="handleRefreshQrCode">
|
||||||
<a-button type="primary" size="large" @click="handleOk">{{ confirmBtnText }} </a-button>
|
重新生成
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
v-if="modalState === MODAL_STATE.SUCCESS || modalState === MODAL_STATE.FAILED"
|
||||||
|
size="large"
|
||||||
|
class="cancel-btn"
|
||||||
|
@click="close"
|
||||||
|
>
|
||||||
|
取消
|
||||||
|
</a-button>
|
||||||
|
<a-button type="primary" size="large" @click="handleOk">
|
||||||
|
{{ confirmBtnText }}
|
||||||
|
</a-button>
|
||||||
</template>
|
</template>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineExpose, ref } from 'vue';
|
import { defineExpose, ref, computed } from '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 icon1 from '@/assets/img/media-account/icon-default-qrcode.png';
|
import icon1 from '@/assets/img/media-account/icon-default-qrcode.png';
|
||||||
@ -75,52 +106,67 @@ import icon2 from '@/assets/img/media-account/icon-feedback-success.png';
|
|||||||
import icon3 from '@/assets/img/media-account/icon-feedback-fail.png';
|
import icon3 from '@/assets/img/media-account/icon-feedback-fail.png';
|
||||||
import icon4 from '@/assets/img/media-account/icon-warn.png';
|
import icon4 from '@/assets/img/media-account/icon-warn.png';
|
||||||
|
|
||||||
// 失效时间
|
|
||||||
|
|
||||||
const emits = defineEmits(['update']);
|
const emits = defineEmits(['update']);
|
||||||
|
|
||||||
const OVERDUE_TIME = 30000;
|
// 状态枚举
|
||||||
|
const MODAL_STATE = {
|
||||||
|
QR_LOADING: 0, // 二维码加载中
|
||||||
|
QR_FAILED: 1, // 二维码生成失败
|
||||||
|
QR_READY: 2, // 二维码就绪,等待扫码
|
||||||
|
QR_EXPIRED: 3, // 二维码已过期
|
||||||
|
LOADING: 4, // 数据同步中
|
||||||
|
SUCCESS: 5, // 授权成功
|
||||||
|
FAILED: 6, // 授权失败
|
||||||
|
};
|
||||||
|
|
||||||
|
const OVERDUE_TIME = 30000; // 失效时间
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
const isOverdue = ref(false); // 二维码失效
|
const modalState = ref(MODAL_STATE.QR_LOADING);
|
||||||
const isLoading = ref(false);
|
|
||||||
const isCompleted = ref(false);
|
|
||||||
const isSuccess = ref(false);
|
|
||||||
const failReason = ref('');
|
const failReason = ref('');
|
||||||
const progress = ref(0);
|
const progress = ref(0);
|
||||||
const id = ref('');
|
const id = ref('');
|
||||||
const platform = ref('');
|
const platform = ref('');
|
||||||
const isFailLoadQrCode = ref(false);
|
|
||||||
const qrCodeUrl = ref('');
|
const qrCodeUrl = ref('');
|
||||||
const qrCodeLoading = ref(false);
|
|
||||||
|
|
||||||
let progressTimer = null;
|
let progressTimer = null;
|
||||||
let overdueTimer = null;
|
let overdueTimer = null;
|
||||||
let statusPollingTimer = null;
|
let statusPollingTimer = null;
|
||||||
|
|
||||||
|
// 按钮文案映射
|
||||||
const confirmBtnText = computed(() => {
|
const confirmBtnText = computed(() => {
|
||||||
if (isFailLoadQrCode.value) return '重新生成';
|
const btnTextMap = {
|
||||||
if (!isCompleted.value) return '完成扫码';
|
[MODAL_STATE.QR_LOADING]: '完成扫码',
|
||||||
return isSuccess.value ? '继续添加' : '重新扫码';
|
[MODAL_STATE.QR_FAILED]: '重新生成',
|
||||||
|
[MODAL_STATE.QR_READY]: '完成扫码',
|
||||||
|
[MODAL_STATE.QR_EXPIRED]: '重新生成',
|
||||||
|
[MODAL_STATE.LOADING]: '处理中...',
|
||||||
|
[MODAL_STATE.SUCCESS]: '继续添加',
|
||||||
|
[MODAL_STATE.FAILED]: '重新扫码',
|
||||||
|
};
|
||||||
|
return btnTextMap[modalState.value] || '确定';
|
||||||
|
});
|
||||||
|
|
||||||
|
// 按钮是否禁用
|
||||||
|
const isBtnDisabled = computed(() => {
|
||||||
|
return false; // 所有状态下按钮都是可点击的
|
||||||
});
|
});
|
||||||
|
|
||||||
const open = (accountId, platformCode) => {
|
const open = (accountId, platformCode) => {
|
||||||
id.value = accountId;
|
id.value = accountId;
|
||||||
platform.value = platformCode === 0 ? '抖音' : '小红书';
|
platform.value = platformCode === 0 ? '抖音' : '小红书';
|
||||||
|
modalState.value = MODAL_STATE.QR_LOADING;
|
||||||
getAuthorizedQrCode();
|
getAuthorizedQrCode();
|
||||||
visible.value = true;
|
visible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetTaskFields = () => {
|
const resetTaskFields = () => {
|
||||||
isOverdue.value = false;
|
modalState.value = MODAL_STATE.QR_LOADING;
|
||||||
isLoading.value = false;
|
|
||||||
isCompleted.value = false;
|
|
||||||
isSuccess.value = false;
|
|
||||||
failReason.value = '';
|
failReason.value = '';
|
||||||
platform.value = '';
|
platform.value = '';
|
||||||
progress.value = 0;
|
progress.value = 0;
|
||||||
qrCodeUrl.value = '';
|
qrCodeUrl.value = '';
|
||||||
qrCodeLoading.value = false;
|
|
||||||
isFailLoadQrCode.value = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const close = () => {
|
const close = () => {
|
||||||
resetTaskFields();
|
resetTaskFields();
|
||||||
id.value = '';
|
id.value = '';
|
||||||
@ -132,24 +178,22 @@ const close = () => {
|
|||||||
|
|
||||||
const getAuthorizedQrCode = async () => {
|
const getAuthorizedQrCode = async () => {
|
||||||
try {
|
try {
|
||||||
qrCodeLoading.value = true;
|
modalState.value = MODAL_STATE.QR_LOADING;
|
||||||
const { code, data } = await getAuthorizedImage(id.value);
|
const { code, data } = await getAuthorizedImage(id.value);
|
||||||
if (code === 200) {
|
if (code === 200) {
|
||||||
qrCodeUrl.value = data.image;
|
qrCodeUrl.value = data.image;
|
||||||
overdueTimer = null;
|
overdueTimer = null;
|
||||||
isOverdue.value = false;
|
modalState.value = MODAL_STATE.QR_READY;
|
||||||
|
|
||||||
// 约定:后端限制40s内必须扫码,前端定30s后失效
|
// 约定:后端限制40s内必须扫码,前端定30s后失效
|
||||||
overdueTimer = setTimeout(() => {
|
overdueTimer = setTimeout(() => {
|
||||||
isOverdue.value = true;
|
modalState.value = MODAL_STATE.QR_EXPIRED;
|
||||||
}, OVERDUE_TIME);
|
}, OVERDUE_TIME);
|
||||||
} else {
|
} else {
|
||||||
isFailLoadQrCode.value = true;
|
modalState.value = MODAL_STATE.QR_FAILED;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
isFailLoadQrCode.value = true;
|
modalState.value = MODAL_STATE.QR_FAILED;
|
||||||
} finally {
|
|
||||||
qrCodeLoading.value = false;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -163,22 +207,14 @@ const clearStatusPollingTimer = () => {
|
|||||||
const startStatusPolling = () => {
|
const startStatusPolling = () => {
|
||||||
clearStatusPollingTimer();
|
clearStatusPollingTimer();
|
||||||
statusPollingTimer = setInterval(async () => {
|
statusPollingTimer = setInterval(async () => {
|
||||||
if (!isCompleted.value) {
|
if (modalState.value === MODAL_STATE.LOADING) {
|
||||||
await getAuthorizedStatus();
|
await getAuthorizedStatus();
|
||||||
if (isCompleted.value) {
|
|
||||||
progress.value = 1;
|
|
||||||
clearFakeProgressTimer();
|
|
||||||
clearStatusPollingTimer();
|
|
||||||
isLoading.value = false;
|
|
||||||
emits('update');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, 2000);
|
}, 2000);
|
||||||
};
|
};
|
||||||
|
|
||||||
const startLoading = async () => {
|
const startLoading = async () => {
|
||||||
isLoading.value = true;
|
modalState.value = MODAL_STATE.LOADING;
|
||||||
isCompleted.value = false;
|
|
||||||
progress.value = 0;
|
progress.value = 0;
|
||||||
startFakeProgressPolling();
|
startFakeProgressPolling();
|
||||||
startStatusPolling();
|
startStatusPolling();
|
||||||
@ -189,10 +225,18 @@ const getAuthorizedStatus = async () => {
|
|||||||
if (code === 200) {
|
if (code === 200) {
|
||||||
const { status, message } = data;
|
const { status, message } = data;
|
||||||
if (status !== 0) {
|
if (status !== 0) {
|
||||||
isCompleted.value = true;
|
progress.value = 1;
|
||||||
isSuccess.value = status === 1;
|
clearFakeProgressTimer();
|
||||||
failReason.value = status === 2 ? message : '';
|
clearStatusPollingTimer();
|
||||||
isOverdue.value = false;
|
|
||||||
|
if (status === 1) {
|
||||||
|
modalState.value = MODAL_STATE.SUCCESS;
|
||||||
|
} else {
|
||||||
|
modalState.value = MODAL_STATE.FAILED;
|
||||||
|
failReason.value = message || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
emits('update');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -200,11 +244,11 @@ const getAuthorizedStatus = async () => {
|
|||||||
const startFakeProgressPolling = () => {
|
const startFakeProgressPolling = () => {
|
||||||
clearFakeProgressTimer();
|
clearFakeProgressTimer();
|
||||||
progressTimer = setInterval(() => {
|
progressTimer = setInterval(() => {
|
||||||
if (!isCompleted.value && progress.value < 0.99) {
|
if (modalState.value === MODAL_STATE.LOADING && progress.value < 0.99) {
|
||||||
const step = Math.random() * 0.04 + 0.01;
|
const step = Math.random() * 0.04 + 0.01;
|
||||||
progress.value = Math.min(progress.value + step, 0.99);
|
progress.value = Math.min(progress.value + step, 0.99);
|
||||||
progress.value = Number(progress.value.toFixed(2));
|
progress.value = Number(progress.value.toFixed(2));
|
||||||
} else if (!isCompleted.value && progress.value >= 0.99) {
|
} else if (modalState.value === MODAL_STATE.LOADING && progress.value >= 0.99) {
|
||||||
progress.value = 0.99; // 卡在99%
|
progress.value = 0.99; // 卡在99%
|
||||||
} else {
|
} else {
|
||||||
clearFakeProgressTimer();
|
clearFakeProgressTimer();
|
||||||
@ -219,44 +263,57 @@ const clearFakeProgressTimer = () => {
|
|||||||
progressTimer = null;
|
progressTimer = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const clearOverdueTimer = () => {
|
const clearOverdueTimer = () => {
|
||||||
if (overdueTimer) {
|
if (overdueTimer) {
|
||||||
clearTimeout(overdueTimer);
|
clearTimeout(overdueTimer);
|
||||||
overdueTimer = null;
|
overdueTimer = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 重新扫码
|
// 重新扫码
|
||||||
const handleRefreshQrCode = () => {
|
const handleRefreshQrCode = () => {
|
||||||
|
clearOverdueTimer();
|
||||||
resetTaskFields();
|
resetTaskFields();
|
||||||
getAuthorizedQrCode();
|
getAuthorizedQrCode();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
if (isFailLoadQrCode.value) {
|
// 二维码已过期
|
||||||
|
if (modalState.value === MODAL_STATE.QR_EXPIRED) {
|
||||||
handleRefreshQrCode();
|
handleRefreshQrCode();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!qrCodeUrl.value) {
|
// 二维码还在加载中
|
||||||
|
if (modalState.value === MODAL_STATE.QR_LOADING) {
|
||||||
AMessage.warning('二维码生成中,请稍等');
|
AMessage.warning('二维码生成中,请稍等');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isOverdue.value) {
|
// 二维码生成失败
|
||||||
AMessage.error('二维码已失效,请重新扫码');
|
if (modalState.value === MODAL_STATE.QR_FAILED) {
|
||||||
|
handleRefreshQrCode();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isCompleted.value) {
|
// 授权成功,关闭弹窗
|
||||||
clearOverdueTimer();
|
if (modalState.value === MODAL_STATE.SUCCESS) {
|
||||||
|
close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isSuccess.value) {
|
// 授权失败,重新扫码
|
||||||
close();
|
if (modalState.value === MODAL_STATE.FAILED) {
|
||||||
} else {
|
handleRefreshQrCode();
|
||||||
handleRefreshQrCode();
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
|
// 二维码就绪,开始授权流程
|
||||||
|
if (modalState.value === MODAL_STATE.QR_READY) {
|
||||||
|
clearOverdueTimer();
|
||||||
startLoading();
|
startLoading();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -9,56 +9,12 @@
|
|||||||
title="重新授权"
|
title="重新授权"
|
||||||
modal-class="reauthorize-account-modal"
|
modal-class="reauthorize-account-modal"
|
||||||
:mask-closable="false"
|
:mask-closable="false"
|
||||||
:footer="taskStep !== TASK_STEP.loading"
|
:footer="modalState !== MODAL_STATE.LOADING"
|
||||||
@close="close"
|
@close="close"
|
||||||
>
|
>
|
||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<template v-if="taskStep === TASK_STEP.default">
|
<!-- 加载中状态 -->
|
||||||
<!-- <template v-if="hasUnsyncData">
|
<template v-if="modalState === MODAL_STATE.LOADING">
|
||||||
<div class="flex items-center mb-20px">
|
|
||||||
<img :src="icon4" width="16" height="16" class="mr-16px" />
|
|
||||||
<span class="s2 color-#3C4043">检测到该账号最后更新日期为x月x日,已有x天未同步最新数据。</span>
|
|
||||||
</div>
|
|
||||||
<a-radio-group v-model="actionType" class="ml-32px">
|
|
||||||
<a-radio :value="1" class="mb-16px"
|
|
||||||
><span class="s2"
|
|
||||||
>立即同步遗漏数据 - 获取完整的最新数据 <span class="color-#6D4CFE">(推荐)</span></span
|
|
||||||
></a-radio
|
|
||||||
>
|
|
||||||
<a-radio :value="2" class="mb-16px"
|
|
||||||
><span class="s2">仅授权不更新 - 继续使用当前不完全的数据</span></a-radio
|
|
||||||
>
|
|
||||||
</a-radio-group>
|
|
||||||
</template> -->
|
|
||||||
<!-- <template v-else> -->
|
|
||||||
<div class="img-box">
|
|
||||||
<template v-if="qrCodeLoading || isFailLoadQrCode">
|
|
||||||
<div class="relative w-160px h-160px">
|
|
||||||
<a-image :src="icon1" width="160" height="160" />
|
|
||||||
<div class="absolute top-0 left-0 z-2 w-full h-full flex flex-col items-center justify-center">
|
|
||||||
<img v-if="isFailLoadQrCode" :src="icon4" width="24" height="24" class="mb-13px" />
|
|
||||||
<icon-loading v-else size="24" class="color-#6D4CFE mb-13px" />
|
|
||||||
<span :class="isFailLoadQrCode ? '!color-#F64B31' : '!color-#6D4CFE'" class="s2">{{
|
|
||||||
isFailLoadQrCode ? '二维码生成失败' : '二维码生成中...'
|
|
||||||
}}</span>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="absolute top-0 left-0 w-full h-full flex items-center justify-center opacity-80 bg-#fff"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<a-image v-else :src="qrCodeUrl" width="160" height="160" />
|
|
||||||
|
|
||||||
<div v-if="isOverdue" class="mask cursor-pointer" @click="handleRefreshQrCode">
|
|
||||||
<icon-refresh size="24" class="mb-13px" />
|
|
||||||
<p class="s1">二维码失效</p>
|
|
||||||
<p class="s1">请点击刷新</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span class="mt-16px"> 请使用{{ platform }}扫码,将公司账号绑定至灵机平台。 </span>
|
|
||||||
</template>
|
|
||||||
<!-- </template> -->
|
|
||||||
<template v-else-if="taskStep === TASK_STEP.loading">
|
|
||||||
<a-progress
|
<a-progress
|
||||||
:percent="progress"
|
:percent="progress"
|
||||||
color="#6D4CFE"
|
color="#6D4CFE"
|
||||||
@ -69,41 +25,94 @@
|
|||||||
/>
|
/>
|
||||||
<p class="s2 mt-16px">数据同步和初始化中,请勿关闭窗口。</p>
|
<p class="s2 mt-16px">数据同步和初始化中,请勿关闭窗口。</p>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- 完成状态 -->
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<template v-if="isNicknameChanged">
|
<template v-if="modalState === MODAL_STATE.SUCCESS || modalState === MODAL_STATE.FAILED">
|
||||||
<div class="flex items-center mb-20px">
|
<template v-if="isNicknameChanged">
|
||||||
<img :src="icon4" width="16" height="16" class="mr-16px" />
|
<div class="flex items-center mb-20px">
|
||||||
<span class="s2 color-#3C4043">当前绑定的账号与之前的昵称不一致,请确认是否覆盖原账号信息。</span>
|
<img :src="icon4" width="16" height="16" class="mr-16px" />
|
||||||
</div>
|
<span class="s2 color-#3C4043">当前绑定的账号与之前的昵称不一致,请确认是否覆盖原账号信息。</span>
|
||||||
<div class="w-100% pl-32px">
|
</div>
|
||||||
<div class="account-tip-box">
|
<div class="w-100% pl-32px">
|
||||||
<p class="mb-4px s2"><span class="color-#3C4043">原账号:</span>全球旅行小助手</p>
|
<div class="account-tip-box">
|
||||||
<p class="s2"><span class="color-#3C4043">当前账号:</span>环球旅行官</p>
|
<p class="mb-4px s2"><span class="color-#3C4043">原账号:</span>全球旅行小助手</p>
|
||||||
|
<p class="s2"><span class="color-#3C4043">当前账号:</span>环球旅行官</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<img :src="modalState === MODAL_STATE.SUCCESS ? icon2 : icon3" width="80" height="80" class="mb-16px" />
|
||||||
|
<p class="s2">{{ `数据初始化${modalState === MODAL_STATE.SUCCESS ? '成功' : '失败'}。` }}</p>
|
||||||
|
<p v-if="modalState === MODAL_STATE.FAILED" class="red-text">失败原因:{{ failReason || '-' }}</p>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 二维码状态 -->
|
||||||
|
<template v-else>
|
||||||
|
<div class="img-box">
|
||||||
|
<!-- 二维码加载中或失败 -->
|
||||||
|
<template v-if="modalState === MODAL_STATE.QR_LOADING || modalState === MODAL_STATE.QR_FAILED">
|
||||||
|
<div class="relative w-160px h-160px">
|
||||||
|
<a-image :src="icon1" width="160" height="160" />
|
||||||
|
<div class="absolute top-0 left-0 z-2 w-full h-full flex flex-col items-center justify-center">
|
||||||
|
<img
|
||||||
|
v-if="modalState === MODAL_STATE.QR_FAILED"
|
||||||
|
:src="icon4"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
class="mb-13px"
|
||||||
|
/>
|
||||||
|
<icon-loading v-else size="24" class="color-#6D4CFE mb-13px" />
|
||||||
|
<span
|
||||||
|
:class="modalState === MODAL_STATE.QR_FAILED ? '!color-#F64B31' : '!color-#6D4CFE'"
|
||||||
|
class="s2"
|
||||||
|
>{{ modalState === MODAL_STATE.QR_FAILED ? '二维码生成失败' : '二维码生成中...' }}</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="absolute top-0 left-0 w-full h-full flex items-center justify-center opacity-80 bg-#fff"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 正常二维码 -->
|
||||||
|
<a-image v-else :src="qrCodeUrl" width="160" height="160" />
|
||||||
|
|
||||||
|
<!-- 二维码失效遮罩 -->
|
||||||
|
<div v-if="modalState === MODAL_STATE.QR_EXPIRED" class="mask cursor-pointer" @click="handleRefreshQrCode">
|
||||||
|
<icon-refresh size="24" class="mb-13px" />
|
||||||
|
<p class="s1">二维码失效</p>
|
||||||
|
<p class="s1">请点击刷新</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<span class="mt-16px"> 请使用{{ platform }}扫码,将公司账号绑定至灵机平台。 </span>
|
||||||
<template v-else>
|
|
||||||
<img :src="isSuccess ? icon2 : icon3" width="80" height="80" class="mb-16px" />
|
|
||||||
<p class="s2">{{ `数据初始化${isSuccess ? '成功' : '失败'}。` }}</p>
|
|
||||||
<p v-if="!isSuccess" class="red-text">失败原因:{{ failReason || '-' }}</p>
|
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
|
<a-button v-if="modalState === MODAL_STATE.QR_READY" size="large" class="cancel-btn" @click="handleRefreshQrCode">
|
||||||
|
重新生成
|
||||||
|
</a-button>
|
||||||
<a-button
|
<a-button
|
||||||
v-if="taskStep === TASK_STEP.default || taskStep === TASK_STEP.end"
|
v-if="modalState === MODAL_STATE.SUCCESS || modalState === MODAL_STATE.FAILED"
|
||||||
size="large"
|
size="large"
|
||||||
class="cancel-btn"
|
class="cancel-btn"
|
||||||
@click="close"
|
@click="close"
|
||||||
>取消</a-button
|
|
||||||
>
|
>
|
||||||
<a-button type="primary" size="large" @click="handleOk">{{ confirmBtnText }} </a-button>
|
取消
|
||||||
|
</a-button>
|
||||||
|
<a-button type="primary" size="large" @click="handleOk">
|
||||||
|
{{ confirmBtnText }}
|
||||||
|
</a-button>
|
||||||
</template>
|
</template>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineExpose, ref, onUnmounted } from 'vue';
|
import { defineExpose, ref, computed } from '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 icon1 from '@/assets/img/media-account/icon-default-qrcode.png';
|
import icon1 from '@/assets/img/media-account/icon-default-qrcode.png';
|
||||||
@ -112,144 +121,148 @@ import icon3 from '@/assets/img/media-account/icon-feedback-fail.png';
|
|||||||
import icon4 from '@/assets/img/media-account/icon-warn-1.png';
|
import icon4 from '@/assets/img/media-account/icon-warn-1.png';
|
||||||
|
|
||||||
const emits = defineEmits(['update']);
|
const emits = defineEmits(['update']);
|
||||||
const OVERDUE_TIME = 30000; // 失效时间
|
|
||||||
const TASK_STEP = {
|
// 状态枚举
|
||||||
default: 1,
|
const MODAL_STATE = {
|
||||||
loading: 2,
|
QR_LOADING: 0, // 二维码加载中
|
||||||
end: 3,
|
QR_FAILED: 1, // 二维码生成失败
|
||||||
|
QR_READY: 2, // 二维码就绪,等待扫码
|
||||||
|
QR_EXPIRED: 3, // 二维码已过期
|
||||||
|
LOADING: 4, // 数据同步中
|
||||||
|
SUCCESS: 5, // 授权成功
|
||||||
|
FAILED: 6, // 授权失败
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const OVERDUE_TIME = 30000; // 失效时间
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
const isOverdue = ref(false); // 二维码失效
|
const modalState = ref(MODAL_STATE.QR_LOADING);
|
||||||
const isSuccess = ref(false);
|
|
||||||
const failReason = ref('');
|
const failReason = ref('');
|
||||||
const progress = ref(0);
|
const progress = ref(0);
|
||||||
const id = ref('');
|
const id = ref('');
|
||||||
const platform = ref('');
|
const platform = ref('');
|
||||||
|
|
||||||
const isFailLoadQrCode = ref(false);
|
|
||||||
const qrCodeUrl = ref('');
|
const qrCodeUrl = ref('');
|
||||||
const qrCodeLoading = ref(false);
|
|
||||||
|
|
||||||
const taskStep = ref(TASK_STEP.default);
|
|
||||||
// const hasUnsyncData = ref(false); // 含有未同步数据
|
|
||||||
const isNicknameChanged = ref(false); // 昵称发生变化
|
const isNicknameChanged = ref(false); // 昵称发生变化
|
||||||
const actionType = ref(1);
|
|
||||||
|
|
||||||
let progressTimer = null;
|
let progressTimer = null;
|
||||||
let overdueTimer = null;
|
let overdueTimer = null;
|
||||||
let statusPollingTimer = null;
|
let statusPollingTimer = null;
|
||||||
|
|
||||||
|
// 按钮文案映射
|
||||||
const confirmBtnText = computed(() => {
|
const confirmBtnText = computed(() => {
|
||||||
if (isFailLoadQrCode.value) return '重新生成';
|
const btnTextMap = {
|
||||||
if (taskStep.value === TASK_STEP.default) {
|
[MODAL_STATE.QR_LOADING]: '完成扫码',
|
||||||
// return hasUnsyncData.value ? '确定' : '完成扫码';
|
[MODAL_STATE.QR_FAILED]: '重新生成',
|
||||||
return '完成扫码';
|
[MODAL_STATE.QR_READY]: '完成扫码',
|
||||||
}
|
[MODAL_STATE.QR_EXPIRED]: '重新生成',
|
||||||
|
[MODAL_STATE.LOADING]: '处理中...',
|
||||||
if (taskStep.value === TASK_STEP.end) {
|
[MODAL_STATE.SUCCESS]: isNicknameChanged.value ? '确定覆盖' : '继续添加',
|
||||||
if (isNicknameChanged.value) return '确定覆盖';
|
[MODAL_STATE.FAILED]: '重新扫码',
|
||||||
return isSuccess.value ? '继续添加' : '重新扫码';
|
};
|
||||||
}
|
return btnTextMap[modalState.value] || '确定';
|
||||||
|
|
||||||
return '';
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const open = (accountId, platformCode) => {
|
const open = (accountId, platformCode) => {
|
||||||
id.value = accountId;
|
id.value = accountId;
|
||||||
platform.value = platformCode === 0 ? '抖音' : '小红书';
|
platform.value = platformCode === 0 ? '抖音' : '小红书';
|
||||||
|
modalState.value = MODAL_STATE.QR_LOADING;
|
||||||
getAuthorizedQrCode();
|
getAuthorizedQrCode();
|
||||||
visible.value = true;
|
visible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetTaskFields = () => {
|
const resetTaskFields = () => {
|
||||||
isOverdue.value = false;
|
modalState.value = MODAL_STATE.QR_LOADING;
|
||||||
isSuccess.value = false;
|
|
||||||
failReason.value = '';
|
failReason.value = '';
|
||||||
platform.value = '';
|
platform.value = '';
|
||||||
progress.value = 0;
|
progress.value = 0;
|
||||||
qrCodeUrl.value = '';
|
qrCodeUrl.value = '';
|
||||||
qrCodeLoading.value = false;
|
|
||||||
isNicknameChanged.value = false;
|
isNicknameChanged.value = false;
|
||||||
isFailLoadQrCode.value = false;
|
|
||||||
actionType.value = 1;
|
|
||||||
taskStep.value = TASK_STEP.default;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const close = () => {
|
const close = () => {
|
||||||
resetTaskFields();
|
resetTaskFields();
|
||||||
id.value = '';
|
id.value = '';
|
||||||
clearFakeProgressTimer();
|
clearFakeProgressTimer();
|
||||||
|
clearStatusPollingTimer();
|
||||||
clearOverdueTimer();
|
clearOverdueTimer();
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getAuthorizedQrCode = async () => {
|
||||||
|
try {
|
||||||
|
modalState.value = MODAL_STATE.QR_LOADING;
|
||||||
|
const { code, data } = await getAuthorizedImage(id.value);
|
||||||
|
if (code === 200) {
|
||||||
|
qrCodeUrl.value = data.image;
|
||||||
|
overdueTimer = null;
|
||||||
|
modalState.value = MODAL_STATE.QR_READY;
|
||||||
|
|
||||||
|
// 约定:后端限制40s内必须扫码,前端定30s后失效
|
||||||
|
overdueTimer = setTimeout(() => {
|
||||||
|
modalState.value = MODAL_STATE.QR_EXPIRED;
|
||||||
|
}, OVERDUE_TIME);
|
||||||
|
} else {
|
||||||
|
modalState.value = MODAL_STATE.QR_FAILED;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
modalState.value = MODAL_STATE.QR_FAILED;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const clearStatusPollingTimer = () => {
|
||||||
|
if (statusPollingTimer) {
|
||||||
|
clearInterval(statusPollingTimer);
|
||||||
|
statusPollingTimer = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const startStatusPolling = () => {
|
||||||
|
clearStatusPollingTimer();
|
||||||
|
statusPollingTimer = setInterval(async () => {
|
||||||
|
if (modalState.value === MODAL_STATE.LOADING) {
|
||||||
|
await getAuthorizedStatus();
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const startLoading = async () => {
|
||||||
|
modalState.value = MODAL_STATE.LOADING;
|
||||||
|
progress.value = 0;
|
||||||
|
startFakeProgressPolling();
|
||||||
|
startStatusPolling();
|
||||||
|
};
|
||||||
|
|
||||||
const getAuthorizedStatus = async () => {
|
const getAuthorizedStatus = async () => {
|
||||||
const { code, data } = await getMediaAccountsAuthorizedStatus(id.value);
|
const { code, data } = await getMediaAccountsAuthorizedStatus(id.value);
|
||||||
if (code === 200) {
|
if (code === 200) {
|
||||||
const { status, message } = data;
|
const { status, message } = data;
|
||||||
if (status !== 0) {
|
if (status !== 0) {
|
||||||
taskStep.value = TASK_STEP.end;
|
progress.value = 1;
|
||||||
isSuccess.value = status === 1;
|
clearFakeProgressTimer();
|
||||||
failReason.value = status === 2 ? message : '';
|
clearStatusPollingTimer();
|
||||||
isOverdue.value = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const startStatusPolling = () => {
|
if (status === 1) {
|
||||||
clearStatusPollingTimer();
|
modalState.value = MODAL_STATE.SUCCESS;
|
||||||
statusPollingTimer = setInterval(async () => {
|
// 这里可以根据实际业务逻辑判断是否需要显示昵称变更提示
|
||||||
if (taskStep.value === TASK_STEP.loading) {
|
// isNicknameChanged.value = true; // 示例:如果需要显示昵称变更
|
||||||
await getAuthorizedStatus();
|
} else {
|
||||||
if (taskStep.value === TASK_STEP.end) {
|
modalState.value = MODAL_STATE.FAILED;
|
||||||
progress.value = 1;
|
failReason.value = message || '';
|
||||||
clearFakeProgressTimer();
|
|
||||||
clearStatusPollingTimer();
|
|
||||||
emits('update');
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}, 2000);
|
|
||||||
};
|
|
||||||
|
|
||||||
const getAuthorizedQrCode = async () => {
|
emits('update');
|
||||||
try {
|
|
||||||
qrCodeLoading.value = true;
|
|
||||||
const { code, data } = await getAuthorizedImage(id.value);
|
|
||||||
if (code === 200) {
|
|
||||||
qrCodeUrl.value = data.image;
|
|
||||||
overdueTimer = null;
|
|
||||||
isOverdue.value = false;
|
|
||||||
|
|
||||||
// 约定:后端限制40s内必须扫码,前端定30s后失效
|
|
||||||
overdueTimer = setTimeout(() => {
|
|
||||||
isOverdue.value = true;
|
|
||||||
}, OVERDUE_TIME);
|
|
||||||
} else {
|
|
||||||
isFailLoadQrCode.value = true;
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
|
||||||
isFailLoadQrCode.value = true;
|
|
||||||
} finally {
|
|
||||||
qrCodeLoading.value = false;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const startLoading = async () => {
|
|
||||||
taskStep.value = TASK_STEP.loading;
|
|
||||||
progress.value = 0;
|
|
||||||
startFakeProgressPolling();
|
|
||||||
startStatusPolling();
|
|
||||||
};
|
|
||||||
|
|
||||||
const startFakeProgressPolling = () => {
|
const startFakeProgressPolling = () => {
|
||||||
clearFakeProgressTimer();
|
clearFakeProgressTimer();
|
||||||
progressTimer = setInterval(() => {
|
progressTimer = setInterval(() => {
|
||||||
if (taskStep.value === TASK_STEP.loading) {
|
if (modalState.value === MODAL_STATE.LOADING && progress.value < 0.99) {
|
||||||
if (progress.value < 0.99) {
|
const step = Math.random() * 0.04 + 0.01;
|
||||||
const step = Math.random() * 0.04 + 0.01;
|
progress.value = Math.min(progress.value + step, 0.99);
|
||||||
progress.value = Math.min(progress.value + step, 0.99);
|
progress.value = Number(progress.value.toFixed(2));
|
||||||
progress.value = Number(progress.value.toFixed(2));
|
} else if (modalState.value === MODAL_STATE.LOADING && progress.value >= 0.99) {
|
||||||
} else if (progress.value >= 0.99) {
|
progress.value = 0.99; // 卡在99%
|
||||||
progress.value = 0.99; // 卡在99%
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
clearFakeProgressTimer();
|
clearFakeProgressTimer();
|
||||||
clearStatusPollingTimer();
|
clearStatusPollingTimer();
|
||||||
@ -263,6 +276,7 @@ const clearFakeProgressTimer = () => {
|
|||||||
progressTimer = null;
|
progressTimer = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const clearOverdueTimer = () => {
|
const clearOverdueTimer = () => {
|
||||||
if (overdueTimer) {
|
if (overdueTimer) {
|
||||||
clearTimeout(overdueTimer);
|
clearTimeout(overdueTimer);
|
||||||
@ -270,52 +284,56 @@ const clearOverdueTimer = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const clearStatusPollingTimer = () => {
|
|
||||||
if (statusPollingTimer) {
|
|
||||||
clearInterval(statusPollingTimer);
|
|
||||||
statusPollingTimer = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 重新扫码
|
// 重新扫码
|
||||||
const handleRefreshQrCode = () => {
|
const handleRefreshQrCode = () => {
|
||||||
|
clearOverdueTimer();
|
||||||
resetTaskFields();
|
resetTaskFields();
|
||||||
getAuthorizedQrCode();
|
getAuthorizedQrCode();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOk = () => {
|
const handleOk = () => {
|
||||||
if (taskStep.value === TASK_STEP.default) {
|
// 二维码已过期
|
||||||
if (isFailLoadQrCode.value) {
|
if (modalState.value === MODAL_STATE.QR_EXPIRED) {
|
||||||
handleRefreshQrCode();
|
AMessage.error('二维码已失效,请重新扫码');
|
||||||
return;
|
handleRefreshQrCode();
|
||||||
}
|
|
||||||
|
|
||||||
clearOverdueTimer();
|
|
||||||
|
|
||||||
if (!qrCodeUrl.value) {
|
|
||||||
AMessage.warning('二维码生成中,请稍等');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isOverdue.value) {
|
|
||||||
AMessage.error('二维码已失效,请重新扫码');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
startLoading();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (taskStep.value === TASK_STEP.end) {
|
// 二维码还在加载中
|
||||||
|
if (modalState.value === MODAL_STATE.QR_LOADING) {
|
||||||
|
AMessage.warning('二维码生成中,请稍等');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 二维码生成失败
|
||||||
|
if (modalState.value === MODAL_STATE.QR_FAILED) {
|
||||||
|
handleRefreshQrCode();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 授权成功
|
||||||
|
if (modalState.value === MODAL_STATE.SUCCESS) {
|
||||||
if (isNicknameChanged.value) {
|
if (isNicknameChanged.value) {
|
||||||
isNicknameChanged.value = false;
|
isNicknameChanged.value = false;
|
||||||
console.log('确定覆盖');
|
console.log('确定覆盖');
|
||||||
|
// 这里可以添加覆盖逻辑
|
||||||
} else {
|
} else {
|
||||||
if (isSuccess.value) {
|
close();
|
||||||
close();
|
|
||||||
} else {
|
|
||||||
handleRefreshQrCode();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 授权失败,重新扫码
|
||||||
|
if (modalState.value === MODAL_STATE.FAILED) {
|
||||||
|
handleRefreshQrCode();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 二维码就绪,开始授权流程
|
||||||
|
if (modalState.value === MODAL_STATE.QR_READY) {
|
||||||
|
clearOverdueTimer();
|
||||||
|
startLoading();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -146,7 +146,7 @@ const dataSource = ref([]);
|
|||||||
const selectedItems = ref([]);
|
const selectedItems = ref([]);
|
||||||
const healthData = ref({});
|
const healthData = ref({});
|
||||||
|
|
||||||
const isAbNormalStatus = computed(() => healthData.value?.abnormal_number > 0);
|
const isAbNormalStatus = computed(() => healthData.value?.total_abnormal_number > 0);
|
||||||
|
|
||||||
const checkedAll = computed(() => selectedItems.value.length === dataSource.value.length);
|
const checkedAll = computed(() => selectedItems.value.length === dataSource.value.length);
|
||||||
const indeterminate = computed(
|
const indeterminate = computed(
|
||||||
@ -159,23 +159,25 @@ const tipLabel = computed(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
abnormal_number = 0,
|
total_abnormal_number = 0,
|
||||||
login_invalid_number = 0,
|
login_invalid_number = 0,
|
||||||
too_many_requests_number = 0,
|
too_many_requests_number = 0,
|
||||||
account_frozen_number = 0,
|
account_frozen_number = 0,
|
||||||
|
miss_data_number = 0,
|
||||||
} = healthData.value;
|
} = healthData.value;
|
||||||
|
|
||||||
// 定义异常类型映射
|
// 定义异常类型映射
|
||||||
const abnormalTypes = [
|
const abnormalTypes = [
|
||||||
{ count: login_invalid_number, label: 'cookie过期' },
|
{ count: login_invalid_number, label: 'cookie过期' },
|
||||||
{ count: too_many_requests_number, label: '已请求频繁' },
|
{ count: too_many_requests_number, label: '请求频繁' },
|
||||||
{ count: account_frozen_number, label: '账号被封' },
|
{ count: account_frozen_number, label: '账号被封' },
|
||||||
|
{ count: miss_data_number, label: '数据缺失' },
|
||||||
];
|
];
|
||||||
|
|
||||||
// 过滤出有异常的项并格式化
|
// 过滤出有异常的项并格式化
|
||||||
const abnormalLabels = abnormalTypes.filter(({ count }) => count > 0).map(({ count, label }) => `${count}个${label}`);
|
const abnormalLabels = abnormalTypes.filter(({ count }) => count > 0).map(({ count, label }) => `${count}个${label}`);
|
||||||
|
|
||||||
return `共有 ${abnormal_number} 个账号存在授权异常,其中:${abnormalLabels.join(',')}。`;
|
return `共有 ${total_abnormal_number} 个账号存在授权异常,其中:${abnormalLabels.join(',')}。`;
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
@ -122,7 +122,7 @@ const dataSource = ref([]);
|
|||||||
const selectedItems = ref([]);
|
const selectedItems = ref([]);
|
||||||
const healthData = ref({});
|
const healthData = ref({});
|
||||||
|
|
||||||
const isAbNormalStatus = computed(() => healthData.value?.abnormal_number > 0);
|
const isAbNormalStatus = computed(() => healthData.value?.total_abnormal_number > 0);
|
||||||
|
|
||||||
const checkedAll = computed(() => selectedItems.value.length === dataSource.value.length);
|
const checkedAll = computed(() => selectedItems.value.length === dataSource.value.length);
|
||||||
const indeterminate = computed(
|
const indeterminate = computed(
|
||||||
@ -135,23 +135,25 @@ const tipLabel = computed(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
abnormal_number = 0,
|
total_abnormal_number = 0,
|
||||||
login_invalid_number = 0,
|
login_invalid_number = 0,
|
||||||
too_many_requests_number = 0,
|
too_many_requests_number = 0,
|
||||||
account_frozen_number = 0,
|
account_frozen_number = 0,
|
||||||
|
miss_data_number = 0,
|
||||||
} = healthData.value;
|
} = healthData.value;
|
||||||
|
|
||||||
// 定义异常类型映射
|
// 定义异常类型映射
|
||||||
const abnormalTypes = [
|
const abnormalTypes = [
|
||||||
{ count: login_invalid_number, label: 'cookie过期' },
|
{ count: login_invalid_number, label: 'cookie过期' },
|
||||||
{ count: too_many_requests_number, label: '已请求频繁' },
|
{ count: too_many_requests_number, label: '请求频繁' },
|
||||||
{ count: account_frozen_number, label: '账号被封' },
|
{ count: account_frozen_number, label: '账号被封' },
|
||||||
|
{ count: miss_data_number, label: '数据缺失' },
|
||||||
];
|
];
|
||||||
|
|
||||||
// 过滤出有异常的项并格式化
|
// 过滤出有异常的项并格式化
|
||||||
const abnormalLabels = abnormalTypes.filter(({ count }) => count > 0).map(({ count, label }) => `${count}个${label}`);
|
const abnormalLabels = abnormalTypes.filter(({ count }) => count > 0).map(({ count, label }) => `${count}个${label}`);
|
||||||
|
|
||||||
return `共有 ${abnormal_number} 个账号存在授权异常,其中:${abnormalLabels.join(',')}。`;
|
return `共有 ${total_abnormal_number} 个账号存在授权异常,其中:${abnormalLabels.join(',')}。`;
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user