feat: 数据处理向导新增模型配置步骤

StepId 新增 model 步骤,DataProcessCreateView 增加模型选择与生成参数编排,各选项面板与样式适配新步骤流程,回归脚本补充断言。
This commit is contained in:
caoxiaozhu
2026-07-13 17:12:49 +08:00
parent 42f2efb449
commit 762d48d090
9 changed files with 257 additions and 121 deletions

View File

@@ -5,7 +5,7 @@ import type { GenerationControlOptions } from './types'
const props = defineProps<{
options: GenerationControlOptions
models: ModelItem[]
models?: ModelItem[]
section: 'model' | 'quality'
validationMessage?: string
}>()
@@ -59,7 +59,7 @@ function sectionValidationMessage() {
@update:model-value="updateField('generationModelId', $event)"
>
<el-option
v-for="model in models"
v-for="model in models || []"
:key="model.id"
:label="model.name"
:value="model.id"
@@ -234,7 +234,22 @@ function sectionValidationMessage() {
.model-config-group {
display: flex;
flex-direction: column;
gap: 16px;
gap: 20px;
padding: 0;
border: 0;
border-radius: 0;
background: transparent;
}
.model-config-group .advanced-settings-grid {
grid-template-columns: 1fr;
gap: 20px;
}
.model-config-group .config-field {
padding: 0;
border: 0;
border-radius: 0;
}
.model-field {

View File

@@ -0,0 +1,90 @@
<script setup lang="ts">
import { computed, ref } from 'vue'
import { ElMessage } from 'element-plus'
import type { ModelItem } from '@/types'
import type { GenerationControlOptions } from './types'
import GenerationOptionsPanel from './GenerationOptionsPanel.vue'
const props = defineProps<{
options: GenerationControlOptions
models: ModelItem[]
}>()
const emit = defineEmits<{
'update:options': [value: GenerationControlOptions]
}>()
const validationAttempted = ref(false)
const modelValidationMessage = computed(() => (
props.options.generationModelId === '' ? '请选择数据生成模型' : ''
))
function validate() {
validationAttempted.value = true
if (!modelValidationMessage.value) return true
ElMessage.error(modelValidationMessage.value)
return false
}
defineExpose({ validate })
</script>
<template>
<section class="model-selection-step" aria-labelledby="model-selection-title">
<div class="form-section">
<div class="section-title-row">
<div>
<h3 id="model-selection-title">大模型选择</h3>
<p>选择本次数据生成使用的模型并设置统一的输出要求</p>
</div>
</div>
<div class="model-form-content">
<GenerationOptionsPanel
:options="options"
:models="models"
section="model"
:validation-message="validationAttempted ? modelValidationMessage : ''"
@update:options="emit('update:options', $event)"
/>
</div>
</div>
</section>
</template>
<style scoped lang="scss">
.model-selection-step {
width: 100%;
}
.form-section {
padding: 0 0 26px;
margin-bottom: 26px;
border-bottom: 1px solid #edf0f5;
}
.section-title-row {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 16px;
h3 {
margin: 0 0 5px;
color: #2f3747;
font-size: 15px;
font-weight: 650;
}
p {
margin: 0;
color: #8a93a3;
font-size: 12px;
line-height: 1.6;
}
}
.model-form-content {
margin-top: 16px;
}
</style>

View File

@@ -1,5 +1,4 @@
<script setup lang="ts">
import type { ModelItem } from '@/types'
import type {
GenerationControlOptions,
PreprocessOption,
@@ -10,9 +9,8 @@ import GenerationOptionsPanel from './GenerationOptionsPanel.vue'
const props = defineProps<{
options: StructuredProcessOptions
generationModels: ModelItem[]
validationAttempted: boolean
generationValidationMessage: string
qualityValidationMessage: string
}>()
const emit = defineEmits<{
@@ -89,9 +87,8 @@ function updatePreprocessOptions(value: Array<string | number | boolean>) {
<div class="generation-option-list">
<GenerationOptionsPanel
:options="options"
:models="generationModels"
section="quality"
:validation-message="validationAttempted ? generationValidationMessage : ''"
:validation-message="validationAttempted ? qualityValidationMessage : ''"
@update:options="updateGenerationOptions"
/>
@@ -116,23 +113,6 @@ function updatePreprocessOptions(value: Array<string | number | boolean>) {
</div>
</div>
<div class="form-section model-options-section">
<div class="section-title-row">
<div>
<h3>大模型</h3>
<p>选择数据生成模型并设置模型输出内容的要求</p>
</div>
</div>
<div class="generation-option-list">
<GenerationOptionsPanel
:options="options"
:models="generationModels"
section="model"
:validation-message="validationAttempted ? generationValidationMessage : ''"
@update:options="updateGenerationOptions"
/>
</div>
</div>
</template>
<style scoped lang="scss">

View File

@@ -1,7 +1,6 @@
<script setup lang="ts">
import { computed, ref } from 'vue'
import { ElMessage, type FormInstance, type FormRules } from 'element-plus'
import type { ModelItem } from '@/types'
import type {
GenerationControlOptions,
ProcessType,
@@ -17,7 +16,6 @@ const props = defineProps<{
processType: ProcessType
structuredOptions: StructuredProcessOptions
unstructuredOptions: UnstructuredProcessOptions
generationModels: ModelItem[]
}>()
const emit = defineEmits<{
@@ -52,10 +50,9 @@ const activeGenerationOptions = computed<GenerationControlOptions | null>(() =>
return null
})
const generationValidationMessage = computed(() => {
const qualityValidationMessage = computed(() => {
const options = activeGenerationOptions.value
if (!options) return ''
if (options.generationModelId === '') return '请选择数据生成模型'
if (options.qualityFilterEnabled && !options.filterLowQuality && !options.filterShortContent) {
return '开启质量筛选后,请至少选择一项筛选规则'
}
@@ -112,8 +109,8 @@ async function validate() {
return false
}
}
if (generationValidationMessage.value) {
ElMessage.error(generationValidationMessage.value)
if (qualityValidationMessage.value) {
ElMessage.error(qualityValidationMessage.value)
return false
}
return true
@@ -210,9 +207,8 @@ defineExpose({ validate })
<StructuredOptionsPanel
v-if="processType === 'structured'"
:options="structuredOptions"
:generation-models="generationModels"
:validation-attempted="validationAttempted"
:generation-validation-message="generationValidationMessage"
:quality-validation-message="qualityValidationMessage"
@update:options="emit('update:structuredOptions', $event)"
/>
@@ -220,9 +216,8 @@ defineExpose({ validate })
v-if="processType === 'unstructured'"
ref="unstructuredOptionsPanelRef"
:options="unstructuredOptions"
:generation-models="generationModels"
:validation-attempted="validationAttempted"
:generation-validation-message="generationValidationMessage"
:quality-validation-message="qualityValidationMessage"
:chunk-validation-message="chunkValidationMessage"
@update:options="emit('update:unstructuredOptions', $event)"
/>

View File

@@ -1,6 +1,5 @@
<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import type { ModelItem } from '@/types'
import type {
ChunkMethod,
GenerationControlOptions,
@@ -12,9 +11,8 @@ import GenerationOptionsPanel from './GenerationOptionsPanel.vue'
const props = defineProps<{
options: UnstructuredProcessOptions
generationModels: ModelItem[]
validationAttempted: boolean
generationValidationMessage: string
qualityValidationMessage: string
chunkValidationMessage: string
}>()
@@ -269,9 +267,8 @@ defineExpose({ revealValidation })
<div class="generation-option-list">
<GenerationOptionsPanel
:options="options"
:models="generationModels"
section="quality"
:validation-message="validationAttempted ? generationValidationMessage : ''"
:validation-message="validationAttempted ? qualityValidationMessage : ''"
@update:options="updateGenerationOptions"
/>
@@ -301,23 +298,6 @@ defineExpose({ revealValidation })
</div>
</div>
<div class="form-section model-options-section">
<div class="section-title-row">
<div>
<h3>大模型</h3>
<p>选择数据生成模型并设置模型输出内容的要求</p>
</div>
</div>
<div class="generation-option-list">
<GenerationOptionsPanel
:options="options"
:models="generationModels"
section="model"
:validation-message="validationAttempted ? generationValidationMessage : ''"
@update:options="updateGenerationOptions"
/>
</div>
</div>
</template>
<style scoped lang="scss">

View File

@@ -37,7 +37,7 @@
display: flex;
align-items: center;
justify-content: space-between;
max-width: 860px;
max-width: 1040px;
margin: 0 auto;
padding: 0 20px;
}
@@ -45,11 +45,7 @@
.step-item {
display: flex;
align-items: center;
flex: 1;
&:first-child {
flex: 0;
}
flex: none;
}
.step-connector {
@@ -60,14 +56,14 @@
transition: background-color 0.3s;
}
.step-item.is-completed .step-connector,
.step-item.is-active .step-connector {
.step-connector.is-active {
background-color: #5146e5;
}
.step-node {
display: flex;
align-items: center;
flex-shrink: 0;
gap: 10px;
}
@@ -149,6 +145,30 @@
min-width: 160px;
}
@media (max-width: 1100px) {
.custom-wizard-steps {
padding: 0;
}
.step-connector {
margin: 0 8px;
}
.step-node {
gap: 7px;
}
.step-title {
display: none;
}
.step-item.is-active .step-title {
display: block;
font-size: 12px;
white-space: nowrap;
}
}
@media (max-width: 760px) {
.wizard-main {
padding: 24px 20px;
@@ -168,9 +188,7 @@
.step-title {
max-width: 72px;
font-size: 12px;
line-height: 1.35;
white-space: normal;
}
.wizard-footer {

View File

@@ -1,6 +1,6 @@
export type ProcessType = 'structured' | 'unstructured' | 'external'
export type StepId = 'create' | 'upload' | 'preview' | 'generate' | 'results'
export type StepId = 'create' | 'model' | 'upload' | 'preview' | 'generate' | 'results'
export type PreprocessOption =
| 'clean_invalid'