feat: add aigc regenerate flow and improve task polling
Add reusable RegenerateConfirmPopup component. Implement full regeneration flow in AIGC detail page with balance checks, insufficient point prompt, task creation and progress page navigation. Refine progress page polling logic with lifecycle handling, duplicate request prevention and timer cleanup.
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import { onHide, onLoad, onShow, onUnload } from "@dcloudio/uni-app";
|
||||
import AigcTopBar from "@/pages-aigc/components/AigcTopBar/index.vue";
|
||||
import { useCurrentCredit } from "@/pages-aigc/hooks/useCurrentCredit.js";
|
||||
import { getAigcGeneratorTaskDetail } from "@/request/api/AigcApi.js";
|
||||
@@ -24,6 +24,10 @@ import GeneratingProgressPanel from "./components/GeneratingProgressPanel/index.
|
||||
const { pointBalance, fetchCurrentCredit } = useCurrentCredit();
|
||||
const taskId = ref("");
|
||||
const taskDetail = ref(null);
|
||||
const DETAIL_POLL_INTERVAL = 3000;
|
||||
let detailPollTimer = null;
|
||||
let isFetchingTaskDetail = false;
|
||||
let isPageVisible = false;
|
||||
|
||||
const showToast = (title) => {
|
||||
uni.showToast({
|
||||
@@ -37,42 +41,99 @@ const getPreviousPageRoute = () => {
|
||||
return pages[pages.length - 2]?.route || "";
|
||||
};
|
||||
|
||||
const fetchTaskDetail = async () => {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
mask: true,
|
||||
});
|
||||
const stopTaskDetailPolling = () => {
|
||||
if (detailPollTimer !== null) {
|
||||
clearTimeout(detailPollTimer);
|
||||
detailPollTimer = null;
|
||||
}
|
||||
};
|
||||
|
||||
const isTaskCompleted = () => Number(taskDetail.value?.taskStatus) === 2;
|
||||
|
||||
const fetchTaskDetail = async ({ showLoading = false } = {}) => {
|
||||
if (isFetchingTaskDetail) return isTaskCompleted();
|
||||
|
||||
isFetchingTaskDetail = true;
|
||||
if (showLoading) {
|
||||
uni.showLoading({
|
||||
title: "加载中",
|
||||
mask: true,
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await getAigcGeneratorTaskDetail({ taskId: taskId.value });
|
||||
if (res?.code === 0 && res.data && typeof res.data === "object" && !Array.isArray(res.data)) {
|
||||
taskDetail.value = res.data;
|
||||
return;
|
||||
if (isTaskCompleted()) {
|
||||
stopTaskDetailPolling();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
taskDetail.value = null;
|
||||
showToast(res?.msg || "获取任务进度失败");
|
||||
if (showLoading) {
|
||||
taskDetail.value = null;
|
||||
showToast(res?.msg || "获取任务进度失败");
|
||||
}
|
||||
return false;
|
||||
} catch (error) {
|
||||
console.error("获取AIGC生成任务进度失败", error);
|
||||
taskDetail.value = null;
|
||||
showToast("获取任务进度失败");
|
||||
if (showLoading) {
|
||||
taskDetail.value = null;
|
||||
showToast("获取任务进度失败");
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
isFetchingTaskDetail = false;
|
||||
if (showLoading) {
|
||||
uni.hideLoading();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onLoad((query = {}) => {
|
||||
const scheduleTaskDetailPolling = () => {
|
||||
if (detailPollTimer !== null || !isPageVisible || !taskId.value || isTaskCompleted()) return;
|
||||
|
||||
detailPollTimer = setTimeout(async () => {
|
||||
detailPollTimer = null;
|
||||
const completed = await fetchTaskDetail();
|
||||
if (!completed) {
|
||||
scheduleTaskDetailPolling();
|
||||
}
|
||||
}, DETAIL_POLL_INTERVAL);
|
||||
};
|
||||
|
||||
onLoad(async (query = {}) => {
|
||||
isPageVisible = true;
|
||||
taskId.value = String(query.taskId || "").trim();
|
||||
if (!taskId.value) {
|
||||
showToast("缺少任务ID");
|
||||
return;
|
||||
}
|
||||
|
||||
fetchTaskDetail();
|
||||
const completed = await fetchTaskDetail({ showLoading: true });
|
||||
if (!completed) {
|
||||
scheduleTaskDetailPolling();
|
||||
}
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
isPageVisible = true;
|
||||
fetchCurrentCredit();
|
||||
if (taskDetail.value) {
|
||||
scheduleTaskDetailPolling();
|
||||
}
|
||||
});
|
||||
|
||||
onHide(() => {
|
||||
isPageVisible = false;
|
||||
stopTaskDetailPolling();
|
||||
});
|
||||
|
||||
onUnload(() => {
|
||||
isPageVisible = false;
|
||||
stopTaskDetailPolling();
|
||||
});
|
||||
|
||||
const handleBack = () => {
|
||||
|
||||
Reference in New Issue
Block a user