This commit is contained in:
2026-08-27 17:54:48 +08:00
parent f89e1e4de8
commit b30ca673cc
12 changed files with 168 additions and 92 deletions
+5 -8
View File
@@ -62,15 +62,15 @@ const addVisible = ref(false)
const addMode = ref('upload') // upload | ai
const uploadList = ref([])
const uploading = ref(false)
const genForm = reactive({ prompt: '', count: 4, size: '1152x2048' })
const genForm = reactive({ prompt: '', count: 1, size: '704x1248' })
const generating = ref(false)
function openAdd() {
addMode.value = 'upload'
uploadList.value = []
genForm.prompt = ''
genForm.count = 4
genForm.size = '1152x2048'
genForm.count = 1
genForm.size = '704x1248'
addVisible.value = true
}
@@ -109,7 +109,7 @@ function submitGen() {
prompt: genForm.prompt.trim(),
count: genForm.count,
size: genForm.size,
}, { timeout: 600000 })
}, { timeout: 2400000 })
.then((data) => {
ElMessage.success(`已生成 ${data.generated || 0} 张(生成图片为付费资产,删除前请确认),自动标注处理中…`)
addVisible.value = false
@@ -633,10 +633,7 @@ onBeforeUnmount(() => {
<el-input-number v-model="genForm.count" :min="1" :max="8" />
</el-form-item>
<el-form-item label="图片尺寸">
<el-radio-group v-model="genForm.size">
<el-radio value="1152x2048">竖版 1152x2048</el-radio>
<el-radio value="704x704">方形 704x704</el-radio>
</el-radio-group>
<span class="gen-size">竖版 704x1248很慢 26 分钟/建议一次只生成 1 </span>
</el-form-item>
<div class="gen-tip">生成图片为付费资产请勿随意删除提示词中不要描述目标在画面中的位置由模型自行构图</div>
</el-form>
+56 -64
View File
@@ -1,7 +1,7 @@
<script setup>
import { onBeforeUnmount, onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Picture, Setting, VideoPlay } from '@element-plus/icons-vue'
import { EditPen, Picture, Plus, VideoPlay } from '@element-plus/icons-vue'
import { useRouter } from 'vue-router'
import request from '../api/request'
@@ -13,14 +13,13 @@ const page = ref(1)
const size = ref(12)
const keyword = ref('')
const createVisible = ref(false)
const createForm = reactive({ name: '' })
const creating = ref(false)
const configVisible = ref(false)
const configSaving = ref(false)
const configForm = reactive({
const formVisible = ref(false)
const saving = ref(false)
// 新建/编辑共用弹窗:edit 模式下名称只读(服务端 update 接口不支持改名)
const dlgForm = reactive({
mode: 'create', // create | edit
id: 0,
name: '',
description: '',
cover: '',
})
@@ -53,45 +52,34 @@ function search() {
load()
}
// ---------- 新建 / 编辑数据集(名称 + 描述 + 封面;AI 端点/训练机 SSH 走 config.yml,与数据集无关) ----------
function resetCoverState() {
coverFile.value = null
coverDeleted.value = false
}
function openCreate() {
createForm.name = ''
createVisible.value = true
Object.assign(dlgForm, { mode: 'create', id: 0, name: '', description: '', cover: '' })
resetCoverState()
coverFileList.value = []
formVisible.value = true
}
function submitCreate() {
if (!createForm.name.trim()) {
ElMessage.warning('请输入数据集名称')
return
}
creating.value = true
request
.post('/datasets', { name: createForm.name.trim(), source: 'manual' })
.then(() => {
ElMessage.success('数据集已创建,请上传或生成图片')
createVisible.value = false
page.value = 1
load()
})
.finally(() => {
creating.value = false
})
}
// ---------- 数据集级配置(描述 + 封面;AI 端点/训练机 SSH 走 config.yml,与数据集无关) ----------
function openConfig(row) {
Object.assign(configForm, {
function openEdit(row) {
Object.assign(dlgForm, {
mode: 'edit',
id: row.id,
name: row.name,
description: row.description || '',
cover: row.cover || '',
})
coverFile.value = null
coverDeleted.value = false
resetCoverState()
// 已有封面回显:el-upload picture-card 直接以 url 项展示(带版本参数防浏览器缓存旧封面)
coverFileList.value = row.cover
? [{ name: '当前封面', url: imgUrl(`/api/v1/admin/datasets/cover?datasetId=${row.id}&v=${encodeURIComponent(row.updatedAt || '')}`) }]
: []
configVisible.value = true
formVisible.value = true
}
// 封面文件选中:多选时只保留最后一个(替换语义);新文件选中即视为不再删除
@@ -106,29 +94,43 @@ function onCoverRemove(file) {
coverFile.value = null
if (!file.raw) {
coverDeleted.value = true
} else if (!coverFileList.value.length && configForm.cover) {
} else if (!coverFileList.value.length && dlgForm.cover) {
coverDeleted.value = true
}
}
async function submitConfig() {
configSaving.value = true
// 提交新建/编辑:create 先建数据集拿 id,封面与描述复用 update/cover 接口串联写入;
// edit 按原配置保存流程。封面为独立 multipart 接口,update 始终不携带 cover。
async function submitDlg() {
const name = dlgForm.name.trim()
if (!name) {
ElMessage.warning('请输入数据集名称')
return
}
saving.value = true
try {
let id = dlgForm.id
if (dlgForm.mode === 'create') {
id = (await request.post('/datasets', { name, source: 'manual' })).id
}
if (coverFile.value) {
const fd = new FormData()
fd.append('datasetId', configForm.id)
fd.append('datasetId', id)
fd.append('file', coverFile.value)
await request.post('/datasets/cover', fd, { timeout: 60000 })
} else if (coverDeleted.value) {
await request.post('/datasets/cover/delete', { datasetId: configForm.id })
} else if (dlgForm.mode === 'edit' && coverDeleted.value) {
await request.post('/datasets/cover/delete', { datasetId: id })
}
// cover 由上传接口单独维护,update 不携带
await request.post('/datasets/update', { ...configForm, cover: '' })
ElMessage.success('配置已保存')
configVisible.value = false
// create 且未填描述时跳过 update(服务端空值不覆盖,避免空跑一次)
if (dlgForm.mode === 'edit' || dlgForm.description.trim()) {
await request.post('/datasets/update', { id, name, description: dlgForm.description.trim(), cover: '' })
}
ElMessage.success(dlgForm.mode === 'create' ? '数据集已创建,请上传或生成图片' : '已保存')
formVisible.value = false
page.value = 1
load()
} finally {
configSaving.value = false
saving.value = false
}
}
@@ -262,7 +264,7 @@ onBeforeUnmount(() => {
>
{{ row.trainingStatus === 'running' ? '训练中' : '开始训练' }}
</el-button>
<el-button size="small" :icon="Setting" @click="openConfig(row)">配置</el-button>
<el-button size="small" :icon="EditPen" @click="openEdit(row)">编辑</el-button>
<el-button size="small" type="danger" @click="removeDataset(row)">删除</el-button>
</div>
@@ -303,29 +305,19 @@ onBeforeUnmount(() => {
@change="load"
/>
<!-- 新建数据集 -->
<el-dialog v-model="createVisible" title="新建数据集" width="min(440px, 92vw)">
<!-- 新建 / 编辑数据集同一弹窗编辑模式回填原值且允许改名 -->
<el-dialog v-model="formVisible" :title="dlgForm.mode === 'create' ? '新建数据集' : '编辑数据集'" width="min(720px, 94vw)">
<el-form label-width="90px">
<el-form-item label="名称">
<el-input
v-model="createForm.name"
v-model="dlgForm.name"
maxlength="50"
show-word-limit
placeholder="中文/字母/数字/下划线/短横线,唯一且作磁盘目录名"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="createVisible = false">取消</el-button>
<el-button type="primary" :loading="creating" @click="submitCreate">创建</el-button>
</template>
</el-dialog>
<!-- 数据集配置 -->
<el-dialog v-model="configVisible" title="数据集配置" width="min(720px, 94vw)">
<el-form label-width="120px">
<el-form-item label="描述">
<el-input v-model="configForm.description" type="textarea" :rows="6" maxlength="500" show-word-limit placeholder="数据集说明,展示在卡片上" />
<el-input v-model="dlgForm.description" type="textarea" :rows="6" maxlength="500" show-word-limit placeholder="数据集说明,展示在卡片上" />
</el-form-item>
<el-form-item label="封面">
<div class="cover-row">
@@ -346,8 +338,8 @@ onBeforeUnmount(() => {
</el-form-item>
</el-form>
<template #footer>
<el-button @click="configVisible = false">取消</el-button>
<el-button type="primary" :loading="configSaving" @click="submitConfig">保存</el-button>
<el-button @click="formVisible = false">取消</el-button>
<el-button type="primary" :loading="saving" @click="submitDlg">{{ dlgForm.mode === 'create' ? '创建' : '保存' }}</el-button>
</template>
</el-dialog>