|
@@ -77,6 +77,9 @@
|
|
|
<el-dropdown-item command="analysis">
|
|
|
<i data-feather="play" class="icons"></i> 批量解析
|
|
|
</el-dropdown-item>
|
|
|
+ <el-dropdown-item command="generateQa">
|
|
|
+ <i data-feather="message-square" class="icons"></i> 生成问答对
|
|
|
+ </el-dropdown-item>
|
|
|
<el-dropdown-item command="modifyFolder">
|
|
|
<i data-feather="folder" class="icons"></i> 批量修改目录
|
|
|
</el-dropdown-item>
|
|
@@ -138,12 +141,13 @@
|
|
|
:reserve-selection="true"
|
|
|
></el-table-column>
|
|
|
<el-table-column prop="id" label="ID" align="center" width="80" />
|
|
|
- <el-table-column prop="name" label="文件名称" sortable width="350">
|
|
|
+ <el-table-column prop="name" label="文件名称" sortable >
|
|
|
<template #default="scope">
|
|
|
<span>{{ scope.row.name }}</span>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column prop="type" label="文件类型" align="center" />
|
|
|
+ <el-table-column prop="qa_count" label="问答对数" align="center"></el-table-column>
|
|
|
<el-table-column prop="chunk_num" label="分块数" align="center" />
|
|
|
<el-table-column
|
|
|
prop="create_time"
|
|
@@ -158,13 +162,13 @@
|
|
|
effect="dark"
|
|
|
placement="top"
|
|
|
:disabled="
|
|
|
- ![1, 4, 7].includes(Number(scope.row.run))
|
|
|
+ ![1, 4, 7].includes(Number(scope.row.run))
|
|
|
"
|
|
|
>
|
|
|
<template #content>
|
|
|
<div style="padding: 5px">
|
|
|
<div style="margin-top: 5px; font-size: 12px">
|
|
|
- {{
|
|
|
+ {{
|
|
|
Number(scope.row.run) === 7
|
|
|
? (scope.row.progress_msg || "正在生成问答对...")
|
|
|
: (scope.row.progress_msg || "正在解析中...")
|
|
@@ -485,7 +489,8 @@
|
|
|
>
|
|
|
</span>
|
|
|
</el-dialog>
|
|
|
- <!-- 问答对弹窗 -->
|
|
|
+
|
|
|
+ <!-- 问答对弹窗 -->
|
|
|
<el-dialog
|
|
|
title="问答对"
|
|
|
:visible.sync="qaDialogVisible"
|
|
@@ -573,11 +578,10 @@ import {
|
|
|
analysisPro,
|
|
|
resultTask,
|
|
|
endClear,
|
|
|
+ generateQa,
|
|
|
} from "@/api/knowledge";
|
|
|
-
|
|
|
import { exportQaToExcel,queryDocumentContent } from "@/api/document";
|
|
|
import { validateExportParams, logJSON, checkJSONSize } from "@/utils/data-validator";
|
|
|
-
|
|
|
export default {
|
|
|
components: {
|
|
|
dataSearch,
|
|
@@ -660,7 +664,7 @@ export default {
|
|
|
selectedRows: [], // 已选择的行
|
|
|
allSelectedRows: new Map(), // 存储所有选中的行
|
|
|
isAllDataSelected: false, // 是否选中所有数据
|
|
|
- /* 问答对弹窗 */
|
|
|
+ /* 问答对弹窗 */
|
|
|
qaDialogVisible: false,
|
|
|
currentDocumentId: null,
|
|
|
qaList: [],
|
|
@@ -680,7 +684,7 @@ export default {
|
|
|
Object.values(this.analysisStatusCheckers).forEach(clearTimeout);
|
|
|
},
|
|
|
methods: {
|
|
|
- /* 导出 */
|
|
|
+ /* 导出 */
|
|
|
async exportData() {
|
|
|
try {
|
|
|
// 显示加载状态
|
|
@@ -695,6 +699,7 @@ export default {
|
|
|
const exportParams = {
|
|
|
kb_id: this.queryForm.bucket_id, // 知识库ID
|
|
|
doc_type_id: this.queryForm.doc_type_id === 0 ? null : this.queryForm.doc_type_id, // 目录ID,0表示全部
|
|
|
+ export_to_local: true,
|
|
|
};
|
|
|
|
|
|
// 如果有选中的文档,只导出选中的
|
|
@@ -729,7 +734,7 @@ export default {
|
|
|
|
|
|
// 调用导出接口
|
|
|
const response = await exportQaToExcel(finalParams);
|
|
|
- console.log(response);
|
|
|
+ console.log(response);
|
|
|
|
|
|
// 检查响应格式
|
|
|
if (response.status === 200) {
|
|
@@ -739,7 +744,9 @@ export default {
|
|
|
// 如果有下载链接,直接使用浏览器下载
|
|
|
if (exportData && exportData.download_url) {
|
|
|
// 直接打开新窗口下载
|
|
|
- window.open(exportData.download_url, '_blank');
|
|
|
+ const url=process.env.VUE_APP_BASE_API+exportData.download_url
|
|
|
+ console.log(url);
|
|
|
+ window.open(url, '_blank');
|
|
|
loading.close();
|
|
|
this.$message.success(message || '导出成功!');
|
|
|
} else {
|
|
@@ -750,7 +757,6 @@ export default {
|
|
|
loading.close();
|
|
|
this.$message.error('导出请求失败');
|
|
|
}
|
|
|
-
|
|
|
} catch (error) {
|
|
|
console.error('导出失败:', error);
|
|
|
this.$message.error('导出失败,请稍后重试');
|
|
@@ -842,6 +848,9 @@ export default {
|
|
|
case "analysis":
|
|
|
this.batchAnalysis();
|
|
|
break;
|
|
|
+ case "generateQa":
|
|
|
+ this.batchGenerateQa();
|
|
|
+ break;
|
|
|
case "modifyFolder":
|
|
|
this.batchModifyFolder();
|
|
|
break;
|
|
@@ -850,6 +859,44 @@ export default {
|
|
|
break;
|
|
|
}
|
|
|
},
|
|
|
+
|
|
|
+ // 批量生成问答对
|
|
|
+ batchGenerateQa() {
|
|
|
+ if (this.selectedRows.length === 0) {
|
|
|
+ this.$message.warning("请选择要生成问答对的文件");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const loading = this.$loading({
|
|
|
+ lock: true,
|
|
|
+ text: '正在生成问答对,请稍候...',
|
|
|
+ spinner: 'el-icon-loading',
|
|
|
+ background: 'rgba(0, 0, 0, 0.7)'
|
|
|
+ });
|
|
|
+
|
|
|
+ const selectedIds = this.selectedRows.map(row => row.id);
|
|
|
+ generateQa({
|
|
|
+ document_ids: JSON.stringify(selectedIds)
|
|
|
+ }).then((res) => {
|
|
|
+ console.log('生成问答对响应:', res);
|
|
|
+ if (res.status === 200) {
|
|
|
+ this.$message.success('问答对生成任务已提交');
|
|
|
+ // 更新选中文档的状态
|
|
|
+ this.selectedRows.forEach(row => {
|
|
|
+ this.$set(row, 'run', 6); // 设置状态为"待生成问答对"
|
|
|
+ this.startAnalysisStatusChecker(row); // 开始检查状态
|
|
|
+ });
|
|
|
+ this.clearSelection(); // 清除选择
|
|
|
+ } else {
|
|
|
+ this.$message.error(res.data?.message || '生成问答对失败');
|
|
|
+ }
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('生成问答对时出错:', error);
|
|
|
+ this.$message.error('生成问答对失败,请稍后重试');
|
|
|
+ }).finally(() => {
|
|
|
+ loading.close();
|
|
|
+ });
|
|
|
+ },
|
|
|
getProgressStatus(progress) {
|
|
|
// el-progress 只接受 'success'/'exception'/'warning' 这几个值
|
|
|
if (progress >= 100) {
|
|
@@ -1369,7 +1416,7 @@ export default {
|
|
|
},
|
|
|
/* 解析 */
|
|
|
analysis(row) {
|
|
|
- if (row.run == 1 || row.run == 5|| row.run == 6) return;
|
|
|
+ if (row.run == 1 || row.run == 5 || row.run == 6) return;
|
|
|
|
|
|
// Set the status to "解析中" (1) immediately
|
|
|
this.$set(row, "run", 1);
|
|
@@ -1406,24 +1453,25 @@ export default {
|
|
|
},
|
|
|
/* 任务监控 */
|
|
|
startAnalysisStatusChecker(row) {
|
|
|
- // Clear any existing checker for this row
|
|
|
+ // 清除该行已存在的检查器
|
|
|
if (this.analysisStatusCheckers[row.id]) {
|
|
|
clearTimeout(this.analysisStatusCheckers[row.id]);
|
|
|
}
|
|
|
- /* 监控任务 */
|
|
|
+
|
|
|
const checkStatus = () => {
|
|
|
resultTask(row.id)
|
|
|
.then((res) => {
|
|
|
if (res.status === 200) {
|
|
|
const newStatus = Number(res.data.document_status);
|
|
|
- const newProgress =Number(res.data.progress) === 100 ? 0 : Number(res.data.progress);
|
|
|
+ const newProgress = Number(res.data.progress) === 100 ? 0 : Number(res.data.progress);
|
|
|
const newProgressMsg = res.data.progress_msg;
|
|
|
+
|
|
|
// 更新状态和进度
|
|
|
this.$set(row, "run", newStatus);
|
|
|
this.$set(row, "progress", newProgress);
|
|
|
this.$set(row, "progress_msg", newProgressMsg);
|
|
|
|
|
|
- // 根据不同状态处理
|
|
|
+ // 根据不同状态处理
|
|
|
switch (newStatus) {
|
|
|
case 3: // 解析成功
|
|
|
this.$message.success("解析成功");
|
|
@@ -1467,7 +1515,7 @@ export default {
|
|
|
});
|
|
|
};
|
|
|
|
|
|
- // Start checking immediately
|
|
|
+ // 立即开始检查
|
|
|
checkStatus();
|
|
|
},
|
|
|
|
|
@@ -1690,7 +1738,7 @@ export default {
|
|
|
|
|
|
// Initialize the analysis status for each row
|
|
|
_this.dataList.forEach((row) => {
|
|
|
- if (row.run == 1 || row.run == 5|| row.run == 6) {
|
|
|
+ if (row.run == 1 || row.run == 5 || row.run == 6) {
|
|
|
_this.startAnalysisStatusChecker(row);
|
|
|
}
|
|
|
});
|
|
@@ -1730,7 +1778,7 @@ export default {
|
|
|
<style lang="scss" scoped>
|
|
|
.project-search {
|
|
|
display: flex;
|
|
|
- height: calc(100vh - 100px); // 假设顶部导航栏高度为60px
|
|
|
+ height: calc(100vh - 100px); // 假设顶部导栏高度为60px
|
|
|
background-color: #f9fafb;
|
|
|
.custom-tree-node {
|
|
|
width: 100%;
|
|
@@ -1821,6 +1869,7 @@ export default {
|
|
|
flex: 1;
|
|
|
padding: 20px;
|
|
|
overflow-y: auto;
|
|
|
+ min-width: 0;
|
|
|
}
|
|
|
|
|
|
.custom-tree-node {
|
|
@@ -1947,6 +1996,37 @@ export default {
|
|
|
padding: 8px 16px;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+// 添加以下样式来处理表格响应式布局
|
|
|
+::v-deep .el-table {
|
|
|
+ width: 100% !important;
|
|
|
+
|
|
|
+ // 设置表格在小屏幕时的行为
|
|
|
+ &__body-wrapper {
|
|
|
+ overflow-x: auto !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保表格单元格内容在空间不足时正确换行
|
|
|
+ .cell {
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 文件名称列允许换行显示
|
|
|
+ .el-table__row td:nth-child(3) .cell {
|
|
|
+ white-space: normal;
|
|
|
+ word-break: break-word;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 确保分页区域不会造成横向滚动
|
|
|
+.page-info {
|
|
|
+ margin-top: 20px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ flex-wrap: wrap;
|
|
|
+}
|
|
|
/* 问答对弹窗样式 */
|
|
|
.qa-dialog-content {
|
|
|
padding: 0;
|