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:
@@ -19,6 +19,10 @@
|
||||
|
||||
<Privacy :visible="privacyVisible" :contract-name="privacyContractName" @agree="handlePrivacyAgree"
|
||||
@disagree="handlePrivacyDisagree" />
|
||||
<RegenerateConfirmPopup ref="regeneratePopupRef" :cost="regenerateCost" :balance="pointBalance"
|
||||
:loading="isRegenerating" @confirm="handleConfirmRegenerate" />
|
||||
<PointInsufficientDialog v-if="pointDialogVisible" :cost="regenerateCost" :balance="pointBalance"
|
||||
@cancel="handleClosePointDialog" @recharge="handlePointRecharge" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -29,9 +33,12 @@ import Privacy from "@/components/Privacy/index.vue";
|
||||
import AigcTopBar from "@/pages-aigc/components/AigcTopBar/index.vue";
|
||||
import { useCurrentCredit } from "@/pages-aigc/hooks/useCurrentCredit.js";
|
||||
import {
|
||||
createAigcGeneratorTask,
|
||||
createAigcGeneratorTaskShare,
|
||||
getAigcGeneratorTaskDetail,
|
||||
} from "@/request/api/AigcApi.js";
|
||||
import PointInsufficientDialog from "@/pages-aigc/useTemplate/components/PointInsufficientDialog/index.vue";
|
||||
import RegenerateConfirmPopup from "./components/RegenerateConfirmPopup/index.vue";
|
||||
import ResultActions from "./components/ResultActions/index.vue";
|
||||
import ResultMeta from "./components/ResultMeta/index.vue";
|
||||
import ResultPreview from "./components/ResultPreview/index.vue";
|
||||
@@ -45,6 +52,9 @@ const shareKey = ref("");
|
||||
const privacyVisible = ref(false);
|
||||
const privacyContractName = ref("隐私保护指引");
|
||||
const pendingSaveAfterPrivacy = ref(false);
|
||||
const regeneratePopupRef = ref(null);
|
||||
const isRegenerating = ref(false);
|
||||
const pointDialogVisible = ref(false);
|
||||
|
||||
const GENERATOR_TYPE_TEXT = {
|
||||
0: "图片版",
|
||||
@@ -124,6 +134,7 @@ const metaItems = computed(() => {
|
||||
});
|
||||
|
||||
const sharePreviewImage = computed(() => taskDetail.value?.imageResultUrl || "");
|
||||
const regenerateCost = computed(() => Math.max(0, Number(taskDetail.value?.generatorCost) || 0));
|
||||
|
||||
const showPlaceholderToast = (title) => {
|
||||
uni.showToast({
|
||||
@@ -425,8 +436,72 @@ const handlePrivacyDisagree = () => {
|
||||
pendingSaveAfterPrivacy.value = false;
|
||||
};
|
||||
|
||||
const handleRegenerate = () => {
|
||||
showPlaceholderToast("再生成一版");
|
||||
const handleRegenerate = async () => {
|
||||
await fetchCurrentCredit();
|
||||
regeneratePopupRef.value?.open();
|
||||
};
|
||||
|
||||
const handleConfirmRegenerate = async () => {
|
||||
if (isRegenerating.value) return;
|
||||
|
||||
isRegenerating.value = true;
|
||||
await fetchCurrentCredit();
|
||||
|
||||
const balance = Number(pointBalance.value) || 0;
|
||||
if (balance < regenerateCost.value) {
|
||||
isRegenerating.value = false;
|
||||
regeneratePopupRef.value?.close();
|
||||
pointDialogVisible.value = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const templateItemId = String(taskDetail.value?.templateItemId || "").trim();
|
||||
const imageResultUrl = String(taskDetail.value?.imageResultUrl || "").trim();
|
||||
if (!templateItemId || !imageResultUrl) {
|
||||
isRegenerating.value = false;
|
||||
showPlaceholderToast(!templateItemId ? "缺少模板生成项" : "缺少可复用素材");
|
||||
return;
|
||||
}
|
||||
|
||||
uni.showLoading({
|
||||
title: "创建中",
|
||||
mask: true,
|
||||
});
|
||||
|
||||
try {
|
||||
const res = await createAigcGeneratorTask({
|
||||
templateItemId,
|
||||
imageUrlList: [imageResultUrl],
|
||||
});
|
||||
const nextTaskId = String(res?.data || "").trim();
|
||||
|
||||
if (res?.code === 0 && nextTaskId) {
|
||||
regeneratePopupRef.value?.close();
|
||||
fetchCurrentCredit();
|
||||
uni.redirectTo({
|
||||
url: `/pages-aigc/progress/progress?taskId=${encodeURIComponent(nextTaskId)}`,
|
||||
fail: () => showPlaceholderToast("打开任务进度失败"),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
showPlaceholderToast(res?.msg || "创建任务失败");
|
||||
} catch (error) {
|
||||
console.error("重新创建AIGC生成任务失败", error);
|
||||
showPlaceholderToast("创建任务失败");
|
||||
} finally {
|
||||
uni.hideLoading();
|
||||
isRegenerating.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const handleClosePointDialog = () => {
|
||||
pointDialogVisible.value = false;
|
||||
};
|
||||
|
||||
const handlePointRecharge = () => {
|
||||
pointDialogVisible.value = false;
|
||||
handleRecharge();
|
||||
};
|
||||
|
||||
const handleChangeTemplate = () => {
|
||||
|
||||
Reference in New Issue
Block a user