Files
Jog/jog-frontend/src/views/admin/AiModels.vue
T

188 lines
6.0 KiB
Vue
Raw Normal View History

<template>
<div>
<h2 class="page-title">AI 模型管理</h2>
<div class="filter-bar">
<el-button type="primary" @click="showAddDialog">新增模型</el-button>
</div>
<el-card class="table-card">
<el-table :data="models" v-loading="loading">
<el-table-column prop="id" label="ID" width="80" />
<el-table-column prop="displayName" label="展示名称" min-width="140" />
<el-table-column prop="modelCode" label="模型编码" min-width="140" />
<el-table-column prop="description" label="描述" min-width="160" show-overflow-tooltip />
<el-table-column label="状态" width="80">
<template #default="{ row }">
<el-tag :type="row.enabled ? 'success' : 'danger'">{{ row.enabled ? '启用' : '禁用' }}</el-tag>
</template>
</el-table-column>
<el-table-column label="图片" width="70">
<template #default="{ row }">
<span>{{ row.allowImageUpload ? '是' : '否' }}</span>
</template>
</el-table-column>
<el-table-column label="语音" width="70">
<template #default="{ row }">
<span>{{ row.allowVoiceUpload ? '是' : '否' }}</span>
</template>
</el-table-column>
<el-table-column label="默认" width="70">
<template #default="{ row }">
<el-tag v-if="row.isDefault" type="warning" size="small">默认</el-tag>
<span v-else></span>
</template>
</el-table-column>
<el-table-column prop="sort" label="排序" width="70" />
<el-table-column label="操作" width="180" fixed="right">
<template #default="{ row }">
<el-button text type="primary" @click="showEditDialog(row)">编辑</el-button>
<el-button text type="danger" @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<el-dialog v-model="dialogVisible" :title="isEdit ? '编辑模型' : '新增模型'" width="520px">
<el-form :model="form" label-width="120px">
<el-form-item label="展示名称" required>
<el-input v-model="form.displayName" maxlength="32" placeholder="如:通义 Turbo · 快速" />
</el-form-item>
<el-form-item label="模型编码" required>
<el-input v-model="form.modelCode" maxlength="64" placeholder="如:qwen-turbo" />
</el-form-item>
<el-form-item label="描述">
<el-input v-model="form.description" type="textarea" :rows="2" maxlength="200" placeholder="可选,如:更强推理,适合复杂问题" />
</el-form-item>
<el-form-item label="启用">
<el-switch v-model="form.enabled" />
</el-form-item>
<el-form-item label="允许上传图片">
<el-switch v-model="form.allowImageUpload" />
</el-form-item>
<el-form-item label="允许上传语音">
<el-switch v-model="form.allowVoiceUpload" />
</el-form-item>
<el-form-item label="默认模型">
<el-switch v-model="form.isDefault" />
</el-form-item>
<el-form-item label="排序">
<el-input-number v-model="form.sort" :min="0" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSubmit">确定</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { listAdminAiModels, createAdminAiModel, updateAdminAiModel, deleteAdminAiModel } from '@/api/aiModel'
import { ElMessage, ElMessageBox } from 'element-plus'
const models = ref([])
const loading = ref(false)
const dialogVisible = ref(false)
const isEdit = ref(false)
const editingId = ref(null)
const form = ref({
modelCode: '',
displayName: '',
description: '',
enabled: true,
allowImageUpload: false,
allowVoiceUpload: false,
isDefault: false,
sort: 0,
})
async function loadModels() {
loading.value = true
try {
const res = await listAdminAiModels()
models.value = res.data || []
} finally {
loading.value = false
}
}
function showAddDialog() {
isEdit.value = false
editingId.value = null
form.value = { modelCode: '', displayName: '', description: '', enabled: true, allowImageUpload: false, allowVoiceUpload: false, isDefault: false, sort: 0 }
dialogVisible.value = true
}
function showEditDialog(row) {
isEdit.value = true
editingId.value = row.id
form.value = {
modelCode: row.modelCode,
displayName: row.displayName,
description: row.description || '',
enabled: row.enabled,
allowImageUpload: row.allowImageUpload,
allowVoiceUpload: row.allowVoiceUpload,
isDefault: row.isDefault,
sort: row.sort,
}
dialogVisible.value = true
}
async function handleSubmit() {
if (!form.value.displayName.trim()) {
ElMessage.warning('请输入展示名称')
return
}
if (!form.value.modelCode.trim()) {
ElMessage.warning('请输入模型编码')
return
}
try {
if (isEdit.value) {
await updateAdminAiModel(editingId.value, form.value)
} else {
await createAdminAiModel(form.value)
}
ElMessage.success('操作成功')
dialogVisible.value = false
loadModels()
} catch {
// error handled by interceptor
}
}
async function handleDelete(row) {
await ElMessageBox.confirm(`确定删除模型"${row.displayName}"`, '提示')
try {
await deleteAdminAiModel(row.id)
ElMessage.success('已删除')
loadModels()
} catch {
// error handled by interceptor
}
}
onMounted(loadModels)
</script>
<style scoped>
.page-title {
color: var(--text-primary);
font-size: var(--font-size-xl);
margin-bottom: var(--spacing-lg);
}
.filter-bar {
margin-bottom: var(--spacing-lg);
display: flex;
gap: var(--spacing-md);
align-items: center;
}
.table-card {
border-radius: var(--radius-md);
overflow: hidden;
}
.table-card :deep(.el-card__body) { padding: 0; }
</style>