<template>
|
<a-popover
|
:popup-visible="visible"
|
title=""
|
trigger="click"
|
position="tl">
|
<a-button
|
type="text"
|
style="border-radius: 24px"
|
@click="visibleChange"
|
>
|
<icon-attachment
|
size="28"
|
style="color: #0960bd"
|
/>
|
</a-button>
|
<template #title>
|
<div style="display: flex; justify-content: space-between">
|
<div>上传文件</div>
|
<div>
|
<icon-upload />
|
</div>
|
</div>
|
</template>
|
<template #content>
|
<a-upload
|
draggable
|
action="/"
|
style="width: 100%"
|
:auto-upload="false"
|
ref="uploadRef"
|
@change="onChange"
|
multiple
|
:limit="1"
|
/>
|
<div style="width: 100%;margin-top: 10px;display: flex; justify-content: space-between;" class="upload-wrap">
|
<div>
|
<span>解析方法: </span>
|
<a-radio-group v-model="parser_id" style="width: 400px;" @change="parserChange">
|
<a-popover title=""
|
v-for="item in filterData"
|
:key="item.value"
|
>
|
<a-radio
|
:value="item.value"
|
style="margin-right: 10px"
|
>{{item.name}}</a-radio>
|
<template #content>
|
<p style="max-width: 300px">{{item.parser_config_str}}</p>
|
</template>
|
</a-popover>
|
</a-radio-group>
|
</div>
|
<a-select :style="{width:'100px', margin: '0 10px'}" :default-value="['通用', '多模态']" v-model="parser_configs" multiple size="small">
|
<a-option v-for="item in parser_ids" :key="item.value">{{ item.name }}</a-option>
|
</a-select>
|
<p class="config-text">更多配置</p>
|
<a-button
|
:loading="onFileSelectedLoading"
|
@click="upDataFile"
|
type="primary"
|
size="mini"
|
style="border-radius: 24px;"
|
>
|
<span style="font-size: 12px;">
|
上传
|
</span>
|
</a-button>
|
</div>
|
</template>
|
</a-popover>
|
</template>
|
|
<script lang="ts" setup>
|
import { onMounted, onBeforeMount, reactive, ref, computed, watch } from "vue";
|
import axios from "axios";
|
import { Message } from "@arco-design/web-vue";
|
import { addSessionApi, getParseMethodsListApi, getSessionDetailsApi, uploadWithoutKb } from "@/api/session";
|
|
const visible = ref(false);
|
const loading = ref(false);
|
const chatDis = ref(false);
|
const directory = ref(false);
|
const filesBtn = ref(null);
|
const onFileSelectedLoading = ref(false);
|
const parser_id = ref("");
|
const parseridConfig = ref(false);
|
const uploaditemList = ref([]);
|
const activeSessionId = ref('');
|
let kbtenantInfo = reactive({
|
asr_id: 'paraformer-realtime-8k-v1',
|
embd_id: 'BAAI/bge-large-zh-v1.5',
|
img2txt_id: 'qwen-vl-max',
|
llm_id: 'qwen-plus',
|
name: 'wanghaos Kingdom',
|
// parser_ids: 'naive:General,qa:Q&A,resume:Resume,manual:Manual,table:Table,paper:Paper,book:Book,laws:Laws,presentation:Presentation,picture:Picture,one:One',
|
parser_ids: 'naive:通用,qa:Q&A,resume:简历,manual:说明书,table:表格,paper:多模态,book:书籍,laws:法律文件,presentation:PPT,picture:图片,one:整体',
|
rerank_id: 'BAAI/bge-reranker-v2-m3',
|
role: 'owner',
|
tenant_id: '948fc6fa41ab11ef8fb80242ac120004',
|
parser_idObj: {},
|
});
|
const parser = reactive({
|
naive: {
|
"chunk_token_num": 676,
|
"layout_recognize": true,
|
"raptor": {
|
"use_raptor": true,
|
"prompt": "请总结以下段落。 小心数字,不要编造。 段落如下:\n {cluster_content}\n以上就是你需要总结的内容。",
|
"max_token": 600,
|
"threshold": 0.32,
|
"max_cluster": 233,
|
"random_seed": 1500
|
}
|
}, // 用户名
|
qa: {
|
"entity_types": [
|
"organization",
|
"person",
|
"location",
|
"event",
|
"time"
|
],
|
"raptor": {
|
"use_raptor": false
|
}
|
},
|
resume: {},
|
manual: {},
|
table: {},
|
paper: {},
|
book: {},
|
laws: {},
|
presentation: {},
|
picture: {},
|
one: {},
|
|
});
|
const parser_configs = ref(['通用', '多模态']);
|
const parser_ids = ref([
|
{
|
name: '通用',
|
value: 'naive',
|
parser_config: parser.naive,
|
parser_config_str: '支持的文件格式为DOCX、EXCEL、PPT、IMAGE、PDF、TXT'
|
},
|
{
|
name: 'Q&A',
|
value: 'qa',
|
parser_config: parser.qa,
|
parser_config_str: '支持 excel 和 csv/txt 文件格式。 \n' +
|
'如果文件以 excel 格式,则应由两个列组成 没有标题:一个提出问题,另一个用于答案, 答案列之前的问题列。\n' +
|
'如果文件以 csv/txt 格式为 用作分开问题和答案的定界符。\n'
|
},
|
{
|
name: '简历',
|
value: 'resume',
|
parser_config: parser.resume,
|
parser_config_str: '支持的文件格式为DOCX、PDF、TXT'
|
},
|
{
|
name: '说明书',
|
value: 'manual',
|
parser_config: parser.manual,
|
parser_config_str: '仅支持PDF'
|
},
|
{
|
name: '表格',
|
value: 'table',
|
parser_config: parser.table,
|
parser_config_str: '支持EXCEL和CSV/TXT格式文。 \n' +
|
'对于 csv 或 txt 文件,列之间的分隔符为 TAB,\n' +
|
'第一行必须是列标题。\n'
|
},
|
{
|
name: '多模态',
|
value: 'paper',
|
parser_config: parser.paper,
|
parser_config_str: '仅支持PDF文件'
|
},
|
{
|
name: '书籍',
|
value: 'book',
|
parser_config: parser.book,
|
parser_config_str: '支持的文件格式为DOCX、PDF、TXT'
|
},
|
{
|
name: '法律文件',
|
value: 'laws',
|
parser_config: parser.laws,
|
parser_config_str: '支持的文件格式为DOCX、PDF、TXT'
|
},
|
{
|
name: 'PPT',
|
value: 'presentation',
|
parser_config: parser.presentation,
|
parser_config_str: '支持的文件格式为PDF、PPTX'
|
},
|
{
|
name: '图片',
|
value: 'picture',
|
parser_config: parser.picture,
|
parser_config_str: '支持图像文件'
|
},
|
{
|
name: '整体',
|
value: 'one',
|
parser_config: parser.one,
|
parser_config_str: '支持的文件格式为DOCX、EXCEL、PDF、TXT'
|
},
|
]);
|
const parser_idsArr = ref([]);
|
const uploadList = ref([]);
|
const props = defineProps(["sessionId"]);
|
const emit = defineEmits(["selectFileCallback"]);
|
const uploadRef = ref();
|
const files = ref([]);
|
const acceptNameList = computed(() => {
|
return ".word, .pdf, .ppt, .excel, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .pptx, .ppt, .pdf, .mp4, .avi, .mp3,.wav, .wma, .wmv, .rm,";
|
});
|
|
const filterData = computed(() => {
|
const result = parser_ids.value.filter(val => parser_configs.value.includes(val.name)).reverse().slice(0,4).reverse();
|
result.unshift({
|
name: '智能识别',
|
value: '',
|
parser_config_str: '',
|
parser_config: ''
|
});
|
return result;
|
});
|
|
const init = () => {
|
// parser_ids.value = kbtenantInfo.parser_ids.split(",").map((item) => {
|
// const [value1, value2] = item.split(":");
|
// return {
|
// name: value2,
|
// value: value1
|
// };
|
// });
|
getParseMethodsList();
|
}
|
|
const chooseParser = (item) => {
|
console.log(item);
|
};
|
|
const onChange = (fileList) => {
|
files.value = fileList;
|
files.value.forEach((item) => {
|
|
});
|
|
};
|
const parserChange = ()=>{
|
parseridConfig.value = false;
|
}
|
|
const visibleChange = (e) => {
|
e.stopPropagation();
|
visible.value = !visible.value;
|
}
|
|
|
const getIconByExtension = (extension) => {
|
const fileExtension = ref('');
|
fileExtension.value = extension.split('.').pop();
|
let type = '';
|
parser_idsArr.value.forEach((item)=>{
|
// 包含元素
|
if (item.formats.includes(fileExtension.value)){
|
type = item.id;
|
}
|
})
|
return type;
|
};
|
|
const upDataFile = async () => {
|
// if (!activeSessionId.value) {
|
// //新建会话
|
// const res = await addSessionApi({
|
// dialog_id: '',
|
// conversation_desc: '',
|
// });
|
// // console.log(res, "res");
|
// if (res.code == 200) {
|
// // console.log(res.data.conversation_id);
|
// activeSessionId.value = res.data?.conversation_id;
|
// const { code, data } = await getSessionDetailsApi(res.data?.conversation_id);
|
// if (code === 200) {
|
// console.log(data, '新建会话详情');
|
// }
|
// } else {
|
// Message.error('创建会话失败,请重试');
|
// }
|
// }
|
|
|
|
|
console.log(files.value, "files");
|
console.log(parser_ids.value, "解析方法");
|
if(files.value.length == 0){
|
Message.warning('请选择文件');
|
return;
|
}
|
uploaditemList.value = files.value.map((item,index)=>{
|
return {
|
index: index,
|
name: item.name,
|
size: (item.file.size/1024).toFixed(2) + 'K',
|
}
|
})
|
onFileSelectedLoading.value = true;
|
const formData = new FormData();
|
for (let i = 0; i < files.value.length; i++) {
|
formData.append('file', files.value[i].file);
|
formData.append('conversation_id', activeSessionId.value);
|
formData.append('parser_config', '');
|
if(!parser_id.value){
|
formData.append('parser_id', getIconByExtension(files.value[i].name));
|
}else{
|
formData.append('parser_id', parser_id.value);
|
}
|
}
|
uploadWithoutKb(formData).then((res) => {
|
onFileSelectedLoading.value = false;
|
if (res.code == 200) {
|
cancel();
|
// uploaditemList.value = [];
|
emit('selectFileCallback', uploaditemList.value);
|
Message.success('上传成功');
|
} else {
|
Message.error('上传失败');
|
}
|
});
|
|
|
|
};
|
|
|
const cancel = () => {
|
if(!onFileSelectedLoading.value){
|
visible.value = false;
|
parser_id.value = "";
|
}
|
};
|
|
defineExpose({
|
cancel
|
})
|
|
const getParseMethodsList = async () => {
|
let res = await getParseMethodsListApi();
|
parser_ids.value = res.data.map((item) => {
|
return {
|
name: item.name,
|
value: item.id,
|
parser_config: '',
|
parser_config_str: item.parser_config_str
|
};
|
});
|
parser_idsArr.value = res.data;
|
}
|
|
|
onBeforeMount(() => {
|
init();
|
|
|
|
});
|
onMounted(() => {
|
});
|
|
watch(
|
()=>props.sessionId,
|
(value, oldValue)=>{
|
activeSessionId.value = value;
|
}
|
)
|
|
|
</script>
|
<style>
|
.upload-wrap .arco-select-view-inner{
|
display: none;
|
}
|
</style>
|
<style scoped lang="less">
|
.aUpload {
|
width: 100%;
|
max-height: 500px;
|
overflow: hidden;
|
overflow-y: auto;
|
}
|
.upload-wrap {
|
position: relative;
|
}
|
.config-text {
|
position: absolute;
|
right: 70px;
|
bottom: -11px;
|
font-size: 12px;
|
}
|
</style>
|