Compare commits
2 Commits
2e56e20f06
...
d6c82204d4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6c82204d4 | ||
|
|
9bdef279b7 |
@@ -3,7 +3,9 @@
|
|||||||
<video v-if="isVideoRecord" class="record-card-image" :src="mediaUrl" :controls="false" :show-play-btn="false"
|
<video v-if="isVideoRecord" class="record-card-image" :src="mediaUrl" :controls="false" :show-play-btn="false"
|
||||||
:show-center-play-btn="false" object-fit="cover" />
|
:show-center-play-btn="false" object-fit="cover" />
|
||||||
<image v-else-if="mediaUrl" class="record-card-image" :src="mediaUrl" mode="aspectFill" />
|
<image v-else-if="mediaUrl" class="record-card-image" :src="mediaUrl" mode="aspectFill" />
|
||||||
<view v-else class="record-card-image record-card-media-placeholder" />
|
<view v-else class="record-card-image record-card-media-placeholder">
|
||||||
|
<text v-if="isGenerating" class="record-card-media-text">生成中</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
<view class="record-card-copy">
|
<view class="record-card-copy">
|
||||||
<text class="record-card-title ellipsis-1">{{ title }}</text>
|
<text class="record-card-title ellipsis-1">{{ title }}</text>
|
||||||
@@ -11,7 +13,7 @@
|
|||||||
<text class="record-card-status ellipsis-1">{{ statusText }}</text>
|
<text class="record-card-status ellipsis-1">{{ statusText }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view v-if="record.taskStatus === 2" class="record-card-action" @tap="emit('view', record)">
|
<view v-if="isCompleted" class="record-card-action" @tap="emit('view', record)">
|
||||||
查看
|
查看
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -44,12 +46,17 @@ const TASK_STATUS_TEXT = {
|
|||||||
|
|
||||||
const title = computed(() => props.record.itemTitle || props.record.taskId || "");
|
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 mediaUrl = computed(() => {
|
const mediaUrl = computed(() => {
|
||||||
|
if (!isCompleted.value) return "";
|
||||||
return props.record.imageResultUrl || props.record.videoResultUrl || "";
|
return props.record.imageResultUrl || props.record.videoResultUrl || "";
|
||||||
});
|
});
|
||||||
|
|
||||||
const isVideoRecord = computed(() => {
|
const isVideoRecord = computed(() => {
|
||||||
return !props.record.imageResultUrl && Boolean(props.record.videoResultUrl);
|
return isCompleted.value && !props.record.imageResultUrl && Boolean(props.record.videoResultUrl);
|
||||||
});
|
});
|
||||||
|
|
||||||
const statusText = computed(() => {
|
const statusText = computed(() => {
|
||||||
|
|||||||
@@ -26,9 +26,19 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.record-card-media-placeholder {
|
.record-card-media-placeholder {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
background: linear-gradient(135deg, #edf5f1 0%, #f6faf8 100%);
|
background: linear-gradient(135deg, #edf5f1 0%, #f6faf8 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.record-card-media-text {
|
||||||
|
color: #263f52;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 16px;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
.record-card-copy {
|
.record-card-copy {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="generating-progress-panel">
|
<view class="generating-task-panel">
|
||||||
|
<view class="generating-task-status">
|
||||||
|
<text class="generating-task-badge">{{ generatorTypeText }}</text>
|
||||||
|
<text class="generating-task-title">接口处理中,可稍后查看</text>
|
||||||
|
<text class="generating-task-desc">{{ displayItemTitle }} · 任务已进入后台队列</text>
|
||||||
|
<text class="generating-task-hint">生成完成后可在最近任务查看结果</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
<view class="generating-progress-row">
|
<view class="generating-progress-row">
|
||||||
<view class="generating-progress-track">
|
<view class="generating-progress-track">
|
||||||
<view class="generating-progress-fill" :style="{ width: progressWidth }" />
|
<view class="generating-progress-fill" :style="{ width: progressWidth }" />
|
||||||
@@ -8,25 +15,37 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="generating-step-list">
|
<view class="generating-step-list">
|
||||||
<view
|
<view v-for="step in displaySteps" :key="step.label" class="generating-step-item"
|
||||||
v-for="(step, index) in steps"
|
:class="{ 'is-complete': step.complete }">
|
||||||
:key="`${step}-${index}`"
|
|
||||||
class="generating-step-item"
|
|
||||||
:class="getStepClass(index)"
|
|
||||||
>
|
|
||||||
<view class="generating-step-dot" />
|
<view class="generating-step-dot" />
|
||||||
<text class="generating-step-label">{{ step }}</text>
|
<text class="generating-step-label">{{ step.label }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<text class="generating-freeze-text">
|
<view class="generating-background-note">
|
||||||
已冻结 {{ cost }} 积分,生成成功后扣除,失败自动退回。
|
<text class="generating-note-title">不用停留等待</text>
|
||||||
</text>
|
<text class="generating-note-desc">
|
||||||
|
系统会继续处理当前任务,你可以先去制作其他模板,完成后会进入最近任务。
|
||||||
|
</text>
|
||||||
|
|
||||||
|
<view class="generating-actions">
|
||||||
|
<view class="generating-action is-primary" hover-class="is-pressed" @tap="emit('continue')">
|
||||||
|
继续生成其他模板
|
||||||
|
</view>
|
||||||
|
<view class="generating-action is-secondary" hover-class="is-pressed" @tap="emit('view')">
|
||||||
|
查看任务
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<text class="generating-freeze-text">
|
||||||
|
已冻结 {{ displayCost }} 积分,生成成功后扣除,失败自动退回。
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed, onMounted, onUnmounted, ref, watch } from "vue";
|
import { computed, onUnmounted, ref, watch } from "vue";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
progress: {
|
progress: {
|
||||||
@@ -37,37 +56,42 @@ const props = defineProps({
|
|||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
default: 100,
|
default: 100,
|
||||||
},
|
},
|
||||||
steps: {
|
generatorType: {
|
||||||
type: Array,
|
type: [Number, String],
|
||||||
default: () => ["素材质检", "图片优化", "套入模板", "导出图片"],
|
default: 0,
|
||||||
|
},
|
||||||
|
itemTitle: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
taskId: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
taskStatus: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: null,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(["complete"]);
|
const emit = defineEmits(["continue", "view"]);
|
||||||
|
|
||||||
const displayProgress = ref(0);
|
|
||||||
let progressTimer = null;
|
|
||||||
let hasCompleted = false;
|
|
||||||
|
|
||||||
const normalizeProgress = (progress) => {
|
const normalizeProgress = (progress) => {
|
||||||
const value = Number(progress);
|
const value = Number(progress);
|
||||||
if (!Number.isFinite(value)) return 0;
|
if (!Number.isFinite(value)) return 0;
|
||||||
return Math.max(0, Math.min(100, Math.round(value)));
|
return Math.max(0, Math.min(99, Math.round(value)));
|
||||||
};
|
};
|
||||||
|
|
||||||
const normalizedProgress = computed(() => {
|
const displayProgress = ref(normalizeProgress(props.progress));
|
||||||
return normalizeProgress(displayProgress.value);
|
let progressTimer = null;
|
||||||
});
|
|
||||||
|
|
||||||
|
const normalizedProgress = computed(() => normalizeProgress(displayProgress.value));
|
||||||
const progressWidth = computed(() => `${normalizedProgress.value}%`);
|
const progressWidth = computed(() => `${normalizedProgress.value}%`);
|
||||||
|
|
||||||
const currentStepIndex = computed(() => {
|
const isAnimatingStatus = (status) => {
|
||||||
const progress = normalizedProgress.value;
|
if (status === null || status === undefined || status === "") return false;
|
||||||
if (progress <= 24) return 0;
|
return [0, 1, 4].includes(Number(status));
|
||||||
if (progress <= 49) return 1;
|
};
|
||||||
if (progress <= 79) return 2;
|
|
||||||
return 3;
|
|
||||||
});
|
|
||||||
|
|
||||||
const clearProgressTimer = () => {
|
const clearProgressTimer = () => {
|
||||||
if (progressTimer) {
|
if (progressTimer) {
|
||||||
@@ -80,56 +104,66 @@ const getNextProgress = (progress) => {
|
|||||||
if (progress < 35) return Math.min(progress + 7, 35);
|
if (progress < 35) return Math.min(progress + 7, 35);
|
||||||
if (progress < 70) return Math.min(progress + 5, 70);
|
if (progress < 70) return Math.min(progress + 5, 70);
|
||||||
if (progress < 92) return Math.min(progress + 3, 92);
|
if (progress < 92) return Math.min(progress + 3, 92);
|
||||||
if (progress < 99) return Math.min(progress + 1, 99);
|
return Math.min(progress + 1, 99);
|
||||||
return 100;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const completeProgress = () => {
|
const startProgressAnimation = () => {
|
||||||
clearProgressTimer();
|
clearProgressTimer();
|
||||||
if (hasCompleted) return;
|
if (!isAnimatingStatus(props.taskStatus) || normalizedProgress.value >= 99) return;
|
||||||
|
|
||||||
hasCompleted = true;
|
|
||||||
emit("complete");
|
|
||||||
};
|
|
||||||
|
|
||||||
const startProgressTimer = () => {
|
|
||||||
clearProgressTimer();
|
|
||||||
|
|
||||||
if (normalizedProgress.value >= 100) {
|
|
||||||
completeProgress();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
progressTimer = setInterval(() => {
|
progressTimer = setInterval(() => {
|
||||||
displayProgress.value = getNextProgress(normalizedProgress.value);
|
displayProgress.value = getNextProgress(normalizedProgress.value);
|
||||||
|
if (normalizedProgress.value >= 99) {
|
||||||
if (normalizedProgress.value >= 100) {
|
clearProgressTimer();
|
||||||
completeProgress();
|
|
||||||
}
|
}
|
||||||
}, 320);
|
}, 320);
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetProgress = () => {
|
const generatorTypeText = computed(() => {
|
||||||
hasCompleted = false;
|
if (props.generatorType === "" || props.generatorType === null || props.generatorType === undefined) {
|
||||||
displayProgress.value = normalizeProgress(props.progress);
|
return "生成任务";
|
||||||
startProgressTimer();
|
}
|
||||||
};
|
if (Number(props.generatorType) === 0) return "图片版";
|
||||||
|
if (Number(props.generatorType) === 1) return "视频版";
|
||||||
|
return `类型${props.generatorType}`;
|
||||||
|
});
|
||||||
|
|
||||||
const getStepClass = (index) => ({
|
const displayItemTitle = computed(() => props.itemTitle || props.taskId || "生成任务");
|
||||||
"is-complete": normalizedProgress.value >= 100 || index < currentStepIndex.value,
|
const displayCost = computed(() => Number(props.cost) || 0);
|
||||||
"is-active": normalizedProgress.value < 100 && index === currentStepIndex.value,
|
|
||||||
|
const displaySteps = computed(() => {
|
||||||
|
const steps =
|
||||||
|
Number(props.generatorType) === 1
|
||||||
|
? ["素材质检", "生成图片底图", "升级动效视频", "导出视频"]
|
||||||
|
: ["素材质检", "图片优化", "套入模板", "导出图片"];
|
||||||
|
const thresholds = [20, 46, 72, 96];
|
||||||
|
|
||||||
|
return steps.map((label, index) => ({
|
||||||
|
label,
|
||||||
|
complete: normalizedProgress.value >= thresholds[index],
|
||||||
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.progress,
|
() => props.progress,
|
||||||
() => {
|
(progress) => {
|
||||||
resetProgress();
|
const initialProgress = normalizeProgress(progress);
|
||||||
|
if (!isAnimatingStatus(props.taskStatus) || displayProgress.value < initialProgress) {
|
||||||
|
displayProgress.value = initialProgress;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
watch(
|
||||||
resetProgress();
|
() => props.taskStatus,
|
||||||
});
|
(status) => {
|
||||||
|
clearProgressTimer();
|
||||||
|
if (isAnimatingStatus(status)) {
|
||||||
|
startProgressAnimation();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
clearProgressTimer();
|
clearProgressTimer();
|
||||||
|
|||||||
@@ -1,13 +1,76 @@
|
|||||||
.generating-progress-panel {
|
.generating-task-panel {
|
||||||
margin-top: 20px;
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generating-task-status {
|
||||||
|
position: relative;
|
||||||
|
min-height: 134px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: block;
|
||||||
|
padding: 18px 18px 16px;
|
||||||
|
border-radius: 22px;
|
||||||
|
background:
|
||||||
|
radial-gradient(96% 120% at 96% 0%, rgba(32, 207, 117, 0.1), rgba(32, 207, 117, 0) 52%),
|
||||||
|
rgba(255, 255, 255, 0.84);
|
||||||
|
box-shadow: 0 12px 28px rgba(15, 29, 37, 0.08);
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generating-task-badge {
|
||||||
|
height: 24px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 10px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: rgba(32, 207, 117, 0.13);
|
||||||
|
color: #0e9f61;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generating-task-title,
|
||||||
|
.generating-task-desc,
|
||||||
|
.generating-task-hint {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generating-task-title {
|
||||||
|
margin-top: 16px;
|
||||||
|
color: #172033;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 30px;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generating-task-desc {
|
||||||
|
margin-top: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #526073;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 18px;
|
||||||
|
font-weight: 800;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generating-task-hint {
|
||||||
|
margin-top: 10px;
|
||||||
|
color: #91a0b1;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 15px;
|
||||||
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
.generating-progress-row {
|
.generating-progress-row {
|
||||||
height: 18px;
|
height: 52px;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(0, 1fr) 34px;
|
grid-template-columns: minmax(0, 1fr) 42px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
margin-top: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.generating-progress-track {
|
.generating-progress-track {
|
||||||
@@ -15,35 +78,34 @@
|
|||||||
height: 12px;
|
height: 12px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
background: rgba(255, 255, 255, 0.78);
|
background: rgba(255, 255, 255, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.generating-progress-fill {
|
.generating-progress-fill {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-width: 24px;
|
min-width: 24px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
background: linear-gradient(90deg, #20cf75 0%, #f2d646 100%);
|
background: linear-gradient(90deg, #20cf75 0%, #f5bd32 100%);
|
||||||
transition: width 0.28s ease;
|
transition: width 280ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.generating-progress-text {
|
.generating-progress-text {
|
||||||
color: #061e34;
|
color: #172033;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
line-height: 18px;
|
line-height: 20px;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.generating-step-list {
|
.generating-step-list {
|
||||||
display: flex;
|
display: grid;
|
||||||
flex-direction: column;
|
gap: 9px;
|
||||||
gap: 10px;
|
margin-top: 12px;
|
||||||
margin-top: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.generating-step-item {
|
.generating-step-item {
|
||||||
height: 40px;
|
height: 42px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
@@ -53,39 +115,25 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.generating-step-item.is-active {
|
|
||||||
background: rgba(255, 255, 255, 0.86);
|
|
||||||
}
|
|
||||||
|
|
||||||
.generating-step-item.is-complete {
|
|
||||||
background: rgba(236, 255, 244, 0.72);
|
|
||||||
}
|
|
||||||
|
|
||||||
.generating-step-dot {
|
.generating-step-dot {
|
||||||
flex: 0 0 18px;
|
flex: 0 0 18px;
|
||||||
width: 18px;
|
width: 18px;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
border: 2px solid #d6e8f4;
|
border: 2px solid #c7d2df;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: rgba(255, 255, 255, 0.7);
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.generating-step-item.is-active .generating-step-dot {
|
.generating-step-item.is-complete .generating-step-dot {
|
||||||
border-color: #20cf75;
|
border-color: #20cf75;
|
||||||
background: #20cf75;
|
background: #20cf75;
|
||||||
box-shadow: 0 0 0 4px rgba(32, 207, 117, 0.12);
|
box-shadow: inset 0 0 0 4px #ffffff;
|
||||||
}
|
|
||||||
|
|
||||||
.generating-step-item.is-complete .generating-step-dot {
|
|
||||||
border-color: rgba(32, 207, 117, 0.42);
|
|
||||||
background: rgba(32, 207, 117, 0.22);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.generating-step-label {
|
.generating-step-label {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
color: #6c7e96;
|
color: #7d899a;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
@@ -93,18 +141,85 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.generating-step-item.is-active .generating-step-label,
|
|
||||||
.generating-step-item.is-complete .generating-step-label {
|
.generating-step-item.is-complete .generating-step-label {
|
||||||
color: #172033;
|
color: #172033;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.generating-background-note {
|
||||||
|
margin-top: 16px;
|
||||||
|
padding: 14px;
|
||||||
|
border-radius: 18px;
|
||||||
|
background:
|
||||||
|
linear-gradient(135deg, rgba(32, 207, 117, 0.11), rgba(255, 255, 255, 0.9) 54%),
|
||||||
|
rgba(255, 255, 255, 0.84);
|
||||||
|
color: #172033;
|
||||||
|
box-shadow: 0 10px 22px rgba(18, 48, 56, 0.07);
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generating-note-title,
|
||||||
|
.generating-note-desc,
|
||||||
.generating-freeze-text {
|
.generating-freeze-text {
|
||||||
display: block;
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generating-note-title {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 19px;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generating-note-desc {
|
||||||
|
margin-top: 4px;
|
||||||
|
color: #526073;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 16px;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generating-actions {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1.2fr 1fr;
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generating-action {
|
||||||
|
min-width: 0;
|
||||||
|
height: 48px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin: 18px 14px 0;
|
border-radius: 999px;
|
||||||
color: #7b8da4;
|
font-size: 15px;
|
||||||
font-size: 12px;
|
line-height: 20px;
|
||||||
line-height: 18px;
|
font-weight: 900;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generating-action.is-primary {
|
||||||
|
background: #20cf75;
|
||||||
|
color: #ffffff;
|
||||||
|
box-shadow: 0 8px 16px rgba(32, 207, 117, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.generating-action.is-secondary {
|
||||||
|
background: rgba(255, 255, 255, 0.78);
|
||||||
|
color: #526073;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generating-action.is-pressed {
|
||||||
|
opacity: 0.82;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generating-freeze-text {
|
||||||
|
overflow: hidden;
|
||||||
|
margin-top: 8px;
|
||||||
|
color: #8c98a8;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 14px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
|||||||
@@ -1,51 +1,34 @@
|
|||||||
<template>
|
<template>
|
||||||
<uni-popup
|
<uni-popup ref="popupRef" type="bottom" background-color="transparent" mask-background-color="rgba(0, 0, 0, 0)"
|
||||||
ref="popupRef"
|
:safe-area="false" :is-mask-click="false">
|
||||||
type="bottom"
|
|
||||||
background-color="transparent"
|
|
||||||
mask-background-color="rgba(0, 0, 0, 0)"
|
|
||||||
:safe-area="false"
|
|
||||||
:is-mask-click="false"
|
|
||||||
>
|
|
||||||
<view class="photo-pick-drawer">
|
<view class="photo-pick-drawer">
|
||||||
<view
|
<view class="photo-pick-close" :class="{ 'is-disabled': loading }" @tap="handleClose">
|
||||||
class="photo-pick-close"
|
|
||||||
:class="{ 'is-disabled': loading }"
|
|
||||||
@tap="handleClose"
|
|
||||||
>
|
|
||||||
<uni-icons type="closeempty" size="30" color="#8fa2ba" />
|
<uni-icons type="closeempty" size="30" color="#8fa2ba" />
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<text class="photo-pick-title">选择照片</text>
|
<text class="photo-pick-title">选择照片</text>
|
||||||
|
|
||||||
<view class="photo-pick-card">
|
<view class="photo-pick-card">
|
||||||
<view class="photo-pick-plus">+</view>
|
<view class="photo-pick-card-title">上传素材要求</view>
|
||||||
<text class="photo-pick-card-title">上传照片素材</text>
|
<view class="photo-pick-card-desc">
|
||||||
<text class="photo-pick-card-desc">
|
请使用清晰半身照,避免墨镜、口罩、强逆光。选择后系统自动进行清晰度、人脸数量和遮挡检测。
|
||||||
选择后会自动进行清晰度、人脸数量和遮挡检测
|
</view>
|
||||||
</text>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="photo-pick-actions">
|
<view class="photo-pick-actions">
|
||||||
<view
|
<view class="photo-pick-action is-primary" :class="{ 'is-disabled': loading }"
|
||||||
class="photo-pick-action"
|
:hover-class="loading ? 'none' : 'is-pressed'" @tap="handleCamera">
|
||||||
:class="{ 'is-disabled': loading }"
|
<text class="photo-pick-action-title">拍照</text>
|
||||||
:hover-class="loading ? 'none' : 'is-pressed'"
|
<text class="photo-pick-action-desc">现场拍摄素材</text>
|
||||||
@tap="handleCamera"
|
|
||||||
>
|
|
||||||
拍照
|
|
||||||
</view>
|
</view>
|
||||||
<view
|
<view class="photo-pick-action" :class="{ 'is-disabled': loading }"
|
||||||
class="photo-pick-action"
|
:hover-class="loading ? 'none' : 'is-pressed'" @tap="handleAlbum">
|
||||||
:class="{ 'is-disabled': loading }"
|
<text class="photo-pick-action-title">相册</text>
|
||||||
:hover-class="loading ? 'none' : 'is-pressed'"
|
<text class="photo-pick-action-desc">从相册选择</text>
|
||||||
@tap="handleAlbum"
|
|
||||||
>
|
|
||||||
相册
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<text class="photo-pick-hint">建议使用半身照,避免墨镜、口罩、强逆光。</text>
|
<text class="photo-pick-hint">入口在这里,选择后进入照片质检与生成确认。</text>
|
||||||
</view>
|
</view>
|
||||||
</uni-popup>
|
</uni-popup>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -39,34 +39,14 @@
|
|||||||
|
|
||||||
.photo-pick-card {
|
.photo-pick-card {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 126px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
padding: 14px 18px;
|
padding: 14px 18px;
|
||||||
border: 1.5px dashed rgba(32, 207, 117, 0.46);
|
border: 1.5px dashed rgba(32, 207, 117, 0.46);
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
background: #f2fbf6;
|
background: #f2fbf6;
|
||||||
text-align: center;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.photo-pick-plus {
|
|
||||||
width: 42px;
|
|
||||||
height: 42px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: #20cf75;
|
|
||||||
color: #ffffff;
|
|
||||||
font-size: 25px;
|
|
||||||
line-height: 42px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.photo-pick-card-title,
|
.photo-pick-card-title,
|
||||||
.photo-pick-card-desc {
|
.photo-pick-card-desc {
|
||||||
display: block;
|
display: block;
|
||||||
@@ -75,16 +55,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.photo-pick-card-title {
|
.photo-pick-card-title {
|
||||||
max-width: 230px;
|
|
||||||
color: #172033;
|
color: #172033;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
font-weight: 900;
|
font-weight: 700;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.photo-pick-card-desc {
|
.photo-pick-card-desc {
|
||||||
max-width: 230px;
|
|
||||||
color: #667386;
|
color: #667386;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 18px;
|
line-height: 18px;
|
||||||
@@ -95,22 +74,58 @@
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
margin-top: 10px;
|
margin-top: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.photo-pick-action {
|
.photo-pick-action {
|
||||||
height: 42px;
|
min-width: 0;
|
||||||
|
min-height: 66px;
|
||||||
|
padding: 8px 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
border-radius: 16px;
|
gap: 3px;
|
||||||
background: #f5f8f7;
|
border-radius: 18px;
|
||||||
|
background: #ffffff;
|
||||||
color: #172033;
|
color: #172033;
|
||||||
font-size: 14px;
|
box-shadow: 0 8px 18px rgba(18, 48, 56, 0.08);
|
||||||
|
transition: opacity 180ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-pick-action.is-primary {
|
||||||
|
background: #20cf75;
|
||||||
|
color: #ffffff;
|
||||||
|
box-shadow: 0 12px 22px rgba(32, 207, 117, 0.22);
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-pick-action-title,
|
||||||
|
.photo-pick-action-desc {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-pick-action-title {
|
||||||
|
font-size: 15px;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.photo-pick-action-desc {
|
||||||
|
color: #7a8596;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 14px;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.photo-pick-action.is-primary .photo-pick-action-desc {
|
||||||
|
color: rgba(255, 255, 255, 0.82);
|
||||||
|
}
|
||||||
|
|
||||||
.photo-pick-action.is-pressed {
|
.photo-pick-action.is-pressed {
|
||||||
opacity: 0.82;
|
opacity: 0.82;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,28 @@
|
|||||||
:safe-area="false"
|
:safe-area="false"
|
||||||
:is-mask-click="false"
|
:is-mask-click="false"
|
||||||
>
|
>
|
||||||
<view class="point-dialog">
|
<view class="point-dialog point-recharge-dialog">
|
||||||
<text class="point-dialog-title">积分不足</text>
|
<text class="point-dialog-badge">充值提醒</text>
|
||||||
|
<text class="point-dialog-title">当前积分不足</text>
|
||||||
<text class="point-dialog-desc">
|
<text class="point-dialog-desc">
|
||||||
本次需 {{ normalizedCost }} 积分,当前仅 {{ normalizedBalance }} 积分,还差 {{ shortage }} 积分。
|
本次生成需要先冻结对应积分,充值后可继续当前素材生成。
|
||||||
</text>
|
</text>
|
||||||
|
|
||||||
|
<view class="point-dialog-summary">
|
||||||
|
<view class="point-summary-item">
|
||||||
|
<text class="point-summary-label">当前积分</text>
|
||||||
|
<text class="point-summary-value">{{ normalizedBalance }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="point-summary-item">
|
||||||
|
<text class="point-summary-label">本次需要</text>
|
||||||
|
<text class="point-summary-value">{{ normalizedCost }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="point-summary-item is-shortage">
|
||||||
|
<text class="point-summary-label">需补足</text>
|
||||||
|
<text class="point-summary-value">{{ shortage }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
<view class="point-dialog-actions">
|
<view class="point-dialog-actions">
|
||||||
<view
|
<view
|
||||||
class="point-dialog-button is-cancel"
|
class="point-dialog-button is-cancel"
|
||||||
|
|||||||
@@ -1,36 +1,96 @@
|
|||||||
.point-dialog {
|
.point-dialog {
|
||||||
width: 318px;
|
width: 318px;
|
||||||
max-width: calc(100vw - 56px);
|
max-width: calc(100vw - 56px);
|
||||||
min-height: 220px;
|
padding: 30px 26px 24px;
|
||||||
padding: 29px 24px 22px;
|
border-radius: 24px;
|
||||||
border: 1px solid rgba(20, 143, 255, 0.8);
|
background: #ffffff;
|
||||||
border-radius: 20px;
|
box-shadow: 0 18px 48px rgba(0, 0, 0, 0.26);
|
||||||
background: #dceeff;
|
|
||||||
box-shadow: 0 18px 38px rgba(8, 28, 44, 0.22);
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.point-recharge-dialog {
|
||||||
|
padding-top: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.point-dialog-badge {
|
||||||
|
width: fit-content;
|
||||||
|
height: 26px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0 auto 12px;
|
||||||
|
padding: 0 12px;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: #e9f9f1;
|
||||||
|
color: #0fa567;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 26px;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
.point-dialog-title {
|
.point-dialog-title {
|
||||||
display: block;
|
display: block;
|
||||||
color: #102942;
|
margin-bottom: 14px;
|
||||||
font-size: 22px;
|
color: #111827;
|
||||||
line-height: 29px;
|
font-size: 20px;
|
||||||
|
line-height: 28px;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.point-dialog-desc {
|
.point-dialog-desc {
|
||||||
display: block;
|
display: block;
|
||||||
overflow: hidden;
|
margin: 0;
|
||||||
margin: 15px auto 0;
|
color: #667386;
|
||||||
max-width: 228px;
|
|
||||||
color: #506985;
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.point-dialog-summary {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 8px;
|
||||||
|
margin-top: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.point-summary-item {
|
||||||
|
min-width: 0;
|
||||||
|
padding: 11px 6px 10px;
|
||||||
|
border-radius: 15px;
|
||||||
|
background: #f3fbf6;
|
||||||
|
color: #172033;
|
||||||
|
text-align: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.point-summary-label,
|
||||||
|
.point-summary-value {
|
||||||
|
display: block;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.point-summary-label {
|
||||||
|
color: #7b8798;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 13px;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.point-summary-value {
|
||||||
|
margin-top: 3px;
|
||||||
|
color: #172033;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 24px;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.point-summary-item.is-shortage .point-summary-value {
|
||||||
|
color: #0fa567;
|
||||||
|
}
|
||||||
|
|
||||||
.point-dialog-actions {
|
.point-dialog-actions {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
@@ -55,9 +115,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.point-dialog-button.is-cancel {
|
.point-dialog-button.is-cancel {
|
||||||
border: 1px solid rgba(124, 168, 207, 0.28);
|
border: 1px solid #e2e6ea;
|
||||||
background: rgba(255, 255, 255, 0.14);
|
background: #ffffff;
|
||||||
color: #102942;
|
color: #172033;
|
||||||
}
|
}
|
||||||
|
|
||||||
.point-dialog-button.is-primary {
|
.point-dialog-button.is-primary {
|
||||||
|
|||||||
@@ -31,6 +31,11 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.aigc-use-template-content.is-generating {
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 12px 12px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.aigc-use-template-popup-host {
|
.aigc-use-template-popup-host {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 30;
|
z-index: 30;
|
||||||
|
|||||||
@@ -4,21 +4,26 @@
|
|||||||
@recharge="handleRecharge" />
|
@recharge="handleRecharge" />
|
||||||
|
|
||||||
<view class="aigc-use-template-body">
|
<view class="aigc-use-template-body">
|
||||||
<view class="aigc-use-template-content">
|
<view class="aigc-use-template-content" :class="{ 'is-generating': currentStep === 'generating' }">
|
||||||
<TemplateVersionHero :template="currentTemplate" />
|
<GeneratingProgressPanel v-if="currentStep === 'generating'" :cost="currentCost" :progress="8"
|
||||||
|
:generator-type="currentTemplateItem.generatorType"
|
||||||
<GenerateConfirmPanel v-if="currentStep === 'generateConfirm'" :cost="currentCost" :balance="pointBalance"
|
:item-title="currentTemplateItem.itemTitle || currentTemplate.templateTitle" :task-id="createdTaskId"
|
||||||
@generate="handleGenerate" @recharge="handleRecharge" />
|
:task-status="taskStatus" @continue="handleContinueTemplates" @view="handleHistory" />
|
||||||
<GeneratingProgressPanel v-else-if="currentStep === 'generating'" :cost="currentCost" :progress="8"
|
|
||||||
@complete="handleGenerateComplete" />
|
|
||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<VersionOptionList :options="templateItems" :selected-value="selectedTemplateItemId"
|
<TemplateVersionHero :template="currentTemplate" />
|
||||||
@select="handleSelectTemplateItem" />
|
|
||||||
|
|
||||||
<text class="aigc-use-template-note">
|
<GenerateConfirmPanel v-if="currentStep === 'generateConfirm'" :cost="currentCost"
|
||||||
动效视频版会先生图,再升级为 5 秒内动效视频。
|
:balance="pointBalance" @generate="handleGenerate" @recharge="handleRecharge" />
|
||||||
</text>
|
|
||||||
|
<template v-else>
|
||||||
|
<VersionOptionList :options="templateItems" :selected-value="selectedTemplateItemId"
|
||||||
|
@select="handleSelectTemplateItem" />
|
||||||
|
|
||||||
|
<text class="aigc-use-template-note">
|
||||||
|
动效视频版会先生图,再升级为 5 秒内动效视频。
|
||||||
|
</text>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -50,6 +55,7 @@ import AigcTopBar from "@/pages-aigc/components/AigcTopBar/index.vue";
|
|||||||
import { useCurrentCredit } from "@/pages-aigc/hooks/useCurrentCredit.js";
|
import { useCurrentCredit } from "@/pages-aigc/hooks/useCurrentCredit.js";
|
||||||
import {
|
import {
|
||||||
createAigcGeneratorTask,
|
createAigcGeneratorTask,
|
||||||
|
getAigcGeneratorTaskDetail,
|
||||||
getAigcTemplateItemList,
|
getAigcTemplateItemList,
|
||||||
getAigcTemplateList,
|
getAigcTemplateList,
|
||||||
} from "@/request/api/AigcApi.js";
|
} from "@/request/api/AigcApi.js";
|
||||||
@@ -73,6 +79,7 @@ const selectedTemplateItemId = ref("");
|
|||||||
const selectedImageLocalPath = ref("");
|
const selectedImageLocalPath = ref("");
|
||||||
const uploadedImageUrl = ref("");
|
const uploadedImageUrl = ref("");
|
||||||
const createdTaskId = ref("");
|
const createdTaskId = ref("");
|
||||||
|
const taskStatus = ref(null);
|
||||||
const currentStep = ref("version");
|
const currentStep = ref("version");
|
||||||
const pointDialogVisible = ref(false);
|
const pointDialogVisible = ref(false);
|
||||||
const isUploading = ref(false);
|
const isUploading = ref(false);
|
||||||
@@ -331,6 +338,19 @@ const handleConfirmPhoto = () => {
|
|||||||
currentStep.value = "generateConfirm";
|
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 () => {
|
const handleGenerate = async () => {
|
||||||
if (isCreatingTask.value) return;
|
if (isCreatingTask.value) return;
|
||||||
|
|
||||||
@@ -355,10 +375,9 @@ const handleGenerate = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isCreatingTask.value = true;
|
isCreatingTask.value = true;
|
||||||
uni.showLoading({
|
createdTaskId.value = "";
|
||||||
title: "创建中",
|
taskStatus.value = null;
|
||||||
mask: true,
|
currentStep.value = "generating";
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await createAigcGeneratorTask({
|
const res = await createAigcGeneratorTask({
|
||||||
@@ -368,28 +387,32 @@ const handleGenerate = async () => {
|
|||||||
|
|
||||||
if (res?.code === 0 && res.data) {
|
if (res?.code === 0 && res.data) {
|
||||||
createdTaskId.value = res.data;
|
createdTaskId.value = res.data;
|
||||||
currentStep.value = "generating";
|
|
||||||
fetchCurrentCredit();
|
fetchCurrentCredit();
|
||||||
|
await fetchCreatedTaskStatus();
|
||||||
} else {
|
} else {
|
||||||
|
currentStep.value = "generateConfirm";
|
||||||
showPlaceholderToast(res?.msg || "创建任务失败");
|
showPlaceholderToast(res?.msg || "创建任务失败");
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn("创建AIGC生成任务失败", error);
|
console.warn("创建AIGC生成任务失败", error);
|
||||||
|
currentStep.value = "generateConfirm";
|
||||||
showPlaceholderToast("创建任务失败");
|
showPlaceholderToast("创建任务失败");
|
||||||
} finally {
|
} finally {
|
||||||
isCreatingTask.value = false;
|
isCreatingTask.value = false;
|
||||||
uni.hideLoading();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleGenerateComplete = () => {
|
const handleContinueTemplates = () => {
|
||||||
if (!createdTaskId.value) {
|
const pages = getCurrentPages();
|
||||||
showPlaceholderToast("任务创建失败");
|
const previousPage = pages[pages.length - 2];
|
||||||
|
if (previousPage?.route === "pages-aigc/home/home") {
|
||||||
|
uni.navigateBack();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uni.navigateTo({
|
uni.redirectTo({
|
||||||
url: `/pages-aigc/detail/detail?taskId=${encodeURIComponent(createdTaskId.value)}`,
|
url: "/pages-aigc/home/home",
|
||||||
|
fail: () => showPlaceholderToast("继续生成其他模板"),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user