feat(知识库): 添加模型配置管理功能并修复向量状态显示
添加模型配置管理相关功能,包括模型配置列表展示、创建和编辑功能。同时修复文档详情中向量状态显示问题,将数字类型转换为布尔类型以正确绑定到el-switch组件。 - 新增模型配置相关API接口和类型定义 - 添加模型配置列表弹窗及创建/编辑表单 - 修复向量状态显示问题,确保与el-switch组件正确绑定 - 优化深拷贝逻辑,自动转换status字段类型
This commit is contained in:
@@ -77,7 +77,7 @@
|
||||
<div class="vector-item" v-for="vector in vectorList" :key="vector.id">
|
||||
<div class="vector-header">
|
||||
<span class="vector-index">块 {{ vector.chunkIndex }}</span>
|
||||
<span class="vector-status">状态: {{ vector.status === 1 ? '启用' : '禁用' }}</span>
|
||||
<span class="vector-status">状态: {{ vector.status ? '启用' : '禁用' }}</span>
|
||||
<span class="vector-vector-status">向量状态: {{ vector.vectorStatus === 1 ? '已生成' : '未生成' }}</span>
|
||||
<el-switch v-model="vector.status" size="small" @change="(value: boolean) => onVectorStatusChange(vector, !value)" />
|
||||
</div>
|
||||
@@ -233,8 +233,13 @@ const getVectorList = async () => {
|
||||
pageNum: vectorPage.value,
|
||||
pageSize: vectorPageSize.value,
|
||||
});
|
||||
// 深拷贝数据,避免v-model触发不必要的更新
|
||||
vectorList.value = (response.data?.list || []).map((item: any) => JSON.parse(JSON.stringify(item)));
|
||||
// 深拷贝数据,避免v-model触发不必要的更新,并将status从数字转换为布尔类型
|
||||
vectorList.value = (response.data?.list || []).map((item: any) => {
|
||||
const clonedItem = JSON.parse(JSON.stringify(item));
|
||||
// 将数字类型的status转换为布尔类型,以便正确绑定到el-switch
|
||||
clonedItem.status = clonedItem.status === 1;
|
||||
return clonedItem;
|
||||
});
|
||||
vectorTotal.value = response.data?.total || 0;
|
||||
} catch (_error) {
|
||||
ElMessage.error('获取向量列表失败');
|
||||
|
||||
@@ -7,10 +7,16 @@
|
||||
<el-icon class="header-icon"><ele-Folder /></el-icon>
|
||||
<span class="header-title">知识库</span>
|
||||
</div>
|
||||
<el-button type="primary" @click="onAddknowledge">
|
||||
<el-icon><ele-Plus /></el-icon>
|
||||
新建知识库
|
||||
</el-button>
|
||||
<div class="header-actions">
|
||||
<el-button type="primary" @click="onAddknowledge">
|
||||
<el-icon><ele-Plus /></el-icon>
|
||||
新建知识库
|
||||
</el-button>
|
||||
<el-button type="success" @click="onOpenModelConfig">
|
||||
<el-icon><ele-Setting /></el-icon>
|
||||
模型配置
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="knowledge-cards" v-loading="knowledgeLoading">
|
||||
@@ -268,6 +274,91 @@
|
||||
:knowledgeName="currentknowledge?.name || ''"
|
||||
:document="currentDocument"
|
||||
/>
|
||||
|
||||
<!-- 模型配置弹窗 -->
|
||||
<el-dialog title="模型配置" v-model="showModelConfigDialog" width="1000px" :close-on-click-modal="false">
|
||||
<div class="model-config-list" v-loading="modelConfigLoading">
|
||||
<el-button type="primary" style="margin-bottom: 16px" @click="onCreateModelConfig">
|
||||
<el-icon><ele-Plus /></el-icon>
|
||||
创建模型配置
|
||||
</el-button>
|
||||
<el-table :data="modelConfigList" style="width: 100%" border>
|
||||
<el-table-column prop="modelName" label="模型名称" min-width="120" />
|
||||
<el-table-column prop="modelType" label="模型类型" min-width="100" />
|
||||
<el-table-column prop="modelDesc" label="模型描述" min-width="150" />
|
||||
<el-table-column prop="configType" label="配置类型" min-width="100" />
|
||||
<el-table-column prop="createTime" label="创建时间" min-width="150">
|
||||
<template #default="{ row }">
|
||||
{{ formatDateTime(row.createTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="updateTime" label="修改时间" min-width="150">
|
||||
<template #default="{ row }">
|
||||
{{ formatDateTime(row.updateTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="80" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button text size="small" type="primary" @click="onEditModelConfig(row)">编辑</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-empty v-if="modelConfigList.length === 0 && !modelConfigLoading" description="暂无模型配置" :image-size="60" />
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="showModelConfigDialog = false">关闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 创建/编辑模型配置弹窗 -->
|
||||
<el-dialog :title="isEditMode ? '编辑模型配置' : '创建模型配置'" v-model="showCreateModelDialog" width="600px" :close-on-click-modal="false">
|
||||
<div v-loading="modelEnumsLoading || modelFormLoading">
|
||||
<el-form :model="modelFormData" label-width="100px">
|
||||
<!-- 模型类型选择 -->
|
||||
<el-form-item label="模型类型" required>
|
||||
<el-select v-model="selectedModelType" style="width: 100%" @change="onModelTypeChange">
|
||||
<el-option v-for="item in modelEnums" :key="item.key" :label="item.value" :value="item.key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 配置类型选择 -->
|
||||
<el-form-item label="配置类型" required>
|
||||
<el-select v-model="selectedConfigType" style="width: 100%" @change="onConfigTypeChange" :disabled="!selectedModelType">
|
||||
<el-option v-for="item in getConfigTypes()" :key="item.key" :label="item.value" :value="item.key" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 动态表单字段 -->
|
||||
<template v-if="modelFormFields.length > 0">
|
||||
<el-form-item v-for="(field, index) in modelFormFields" :key="field.name || index" :label="field.label" :required="field.required">
|
||||
<template v-if="field.type === 'textarea'">
|
||||
<el-input
|
||||
v-model="modelFormData[field.name]"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
:placeholder="field.placeholder"
|
||||
:disabled="field.disabled"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</template>
|
||||
<template v-else-if="field.type === 'switch'">
|
||||
<el-switch v-model="modelFormData[field.name]" :disabled="field.disabled" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-input v-model="modelFormData[field.name]" :placeholder="field.placeholder" :disabled="field.disabled" style="width: 100%" />
|
||||
</template>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<!-- 无表单字段提示 -->
|
||||
<el-empty v-else description="暂无表单字段" :image-size="60" />
|
||||
</el-form>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="showCreateModelDialog = false">取消</el-button>
|
||||
<el-button type="primary" @click="onSaveModelConfig()" :disabled="!selectedModelType || !selectedConfigType"> 保存 </el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -284,6 +375,7 @@ import type { FormInstance, FormRules, UploadFile } from 'element-plus';
|
||||
import DocumentDetailDialog from './component/documentDetailDialog.vue';
|
||||
import { listknowledges, createknowledge, updateknowledge, deleteknowledge } from '/@/api/knowledge/dataset';
|
||||
import { listDocuments, uploadFile, createDocument, deleteDocument, updateDocument, generateVector, getDocument } from '/@/api/knowledge/document';
|
||||
import { listModelConfigs, createModelConfig, updateModelConfig, getModelConfig, getAllModelEnums, getModelFormField } from '/@/api/knowledge/model';
|
||||
|
||||
// 数据集相关
|
||||
const knowledgeLoading = ref(false);
|
||||
@@ -291,6 +383,23 @@ const knowledgeList = ref<any[]>([]);
|
||||
const currentknowledge = ref<any>(null);
|
||||
const showknowledgeDialog = ref(false);
|
||||
const knowledgeSaving = ref(false);
|
||||
|
||||
// 模型配置相关
|
||||
const showModelConfigDialog = ref(false);
|
||||
const modelConfigList = ref<any[]>([]);
|
||||
const modelConfigLoading = ref(false);
|
||||
|
||||
// 创建模型配置相关
|
||||
const showCreateModelDialog = ref(false);
|
||||
const modelEnums = ref<any[]>([]);
|
||||
const selectedModelType = ref('');
|
||||
const selectedConfigType = ref('');
|
||||
const modelFormFields = ref<any[]>([]);
|
||||
const modelFormData = ref<any>({});
|
||||
const modelFormLoading = ref(false);
|
||||
const modelEnumsLoading = ref(false);
|
||||
const isEditMode = ref(false);
|
||||
const currentModelId = ref<number | null>(null);
|
||||
const knowledgeFormRef = ref<FormInstance>();
|
||||
const knowledgeForm = reactive({
|
||||
id: '',
|
||||
@@ -675,8 +784,215 @@ const getLogList = () => {
|
||||
};
|
||||
|
||||
// 保存配置
|
||||
const onSaveSettings = () => {
|
||||
ElMessage.success('配置保存成功');
|
||||
const onSaveSettings = async () => {
|
||||
ElMessage.success('保存成功');
|
||||
};
|
||||
|
||||
// 打开模型配置弹窗
|
||||
const onOpenModelConfig = async () => {
|
||||
await getModelConfigList();
|
||||
showModelConfigDialog.value = true;
|
||||
};
|
||||
|
||||
// 打开创建模型配置弹窗
|
||||
const onCreateModelConfig = async () => {
|
||||
// 重置状态
|
||||
selectedModelType.value = '';
|
||||
selectedConfigType.value = '';
|
||||
modelFormFields.value = [];
|
||||
modelFormData.value = {};
|
||||
isEditMode.value = false;
|
||||
currentModelId.value = null;
|
||||
|
||||
// 获取模型类型和配置类型枚举
|
||||
await getModelEnums();
|
||||
|
||||
// 打开创建弹窗
|
||||
showCreateModelDialog.value = true;
|
||||
};
|
||||
|
||||
// 编辑模型配置
|
||||
const onEditModelConfig = async (row: any) => {
|
||||
try {
|
||||
// 重置状态
|
||||
selectedModelType.value = '';
|
||||
selectedConfigType.value = '';
|
||||
modelFormFields.value = [];
|
||||
modelFormData.value = {};
|
||||
isEditMode.value = true;
|
||||
currentModelId.value = row.id;
|
||||
|
||||
// 获取模型类型和配置类型枚举
|
||||
await getModelEnums();
|
||||
|
||||
// 调用获取详情接口
|
||||
const response = await getModelConfig(row.id, row.modelType);
|
||||
const modelData = response.data;
|
||||
|
||||
// 设置模型类型和配置类型
|
||||
selectedModelType.value = modelData.modelType;
|
||||
selectedConfigType.value = modelData.configType;
|
||||
|
||||
// 填充表单数据
|
||||
modelFormData.value = {
|
||||
modelName: modelData.modelName,
|
||||
modelDesc: modelData.modelDesc,
|
||||
};
|
||||
|
||||
// 将configContent中的数据添加到表单数据中
|
||||
if (modelData.configContent) {
|
||||
Object.keys(modelData.configContent).forEach((key) => {
|
||||
modelFormData.value[key] = modelData.configContent[key];
|
||||
});
|
||||
}
|
||||
|
||||
// 获取动态表单字段
|
||||
await getModelFormFields();
|
||||
|
||||
// 打开弹窗
|
||||
showCreateModelDialog.value = true;
|
||||
} catch (error) {
|
||||
ElMessage.error('获取模型配置详情失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 获取模型类型和配置类型枚举
|
||||
const getModelEnums = async () => {
|
||||
modelEnumsLoading.value = true;
|
||||
try {
|
||||
const response = await getAllModelEnums();
|
||||
modelEnums.value = response.data?.options || [];
|
||||
} catch (error) {
|
||||
ElMessage.error('获取模型类型枚举失败');
|
||||
modelEnums.value = [];
|
||||
} finally {
|
||||
modelEnumsLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 模型类型选择变化
|
||||
const onModelTypeChange = async () => {
|
||||
selectedConfigType.value = '';
|
||||
modelFormFields.value = [];
|
||||
// 在编辑模式下,只保留模型名称和描述,清空其他字段
|
||||
if (isEditMode.value) {
|
||||
const { modelName, modelDesc } = modelFormData.value;
|
||||
modelFormData.value = {
|
||||
modelName,
|
||||
modelDesc,
|
||||
};
|
||||
} else {
|
||||
// 创建模式下清空所有字段
|
||||
modelFormData.value = {};
|
||||
}
|
||||
};
|
||||
|
||||
// 配置类型选择变化
|
||||
const onConfigTypeChange = async () => {
|
||||
if (selectedModelType.value && selectedConfigType.value) {
|
||||
await getModelFormFields();
|
||||
}
|
||||
};
|
||||
|
||||
// 获取模型表单字段
|
||||
const getModelFormFields = async () => {
|
||||
modelFormLoading.value = true;
|
||||
try {
|
||||
const response = await getModelFormField(selectedModelType.value, selectedConfigType.value);
|
||||
// 过滤掉模型类型和配置类型字段,避免重复显示
|
||||
modelFormFields.value = (response.data?.fields || []).filter((field: any) => {
|
||||
return field.name !== 'modelType' && field.name !== 'configType';
|
||||
});
|
||||
// 设置字段的默认值,但保留已有的表单数据
|
||||
modelFormFields.value.forEach((field: any) => {
|
||||
if (field.value !== undefined && modelFormData.value[field.name] === undefined) {
|
||||
modelFormData.value[field.name] = field.value;
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
ElMessage.error('获取模型表单字段失败');
|
||||
modelFormFields.value = [];
|
||||
} finally {
|
||||
modelFormLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 保存模型配置
|
||||
const onSaveModelConfig = async () => {
|
||||
try {
|
||||
// 构建请求数据,只传递接口需要的字段
|
||||
const data = {
|
||||
modelType: selectedModelType.value,
|
||||
configType: selectedConfigType.value,
|
||||
modelName: modelFormData.value.modelName,
|
||||
modelDesc: modelFormData.value.modelDesc,
|
||||
configContent: {} as Record<string, any>,
|
||||
};
|
||||
|
||||
// 将动态表单字段(除了modelType、configType、modelName、modelDesc)添加到configContent中,以key-value形式
|
||||
Object.keys(modelFormData.value).forEach((key) => {
|
||||
if (!['modelType', 'configType', 'modelName', 'modelDesc'].includes(key)) {
|
||||
data.configContent[key] = modelFormData.value[key];
|
||||
}
|
||||
});
|
||||
|
||||
// 根据模式调用不同的接口
|
||||
if (isEditMode.value && currentModelId.value) {
|
||||
// 编辑模式,调用更新接口
|
||||
await updateModelConfig({ ...data, id: currentModelId.value });
|
||||
ElMessage.success('更新模型配置成功');
|
||||
} else {
|
||||
// 创建模式,调用创建接口
|
||||
await createModelConfig(data);
|
||||
ElMessage.success('创建模型配置成功');
|
||||
}
|
||||
|
||||
// 关闭弹窗并刷新列表
|
||||
showCreateModelDialog.value = false;
|
||||
getModelConfigList();
|
||||
} catch (error) {
|
||||
ElMessage.error(isEditMode.value ? '更新模型配置失败' : '创建模型配置失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 根据选中的模型类型获取配置类型列表
|
||||
const getConfigTypes = () => {
|
||||
if (!selectedModelType.value) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const selectedModel = modelEnums.value.find((item: any) => item.key === selectedModelType.value);
|
||||
return selectedModel?.configTypes || [];
|
||||
};
|
||||
|
||||
// 获取模型配置列表
|
||||
const getModelConfigList = async () => {
|
||||
modelConfigLoading.value = true;
|
||||
try {
|
||||
const response = await listModelConfigs({
|
||||
pageNum: 1,
|
||||
pageSize: 100,
|
||||
});
|
||||
modelConfigList.value = response.data?.list || [];
|
||||
} catch (error) {
|
||||
ElMessage.error('获取模型配置列表失败');
|
||||
modelConfigList.value = [];
|
||||
} finally {
|
||||
modelConfigLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 格式化时间
|
||||
const formatDateTime = (dateTime: string) => {
|
||||
if (!dateTime) return '-';
|
||||
const date = new Date(dateTime);
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
};
|
||||
|
||||
// 页面加载
|
||||
|
||||
Reference in New Issue
Block a user