1
This commit is contained in:
@@ -52,6 +52,14 @@ async function loadAll() {
|
||||
const tasks = await request.get('/label-tasks', { params: { page: 1, size: 100 } }).catch(() => null)
|
||||
const running = (tasks?.list || []).find((t) => t.datasetId === datasetId.value && t.status === 'running')
|
||||
if (running) pollLabelTask(running.id)
|
||||
// 刷新时恢复进行中的 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 }
|
||||
pollGenTask()
|
||||
} else if (gt && gt.error) {
|
||||
genTask.value = gt
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
@@ -59,41 +67,63 @@ async function loadAll() {
|
||||
|
||||
// ---------- 添加图片(AI 生成) ----------
|
||||
const addVisible = ref(false)
|
||||
const genForm = reactive({ species: '', count: 1, size: '704x1248', distance: 25 })
|
||||
const speciesOptions = ref([])
|
||||
// 单物种规则:物种固定取数据集名,表单无物种输入
|
||||
const genForm = reactive({ count: 1, size: '704x1248', distance: 25 })
|
||||
const generating = ref(false)
|
||||
|
||||
// 生成表单选项(物种池/场景池来自 config,随配置热更新)
|
||||
function loadGenOptions() {
|
||||
request.get('/datasets/gen-options', { params: { datasetId: datasetId.value } }).then((d) => {
|
||||
speciesOptions.value = d.species || []
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
function openAdd() {
|
||||
genForm.species = ''
|
||||
loadGenOptions()
|
||||
genForm.count = 1
|
||||
genForm.size = '704x1248'
|
||||
genForm.distance = 25
|
||||
addVisible.value = true
|
||||
}
|
||||
|
||||
// AI 生成为异步任务:提交即返回 taskId,轮询 /datasets/gen-task 看进度
|
||||
const genTask = ref(null)
|
||||
const genPoll = ref(null)
|
||||
const genRunning = computed(() => genTask.value && genTask.value.status === 'running')
|
||||
|
||||
function pollGenTask() {
|
||||
stopGenPoll()
|
||||
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 }
|
||||
if (d.status !== 'running') {
|
||||
stopGenPoll()
|
||||
if (d.error) {
|
||||
ElMessage.error(`AI 生成未完成:${d.error}`)
|
||||
} else if (d.total > 0) {
|
||||
ElMessage.success(`AI 生成完成(${d.done}/${d.total} 张),自动标注处理中…`)
|
||||
}
|
||||
loadAll().then(() => {
|
||||
if (editorVisible.value) nextTick(resetEditor)
|
||||
})
|
||||
}
|
||||
}, 3000)
|
||||
}
|
||||
|
||||
function stopGenPoll() {
|
||||
if (genPoll.value) {
|
||||
clearInterval(genPoll.value)
|
||||
genPoll.value = null
|
||||
}
|
||||
}
|
||||
|
||||
function submitGen() {
|
||||
generating.value = true
|
||||
request
|
||||
.post('/datasets/generate', {
|
||||
datasetId: datasetId.value,
|
||||
species: genForm.species.trim(),
|
||||
count: genForm.count,
|
||||
size: genForm.size,
|
||||
distance: genForm.distance,
|
||||
}, { timeout: 2400000 })
|
||||
})
|
||||
.then((data) => {
|
||||
const rj = data.rejected ? `,${data.rejected} 张不合格已跳过` : ''
|
||||
ElMessage.success(`已生成 ${data.generated || 0} 张${rj}(生成图片为付费资产,删除前请确认),自动标注处理中…`)
|
||||
addVisible.value = false
|
||||
loadAll()
|
||||
genTask.value = { id: data.taskId, status: 'running', total: data.total, done: 0, error: '' }
|
||||
ElMessage.success(`已提交生成任务(共 ${data.total} 张,约 40 秒/张),进度见页顶进度条`)
|
||||
pollGenTask()
|
||||
})
|
||||
.catch(() => {})
|
||||
.finally(() => {
|
||||
@@ -491,6 +521,7 @@ onMounted(() => {
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
stopLabelPoll()
|
||||
stopGenPoll()
|
||||
stopHighlight()
|
||||
window.removeEventListener('resize', onWinResize)
|
||||
})
|
||||
@@ -512,7 +543,7 @@ onBeforeUnmount(() => {
|
||||
|
||||
<!-- 图片工具 -->
|
||||
<div class="img-toolbar">
|
||||
<el-button type="primary" :icon="Plus" @click="openAdd">添加</el-button>
|
||||
<el-button type="primary" :icon="Plus" :disabled="genRunning" @click="openAdd">添加</el-button>
|
||||
<el-button :icon="MagicStick" :disabled="labelRunning" @click="startFullLabelTask">全量标注</el-button>
|
||||
</div>
|
||||
|
||||
@@ -526,6 +557,16 @@ onBeforeUnmount(() => {
|
||||
<div v-if="labelTask && labelTask.status === 'done' && labelTask.error" class="label-error">
|
||||
自动标注未完成:{{ labelTask.error }}
|
||||
</div>
|
||||
<div v-if="genRunning" class="label-progress">
|
||||
<el-progress
|
||||
: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>
|
||||
</div>
|
||||
<div v-if="genTask && genTask.status !== 'running' && genTask.error" class="label-error">
|
||||
AI 生成未完成:{{ genTask.error }}
|
||||
</div>
|
||||
|
||||
<!-- 图片卡片:点击缩略图直接进标注弹窗(有标注框直接显示在图上,可继续画框) -->
|
||||
<div v-loading="loading" class="rows-area">
|
||||
@@ -564,21 +605,8 @@ onBeforeUnmount(() => {
|
||||
<!-- 添加图片:AI 生成 -->
|
||||
<el-dialog v-model="addVisible" title="AI 生成图片" width="min(520px, 92vw)" append-to-body>
|
||||
<el-form label-width="90px">
|
||||
<el-form-item label="动物名称">
|
||||
<el-select
|
||||
v-model="genForm.species"
|
||||
filterable
|
||||
allow-create
|
||||
default-first-option
|
||||
clearable
|
||||
placeholder="留空按数据集物种池随机"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option v-for="s in speciesOptions" :key="s" :label="s" :value="s" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="生成张数">
|
||||
<el-input-number v-model="genForm.count" :min="1" :max="8" />
|
||||
<el-input-number v-model="genForm.count" :min="1" :max="1000" />
|
||||
</el-form-item>
|
||||
<el-form-item label="目标距离">
|
||||
<div class="gen-inline">
|
||||
@@ -589,11 +617,11 @@ onBeforeUnmount(() => {
|
||||
<el-form-item label="图片尺寸">
|
||||
<span class="gen-size">竖版 704x1248</span>
|
||||
</el-form-item>
|
||||
<div class="gen-tip">生成图片为付费资产,请勿随意删除;手填提示词时无需写目标位置(系统统一约束目标只出现在画面上部三分之一区域)。</div>
|
||||
<div class="gen-tip">按本数据集物种({{ dataset?.name || '' }})生成,每张固定 1 只;生成图片为付费资产,请勿随意删除;批量生成为后台任务(约 40 秒/张),进度见页顶进度条;手填提示词时无需写拍摄角度/位置(系统自动约束画面中有且只有这一只动物)。</div>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button type="primary" :loading="generating" @click="submitGen">开始生成(可能需数分钟)</el-button>
|
||||
<el-button type="primary" :loading="generating" @click="submitGen">开始生成</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user