Files
YG_FT/frontend/src/views/compare/CompareChatView.vue
2026-07-27 09:12:47 +08:00

144 lines
4.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { ref, reactive, computed, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import PageCard from '@/components/PageCard.vue'
import { usePolling } from '@/composables/usePolling'
import { getCompare } from '@/api/modules/compare'
import type { CompareTask, LoadedModel } from '@/types'
const route = useRoute()
const router = useRouter()
const taskId = route.params.id as string
const task = ref<CompareTask | null>(null)
const form = reactive({
systemPrompt: '',
question: '',
temperature: 0.7,
topP: 0.9,
topK: 40,
maxTokens: 2048,
})
const loadedModels = computed<LoadedModel[]>(() => {
if (!task.value?.load_status) return []
try {
const ls =
typeof task.value.load_status === 'string'
? JSON.parse(task.value.load_status)
: task.value.load_status
return ls.loaded_models || []
} catch {
return []
}
})
const allReady = computed(
() => loadedModels.value.length > 0 && loadedModels.value.every((m) => m.status === 'ready' || m.status === 'running'),
)
const isStarting = computed(() => loadedModels.value.some((m) => m.status === 'starting'))
async function loadTask() {
try {
task.value = await getCompare(taskId)
} catch {
// ignore
}
}
function handleSubmit() {
if (!form.question.trim()) {
ElMessage.warning('请输入问题')
return
}
if (isStarting.value) {
ElMessage.warning('模型仍在启动中,请稍候')
return
}
// 在新窗口打开结果页(原项目用 window.open
const params = new URLSearchParams({
taskId,
taskName: task.value?.model_name || task.value?.name || '',
question: form.question,
systemPrompt: form.systemPrompt,
temperature: String(form.temperature),
topP: String(form.topP),
topK: String(form.topK),
maxTokens: String(form.maxTokens),
})
const url = router.resolve(`/model-compare/result?${params.toString()}`).href
window.open(url, '_blank')
}
const { start: startPolling } = usePolling(loadTask, 5000, { immediate: false })
onMounted(async () => {
await loadTask()
startPolling()
})
</script>
<template>
<PageCard title="模型对比配置">
<!-- 已启动模型 -->
<el-divider content-position="left">已启动模型</el-divider>
<div class="model-list">
<el-tag
v-for="(m, idx) in loadedModels"
:key="idx"
:type="m.status === 'ready' || m.status === 'running' ? 'success' : m.status === 'starting' ? 'warning' : 'danger'"
size="large"
>
{{ m.model_name }} ({{ m.status }})
</el-tag>
<span v-if="!loadedModels.length" class="empty-hint">暂无已启动模型</span>
</div>
<!-- 输入配置 -->
<el-divider content-position="left">对话配置</el-divider>
<el-form label-width="120px" style="max-width: 700px">
<el-form-item label="系统提示词">
<el-input v-model="form.systemPrompt" type="textarea" :rows="3" placeholder="可选" />
</el-form-item>
<el-form-item label="问题">
<el-input v-model="form.question" type="textarea" :rows="4" placeholder="请输入要对比的问题" />
</el-form-item>
<el-form-item label="Temperature">
<el-slider v-model="form.temperature" :min="0" :max="2" :step="0.1" show-input style="max-width: 500px" />
</el-form-item>
<el-form-item label="Top-p">
<el-slider v-model="form.topP" :min="0" :max="1" :step="0.05" show-input style="max-width: 500px" />
</el-form-item>
<el-form-item label="Top-k">
<el-slider v-model="form.topK" :min="1" :max="100" :step="1" show-input style="max-width: 500px" />
</el-form-item>
<el-form-item label="Max Tokens">
<el-slider v-model="form.maxTokens" :min="256" :max="4096" :step="128" show-input style="max-width: 500px" />
</el-form-item>
<el-form-item>
<el-button type="primary" :disabled="!allReady || isStarting" @click="handleSubmit">
开始对比
</el-button>
<el-button @click="router.back()">返回</el-button>
</el-form-item>
</el-form>
</PageCard>
</template>
<style scoped>
.model-list {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-bottom: 12px;
}
.empty-hint {
color: #909399;
}
</style>