feat: 收口知识库分享链路
- 新增 shareKey 单参数 URL 分享页与失效页 - 新增知识库分享后端鉴权、审计与迁移脚本 - 在访问令牌中增加知识库分享授权入口
This commit is contained in:
@@ -0,0 +1,227 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
|
||||
import { $t } from '@easyflow/locales';
|
||||
|
||||
import {
|
||||
ElButton,
|
||||
ElCard,
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
ElInputNumber,
|
||||
ElMessage,
|
||||
ElOption,
|
||||
ElSelect,
|
||||
ElSwitch,
|
||||
} from 'element-plus';
|
||||
|
||||
import { api } from '#/api/request';
|
||||
import { buildKnowledgePath } from '#/views/ai/documentCollection/share-path';
|
||||
|
||||
const props = defineProps({
|
||||
knowledgeId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
detailData: {
|
||||
type: Object as any,
|
||||
default: () => ({}),
|
||||
},
|
||||
requestClient: {
|
||||
type: Object as any,
|
||||
default: () => api,
|
||||
},
|
||||
endpointPrefix: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['reload']);
|
||||
|
||||
const form = ref<any>({
|
||||
knowledgeId: '',
|
||||
vectorEmbedModelId: '',
|
||||
rerankModelId: '',
|
||||
rerankEnable: false,
|
||||
docRecallMaxNum: 5,
|
||||
simThreshold: 0.6,
|
||||
rebuildVectors: false,
|
||||
});
|
||||
|
||||
const embeddingModels = ref<any[]>([]);
|
||||
const rerankModels = ref<any[]>([]);
|
||||
const saving = ref(false);
|
||||
|
||||
const syncForm = () => {
|
||||
const options = props.detailData?.options || {};
|
||||
form.value = {
|
||||
knowledgeId: props.knowledgeId,
|
||||
vectorEmbedModelId: props.detailData?.vectorEmbedModelId || '',
|
||||
rerankModelId: props.detailData?.rerankModelId || '',
|
||||
rerankEnable:
|
||||
options?.rerankEnable === undefined
|
||||
? !!props.detailData?.rerankModelId
|
||||
: !!options.rerankEnable,
|
||||
docRecallMaxNum: Number(options?.docRecallMaxNum || 5),
|
||||
simThreshold: Number(options?.simThreshold || 0.6),
|
||||
rebuildVectors: false,
|
||||
};
|
||||
};
|
||||
|
||||
watch(
|
||||
() => [props.detailData, props.knowledgeId],
|
||||
() => {
|
||||
syncForm();
|
||||
},
|
||||
{ immediate: true, deep: true },
|
||||
);
|
||||
|
||||
const loadModels = async () => {
|
||||
const [embeddingRes, rerankRes] = await Promise.all([
|
||||
props.requestClient.get(
|
||||
buildKnowledgePath(
|
||||
props.endpointPrefix,
|
||||
'/api/v1/documentCollection/modelList',
|
||||
),
|
||||
{ params: { modelType: 'embeddingModel' } },
|
||||
),
|
||||
props.requestClient.get(
|
||||
buildKnowledgePath(
|
||||
props.endpointPrefix,
|
||||
'/api/v1/documentCollection/modelList',
|
||||
),
|
||||
{ params: { modelType: 'rerankModel' } },
|
||||
),
|
||||
]);
|
||||
embeddingModels.value = embeddingRes?.data || [];
|
||||
rerankModels.value = rerankRes?.data || [];
|
||||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
saving.value = true;
|
||||
try {
|
||||
const res = await props.requestClient.post(
|
||||
buildKnowledgePath(
|
||||
props.endpointPrefix,
|
||||
'/api/v1/documentCollection/shareConfigUpdate',
|
||||
),
|
||||
form.value,
|
||||
);
|
||||
if (res.errorCode === 0) {
|
||||
ElMessage.success($t('message.saveOkMessage'));
|
||||
emit('reload');
|
||||
}
|
||||
} finally {
|
||||
saving.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadModels();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ElCard shadow="never" class="share-config-card">
|
||||
<template #header>
|
||||
<div class="share-config-card__header">
|
||||
<div>
|
||||
<div class="share-config-card__title">受限配置</div>
|
||||
<div class="share-config-card__desc">
|
||||
仅开放模型切换、检索参数与向量重建
|
||||
</div>
|
||||
</div>
|
||||
<ElButton type="primary" :loading="saving" @click="handleSave">
|
||||
{{ $t('button.save') }}
|
||||
</ElButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<ElForm label-position="top" class="share-config-form">
|
||||
<ElFormItem :label="$t('documentCollection.vectorEmbedLlmId')">
|
||||
<ElSelect v-model="form.vectorEmbedModelId">
|
||||
<ElOption
|
||||
v-for="item in embeddingModels"
|
||||
:key="item.id"
|
||||
:label="item.title"
|
||||
:value="item.id"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
|
||||
<ElFormItem :label="$t('documentCollection.rerankLlmId')">
|
||||
<ElSelect v-model="form.rerankModelId" clearable>
|
||||
<ElOption
|
||||
v-for="item in rerankModels"
|
||||
:key="item.id"
|
||||
:label="item.title"
|
||||
:value="item.id"
|
||||
/>
|
||||
</ElSelect>
|
||||
</ElFormItem>
|
||||
|
||||
<ElFormItem :label="$t('documentCollection.rerankEnable')">
|
||||
<ElSwitch v-model="form.rerankEnable" />
|
||||
</ElFormItem>
|
||||
|
||||
<ElFormItem :label="$t('documentCollectionSearch.docRecallMaxNum.label')">
|
||||
<ElInputNumber v-model="form.docRecallMaxNum" :min="1" :max="50" />
|
||||
</ElFormItem>
|
||||
|
||||
<ElFormItem :label="$t('documentCollectionSearch.simThreshold.label')">
|
||||
<ElInputNumber
|
||||
v-model="form.simThreshold"
|
||||
:min="0"
|
||||
:max="1"
|
||||
:step="0.01"
|
||||
/>
|
||||
</ElFormItem>
|
||||
|
||||
<ElFormItem label="保存后重建向量">
|
||||
<ElSwitch v-model="form.rebuildVectors" />
|
||||
</ElFormItem>
|
||||
</ElForm>
|
||||
</ElCard>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.share-config-card {
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.share-config-card__header {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.share-config-card__title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.share-config-card__desc {
|
||||
margin-top: 4px;
|
||||
font-size: 13px;
|
||||
color: var(--el-text-color-secondary);
|
||||
}
|
||||
|
||||
.share-config-form {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 0 16px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.share-config-form {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.share-config-card__header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user