feat(data-process): 完善后台生成与失败重试
This commit is contained in:
@@ -27,6 +27,7 @@ import {
|
||||
} from './create/useDataProcessSourceUpload'
|
||||
import { useModelsStore } from '@/stores/models'
|
||||
import {
|
||||
confirmDataProcessResults,
|
||||
createDataProcessPreview,
|
||||
createDataProcessTask,
|
||||
deleteDataProcessPreview,
|
||||
@@ -37,10 +38,16 @@ import {
|
||||
testDataProcessExternalSource,
|
||||
updateDataProcessPreview,
|
||||
updateDataProcessTask,
|
||||
updateDataProcessWorkflowStep,
|
||||
type DataProcessExternalSourcePayload,
|
||||
type DataProcessPreviewItem,
|
||||
} from '@/api/modules/dataProcess'
|
||||
import type { DataProcessConfig } from '@/types/dataProcess'
|
||||
import type {
|
||||
DataProcessConfig,
|
||||
DataProcessPreviewProgress,
|
||||
DataProcessTask,
|
||||
DataProcessWorkflowStep,
|
||||
} from '@/types/dataProcess'
|
||||
import type {
|
||||
ExternalDataSource,
|
||||
GenerationControlOptions,
|
||||
@@ -81,7 +88,11 @@ const modelSelectionOptions = computed<GenerationControlOptions>(() => (
|
||||
))
|
||||
const uploadedFiles = ref<UploadedDataFile[]>([])
|
||||
const previewBuilding = ref(false)
|
||||
const { buildPreviewsByFile } = useDataProcessPreviewBuild()
|
||||
const {
|
||||
resumePreviewBuild,
|
||||
startPreviewBuild,
|
||||
stopPreviewPolling,
|
||||
} = useDataProcessPreviewBuild()
|
||||
const externalSource = reactive<ExternalDataSource>({
|
||||
type: 'postgresql',
|
||||
url: '',
|
||||
@@ -104,14 +115,18 @@ const dirty = ref(false)
|
||||
const modelSubmitLoading = ref(false)
|
||||
let allowLeave = false
|
||||
const {
|
||||
bulkRegeneration,
|
||||
generation,
|
||||
regeneratingResultId,
|
||||
resultRegenerationBusy,
|
||||
results,
|
||||
selectedResultId,
|
||||
persistResultChanges,
|
||||
resetDownstream,
|
||||
restoreResult,
|
||||
regenerateAllResults,
|
||||
regenerateResult,
|
||||
resumeGeneration,
|
||||
startGeneration,
|
||||
stopGeneration,
|
||||
stopGenerationTimer,
|
||||
updateResultField,
|
||||
validateResults,
|
||||
@@ -241,6 +256,26 @@ function taskPayload() {
|
||||
}
|
||||
}
|
||||
|
||||
async function persistWorkflowStep(step: StepId) {
|
||||
if (!taskId.value) return
|
||||
await updateDataProcessWorkflowStep(taskId.value, step as DataProcessWorkflowStep)
|
||||
}
|
||||
|
||||
async function saveTaskConfiguration() {
|
||||
if (isRegeneration.value) {
|
||||
const regenerated = await prepareRegeneration(taskPayload())
|
||||
taskId.value = String(regenerated.task.id)
|
||||
dirty.value = false
|
||||
return regenerated.task
|
||||
}
|
||||
const saved = taskId.value
|
||||
? await updateDataProcessTask(taskId.value, taskPayload())
|
||||
: await createDataProcessTask(taskPayload())
|
||||
taskId.value = String(saved.id)
|
||||
dirty.value = false
|
||||
return saved
|
||||
}
|
||||
|
||||
function externalPayload(): DataProcessExternalSourcePayload {
|
||||
return {
|
||||
type: 'postgresql',
|
||||
@@ -260,6 +295,7 @@ function mapPreviewItem(item: DataProcessPreviewItem): PreviewItem {
|
||||
sourceFileId: String(item.source_file_id),
|
||||
originalContent: item.original_content,
|
||||
editedContent: item.edited_content,
|
||||
savedEditedContent: item.edited_content,
|
||||
sourceStart: item.source_start,
|
||||
sourceEnd: item.source_end,
|
||||
sourceStartLine: item.source_start_line,
|
||||
@@ -273,6 +309,18 @@ function mapPreviewItem(item: DataProcessPreviewItem): PreviewItem {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadAllPreviewItems() {
|
||||
if (!taskId.value) return []
|
||||
const first = await getDataProcessPreview(taskId.value, { page: 1, page_size: 500 })
|
||||
const items = [...first.items]
|
||||
const pages = Math.ceil(first.total / first.page_size)
|
||||
for (let page = 2; page <= pages; page += 1) {
|
||||
const next = await getDataProcessPreview(taskId.value, { page, page_size: 500 })
|
||||
items.push(...next.items)
|
||||
}
|
||||
return items.map(mapPreviewItem)
|
||||
}
|
||||
|
||||
function previewAffectingOptions() {
|
||||
return previewAffectingOptionsFor(processType.value, structuredOptions.value, unstructuredOptions.value)
|
||||
}
|
||||
@@ -291,6 +339,7 @@ function buildPreviewSignature() {
|
||||
}
|
||||
const {
|
||||
isRegeneration,
|
||||
isWorkflowResume,
|
||||
originalProcessType,
|
||||
regenerationPrepared,
|
||||
hydrating,
|
||||
@@ -299,8 +348,6 @@ const {
|
||||
confirmPreviewConfigChange,
|
||||
prepareRegeneration,
|
||||
confirmStartGeneration,
|
||||
returnToDetail,
|
||||
leaveWarning,
|
||||
} = useDataProcessRegeneration({
|
||||
task,
|
||||
processType,
|
||||
@@ -324,8 +371,6 @@ async function beforeStartGeneration() {
|
||||
syncPreviewChanges,
|
||||
)
|
||||
}
|
||||
const leaveWarningMessage = computed(() => leaveWarning(generation.status))
|
||||
const leaveConfirmText = computed(() => isRegeneration.value ? '返回详情' : '放弃修改')
|
||||
watch(
|
||||
[() => task.name, () => task.description, processType, structuredOptions, unstructuredOptions, externalSource],
|
||||
() => {
|
||||
@@ -504,6 +549,14 @@ async function nextFromCreate() {
|
||||
confirmDialogRef.value?.open(options) ?? Promise.resolve(false)
|
||||
))
|
||||
if (!confirmed) return
|
||||
if (!isRegeneration.value) {
|
||||
try {
|
||||
await saveTaskConfiguration()
|
||||
await persistWorkflowStep('model')
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
}
|
||||
goToStep('model')
|
||||
}
|
||||
|
||||
@@ -527,18 +580,17 @@ async function nextFromModel() {
|
||||
if (isRegeneration.value) {
|
||||
const regenerated = await prepareRegeneration(taskPayload())
|
||||
taskId.value = String(regenerated.task.id)
|
||||
dirty.value = false
|
||||
if (regenerated.preview_invalidated) {
|
||||
ElMessage.info('切分配置已保存,后续将按新配置重新切分;点击“开始生成”前,原生成结果和已发布数据保持不变')
|
||||
} else if (regenerated.published_outputs_preserved) {
|
||||
ElMessage.info('重新生成配置已保存;点击“开始生成”前,原生成结果和已发布数据保持不变')
|
||||
}
|
||||
} else {
|
||||
const saved = taskId.value
|
||||
? await updateDataProcessTask(taskId.value, taskPayload())
|
||||
: await createDataProcessTask(taskPayload())
|
||||
taskId.value = String(saved.id)
|
||||
await saveTaskConfiguration()
|
||||
}
|
||||
dirty.value = true
|
||||
await persistWorkflowStep('upload')
|
||||
dirty.value = false
|
||||
goToStep('upload')
|
||||
} catch {
|
||||
// 请求层已展示名称冲突或配置非法等具体原因。
|
||||
@@ -547,6 +599,76 @@ async function nextFromModel() {
|
||||
}
|
||||
}
|
||||
|
||||
function applyPreviewProgress(progress: DataProcessPreviewProgress) {
|
||||
const active = progress.preview_status === 'queued' || progress.preview_status === 'running'
|
||||
previewBuilding.value = active
|
||||
for (const file of uploadedFiles.value) {
|
||||
if (!file.sourceFileId || file.previewStatus === 'success') continue
|
||||
if (active) {
|
||||
file.previewStatus = 'processing'
|
||||
file.previewProgress = Math.max(0, Math.min(99, Number(progress.preview_progress) || 0))
|
||||
file.previewError = undefined
|
||||
} else if (progress.preview_status === 'failed' || progress.preview_status === 'cancelled') {
|
||||
file.previewStatus = 'failed'
|
||||
file.previewProgress = 0
|
||||
file.previewError = progress.preview_failure_reason || '切分失败,请重试'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function completePreviewWorkspace() {
|
||||
previewItems.value = await loadAllPreviewItems()
|
||||
const configSignature = buildPreviewConfigSignature()
|
||||
const previewCounts = new Map<string, number>()
|
||||
for (const item of previewItems.value) {
|
||||
previewCounts.set(item.sourceFileId, (previewCounts.get(item.sourceFileId) || 0) + 1)
|
||||
}
|
||||
for (const file of uploadedFiles.value) {
|
||||
const count = previewCounts.get(String(file.sourceFileId)) || 0
|
||||
file.previewCount = count
|
||||
file.previewStatus = count > 0 ? 'success' : 'failed'
|
||||
file.previewProgress = count > 0 ? 100 : 0
|
||||
file.previewError = count > 0 ? undefined : '该文件没有生成可用的预览条目'
|
||||
file.previewConfigSignature = count > 0 ? configSignature : undefined
|
||||
}
|
||||
const failedCount = uploadedFiles.value.filter((file) => file.previewStatus === 'failed').length
|
||||
if (failedCount || !previewItems.value.length) {
|
||||
ElMessage.warning(`${failedCount || 1} 个文件切分失败;修正问题后可重新切分`)
|
||||
return false
|
||||
}
|
||||
selectedPreviewFileId.value = String(uploadedFiles.value[0]?.uid ?? '') || null
|
||||
selectedPreviewId.value = activePreviewItems.value[0]?.id ?? null
|
||||
selectedPreviewIdsByFile.value = selectedPreviewId.value && selectedPreviewFileId.value
|
||||
? { [selectedPreviewFileId.value]: selectedPreviewId.value }
|
||||
: {}
|
||||
previewSignature.value = buildPreviewSignature()
|
||||
resetDownstream()
|
||||
await persistWorkflowStep('preview')
|
||||
dirty.value = false
|
||||
goToStep('preview')
|
||||
return true
|
||||
}
|
||||
|
||||
async function monitorPreviewBuild(sourceFileIds: string[], resume = false) {
|
||||
if (!taskId.value) return
|
||||
previewBuilding.value = true
|
||||
try {
|
||||
const finalProgress = resume
|
||||
? await resumePreviewBuild(taskId.value, applyPreviewProgress)
|
||||
: await startPreviewBuild(taskId.value, sourceFileIds, applyPreviewProgress)
|
||||
applyPreviewProgress(finalProgress)
|
||||
if (finalProgress.preview_status === 'completed') {
|
||||
await completePreviewWorkspace()
|
||||
} else if (finalProgress.preview_status === 'failed') {
|
||||
ElMessage.warning(finalProgress.preview_failure_reason || '文件切分失败,请修正后重试')
|
||||
}
|
||||
} catch {
|
||||
// 请求层已经展示错误;后端运行状态可在重新进入任务后继续查询。
|
||||
} finally {
|
||||
previewBuilding.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function nextFromUpload() {
|
||||
if (previewBuilding.value || sourceUploading.value) return
|
||||
if (!taskId.value) {
|
||||
@@ -586,59 +708,12 @@ async function nextFromUpload() {
|
||||
file.previewCount = undefined
|
||||
}
|
||||
|
||||
previewBuilding.value = true
|
||||
try {
|
||||
const pendingFileIds = uploadedFiles.value
|
||||
.filter((file) => file.previewStatus !== 'success' || file.previewConfigSignature !== configSignature)
|
||||
.map((file) => file.sourceFileId)
|
||||
.filter((fileId): fileId is string => Boolean(fileId))
|
||||
// 构建接口是同步响应:请求中只展示真实的“处理中”,响应成功后才记为 100%。
|
||||
await buildPreviewsByFile(taskId.value, pendingFileIds, (progress) => {
|
||||
const file = uploadedFiles.value.find((item) => (
|
||||
String(item.sourceFileId) === String(progress.source_file_id)
|
||||
))
|
||||
if (!file) return
|
||||
file.previewStatus = progress.status
|
||||
file.previewProgress = progress.progress
|
||||
file.previewCount = progress.preview_count
|
||||
file.previewError = progress.error
|
||||
if (progress.status === 'success') file.previewConfigSignature = configSignature
|
||||
})
|
||||
|
||||
const failedCount = uploadedFiles.value.filter((file) => file.previewStatus === 'failed').length
|
||||
if (failedCount || !allFilesSucceeded()) {
|
||||
ElMessage.warning(`${failedCount || 1} 个文件切分失败;修正问题后点击“继续:数据预览”即可重试`)
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const first = await getDataProcessPreview(taskId.value, { page: 1, page_size: 500 })
|
||||
const items = [...first.items]
|
||||
const pages = Math.ceil(first.total / first.page_size)
|
||||
for (let page = 2; page <= pages; page += 1) {
|
||||
const next = await getDataProcessPreview(taskId.value, { page, page_size: 500 })
|
||||
items.push(...next.items)
|
||||
}
|
||||
previewItems.value = items.map(mapPreviewItem)
|
||||
} catch {
|
||||
ElMessage.warning('文件切分已经完成,但预览加载失败;请再次点击继续重试加载')
|
||||
return
|
||||
}
|
||||
if (!previewItems.value.length) {
|
||||
ElMessage.warning('源文件没有生成可用的预览条目,请检查文件内容和预处理配置')
|
||||
return
|
||||
}
|
||||
selectedPreviewFileId.value = String(uploadedFiles.value[0]?.uid ?? '') || null
|
||||
selectedPreviewId.value = activePreviewItems.value[0]?.id ?? null
|
||||
selectedPreviewIdsByFile.value = selectedPreviewId.value && selectedPreviewFileId.value
|
||||
? { [selectedPreviewFileId.value]: selectedPreviewId.value }
|
||||
: {}
|
||||
previewSignature.value = signature
|
||||
resetDownstream()
|
||||
goToStep('preview')
|
||||
} finally {
|
||||
previewBuilding.value = false
|
||||
}
|
||||
const pendingFileIds = uploadedFiles.value
|
||||
.filter((file) => file.previewStatus !== 'success' || file.previewConfigSignature !== configSignature)
|
||||
.map((file) => file.sourceFileId)
|
||||
.filter((fileId): fileId is string => Boolean(fileId))
|
||||
await persistWorkflowStep('upload')
|
||||
await monitorPreviewBuild(pendingFileIds)
|
||||
}
|
||||
|
||||
function selectPreviewFile(fileId: string) {
|
||||
@@ -668,7 +743,9 @@ function updatePreviewContent(id: string, value: string) {
|
||||
|
||||
async function syncPreviewChanges() {
|
||||
if (!taskId.value) throw new Error('任务尚未创建')
|
||||
const changedItems = previewItems.value.filter((item) => item.status === 'modified' || item.status === 'manual')
|
||||
const changedItems = previewItems.value.filter((item) => (
|
||||
item.editedContent !== item.savedEditedContent
|
||||
))
|
||||
for (const item of changedItems) {
|
||||
const saved = await updateDataProcessPreview(taskId.value, item.id, {
|
||||
edited_content: item.editedContent,
|
||||
@@ -751,21 +828,67 @@ async function handlePrimaryAction() {
|
||||
ElMessage.warning('当前没有可生成的预览内容')
|
||||
return
|
||||
}
|
||||
try {
|
||||
await syncPreviewChanges()
|
||||
await persistWorkflowStep('generate')
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
dirty.value = false
|
||||
goToStep('generate')
|
||||
return
|
||||
}
|
||||
if (currentStepId.value === 'generate') {
|
||||
if (generation.status === 'success') {
|
||||
try {
|
||||
await persistWorkflowStep('results')
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
dirty.value = false
|
||||
goToStep('results')
|
||||
} else if (generation.status !== 'running') {
|
||||
await startGeneration()
|
||||
await handleStartGeneration()
|
||||
}
|
||||
return
|
||||
}
|
||||
await saveTask()
|
||||
}
|
||||
|
||||
function handleBack() {
|
||||
async function handleStartGeneration() {
|
||||
try {
|
||||
await persistWorkflowStep('generate')
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
const started = await startGeneration()
|
||||
if (!started) return
|
||||
dirty.value = false
|
||||
}
|
||||
|
||||
async function persistWorkspaceForStep(targetStep: StepId) {
|
||||
if (isRegeneration.value && !dirty.value) return
|
||||
if (currentStepId.value === 'create') {
|
||||
if (!taskId.value && !task.name.trim()) return
|
||||
const valid = await taskSetupRef.value?.validate()
|
||||
if (!valid) throw new Error('请先完善任务信息')
|
||||
await saveTaskConfiguration()
|
||||
} else if (currentStepId.value === 'model' && dirty.value) {
|
||||
await saveTaskConfiguration()
|
||||
} else if (currentStepId.value === 'preview') {
|
||||
await syncPreviewChanges()
|
||||
} else if (currentStepId.value === 'results') {
|
||||
await persistResultChanges()
|
||||
}
|
||||
if (taskId.value) await persistWorkflowStep(targetStep)
|
||||
dirty.value = false
|
||||
}
|
||||
|
||||
async function persistWorkspaceBeforeLeave() {
|
||||
await persistWorkspaceForStep(currentStepId.value)
|
||||
}
|
||||
|
||||
async function handleBack() {
|
||||
if (sourceUploading.value) {
|
||||
ElMessage.warning('请等待当前文件上传完成')
|
||||
return
|
||||
@@ -774,15 +897,25 @@ function handleBack() {
|
||||
ElMessage.warning('请等待当前文件切分完成')
|
||||
return
|
||||
}
|
||||
if (generation.status === 'running') {
|
||||
ElMessage.warning('请先停止当前生成任务')
|
||||
return
|
||||
if (currentStepId.value === 'generate') return
|
||||
if (currentStep.value > 0) {
|
||||
const targetStep = WIZARD_STEPS[currentStep.value - 1]?.id
|
||||
if (!targetStep) return
|
||||
try {
|
||||
await persistWorkspaceForStep(targetStep)
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
currentStep.value -= 1
|
||||
}
|
||||
if (currentStep.value > 0) currentStep.value -= 1
|
||||
}
|
||||
|
||||
|
||||
async function saveTask() {
|
||||
if (!taskId.value) {
|
||||
ElMessage.error('任务尚未创建,请返回上一步重试')
|
||||
return
|
||||
}
|
||||
if (!validateResults()) {
|
||||
ElMessage.warning('请先修正校验失败的结果')
|
||||
return
|
||||
@@ -796,58 +929,103 @@ async function saveTask() {
|
||||
ElMessage.warning('仍有结果未通过后端质量校验,请继续修正')
|
||||
return
|
||||
}
|
||||
try {
|
||||
await persistWorkflowStep('results')
|
||||
await confirmDataProcessResults(taskId.value)
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
dirty.value = false
|
||||
allowLeave = true
|
||||
ElMessage.success('数据处理任务已保存')
|
||||
await router.push('/data-process')
|
||||
ElMessage.success('生成结果已确认')
|
||||
await router.replace({ name: 'data-process-detail', params: { id: taskId.value } })
|
||||
}
|
||||
|
||||
async function handleCancel() {
|
||||
if (!dirty.value) {
|
||||
await returnToPreviousPage()
|
||||
return
|
||||
}
|
||||
const confirmed = await confirmDialogRef.value?.open({
|
||||
title: '确认离开当前页面?',
|
||||
message: leaveWarningMessage.value,
|
||||
confirmText: leaveConfirmText.value,
|
||||
cancelText: '继续编辑',
|
||||
tone: 'danger',
|
||||
})
|
||||
if (!confirmed) return
|
||||
await returnToPreviousPage()
|
||||
}
|
||||
|
||||
async function returnToPreviousPage() {
|
||||
allowLeave = true
|
||||
if (isRegeneration.value && await returnToDetail()) return
|
||||
router.back()
|
||||
await router.push({ name: 'data-process' })
|
||||
}
|
||||
|
||||
onBeforeRouteLeave(async () => {
|
||||
if (sourceUploading.value) {
|
||||
ElMessage.warning('请等待当前文件上传完成后再离开页面')
|
||||
onBeforeRouteLeave(async (to) => {
|
||||
if (allowLeave) return true
|
||||
if (to.name === 'data-process' && taskId.value) {
|
||||
try {
|
||||
await persistWorkspaceBeforeLeave()
|
||||
allowLeave = true
|
||||
return true
|
||||
} catch {
|
||||
ElMessage.error('当前步骤自动保存失败,已停留在本页,请重试')
|
||||
return false
|
||||
}
|
||||
}
|
||||
try {
|
||||
await persistWorkspaceBeforeLeave()
|
||||
allowLeave = true
|
||||
return true
|
||||
} catch {
|
||||
ElMessage.error('当前步骤自动保存失败,已停留在本页,请重试')
|
||||
return false
|
||||
}
|
||||
if (allowLeave || !dirty.value) return true
|
||||
const confirmed = await confirmDialogRef.value?.open({
|
||||
title: '确认离开当前页面?',
|
||||
message: leaveWarningMessage.value,
|
||||
confirmText: leaveConfirmText.value,
|
||||
cancelText: '继续编辑',
|
||||
tone: 'danger',
|
||||
})
|
||||
if (confirmed) allowLeave = true
|
||||
return Boolean(confirmed)
|
||||
})
|
||||
|
||||
function inferWorkflowStep(sourceTask: DataProcessTask): StepId {
|
||||
if (sourceTask.status === 'running' || sourceTask.status === 'failed' || sourceTask.status === 'stopped') {
|
||||
return 'generate'
|
||||
}
|
||||
if (sourceTask.status === 'completed' && sourceTask.results_confirmed === false) return 'generate'
|
||||
if (Number(sourceTask.preview_count || previewItems.value.length) > 0) return 'preview'
|
||||
if ((sourceTask.source_files || []).length > 0) return 'upload'
|
||||
return 'model'
|
||||
}
|
||||
|
||||
async function initializeExistingWorkflow() {
|
||||
const sourceTask = await loadRegenerationSource()
|
||||
if (!sourceTask) return
|
||||
taskId.value = String(sourceTask.id)
|
||||
if (!isWorkflowResume.value) return
|
||||
if (sourceTask.status === 'completed' && sourceTask.results_confirmed !== false) {
|
||||
allowLeave = true
|
||||
await router.replace({ name: 'data-process-detail', params: { id: sourceTask.id } })
|
||||
return
|
||||
}
|
||||
if (sourceTask.preview_status === 'queued' || sourceTask.preview_status === 'running') {
|
||||
goToStep('upload')
|
||||
applyPreviewProgress({
|
||||
task_id: sourceTask.id,
|
||||
workflow_step: 'upload',
|
||||
preview_status: sourceTask.preview_status,
|
||||
preview_progress: Number(sourceTask.preview_progress) || 0,
|
||||
preview_run_id: sourceTask.preview_run_id,
|
||||
preview_failure_reason: sourceTask.preview_failure_reason,
|
||||
preview_total_files: sourceTask.preview_total_files,
|
||||
preview_completed_files: sourceTask.preview_completed_files,
|
||||
})
|
||||
const sourceFileIds = uploadedFiles.value
|
||||
.map((file) => file.sourceFileId)
|
||||
.filter((fileId): fileId is string => Boolean(fileId))
|
||||
void monitorPreviewBuild(sourceFileIds, true)
|
||||
return
|
||||
}
|
||||
let resumeStep = (sourceTask.workflow_step || inferWorkflowStep(sourceTask)) as StepId
|
||||
if (sourceTask.preview_status === 'failed') resumeStep = 'upload'
|
||||
if (sourceTask.status === 'running') resumeStep = 'generate'
|
||||
if (resumeStep === 'preview' && !previewItems.value.length) resumeStep = 'upload'
|
||||
if (resumeStep === 'results' && sourceTask.status !== 'completed') resumeStep = 'generate'
|
||||
goToStep(resumeStep)
|
||||
if (resumeStep === 'generate' || resumeStep === 'results') await resumeGeneration()
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
stopPreviewPolling()
|
||||
stopGenerationTimer()
|
||||
})
|
||||
onMounted(() => {
|
||||
localStorage.removeItem('yg-data-process-create-draft')
|
||||
void modelsStore.load(true)
|
||||
if (isRegeneration.value) void loadRegenerationSource()
|
||||
if (isRegeneration.value || isWorkflowResume.value) void initializeExistingWorkflow()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -954,8 +1132,7 @@ onMounted(() => {
|
||||
:preview-count="previewItems.length"
|
||||
:modified-count="modifiedPreviewCount"
|
||||
:generation="generation"
|
||||
@stop="stopGeneration"
|
||||
@retry="startGeneration"
|
||||
@retry="handleStartGeneration"
|
||||
/>
|
||||
|
||||
<ResultEditorStep
|
||||
@@ -963,8 +1140,11 @@ onMounted(() => {
|
||||
v-model:selected-id="selectedResultId"
|
||||
:items="results"
|
||||
:preview-items="previewItems"
|
||||
:regenerating-result-id="regeneratingResultId"
|
||||
:bulk-regeneration="bulkRegeneration"
|
||||
@update:field="updateResultField"
|
||||
@restore:item="restoreResult"
|
||||
@regenerate:all="regenerateAllResults"
|
||||
@regenerate:item="regenerateResult"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -972,7 +1152,11 @@ onMounted(() => {
|
||||
|
||||
<footer class="wizard-footer">
|
||||
<div class="footer-left">
|
||||
<el-button v-if="currentStep > 0" :disabled="previewBuilding || sourceUploading" @click="handleBack">
|
||||
<el-button
|
||||
v-if="currentStep > 0"
|
||||
:disabled="currentStepId === 'generate' || previewBuilding || sourceUploading"
|
||||
@click="handleBack"
|
||||
>
|
||||
<i class="fa fa-arrow-left" style="margin-right: 6px;" /> 返回:{{ previousStepLabel }}
|
||||
</el-button>
|
||||
<el-button v-else @click="handleCancel">{{ isRegeneration ? '返回详情' : '取消' }}</el-button>
|
||||
@@ -983,8 +1167,8 @@ onMounted(() => {
|
||||
<el-button
|
||||
class="wizard-primary-action"
|
||||
type="primary"
|
||||
:loading="modelSubmitLoading || generation.status === 'running' || (currentStepId === 'upload' && (sourceUploading || previewBuilding))"
|
||||
:disabled="hydrating || modelSubmitLoading || Boolean(initializationError) || (currentStepId === 'generate' && generation.status === 'running') || previewBuilding || sourceUploading || (currentStepId === 'upload' && hasUnfinishedUploads)"
|
||||
:loading="modelSubmitLoading || generation.status === 'running' || resultRegenerationBusy || (currentStepId === 'upload' && (sourceUploading || previewBuilding))"
|
||||
:disabled="hydrating || modelSubmitLoading || Boolean(initializationError) || resultRegenerationBusy || (currentStepId === 'generate' && generation.status === 'running') || previewBuilding || sourceUploading || (currentStepId === 'upload' && hasUnfinishedUploads)"
|
||||
@click="handlePrimaryAction"
|
||||
>
|
||||
{{ primaryActionLabel }} <i class="fa" :class="primaryActionIcon" style="margin-left: 6px;" />
|
||||
|
||||
Reference in New Issue
Block a user