diff --git a/src/pages-aigc/useTemplate/components/GeneratingProgressPanel/index.vue b/src/pages-aigc/progress/components/GeneratingProgressPanel/index.vue
similarity index 76%
rename from src/pages-aigc/useTemplate/components/GeneratingProgressPanel/index.vue
rename to src/pages-aigc/progress/components/GeneratingProgressPanel/index.vue
index a237e00..00113a3 100644
--- a/src/pages-aigc/useTemplate/components/GeneratingProgressPanel/index.vue
+++ b/src/pages-aigc/progress/components/GeneratingProgressPanel/index.vue
@@ -48,10 +48,6 @@
import { computed, onUnmounted, ref, watch } from "vue";
const props = defineProps({
- progress: {
- type: [Number, String],
- default: 8,
- },
cost: {
type: [Number, String],
default: 100,
@@ -76,47 +72,50 @@ const props = defineProps({
const emit = defineEmits(["continue", "view"]);
+const TASK_STATUS_PROGRESS = {
+ 0: 23,
+ 1: 56,
+ 2: 100,
+ 4: 74,
+};
+
const normalizeProgress = (progress) => {
const value = Number(progress);
if (!Number.isFinite(value)) return 0;
- return Math.max(0, Math.min(99, Math.round(value)));
+ return Math.max(0, Math.min(100, Math.round(value)));
};
-const displayProgress = ref(normalizeProgress(props.progress));
+const displayProgress = ref(0);
let progressTimer = null;
const normalizedProgress = computed(() => normalizeProgress(displayProgress.value));
const progressWidth = computed(() => `${normalizedProgress.value}%`);
-
-const isAnimatingStatus = (status) => {
- if (status === null || status === undefined || status === "") return false;
- return [0, 1, 4].includes(Number(status));
-};
+const targetProgress = computed(() => TASK_STATUS_PROGRESS[Number(props.taskStatus)] ?? 0);
const clearProgressTimer = () => {
- if (progressTimer) {
+ if (progressTimer !== null) {
clearInterval(progressTimer);
progressTimer = null;
}
};
-const getNextProgress = (progress) => {
- if (progress < 35) return Math.min(progress + 7, 35);
- if (progress < 70) return Math.min(progress + 5, 70);
- if (progress < 92) return Math.min(progress + 3, 92);
- return Math.min(progress + 1, 99);
-};
-
const startProgressAnimation = () => {
clearProgressTimer();
- if (!isAnimatingStatus(props.taskStatus) || normalizedProgress.value >= 99) return;
+ const target = targetProgress.value;
+ if (normalizedProgress.value === target) return;
progressTimer = setInterval(() => {
- displayProgress.value = getNextProgress(normalizedProgress.value);
- if (normalizedProgress.value >= 99) {
+ const current = normalizedProgress.value;
+ const direction = current < target ? 1 : -1;
+ const distance = Math.abs(target - current);
+ const step = distance > 36 ? 4 : distance > 16 ? 2 : 1;
+ const nextProgress = current + direction * Math.min(step, distance);
+
+ displayProgress.value = nextProgress;
+ if (nextProgress === target) {
clearProgressTimer();
}
- }, 320);
+ }, 60);
};
const generatorTypeText = computed(() => {
@@ -144,23 +143,10 @@ const displaySteps = computed(() => {
}));
});
-watch(
- () => props.progress,
- (progress) => {
- const initialProgress = normalizeProgress(progress);
- if (!isAnimatingStatus(props.taskStatus) || displayProgress.value < initialProgress) {
- displayProgress.value = initialProgress;
- }
- }
-);
-
watch(
() => props.taskStatus,
- (status) => {
- clearProgressTimer();
- if (isAnimatingStatus(status)) {
- startProgressAnimation();
- }
+ () => {
+ startProgressAnimation();
},
{ immediate: true }
);
diff --git a/src/pages-aigc/useTemplate/components/GeneratingProgressPanel/styles/index.scss b/src/pages-aigc/progress/components/GeneratingProgressPanel/styles/index.scss
similarity index 100%
rename from src/pages-aigc/useTemplate/components/GeneratingProgressPanel/styles/index.scss
rename to src/pages-aigc/progress/components/GeneratingProgressPanel/styles/index.scss
diff --git a/src/pages-aigc/progress/progress.vue b/src/pages-aigc/progress/progress.vue
new file mode 100644
index 0000000..13b7718
--- /dev/null
+++ b/src/pages-aigc/progress/progress.vue
@@ -0,0 +1,124 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages-aigc/progress/styles/index.scss b/src/pages-aigc/progress/styles/index.scss
new file mode 100644
index 0000000..07c1d92
--- /dev/null
+++ b/src/pages-aigc/progress/styles/index.scss
@@ -0,0 +1,28 @@
+.aigc-progress-page {
+ display: flex;
+ flex-direction: column;
+ width: 100vw;
+ height: 100vh;
+ overflow: hidden;
+ color: #172033;
+ background:
+ radial-gradient(
+ 130% 78% at 0% 0%,
+ rgba(255, 249, 226, 0.76),
+ rgba(255, 249, 226, 0) 42%
+ ),
+ linear-gradient(180deg, #effaf5 0%, #f4fbf7 58%, #eef8ff 100%);
+ box-sizing: border-box;
+}
+
+.aigc-progress-body {
+ flex: 1 1 0;
+ min-height: 0;
+ overflow: hidden;
+}
+
+.aigc-progress-content {
+ min-height: 100%;
+ padding: 12px 12px 16px;
+ box-sizing: border-box;
+}
diff --git a/src/pages-aigc/record/components/RecordCard/index.vue b/src/pages-aigc/record/components/RecordCard/index.vue
index a650acb..69deb35 100644
--- a/src/pages-aigc/record/components/RecordCard/index.vue
+++ b/src/pages-aigc/record/components/RecordCard/index.vue
@@ -13,8 +13,8 @@
{{ statusText }}
-
- 查看
+
+ {{ actionText }}
@@ -48,7 +48,12 @@ const title = computed(() => props.record.itemTitle || props.record.taskId || ""
const normalizedTaskStatus = computed(() => Number(props.record.taskStatus));
const isCompleted = computed(() => normalizedTaskStatus.value === 2);
-const isGenerating = computed(() => [0, 1].includes(normalizedTaskStatus.value));
+const isGenerating = computed(() => [0, 1, 4].includes(normalizedTaskStatus.value));
+const actionText = computed(() => {
+ if (isCompleted.value) return "查看";
+ if (isGenerating.value) return "进度";
+ return "";
+});
const mediaUrl = computed(() => {
if (!isCompleted.value) return "";
diff --git a/src/pages-aigc/record/record.vue b/src/pages-aigc/record/record.vue
index 13305b3..ef0f710 100644
--- a/src/pages-aigc/record/record.vue
+++ b/src/pages-aigc/record/record.vue
@@ -49,12 +49,21 @@ const handleBack = () => {
};
const handleViewRecord = (record) => {
- if (record?.taskStatus === 2 && record.taskId) {
+ if (!record?.taskId) return;
+
+ const taskStatus = Number(record.taskStatus);
+ if (taskStatus === 2) {
uni.navigateTo({
url: `/pages-aigc/detail/detail?taskId=${encodeURIComponent(record.taskId)}`,
});
return;
}
+
+ if ([0, 1, 4].includes(taskStatus)) {
+ uni.navigateTo({
+ url: `/pages-aigc/progress/progress?taskId=${encodeURIComponent(record.taskId)}`,
+ });
+ }
};
diff --git a/src/pages-aigc/useTemplate/styles/index.scss b/src/pages-aigc/useTemplate/styles/index.scss
index d7256b8..0f36d42 100644
--- a/src/pages-aigc/useTemplate/styles/index.scss
+++ b/src/pages-aigc/useTemplate/styles/index.scss
@@ -31,11 +31,6 @@
box-sizing: border-box;
}
-.aigc-use-template-content.is-generating {
- overflow-y: auto;
- padding: 12px 12px 16px;
-}
-
.aigc-use-template-popup-host {
position: fixed;
z-index: 30;
diff --git a/src/pages-aigc/useTemplate/useTemplate.vue b/src/pages-aigc/useTemplate/useTemplate.vue
index 07eaf21..b11fffd 100644
--- a/src/pages-aigc/useTemplate/useTemplate.vue
+++ b/src/pages-aigc/useTemplate/useTemplate.vue
@@ -4,26 +4,19 @@
@recharge="handleRecharge" />
-
-
+
+
+
+
-
+
-
-
-
-
-
-
- 动效视频版会先生图,再升级为 5 秒内动效视频。
-
-
+
+ 动效视频版会先生图,再升级为 5 秒内动效视频。
+
@@ -55,14 +48,12 @@ import AigcTopBar from "@/pages-aigc/components/AigcTopBar/index.vue";
import { useCurrentCredit } from "@/pages-aigc/hooks/useCurrentCredit.js";
import {
createAigcGeneratorTask,
- getAigcGeneratorTaskDetail,
getAigcTemplateItemList,
getAigcTemplateList,
} from "@/request/api/AigcApi.js";
import { updateImageFile } from "@/request/api/UpdateFile.js";
import guideAvatar from "./assets/xiaoqi-avatar.png";
import GenerateConfirmPanel from "./components/GenerateConfirmPanel/index.vue";
-import GeneratingProgressPanel from "./components/GeneratingProgressPanel/index.vue";
import PhotoConfirmDrawer from "./components/PhotoConfirmDrawer/index.vue";
import PhotoGuidePanel from "./components/PhotoGuidePanel/index.vue";
import PhotoPickDrawer from "./components/PhotoPickDrawer/index.vue";
@@ -78,8 +69,6 @@ const templateItems = ref([]);
const selectedTemplateItemId = ref("");
const selectedImageLocalPath = ref("");
const uploadedImageUrl = ref("");
-const createdTaskId = ref("");
-const taskStatus = ref(null);
const currentStep = ref("version");
const pointDialogVisible = ref(false);
const isUploading = ref(false);
@@ -338,19 +327,6 @@ const handleConfirmPhoto = () => {
currentStep.value = "generateConfirm";
};
-const fetchCreatedTaskStatus = async () => {
- if (!createdTaskId.value) return;
-
- try {
- const res = await getAigcGeneratorTaskDetail({ taskId: createdTaskId.value });
- if (res?.code === 0 && res.data) {
- taskStatus.value = res.data.taskStatus;
- }
- } catch (error) {
- console.warn("获取AIGC生成任务状态失败", error);
- }
-};
-
const handleGenerate = async () => {
if (isCreatingTask.value) return;
@@ -375,9 +351,10 @@ const handleGenerate = async () => {
}
isCreatingTask.value = true;
- createdTaskId.value = "";
- taskStatus.value = null;
- currentStep.value = "generating";
+ uni.showLoading({
+ title: "创建中",
+ mask: true,
+ });
try {
const res = await createAigcGeneratorTask({
@@ -385,37 +362,25 @@ const handleGenerate = async () => {
imageUrlList: [uploadedImageUrl.value],
});
- if (res?.code === 0 && res.data) {
- createdTaskId.value = res.data;
+ const taskId = String(res?.data || "").trim();
+ if (res?.code === 0 && taskId) {
fetchCurrentCredit();
- await fetchCreatedTaskStatus();
+ uni.redirectTo({
+ url: `/pages-aigc/progress/progress?taskId=${encodeURIComponent(taskId)}`,
+ fail: () => showPlaceholderToast("打开任务进度失败"),
+ });
} else {
- currentStep.value = "generateConfirm";
showPlaceholderToast(res?.msg || "创建任务失败");
}
} catch (error) {
console.warn("创建AIGC生成任务失败", error);
- currentStep.value = "generateConfirm";
showPlaceholderToast("创建任务失败");
} finally {
+ uni.hideLoading();
isCreatingTask.value = false;
}
};
-const handleContinueTemplates = () => {
- const pages = getCurrentPages();
- const previousPage = pages[pages.length - 2];
- if (previousPage?.route === "pages-aigc/home/home") {
- uni.navigateBack();
- return;
- }
-
- uni.redirectTo({
- url: "/pages-aigc/home/home",
- fail: () => showPlaceholderToast("继续生成其他模板"),
- });
-};
-
const handleClosePointDialog = () => {
pointDialogVisible.value = false;
};
diff --git a/src/pages.json b/src/pages.json
index bc9bce8..ee05b64 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -170,6 +170,12 @@
"navigationStyle": "custom"
}
},
+ {
+ "path": "progress/progress",
+ "style": {
+ "navigationStyle": "custom"
+ }
+ },
{
"path": "detail/detail",
"style": {
diff --git a/src/pages/ChatMain/ChatQuickAccess/index.vue b/src/pages/ChatMain/ChatQuickAccess/index.vue
index 0d50325..47417f4 100644
--- a/src/pages/ChatMain/ChatQuickAccess/index.vue
+++ b/src/pages/ChatMain/ChatQuickAccess/index.vue
@@ -12,10 +12,7 @@
-
+
@@ -36,16 +33,16 @@ const itemList = ref([
title: "快速预定",
type: Command.quickBooking,
},
- // {
- // icon: "",
- // title: "旅行记录",
- // type: Command.travelAIGC,
- // },
{
icon: "",
- title: "我的订单",
- type: Command.myOrder,
+ title: "旅行记录",
+ type: Command.travelAIGC,
},
+ // {
+ // icon: "",
+ // title: "我的订单",
+ // type: Command.myOrder,
+ // },
{
icon: "",
title: "呼叫服务",