Files
YG_FT/frontend/src/views/eval/create/EvalTaskSetupStep.vue
caoxiaozhu 862a7972cf refactor: 简化评测创建向导规则来源
移除已有维度/基线两种规则来源,评测创建仅保留新建维度流程并自动生成维度名称;维度名称字段回归独立创建页,表单校验改为返回精确布尔值并启用 scroll-to-error。
2026-07-12 22:49:05 +08:00

164 lines
4.2 KiB
Vue

<script setup lang="ts">
import { ref, watch } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'
import type { DatasetItem, GpuInfo, TrainedModel } from '@/types'
export interface EvalTaskSetupDraft {
eval_task_name: string
model_id: string | number
gpu_id: string | number
data_source: 'dataset' | 'inference'
dataset_id: string | number
leaderboard: boolean
}
defineProps<{
trainedModels: TrainedModel[]
evalDatasets: DatasetItem[]
gpus: GpuInfo[]
loading?: boolean
disabled?: boolean
}>()
const form = defineModel<EvalTaskSetupDraft>({ required: true })
const formRef = ref<FormInstance>()
const rules: FormRules<EvalTaskSetupDraft> = {
eval_task_name: [
{ required: true, message: '请输入任务名称', trigger: 'blur' },
{ max: 50, message: '任务名称不超过 50 个字符', trigger: 'blur' },
],
model_id: [{ required: true, message: '请选择评测模型', trigger: 'change' }],
gpu_id: [{ required: true, message: '请选择 GPU', trigger: 'change' }],
dataset_id: [
{
validator: (_rule, value, callback) => {
if (form.value.data_source === 'dataset' && (value === '' || value === null || value === undefined)) {
callback(new Error('请选择评测数据集'))
return
}
callback()
},
trigger: 'change',
},
],
}
watch(
() => form.value.data_source,
(source) => {
if (source !== 'dataset') {
form.value.dataset_id = ''
formRef.value?.clearValidate('dataset_id')
}
},
)
async function validate() {
if (!formRef.value) return false
try {
const valid = await formRef.value.validate()
return !!valid
} catch {
return false
}
}
defineExpose({ validate })
</script>
<template>
<el-form
ref="formRef"
:model="form"
:rules="rules"
label-width="120px"
class="step-form"
:disabled="disabled"
scroll-to-error
>
<el-form-item label="任务名称" prop="eval_task_name">
<el-input v-model="form.eval_task_name" placeholder="请输入任务名称" maxlength="50" show-word-limit />
</el-form-item>
<el-form-item label="评测模型" prop="model_id">
<el-select
v-model="form.model_id"
placeholder="请选择已训练且已合并的模型"
filterable
style="width: 100%"
:loading="loading"
>
<el-option
v-for="model in trainedModels"
:key="model.id"
:label="model.name"
:value="model.id"
:disabled="!model.merged"
/>
</el-select>
<div class="field-tip">未完成合并的模型不可用于评测</div>
</el-form-item>
<el-form-item label="选择 GPU" prop="gpu_id">
<el-select v-model="form.gpu_id" placeholder="请选择 GPU" style="width: 100%" :loading="loading">
<el-option
v-for="(gpu, index) in gpus"
:key="index"
:label="`${gpu.name} (GPU ${index})`"
:value="index"
/>
</el-select>
</el-form-item>
<el-form-item label="数据来源">
<el-radio-group v-model="form.data_source">
<el-radio value="dataset">评测数据集</el-radio>
<el-radio value="inference">推理结果集</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="form.data_source === 'dataset'" label="评测数据集" prop="dataset_id">
<el-select
v-model="form.dataset_id"
placeholder="请选择评测数据集"
filterable
style="width: 100%"
:loading="loading"
>
<el-option v-for="dataset in evalDatasets" :key="dataset.id" :label="dataset.name" :value="dataset.id" />
</el-select>
</el-form-item>
<el-alert
v-else
title="将使用该模型最近一次可用的推理结果集。"
type="info"
:closable="false"
show-icon
class="source-alert"
/>
<el-form-item label="加入排行榜">
<el-switch v-model="form.leaderboard" />
</el-form-item>
</el-form>
</template>
<style scoped>
.step-form {
max-width: 760px;
}
.field-tip {
color: #909399;
font-size: 12px;
line-height: 20px;
}
.source-alert {
margin: -4px 0 20px 120px;
max-width: 640px;
}
</style>