功能分析
首先分析知识库需要实现的功能:
- 支持用户创建自己的知识库
- 支持用户上传文件(支持多文件上传)
- 显示当前知识库文件
- 显示用户所有的知识库
方便起见,我选择了elmentplus的el-select实现了一个下拉框,用户可以在其中选择新建知识库或者是已有的知识库:
代码实现:
<el-select v-model="KnowledgeValue" placeholder="请选择知识库" style="width: 240px" @focus="getKnowledgeBaseList"
@change="changeKnowledge">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
实现效果:
我使用hasKnowledge动态判断当前知识库状态,如果当前选择新建知识库,则显示创建知识库的界面:
如果用户选择了已有的知识库,则显示当前知识库的文件,并可以上传文件:
用户创建自己的知识库
新建知识库需要知识库的名称和描述,然后用户点击创建即可调用接口。这里没有太大的问题。
用户上传文件(支持多文件上传)
用户上传文件时需要注意,上传的文件应为二进制格式,也就是header中需要添加
'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundarynl6gT1BKdPWIejNq'
上传文件之前需要自定义处理逻辑,设置action
为false
。
方便起见,我选择手动上传:
即用户点击上传文件的按钮才是真正的将文件传到服务器,而拖拉或者选择仅仅为前端可见,方便用户删除或者更改文件。
在el-upload中,我绑定了fileLists作为文件的列表,通过监听on-remove和on-change动态接收文件变化:
因为需要上传文件的二进制,所以需要fileLists.value[i].raw
,单个文件上传如下:
if (fileLists.value[i].raw) {
//新建FormData
let fileData = new FormData();
//与后端格式保持一致:
fileData.append('files', fileLists.value[i].raw);
fileData.append('kb_id', KnowledgeValue.value);
//上传文件
uploadFile(fileData, fileLists.value[i].name);
}
最后记得文件上传完毕后,清空组件中的文件列表:
uploadRef.value.clearFiles();
这里有个小问题,正确的返回内容如下:
有时候failed_files中可能会描述文件上传失败的消息,但是有时候文件上传失败也不会通知。
显示当前知识库文件
通过接口得到文件即可。接口返回data格式如下:
{
"code": 200,
"msg": "success",
"data": [
"bagua.png",
"yj.jpg",
"background.png"
]
}
显示用户所有的知识库
通过focus监听下拉框变化,这里的实现是用户每点击一次框选,刷新一次列表,防止更新不及时的问题。
为了保证第一行是新建知识库,将option.value首先设置如下:
options.value = [
{
value: '新建知识库',//值 加载出
label: '新建知识库',//文本
}
];
然后将接口返回的list一个一个push进options即可。使用ref可以动态更新。