1
This commit is contained in:
@@ -117,7 +117,7 @@ async function loadAll() {
|
||||
// 刷新时恢复进行中的 AI 生成任务(或展示最近一次失败的提示)
|
||||
const gt = await request.get('/datasets/gen-task', { params: { datasetId: datasetId.value } }).catch(() => null)
|
||||
if (gt && gt.status === 'running') {
|
||||
genTask.value = { id: gt.id, status: gt.status, total: gt.total, done: gt.done, error: gt.error }
|
||||
genTask.value = { id: gt.id, status: gt.status, total: gt.total, done: gt.done, error: gt.error, createdAt: gt.createdAt }
|
||||
pollGenTask()
|
||||
} else if (gt && gt.error) {
|
||||
genTask.value = gt
|
||||
@@ -153,7 +153,7 @@ function pollGenTask() {
|
||||
genPoll.value = setInterval(async () => {
|
||||
const d = await request.get('/datasets/gen-task', { params: { datasetId: datasetId.value } }).catch(() => null)
|
||||
if (!d) return
|
||||
genTask.value = { id: d.id, status: d.status, total: d.total, done: d.done, error: d.error }
|
||||
genTask.value = { id: d.id, status: d.status, total: d.total, done: d.done, error: d.error, createdAt: d.createdAt }
|
||||
if (d.status !== 'running') {
|
||||
stopGenPoll()
|
||||
if (d.error) {
|
||||
@@ -175,6 +175,29 @@ function stopGenPoll() {
|
||||
}
|
||||
}
|
||||
|
||||
// 实际速率/预计剩余:按服务端 createdAt 起算(均速=运行时长/已完成张数,刷新页面后依然准);
|
||||
// done=0 时无速率可估,进度条上先不展示。轮询每 3s 替换 genTask,computed 随之重算
|
||||
function parseGtime(s) {
|
||||
const t = new Date(String(s || '').replace(' ', 'T'))
|
||||
return isNaN(t.getTime()) ? null : t
|
||||
}
|
||||
|
||||
function fmtDuration(sec) {
|
||||
sec = Math.round(sec)
|
||||
const m = Math.floor(sec / 60)
|
||||
return m > 0 ? `${m} 分 ${sec % 60} 秒` : `${sec} 秒`
|
||||
}
|
||||
|
||||
const genRateSec = computed(() => {
|
||||
if (!genRunning.value || !genTask.value.done) return 0
|
||||
const start = parseGtime(genTask.value.createdAt)
|
||||
if (!start) return 0
|
||||
const elapsed = (Date.now() - start.getTime()) / 1000
|
||||
return elapsed > 0 ? elapsed / genTask.value.done : 0
|
||||
})
|
||||
const genRateText = computed(() => (genRateSec.value >= 10 ? String(Math.round(genRateSec.value)) : genRateSec.value.toFixed(1)))
|
||||
const genEtaText = computed(() => (genRateSec.value ? fmtDuration(genRateSec.value * (genTask.value.total - genTask.value.done)) : ''))
|
||||
|
||||
function submitGen() {
|
||||
generating.value = true
|
||||
request
|
||||
@@ -187,7 +210,7 @@ function submitGen() {
|
||||
.then((data) => {
|
||||
addVisible.value = false
|
||||
genTask.value = { id: data.taskId, status: 'running', total: data.total, done: 0, error: '' }
|
||||
ElMessage.success(`已提交生成任务(共 ${data.total} 张,约 40 秒/张),进度见页顶进度条`)
|
||||
ElMessage.success(`已提交生成任务(共 ${data.total} 张),实际速率与预计剩余时长见页顶进度条`)
|
||||
pollGenTask()
|
||||
})
|
||||
.catch(() => {})
|
||||
@@ -1011,7 +1034,7 @@ onBeforeUnmount(() => {
|
||||
:percentage="genTask.total ? Math.min(100, Math.round((genTask.done / genTask.total) * 100)) : 0"
|
||||
:stroke-width="10"
|
||||
/>
|
||||
<span class="label-progress-tip">AI 生成中 {{ genTask.done }}/{{ genTask.total }} 张(约 40 秒/张)…</span>
|
||||
<span class="label-progress-tip">AI 生成中 {{ genTask.done }}/{{ genTask.total }} 张<template v-if="genRateSec">(实际约 {{ genRateText }} 秒/张,预计剩余 {{ genEtaText }})</template>…</span>
|
||||
</div>
|
||||
<div v-if="genTask && genTask.status !== 'running' && genTask.error" class="label-error">
|
||||
AI 生成未完成:{{ genTask.error }}
|
||||
@@ -1074,7 +1097,7 @@ onBeforeUnmount(() => {
|
||||
<el-form-item label="图片尺寸">
|
||||
<span class="gen-size">竖版 704x1248</span>
|
||||
</el-form-item>
|
||||
<div class="gen-tip">按本数据集物种({{ dataset?.name || '' }})生成,每张固定 1 只;生成图片为付费资产,请勿随意删除;批量生成为后台任务(约 40 秒/张),进度见页顶进度条;手填提示词时无需写拍摄角度/位置(系统自动约束画面中有且只有这一只动物)。</div>
|
||||
<div class="gen-tip">按本数据集物种({{ dataset?.name || '' }})生成,每张固定 1 只;生成图片为付费资产,请勿随意删除;批量生成为后台任务,实际速率与预计剩余时长见页顶进度条;手填提示词时无需写拍摄角度/位置(系统自动约束画面中有且只有这一只动物)。</div>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
|
||||
Reference in New Issue
Block a user