feat: 授权/重新授权逻辑

This commit is contained in:
rd
2025-06-28 16:57:30 +08:00
parent 78b9083ce8
commit 126c0eab38
2 changed files with 152 additions and 85 deletions

View File

@ -31,19 +31,19 @@
<p v-if="!isSuccess" class="red-text">失败原因{{ failReason || '-' }}</p>
</template>
<template v-else>
<div class="flex items-center mb-16px">
<!-- <div class="flex items-center mb-16px">
<img :src="icon1" width="16" height="16" />
<span class="ml-8px red-text">未识别到有效二维码</span>
</div>
</div> -->
<div class="img-box">
<img :src="imgUrl" width="160" height="160" class="mb-16px" />
<div v-if="isOverdue" class="mask">
<div v-if="isOverdue" class="mask" @click="getAuthorizedQrCode">
<icon-refresh size="24" class="mb-13px" />
<p class="s1">二维码失效</p>
<p class="s1">请点击刷新</p>
</div>
</div>
<span class="mt-16px"> 请使用抖音扫码将公司账号绑定至灵机平台 </span>
<span> 请使用抖音扫码将公司账号绑定至灵机平台 </span>
</template>
</template>
</div>
@ -62,8 +62,10 @@ import icon1 from '@/assets/img/media-account/icon-warn.png';
import icon2 from '@/assets/img/media-account/icon-feedback-success.png';
import icon3 from '@/assets/img/media-account/icon-feedback-fail.png';
const OVERDUE_TIME = 30000; // 失效时间
const visible = ref(false);
const isOverdue = ref(false);
const isOverdue = ref(false); // 二维码失效
const isLoading = ref(false);
const isCompleted = ref(false);
const isSuccess = ref(false);
@ -73,6 +75,7 @@ const id = ref('');
const imgUrl = ref('');
let progressTimer = null;
let overdueTimer = null;
const notCompleted = computed(() => {
return !isCompleted.value;
@ -84,7 +87,7 @@ const confirmBtnText = computed(() => {
const open = (accountId) => {
id.value = accountId;
handleAuthorizedImage();
getAuthorizedQrCode();
visible.value = true;
};
const close = () => {
@ -95,14 +98,21 @@ const close = () => {
failReason.value = '';
progress.value = 0;
id.value = '';
clearFakeProgressTimer();
clearOverdueTimer();
visible.value = false;
};
const handleAuthorizedImage = async () => {
const getAuthorizedQrCode = async () => {
const { code, data } = await getAuthorizedImage(id.value);
if (code === 200) {
imgUrl.value = data.url;
overdueTimer = null;
// 约定后端限制40s内必须扫码前端定30s后失效
overdueTimer = setTimeout(() => {
isOverdue.value = true;
}, OVERDUE_TIME);
}
};
const startLoading = async () => {
@ -136,18 +146,27 @@ const clearFakeProgressTimer = () => {
progressTimer = null;
}
};
const clearOverdueTimer = () => {
if (overdueTimer) {
clearTimeout(overdueTimer);
overdueTimer = null;
}
};
const handleOk = () => {
if (notCompleted.value) {
clearOverdueTimer();
if (isOverdue.value) {
AMessage.error('二维码已失效,请重新扫码');
return;
}
startLoading();
return;
}
};
onUnmounted(() => {
clearFakeProgressTimer();
});
defineExpose({
open,
});

View File

@ -9,22 +9,12 @@
title="重新授权"
modal-class="reauthorize-account-modal"
:mask-closable="false"
:footer="!isLoading"
:footer="taskStep !== TASK_STEP.loading"
@close="close"
>
<div class="flex flex-col items-center">
<template v-if="isLoading">
<a-progress
:percent="progress"
color="#6D4CFE"
trackColor="#E6E6E8"
size="large"
:stroke-width="4"
type="circle"
/>
<p class="s2 mt-16px">数据同步和初始化中请勿关闭窗口</p>
</template>
<template v-else-if="loadingStep === 1">
<template v-if="taskStep === TASK_STEP.default">
<template v-if="hasUnsyncData">
<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>
@ -35,10 +25,36 @@
>立即同步遗漏数据 - 获取完整的最新数据 <span class="color-#6D4CFE">推荐</span></span
></a-radio
>
<a-radio :value="2" class="mb-16px"><span class="s2">仅授权不更新 - 继续使用当前不完全的数据</span></a-radio>
<a-radio :value="2" class="mb-16px"
><span class="s2">仅授权不更新 - 继续使用当前不完全的数据</span></a-radio
>
</a-radio-group>
</template>
<template v-else-if="loadingStep === 2">
<template v-else>
<div class="img-box">
<img :src="imgUrl" width="160" height="160" class="mb-16px" />
<div v-if="isOverdue" class="mask" @click="getAuthorizedQrCode">
<icon-refresh size="24" class="mb-13px" />
<p class="s1">二维码失效</p>
<p class="s1">请点击刷新</p>
</div>
</div>
<span> 请使用抖音扫码将公司账号绑定至灵机平台 </span>
</template>
</template>
<template v-else-if="taskStep === TASK_STEP.loading">
<a-progress
:percent="progress"
color="#6D4CFE"
trackColor="#E6E6E8"
size="large"
:stroke-width="4"
type="circle"
/>
<p class="s2 mt-16px">数据同步和初始化中请勿关闭窗口</p>
</template>
<template v-else>
<template v-if="isNicknameChanged">
<div class="flex items-center mb-20px">
<img :src="icon4" width="16" height="16" class="mr-16px" />
<span class="s2 color-#3C4043">当前绑定的账号与之前的昵称不一致请确认是否覆盖原账号信息</span>
@ -51,30 +67,18 @@
</div>
</template>
<template v-else>
<template v-if="isCompleted">
<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 v-else>
<div class="flex items-center mb-16px">
<img :src="icon1" width="16" height="16" />
<span class="ml-8px red-text">未识别到有效二维码</span>
</div>
<div class="img-box">
<img :src="imgUrl" width="160" height="160" class="mb-16px" />
<div v-if="isOverdue" class="mask">
<icon-refresh size="24" class="mb-13px" />
<p class="s1">二维码失效</p>
<p class="s1">请点击刷新</p>
</div>
</div>
<span class="mt-16px"> 请使用抖音扫码将公司账号绑定至灵机平台 </span>
</template>
</template>
</div>
<template #footer>
<a-button v-if="isCompleted || [1, 3].includes(actionType)" size="large" class="cancel-btn" @click="close"
<a-button
v-if="(taskStep === TASK_STEP.default && hasUnsyncData) || taskStep === TASK_STEP.end"
size="large"
class="cancel-btn"
@click="close"
>取消</a-button
>
<a-button type="primary" size="large" @click="handleOk">{{ confirmBtnText }} </a-button>
@ -91,64 +95,81 @@ import icon2 from '@/assets/img/media-account/icon-feedback-success.png';
import icon3 from '@/assets/img/media-account/icon-feedback-fail.png';
import icon4 from '@/assets/img/media-account/icon-warn-1.png';
const OVERDUE_TIME = 30000; // 失效时间
const TASK_STEP = {
default: 1,
loading: 2,
end: 3,
};
const visible = ref(false);
const isOverdue = ref(false);
const isLoading = ref(false);
const isCompleted = ref(false);
const isOverdue = ref(false); // 二维码失效
const isSuccess = ref(false);
const failReason = ref('');
const progress = ref(0);
const id = ref('');
const imgUrl = ref('');
const loadingStep = ref(0); // 1 | 2
const taskStep = ref(TASK_STEP.default);
const hasUnsyncData = ref(false); // 含有未同步数据
const isNicknameChanged = ref(false); // 昵称发生变化
const actionType = ref(1);
let progressTimer = null;
let overdueTimer = null;
const notCompleted = computed(() => {
return !isCompleted.value;
});
const confirmBtnText = computed(() => {
if (loadingStep.value === 1) return '确定';
if (loadingStep.value === 2) return '确定覆盖';
if (notCompleted.value) return '完成扫码';
if (taskStep.value === TASK_STEP.default) {
return hasUnsyncData.value ? '确定' : '完成扫码';
}
if (taskStep.value === TASK_STEP.end) {
if (isNicknameChanged.value) return '确定覆盖';
return isSuccess.value ? '继续添加' : '重新扫码';
}
return '';
});
const open = (accountId) => {
id.value = accountId;
handleAuthorizedImage();
getAuthorizedQrCode();
visible.value = true;
};
const close = () => {
isOverdue.value = false;
isLoading.value = false;
isCompleted.value = false;
isSuccess.value = false;
failReason.value = '';
progress.value = 0;
loadingStep.value = 0;
taskStep.value = TASK_STEP.default;
actionType.value = 1;
hasUnsyncData.value = false;
isNicknameChanged.value = false;
id.value = '';
clearFakeProgressTimer();
clearOverdueTimer();
visible.value = false;
};
const handleAuthorizedImage = async () => {
const getAuthorizedQrCode = async () => {
const { code, data } = await getAuthorizedImage(id.value);
if (code === 200) {
imgUrl.value = data.url;
overdueTimer = null;
// 约定后端限制40s内必须扫码前端定30s后失效
overdueTimer = setTimeout(() => {
isOverdue.value = true;
}, OVERDUE_TIME);
}
};
const startLoading = async () => {
isLoading.value = true;
taskStep.value = TASK_STEP.loading;
progress.value = 0;
startFakeProgressPolling();
// const { code } = await startPatchAccount(id.value);
// if (code === 200) {
// isLoading.value = true;
// taskStep.value = TASK_STEP.loading;
// progress.value = 0;
// startFakeProgressPolling();
// }
@ -162,7 +183,7 @@ const startFakeProgressPolling = () => {
progress.value = Math.min(progress.value + step, 0.99);
progress.value = Number(progress.value.toFixed(2));
} else {
loadingStep.value = 2;
taskStep.value = TASK_STEP.end;
clearFakeProgressTimer();
}
}, 1000);
@ -174,23 +195,50 @@ const clearFakeProgressTimer = () => {
progressTimer = null;
}
};
const clearOverdueTimer = () => {
if (overdueTimer) {
clearTimeout(overdueTimer);
overdueTimer = null;
}
};
const getSyncDataStatus = () => {
return hasUnsyncData.value;
};
const handleOk = () => {
if (loadingStep.value === 1) {
if (taskStep.value === TASK_STEP.default) {
clearOverdueTimer();
if (isOverdue.value) {
AMessage.error('二维码已失效,请重新扫码');
return;
}
const _hasUnsyncData = getSyncDataStatus();
if (!_hasUnsyncData) {
hasUnsyncData.value = true;
return;
}
startLoading();
return;
}
if (notCompleted.value) {
loadingStep.value = 1;
return;
if (taskStep.value === TASK_STEP.end) {
if (isNicknameChanged.value) {
isNicknameChanged.value = false;
console.log('确定覆盖');
} else {
if (isSuccess.value) {
console.log('继续添加');
} else {
console.log('重新扫码');
}
}
}
};
onUnmounted(() => {
clearFakeProgressTimer();
});
defineExpose({
open,
});