mirror of
https://github.com/Tencent/WeKnora.git
synced 2025-11-25 19:37:45 +08:00
fix(ui): Fix Drag Upload File failed in knowlegebase
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { ref, reactive, onMounted } from "vue";
|
import { ref, reactive } from "vue";
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
import { formatStringDate, kbFileTypeVerification } from "../utils/index";
|
import { formatStringDate, kbFileTypeVerification } from "../utils/index";
|
||||||
import { MessagePlugin } from "tdesign-vue-next";
|
import { MessagePlugin } from "tdesign-vue-next";
|
||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
} from "@/api/knowledge-base/index";
|
} from "@/api/knowledge-base/index";
|
||||||
import { knowledgeStore } from "@/stores/knowledge";
|
import { knowledgeStore } from "@/stores/knowledge";
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
const usemenuStore = knowledgeStore();
|
const usemenuStore = knowledgeStore();
|
||||||
export default function (knowledgeBaseId?: string) {
|
export default function (knowledgeBaseId?: string) {
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
@@ -23,34 +24,32 @@ export default function (knowledgeBaseId?: string) {
|
|||||||
id: "",
|
id: "",
|
||||||
total: 0
|
total: 0
|
||||||
});
|
});
|
||||||
const getKnowled = (query = { page: 1, page_size: 35 }) => {
|
const getKnowled = (query = { page: 1, page_size: 35 }, kbId?: string) => {
|
||||||
if (!knowledgeBaseId) return;
|
const targetKbId = kbId || knowledgeBaseId;
|
||||||
listKnowledgeFiles(knowledgeBaseId, query)
|
if (!targetKbId) return;
|
||||||
|
|
||||||
|
listKnowledgeFiles(targetKbId, query)
|
||||||
.then((result: any) => {
|
.then((result: any) => {
|
||||||
let { data, total: totalResult } = result;
|
const { data, total: totalResult } = result;
|
||||||
let cardList_ = data.map((item: any) => {
|
const cardList_ = data.map((item: any) => ({
|
||||||
item["file_name"] = item.file_name.substring(
|
...item,
|
||||||
0,
|
file_name: item.file_name.substring(0, item.file_name.lastIndexOf(".")),
|
||||||
item.file_name.lastIndexOf(".")
|
updated_at: formatStringDate(new Date(item.updated_at)),
|
||||||
);
|
isMore: false,
|
||||||
return {
|
file_type: item.file_type.toLocaleUpperCase(),
|
||||||
...item,
|
}));
|
||||||
updated_at: formatStringDate(new Date(item.updated_at)),
|
|
||||||
isMore: false,
|
if (query.page === 1) {
|
||||||
file_type: item.file_type.toLocaleUpperCase(),
|
cardList.value = cardList_;
|
||||||
};
|
|
||||||
});
|
|
||||||
if (query.page == 1) {
|
|
||||||
cardList.value = cardList_ as any[];
|
|
||||||
} else {
|
} else {
|
||||||
(cardList.value as any[]).push(...cardList_);
|
cardList.value.push(...cardList_);
|
||||||
}
|
}
|
||||||
total.value = totalResult;
|
total.value = totalResult;
|
||||||
})
|
})
|
||||||
.catch((_err) => {});
|
.catch(() => {});
|
||||||
};
|
};
|
||||||
const delKnowledge = (index: number, item: any) => {
|
const delKnowledge = (index: number, item: any) => {
|
||||||
(cardList.value as any[])[index].isMore = false;
|
cardList.value[index].isMore = false;
|
||||||
moreIndex.value = -1;
|
moreIndex.value = -1;
|
||||||
delKnowledgeDetails(item.id)
|
delKnowledgeDetails(item.id)
|
||||||
.then((result: any) => {
|
.then((result: any) => {
|
||||||
@@ -61,7 +60,7 @@ export default function (knowledgeBaseId?: string) {
|
|||||||
MessagePlugin.error("知识删除失败!");
|
MessagePlugin.error("知识删除失败!");
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((_err) => {
|
.catch(() => {
|
||||||
MessagePlugin.error("知识删除失败!");
|
MessagePlugin.error("知识删除失败!");
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -74,63 +73,45 @@ export default function (knowledgeBaseId?: string) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const requestMethod = (file: any, uploadInput: any) => {
|
const requestMethod = (file: any, uploadInput: any) => {
|
||||||
if (file instanceof File && uploadInput) {
|
if (!(file instanceof File) || !uploadInput) {
|
||||||
if (kbFileTypeVerification(file)) {
|
MessagePlugin.error("文件类型错误!");
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
// 每次上传时动态解析当前 kbId(优先:路由 -> URL -> 初始参数)
|
|
||||||
let currentKbId: string | undefined;
|
|
||||||
try {
|
|
||||||
currentKbId = (route.params as any)?.kbId as string;
|
|
||||||
} catch {}
|
|
||||||
if (!currentKbId && typeof window !== 'undefined') {
|
|
||||||
try {
|
|
||||||
const match = window.location.pathname.match(/knowledge-bases\/([^/]+)/);
|
|
||||||
if (match && match[1]) currentKbId = match[1];
|
|
||||||
} catch {}
|
|
||||||
}
|
|
||||||
if (!currentKbId) {
|
|
||||||
currentKbId = knowledgeBaseId;
|
|
||||||
}
|
|
||||||
if (!currentKbId) {
|
|
||||||
MessagePlugin.error("缺少知识库ID");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uploadKnowledgeFile(currentKbId, { file })
|
|
||||||
.then((result: any) => {
|
|
||||||
if (result.success) {
|
|
||||||
MessagePlugin.info("上传成功!");
|
|
||||||
getKnowled();
|
|
||||||
} else {
|
|
||||||
// 改进错误信息提取逻辑
|
|
||||||
let errorMessage = "上传失败!";
|
|
||||||
if (result.error && result.error.message) {
|
|
||||||
errorMessage = result.error.message;
|
|
||||||
} else if (result.message) {
|
|
||||||
errorMessage = result.message;
|
|
||||||
}
|
|
||||||
if (result.code === 'duplicate_file' || (result.error && result.error.code === 'duplicate_file')) {
|
|
||||||
errorMessage = "文件已存在";
|
|
||||||
}
|
|
||||||
MessagePlugin.error(errorMessage);
|
|
||||||
}
|
|
||||||
uploadInput.value.value = "";
|
|
||||||
})
|
|
||||||
.catch((err: any) => {
|
|
||||||
let errorMessage = "上传失败!";
|
|
||||||
if (err.code === 'duplicate_file') {
|
|
||||||
errorMessage = "文件已存在";
|
|
||||||
} else if (err.error && err.error.message) {
|
|
||||||
errorMessage = err.error.message;
|
|
||||||
} else if (err.message) {
|
|
||||||
errorMessage = err.message;
|
|
||||||
}
|
|
||||||
MessagePlugin.error(errorMessage);
|
|
||||||
uploadInput.value.value = "";
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
MessagePlugin.error("file文件类型错误!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (kbFileTypeVerification(file)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前知识库ID
|
||||||
|
let currentKbId: string | undefined = (route.params as any)?.kbId as string;
|
||||||
|
if (!currentKbId && typeof window !== 'undefined') {
|
||||||
|
const match = window.location.pathname.match(/knowledge-bases\/([^/]+)/);
|
||||||
|
if (match?.[1]) currentKbId = match[1];
|
||||||
|
}
|
||||||
|
if (!currentKbId) {
|
||||||
|
currentKbId = knowledgeBaseId;
|
||||||
|
}
|
||||||
|
if (!currentKbId) {
|
||||||
|
MessagePlugin.error("缺少知识库ID");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uploadKnowledgeFile(currentKbId, { file })
|
||||||
|
.then((result: any) => {
|
||||||
|
if (result.success) {
|
||||||
|
MessagePlugin.info("上传成功!");
|
||||||
|
getKnowled({ page: 1, page_size: 35 }, currentKbId);
|
||||||
|
} else {
|
||||||
|
const errorMessage = result.error?.message || result.message || "上传失败!";
|
||||||
|
MessagePlugin.error(result.code === 'duplicate_file' ? "文件已存在" : errorMessage);
|
||||||
|
}
|
||||||
|
uploadInput.value.value = "";
|
||||||
|
})
|
||||||
|
.catch((err: any) => {
|
||||||
|
const errorMessage = err.error?.message || err.message || "上传失败!";
|
||||||
|
MessagePlugin.error(err.code === 'duplicate_file' ? "文件已存在" : errorMessage);
|
||||||
|
uploadInput.value.value = "";
|
||||||
|
});
|
||||||
};
|
};
|
||||||
const getCardDetails = (item: any) => {
|
const getCardDetails = (item: any) => {
|
||||||
Object.assign(details, {
|
Object.assign(details, {
|
||||||
@@ -142,7 +123,7 @@ export default function (knowledgeBaseId?: string) {
|
|||||||
getKnowledgeDetails(item.id)
|
getKnowledgeDetails(item.id)
|
||||||
.then((result: any) => {
|
.then((result: any) => {
|
||||||
if (result.success && result.data) {
|
if (result.success && result.data) {
|
||||||
let { data } = result;
|
const { data } = result;
|
||||||
Object.assign(details, {
|
Object.assign(details, {
|
||||||
title: data.file_name,
|
title: data.file_name,
|
||||||
time: formatStringDate(new Date(data.updated_at)),
|
time: formatStringDate(new Date(data.updated_at)),
|
||||||
@@ -150,23 +131,24 @@ export default function (knowledgeBaseId?: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((_err) => {});
|
.catch(() => {});
|
||||||
getfDetails(item.id, 1);
|
getfDetails(item.id, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getfDetails = (id: string, page: number) => {
|
const getfDetails = (id: string, page: number) => {
|
||||||
getKnowledgeDetailsCon(id, page)
|
getKnowledgeDetailsCon(id, page)
|
||||||
.then((result: any) => {
|
.then((result: any) => {
|
||||||
if (result.success && result.data) {
|
if (result.success && result.data) {
|
||||||
let { data, total: totalResult } = result;
|
const { data, total: totalResult } = result;
|
||||||
if (page == 1) {
|
if (page === 1) {
|
||||||
(details.md as any[]) = data;
|
details.md = data;
|
||||||
} else {
|
} else {
|
||||||
(details.md as any[]).push(...data);
|
details.md.push(...data);
|
||||||
}
|
}
|
||||||
details.total = totalResult;
|
details.total = totalResult;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((_err) => {});
|
.catch(() => {});
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
cardList,
|
cardList,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main" ref="dropzone" @dragover="dragover" @drop="drop" @dragstart="dragstart">
|
<div class="main" ref="dropzone">
|
||||||
<Menu></Menu>
|
<Menu></Menu>
|
||||||
<RouterView />
|
<RouterView />
|
||||||
<div class="upload-mask" v-show="ismask">
|
<div class="upload-mask" v-show="ismask">
|
||||||
@@ -10,34 +10,26 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Menu from '@/components/menu.vue'
|
import Menu from '@/components/menu.vue'
|
||||||
import { ref } from 'vue';
|
import { ref, onMounted, onUnmounted } from 'vue';
|
||||||
import { useRouter, useRoute } from 'vue-router'
|
import { useRoute } from 'vue-router'
|
||||||
import { storeToRefs } from "pinia";
|
|
||||||
import { knowledgeStore } from "@/stores/knowledge";
|
|
||||||
const usemenuStore = knowledgeStore();
|
|
||||||
import useKnowledgeBase from '@/hooks/useKnowledgeBase'
|
import useKnowledgeBase from '@/hooks/useKnowledgeBase'
|
||||||
import UploadMask from '@/components/upload-mask.vue'
|
import UploadMask from '@/components/upload-mask.vue'
|
||||||
import { getKnowledgeBaseById } from '@/api/knowledge-base/index'
|
import { getKnowledgeBaseById } from '@/api/knowledge-base/index'
|
||||||
import { MessagePlugin } from 'tdesign-vue-next'
|
import { MessagePlugin } from 'tdesign-vue-next'
|
||||||
|
|
||||||
let { requestMethod } = useKnowledgeBase()
|
let { requestMethod } = useKnowledgeBase()
|
||||||
const router = useRouter();
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
let ismask = ref(false)
|
let ismask = ref(false)
|
||||||
let dropzone = ref();
|
|
||||||
let uploadInput = ref();
|
let uploadInput = ref();
|
||||||
|
|
||||||
// 获取当前知识库ID
|
// 获取当前知识库ID
|
||||||
const getCurrentKbId = async (): Promise<string | null> => {
|
const getCurrentKbId = (): string | null => {
|
||||||
let kbId = (route.params as any)?.kbId as string
|
return (route.params as any)?.kbId as string || null
|
||||||
if (!kbId && route.name === 'chat' && (route.params as any)?.kbId) {
|
|
||||||
kbId = (route.params as any).kbId
|
|
||||||
}
|
|
||||||
return kbId || null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查知识库初始化状态
|
// 检查知识库初始化状态
|
||||||
const checkKnowledgeBaseInitialization = async (): Promise<boolean> => {
|
const checkKnowledgeBaseInitialization = async (): Promise<boolean> => {
|
||||||
const currentKbId = await getCurrentKbId();
|
const currentKbId = getCurrentKbId();
|
||||||
|
|
||||||
if (!currentKbId) {
|
if (!currentKbId) {
|
||||||
MessagePlugin.error("缺少知识库ID");
|
MessagePlugin.error("缺少知识库ID");
|
||||||
@@ -48,53 +40,74 @@ const checkKnowledgeBaseInitialization = async (): Promise<boolean> => {
|
|||||||
const kbResponse = await getKnowledgeBaseById(currentKbId);
|
const kbResponse = await getKnowledgeBaseById(currentKbId);
|
||||||
const kb = kbResponse.data;
|
const kb = kbResponse.data;
|
||||||
|
|
||||||
// 检查知识库是否已初始化(有 EmbeddingModelID 和 SummaryModelID)
|
if (!kb.embedding_model_id || !kb.summary_model_id) {
|
||||||
if (!kb.embedding_model_id || kb.embedding_model_id === '' ||
|
|
||||||
!kb.summary_model_id || kb.summary_model_id === '') {
|
|
||||||
MessagePlugin.warning("该知识库尚未完成初始化配置,请先前往设置页面配置模型信息后再上传文件");
|
MessagePlugin.warning("该知识库尚未完成初始化配置,请先前往设置页面配置模型信息后再上传文件");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取知识库信息失败:', error);
|
|
||||||
MessagePlugin.error("获取知识库信息失败,无法上传文件");
|
MessagePlugin.error("获取知识库信息失败,无法上传文件");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const dragover = (event: DragEvent) => {
|
|
||||||
|
// 全局拖拽事件处理
|
||||||
|
const handleGlobalDragEnter = (event: DragEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
ismask.value = true;
|
if (event.dataTransfer) {
|
||||||
if (((window.innerWidth - event.clientX) < 50) || ((window.innerHeight - event.clientY) < 50) || event.clientX < 50 || event.clientY < 50) {
|
event.dataTransfer.effectAllowed = 'all';
|
||||||
ismask.value = false
|
|
||||||
}
|
}
|
||||||
|
ismask.value = true;
|
||||||
}
|
}
|
||||||
const drop = async (event: DragEvent) => {
|
|
||||||
|
const handleGlobalDragOver = (event: DragEvent) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
ismask.value = false
|
if (event.dataTransfer) {
|
||||||
|
event.dataTransfer.dropEffect = 'copy';
|
||||||
|
}
|
||||||
|
ismask.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleGlobalDrop = async (event: DragEvent) => {
|
||||||
|
event.preventDefault();
|
||||||
|
ismask.value = false;
|
||||||
|
|
||||||
|
const DataTransferFiles = event.dataTransfer?.files ? Array.from(event.dataTransfer.files) : [];
|
||||||
|
const DataTransferItemList = event.dataTransfer?.items ? Array.from(event.dataTransfer.items) : [];
|
||||||
|
|
||||||
// 检查知识库初始化状态
|
|
||||||
const isInitialized = await checkKnowledgeBaseInitialization();
|
const isInitialized = await checkKnowledgeBaseInitialization();
|
||||||
if (!isInitialized) {
|
if (!isInitialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DataTransferItemList = event.dataTransfer?.items;
|
if (DataTransferFiles.length > 0) {
|
||||||
if (DataTransferItemList) {
|
DataTransferFiles.forEach(file => requestMethod(file, uploadInput));
|
||||||
for (const dataTransferItem of DataTransferItemList) {
|
} else if (DataTransferItemList.length > 0) {
|
||||||
|
DataTransferItemList.forEach(dataTransferItem => {
|
||||||
const fileEntry = dataTransferItem.webkitGetAsEntry() as FileSystemFileEntry | null;
|
const fileEntry = dataTransferItem.webkitGetAsEntry() as FileSystemFileEntry | null;
|
||||||
if (fileEntry) {
|
if (fileEntry) {
|
||||||
fileEntry.file((file: File) => {
|
fileEntry.file((file: File) => requestMethod(file, uploadInput));
|
||||||
requestMethod(file, uploadInput)
|
|
||||||
// 修复页面跳转问题:不跳转,让上传成功后的逻辑处理
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
} else {
|
||||||
|
MessagePlugin.warning('请拖拽文件而不是文本或链接');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const dragstart = (event: DragEvent) => {
|
|
||||||
event.preventDefault();
|
// 组件挂载时添加全局事件监听器
|
||||||
}
|
onMounted(() => {
|
||||||
|
document.addEventListener('dragenter', handleGlobalDragEnter, true);
|
||||||
|
document.addEventListener('dragover', handleGlobalDragOver, true);
|
||||||
|
document.addEventListener('drop', handleGlobalDrop, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 组件卸载时移除全局事件监听器
|
||||||
|
onUnmounted(() => {
|
||||||
|
document.removeEventListener('dragenter', handleGlobalDragEnter, true);
|
||||||
|
document.removeEventListener('dragover', handleGlobalDragOver, true);
|
||||||
|
document.removeEventListener('drop', handleGlobalDrop, true);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.main {
|
.main {
|
||||||
|
|||||||
Reference in New Issue
Block a user