| | |
| | | <template> |
| | | <div class="main-container"> |
| | | <div ref="scrollContainer" class="main-container"> |
| | | <div style="position: absolute;top: 0;left: 0;width: 100%;padding: 0 20px"> |
| | | <h4 style="margin-bottom: 10px"></h4> |
| | | <div style="color: #666666;">在这里更新您的知识库详细信息,尤其是解析方法。</div> |
| | |
| | | </a-form-item> |
| | | <a-form-item field="section" label="知识库图片"> |
| | | <a-space direction="vertical" :style="{ width: '100%' }"> |
| | | <a-upload |
| | | :auto-upload="false" |
| | | :fileList="file ? [file] : []" |
| | | :show-file-list="false" |
| | | @change="onChange" |
| | | @progress="onProgress" |
| | | > |
| | | <template #upload-button> |
| | | <div |
| | | :class="`arco-upload-list-item${ |
| | | file && file.status === 'error' ? ' arco-upload-list-item-error' : '' |
| | | }`" |
| | | > |
| | | <div |
| | | class="arco-upload-list-picture custom-upload-avatar" |
| | | v-if="file && file.url" |
| | | > |
| | | <img :src="file.url" /> |
| | | <div class="arco-upload-list-picture-mask"> |
| | | <IconEdit /> |
| | | </div> |
| | | <a-progress |
| | | v-if="file.status === 'uploading' && file.percent < 100" |
| | | :percent="file.percent" |
| | | type="circle" |
| | | size="mini" |
| | | :style="{ |
| | | position: 'absolute', |
| | | left: '50%', |
| | | top: '50%', |
| | | transform: 'translateX(-50%) translateY(-50%)', |
| | | }" |
| | | /> |
| | | </div> |
| | | <div class="arco-upload-picture-card" v-else> |
| | | <div class="arco-upload-picture-card-text"> |
| | | <IconPlus /> |
| | | <div style="margin-top: 10px; font-weight: 600">上传</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </a-upload> |
| | | <Upload |
| | | v-if="avatarShow" |
| | | :action="uploadAction" |
| | | :limit="1" |
| | | :url="form.avatar ? httpUrl + form.avatar : ''" |
| | | @update:fileList="updateFileList" |
| | | @success="handleSuccess" |
| | | ></Upload> |
| | | </a-space> |
| | | </a-form-item> |
| | | <a-form-item field="section" label="描述"> |
| | |
| | | <!-- <a-option value="1">英文</a-option>--> |
| | | <!-- </a-select>--> |
| | | <!-- </a-form-item>--> |
| | | <a-form-item field="section" label="嵌入模型"> |
| | | <a-space direction="vertical" size="large"> |
| | | <a-select :size="'large'" v-model="form.embd_id" :style="{width:'100%'}" placeholder="请选择 ..." :disabled="kbObj.chunk_num==0 && kbObj.token_num==0" allow-clear> |
| | | <a-optgroup :label="index" v-for="(item,index) in modelList" :key=index> |
| | | <a-option |
| | | v-for="(obj) in item" |
| | | :key='obj.fid' |
| | | :value="obj.llm_name" |
| | | > |
| | | {{obj.llm_name}} |
| | | </a-option> |
| | | </a-optgroup> |
| | | </a-select> |
| | | </a-space> |
| | | <a-form-item field="embd_id" label="嵌入模型"> |
| | | <a-select :size="'large'" v-model="form.embd_id" placeholder="请选择 ..." :disabled="kbObj.chunk_num && kbObj.token_num"> |
| | | <!-- <a-optgroup :label="index" v-for="(item,index) in mobileData" :key=index> |
| | | <a-option |
| | | v-for="(obj) in item" |
| | | :key='obj.fid' |
| | | :value="obj.llm_name" |
| | | > |
| | | {{obj.llm_name}} |
| | | </a-option> |
| | | </a-optgroup> --> |
| | | <a-option |
| | | v-for="(item,index) in mobileData" |
| | | :key='item.name' |
| | | :value="item.name" |
| | | > |
| | | {{item.name}} |
| | | </a-option> |
| | | </a-select> |
| | | </a-form-item> |
| | | <a-form-item field="parser_id" label="解析方法"> |
| | | <a-select v-model="form.parser_id" placeholder="请选择" :disabled="kbObj.chunk_num==0 && kbObj.token_num==0" allow-clear> |
| | | <a-select v-model="form.parser_id" placeholder="请选择" :disabled="!!(kbObj.chunk_num && kbObj.token_num)" > |
| | | <a-option v-for="item in parser_ids" :key="item.value" :label="item.name" :value="item.value"></a-option> |
| | | </a-select> |
| | | </a-form-item> |
| | |
| | | <a-slider v-model="form.chunk_token_num" :min="0" :max="2048" show-input /> |
| | | </a-form-item> |
| | | <a-form-item label="布局识别" > |
| | | <a-space direction="vertical" size="large"> |
| | | <a-switch v-model="form.layout_recognize" /> |
| | | <a-space direction="vertical"> |
| | | <a-switch v-model="form.layout_recognize" size="small" /> |
| | | </a-space> |
| | | </a-form-item> |
| | | <a-form-item field="raptor" label="使用召回增强RAPTOR策略"> |
| | | <a-space direction="vertical" size="large"> |
| | | <a-switch v-model="form.use_raptor" /> |
| | | </a-space> |
| | | <a-switch v-model="form.use_raptor" size="small" /> |
| | | </a-form-item> |
| | | <div v-if="form.use_raptor"> |
| | | <a-form-item field="prompt" label="提示词"> |
| | |
| | | <div style="width: 100%;text-align: right"> |
| | | <a-space> |
| | | <a-button @click="cancelConfig">取消</a-button> |
| | | <a-button type="primary" html-type="submit">保存</a-button> |
| | | <a-button :loading="loading" type="primary" html-type="submit">保存</a-button> |
| | | </a-space> |
| | | </div> |
| | | </a-form-item> |
| | |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { onMounted, onBeforeMount, reactive, ref } from "vue"; |
| | | import { onMounted, onBeforeMount, reactive, ref, nextTick } from "vue"; |
| | | import { Message } from "@arco-design/web-vue"; |
| | | import { queryModelList,kbUpdate } from "@/api/kbList"; |
| | | import { queryModelList,kbUpdate,getKnowledgeBaseModel } from "@/api/kbList"; |
| | | import message from "@arco-design/web-vue/es/message"; |
| | | |
| | | |
| | | import useLoading from "@/hooks/loading"; |
| | | const { loading,setLoading } = useLoading(true); |
| | | const scrollContainer = ref(); |
| | | const props = defineProps(['kbtenantInfo']) |
| | | const emit = defineEmits(['cancleConfig']) |
| | | const emit = defineEmits(['cancleConfig','saveConfig']) |
| | | // 解析方法列表 |
| | | let parser_ids = props.kbtenantInfo.parser_ids.split(",").map((item) => { |
| | | const [value1, value2] = item.split(":"); |
| | |
| | | }); |
| | | |
| | | let kbObj = reactive({}); |
| | | let avatarShow = ref(true); |
| | | |
| | | const form = reactive({ |
| | | name: kbObj.name, |
| | | avatar: '',// |
| | | name: '', |
| | | avatar: '',//头像 |
| | | max_token: 600, |
| | | threshold: 0.32, |
| | | max_cluster: 233, |
| | |
| | | description: "", |
| | | language: "English", |
| | | permission: "", |
| | | embd_id: "BAAI/bge-large-zh-v1.5", |
| | | parser_id: kbObj.parser_id, |
| | | embd_id: "", |
| | | parser_id: '', |
| | | layout_recognize: true |
| | | }); |
| | | |
| | |
| | | message:'知识库名称不允许为空', |
| | | }, |
| | | ], |
| | | embd_id: [ |
| | | { |
| | | required: true, |
| | | message:'请选择', |
| | | }, |
| | | ], |
| | | parser_id: [ |
| | | { |
| | | required: true, |
| | | message:'请选择', |
| | | }, |
| | | ], |
| | | prompt: [ |
| | | { |
| | | required: true, |
| | | message:'提示词不允许为空', |
| | | }, |
| | | ], |
| | | } |
| | | |
| | | |
| | | let visible = ref(false); |
| | | let loading = ref(false); |
| | | const formRef = ref(null); |
| | | const formRef = ref(); |
| | | const modelList = ref({}); |
| | | const mobileData= ref<any>([]) |
| | | const file = ref(); |
| | | |
| | | const onChange = (_, currentFile) => { |
| | | file.value = currentFile; |
| | | convertImageToBase64(file.value.file).then((result)=>{ |
| | | form.avatar = result; |
| | | }) |
| | | const uploadAction = '/api/v1/llm/upload'; // 替换为你的上传API |
| | | const fileList = ref([]); |
| | | const imageUrls = ref([]); |
| | | const httpUrl = localStorage.getItem('httpUrl'); |
| | | |
| | | const updateFileList = (newFileList) => { |
| | | fileList.value = newFileList; |
| | | console.log(newFileList, 88); |
| | | }; |
| | | |
| | | function convertImageToBase64(file) { |
| | | return new Promise((resolve, reject) => { |
| | | const reader = new FileReader(); |
| | | reader.onloadend = function() { |
| | | resolve(reader.result); |
| | | }; |
| | | reader.onerror = reject; |
| | | reader.readAsDataURL(file); |
| | | }); |
| | | } |
| | | |
| | | const onProgress = (currentFile) => { |
| | | file.value = currentFile; |
| | | const handleSuccess = (urls) => { |
| | | imageUrls.value = urls; // 拿到上传的图片地址 |
| | | form.avatar = urls[0]; |
| | | }; |
| | | |
| | | |
| | |
| | | if (errors){ |
| | | return; |
| | | } |
| | | console.log(form.chunk_token_num); |
| | | let parms = { |
| | | name: form.name, |
| | | avatar: form.avatar, |
| | |
| | | }; |
| | | } |
| | | try { |
| | | |
| | | setLoading(true) |
| | | const data = await kbUpdate(parms); |
| | | if(data.code == '0'){ |
| | | Message.success("配置成功"); |
| | | // window.location.reload(); |
| | | emit('saveConfig') |
| | | |
| | | } |
| | | // emit('upTabdateItem') |
| | | setLoading(false) |
| | | |
| | | } catch (err) { |
| | | Message.error(err.message); |
| | | setLoading(false) |
| | | } |
| | | |
| | | |
| | |
| | | Object.assign(form,{ |
| | | |
| | | }); |
| | | formRef.value.resetFields(); |
| | | // formRef.value.resetFields(); |
| | | } |
| | | |
| | | const queryModel = async (params) => { |
| | | try { |
| | | const data = await queryModelList(params); |
| | | const data = await getKnowledgeBaseModel(params); |
| | | // const res =await queryModelList(params) |
| | | // console.log(data.data, '大模型列表'); |
| | | modelList.value = data.data |
| | | for(let key in data.data) { |
| | | if (data.data.hasOwnProperty(key)) { // 确保是对象自有属性,不是原型链上的属性 |
| | | if(data.data[key].llm.length > 0){ |
| | | mobileData.value= data.data[key].llm.filter(item => item.type == "embedding") |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | } catch (err) { |
| | | // you can report use errorHandler or other |
| | | } finally { |
| | |
| | | }; |
| | | |
| | | const changekbObj = (value) => { |
| | | formRef.value.resetFields(); |
| | | kbObj = value; |
| | | console.log(kbObj, 'kbObj'); |
| | | // if(kbObj.avatar){ |
| | | // file.value.url = kbObj.avatar |
| | | // } |
| | | let configObj = { |
| | | name: kbObj.name, |
| | | avatar: kbObj.avatar, |
| | | pages: kbObj.parser_config.pages, |
| | | description: kbObj.description, |
| | | language: "English", |
| | | permission: kbObj.permission, |
| | | embd_id: props.kbtenantInfo.embd_id || kbObj.embd_id, |
| | | parser_id: kbObj.parser_id, |
| | | layout_recognize: true, |
| | | } |
| | | let raptor = {} |
| | | if(kbObj.parser_config && kbObj.parser_config.raptor){ |
| | | raptor = kbObj.parser_config.raptor; |
| | | Object.assign(form,{ |
| | | ...configObj, |
| | | ...raptor, |
| | | use_raptor: kbObj.parser_config.raptor.use_raptor, |
| | | }); |
| | | }else{ |
| | | Object.assign(form,configObj); |
| | | } |
| | | console.log(form,'配置页面表单信息'); |
| | | |
| | | formRef.value.resetFields(); |
| | | nextTick(()=>{ |
| | | kbObj = value; |
| | | console.log(kbObj, 'kbObj'); |
| | | let configObj = { |
| | | name: kbObj.name, |
| | | avatar: kbObj.avatar, |
| | | pages: kbObj.parser_config.pages, |
| | | chunk_token_num: kbObj.parser_config.chunk_token_num, |
| | | description: kbObj.description, |
| | | language: "English", |
| | | permission: kbObj.permission, |
| | | embd_id: kbObj.embd_id || props.kbtenantInfo.embd_id, |
| | | parser_id: kbObj.parser_id, |
| | | layout_recognize: true, |
| | | } |
| | | let raptor = {} |
| | | if(kbObj.parser_config && kbObj.parser_config.raptor){ |
| | | raptor = kbObj.parser_config.raptor; |
| | | Object.assign(form,{ |
| | | ...configObj, |
| | | ...raptor, |
| | | use_raptor: kbObj.parser_config.raptor.use_raptor, |
| | | }); |
| | | }else{ |
| | | Object.assign(form,{ |
| | | ...configObj, |
| | | use_raptor: false, |
| | | }); |
| | | } |
| | | imageUrls.value = [kbObj.avatar]; |
| | | console.log(form,'配置页面表单信息'); |
| | | avatarShow.value = false; |
| | | setTimeout(() => { |
| | | avatarShow.value = true; |
| | | },100); |
| | | scrollContainer.value.scrollTop = 0; |
| | | }) |
| | | } |
| | | |
| | | defineExpose({ |
| | |
| | | |
| | | |
| | | onBeforeMount(()=>{ |
| | | setLoading(false) |
| | | queryModel({}) |
| | | }) |
| | | onMounted(()=>{ |
| | |
| | | justify-content: space-between; |
| | | height: 100%; |
| | | overflow: auto; |
| | | //background: #626aea; |
| | | border-radius: 8px; |
| | | background: var(--color-bg-2); |
| | | padding-top: 80px; |
| | | |