init
This commit is contained in:
317
src/views/knowledge/aiEmbedStore/form.vue
Normal file
317
src/views/knowledge/aiEmbedStore/form.vue
Normal file
@@ -0,0 +1,317 @@
|
||||
<template>
|
||||
<el-dialog width="40%" :title="form.storeId ? '编辑' : '新增'" v-model="visible" :close-on-click-modal="false" draggable>
|
||||
<el-form ref="dataFormRef" :model="form" :rules="dataRules" formDialogRef label-width="90px" v-loading="loading">
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="类型" prop="storeType">
|
||||
<el-select v-model="form.storeType" placeholder="请选择类型">
|
||||
<el-option :label="item.label" :value="item.value" v-for="(item, index) in embed_store_type" :key="index"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入名称" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24" class="mb20" v-if="form.storeType !== 'qdrant' && form.storeType !== 'redis' && form.storeType !== 'pgvector'">
|
||||
<el-form-item label="URI" prop="uri">
|
||||
<el-input v-model="form.uri" placeholder="请输入链接地址" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24" class="mb20" v-if="form.storeType === 'qdrant' || form.storeType === 'redis' || form.storeType === 'pgvector'">
|
||||
<el-form-item label="Host" prop="host">
|
||||
<el-input v-model="form.host" placeholder="请输入Host" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24" class="mb20" v-if="form.storeType === 'qdrant' || form.storeType === 'redis' || form.storeType === 'pgvector'">
|
||||
<el-form-item label="端口" prop="port">
|
||||
<el-input-number v-model="form.port" placeholder="请输入端口" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24" class="mb20" v-if="form.storeType !== 'pgvector'">
|
||||
<el-form-item label="密钥" prop="apiKey">
|
||||
<el-input v-model="form.apiKey" placeholder="请输入密钥" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24" class="mb20" v-if="form.storeType === 'milvus'">
|
||||
<el-form-item label="数据库" prop="extData">
|
||||
<el-input v-model="form.extData" placeholder="请输入数据库" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<!-- PgVector 特有配置 -->
|
||||
<template v-if="form.storeType === 'pgvector'">
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="用户名" prop="pgUsername">
|
||||
<el-input v-model="form.pgUsername" placeholder="请输入用户名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="密码" prop="pgPassword">
|
||||
<el-input v-model="form.pgPassword" type="password" placeholder="请输入密码" show-password />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="数据库" prop="pgDatabase">
|
||||
<el-input v-model="form.pgDatabase" placeholder="请输入数据库名" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item label="维度" prop="pgDimension">
|
||||
<el-input-number v-model="form.pgDimension" :min="1" :max="4096" placeholder="请输入向量维度" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<el-col :span="24" class="mb20">
|
||||
<el-form-item prop="useTls" v-if="form.storeType === 'qdrant'">
|
||||
<template #label> TLS<tip content="HTTPS安全认证" /> </template>
|
||||
<el-radio-group v-model="form.useTls">
|
||||
<el-radio :key="index" :label="item.value" border v-for="(item, index) in yes_no_type">{{ item.label }} </el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="visible = false">取消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" :disabled="loading">确认</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="AiEmbedStoreDialog">
|
||||
import { useDict } from '/@/hooks/dict';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
import { getObj, addObj, putObj, validateExist } from '/@/api/knowledge/aiEmbedStore';
|
||||
const emit = defineEmits(['refresh']);
|
||||
|
||||
// 定义变量内容
|
||||
const dataFormRef = ref();
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
// 定义字典
|
||||
const { embed_store_type, yes_no_type } = useDict('embed_store_type', 'yes_no_type');
|
||||
|
||||
// 提交表单数据
|
||||
const form = reactive({
|
||||
storeId: '',
|
||||
name: '',
|
||||
storeType: 'milvus',
|
||||
host: '127.0.0.1',
|
||||
port: 6334,
|
||||
uri: 'http://127.0.0.1:19530',
|
||||
apiKey: '',
|
||||
extData: 'default',
|
||||
useTls: '0',
|
||||
// PgVector 特有字段
|
||||
pgUsername: 'postgres',
|
||||
pgPassword: 'postgres',
|
||||
pgDatabase: 'database',
|
||||
pgDimension: 4096,
|
||||
});
|
||||
|
||||
// 监听 storeType 变化,设置默认端口
|
||||
watch(
|
||||
() => form.storeType,
|
||||
(newType) => {
|
||||
if (newType === 'pgvector') {
|
||||
form.port = 5432;
|
||||
} else if (newType === 'qdrant') {
|
||||
form.port = 6334;
|
||||
} else if (newType === 'redis') {
|
||||
form.port = 6379;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 定义校验规则
|
||||
const dataRules = ref({
|
||||
name: [
|
||||
{ required: true, message: '名称不能为空', trigger: 'blur' },
|
||||
{ max: 64, message: '长度不能超过64个字符', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
validateExist(rule, value, callback, form.storeId !== '');
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
storeType: [{ required: true, message: '类型不能为空', trigger: 'blur' }],
|
||||
host: [
|
||||
{ required: true, message: 'Host不能为空', trigger: 'blur' },
|
||||
{ max: 255, message: '长度不能超过255个字符', trigger: 'blur' },
|
||||
],
|
||||
port: [
|
||||
{ required: true, message: '端口不能为空', trigger: 'blur' },
|
||||
{ type: 'number', max: 65535, message: '端口不能超过65535', trigger: 'blur' },
|
||||
],
|
||||
uri: [
|
||||
{ required: true, message: '地址不能为空', trigger: 'blur' },
|
||||
{ max: 255, message: '长度不能超过255个字符', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
// URI变化时,重新验证数据库字段
|
||||
nextTick(() => {
|
||||
if (dataFormRef.value) {
|
||||
dataFormRef.value.validateField('extData');
|
||||
}
|
||||
});
|
||||
callback();
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
extData: [
|
||||
{ max: 255, message: '长度不能超过255个字符', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
// 检查URI是否包含.zilliz.com.cn(在线服务)
|
||||
if (form.uri && form.uri.includes('.zilliz.com.cn')) {
|
||||
if (!value) {
|
||||
callback(new Error('使用Zilliz在线服务时,数据库字段不能为空'));
|
||||
return;
|
||||
}
|
||||
// 检查数据库字段格式是否为 db_xxxx
|
||||
const dbPattern = /^db_\w+$/;
|
||||
if (!dbPattern.test(value)) {
|
||||
callback(new Error('使用Zilliz在线服务时,数据库字段必须是 db_id 的形式'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
callback();
|
||||
},
|
||||
trigger: 'blur',
|
||||
},
|
||||
],
|
||||
// PgVector 校验规则
|
||||
pgUsername: [
|
||||
{ required: true, message: '用户名不能为空', trigger: 'blur' },
|
||||
{ max: 64, message: '长度不能超过64个字符', trigger: 'blur' },
|
||||
],
|
||||
pgPassword: [
|
||||
{ required: true, message: '密码不能为空', trigger: 'blur' },
|
||||
{ max: 255, message: '长度不能超过255个字符', trigger: 'blur' },
|
||||
],
|
||||
pgDatabase: [
|
||||
{ required: true, message: '数据库名不能为空', trigger: 'blur' },
|
||||
{ max: 64, message: '长度不能超过64个字符', trigger: 'blur' },
|
||||
],
|
||||
pgDimension: [
|
||||
{ required: true, message: '维度不能为空', trigger: 'blur' },
|
||||
{ type: 'number', min: 1, max: 4096, message: '维度必须在1-4096之间', trigger: 'blur' },
|
||||
],
|
||||
});
|
||||
|
||||
// 打开弹窗
|
||||
const openDialog = (id: string) => {
|
||||
visible.value = true;
|
||||
form.storeId = '';
|
||||
form.extData = '';
|
||||
|
||||
// 重置表单数据
|
||||
nextTick(() => {
|
||||
dataFormRef.value?.resetFields();
|
||||
});
|
||||
|
||||
// 获取aiEmbedStore信息
|
||||
if (id) {
|
||||
form.storeId = id;
|
||||
getaiEmbedStoreData(id);
|
||||
}
|
||||
};
|
||||
|
||||
// 提交
|
||||
const onSubmit = async () => {
|
||||
const valid = await dataFormRef.value.validate().catch(() => {});
|
||||
if (!valid) return false;
|
||||
|
||||
try {
|
||||
loading.value = true;
|
||||
// 修复TypeScript错误:正确处理apiKey的类型
|
||||
const submitForm = { ...form };
|
||||
|
||||
// 处理 pgvector 类型的特殊逻辑
|
||||
if (form.storeType === 'pgvector') {
|
||||
// 将 pgvector 的配置信息存储到 extData 中
|
||||
const pgConfig = {
|
||||
username: form.pgUsername,
|
||||
password: form.pgPassword,
|
||||
database: form.pgDatabase,
|
||||
dimension: form.pgDimension,
|
||||
};
|
||||
submitForm.extData = JSON.stringify(pgConfig);
|
||||
|
||||
// 清空不需要的字段
|
||||
submitForm.apiKey = '';
|
||||
} else {
|
||||
// 处理其他类型的 apiKey
|
||||
if (submitForm.apiKey?.includes('***')) {
|
||||
submitForm.apiKey = '';
|
||||
}
|
||||
}
|
||||
|
||||
// 移除 pgvector 特有的临时字段
|
||||
delete (submitForm as any).pgUsername;
|
||||
delete (submitForm as any).pgPassword;
|
||||
delete (submitForm as any).pgDatabase;
|
||||
delete (submitForm as any).pgDimension;
|
||||
|
||||
form.storeId ? await putObj(submitForm) : await addObj(submitForm);
|
||||
useMessage().success(form.storeId ? '修改成功' : '添加成功');
|
||||
visible.value = false;
|
||||
emit('refresh');
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 初始化表单数据
|
||||
const getaiEmbedStoreData = (id: string) => {
|
||||
// 获取数据
|
||||
loading.value = true;
|
||||
getObj({ storeId: id })
|
||||
.then((res: any) => {
|
||||
Object.assign(form, res.data);
|
||||
|
||||
// 如果是 pgvector 类型,解析 extData 中的配置
|
||||
if (form.storeType === 'pgvector' && form.extData) {
|
||||
try {
|
||||
const pgConfig = JSON.parse(form.extData);
|
||||
form.pgUsername = pgConfig.username || 'postgres';
|
||||
form.pgPassword = pgConfig.password || 'postgres';
|
||||
form.pgDatabase = pgConfig.database || 'database';
|
||||
form.pgDimension = pgConfig.dimension || 4096;
|
||||
} catch (e) {
|
||||
// 解析失败时使用默认值
|
||||
form.pgUsername = 'postgres';
|
||||
form.pgPassword = 'postgres';
|
||||
form.pgDatabase = 'database';
|
||||
form.pgDimension = 4096;
|
||||
}
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
openDialog,
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user