|
@@ -89,6 +89,9 @@
|
|
<i data-feather="stop-circle" class="icons"></i>
|
|
<i data-feather="stop-circle" class="icons"></i>
|
|
终止所有任务
|
|
终止所有任务
|
|
</el-button>
|
|
</el-button>
|
|
|
|
+ <el-button type="primary" @click="exportData()">
|
|
|
|
+ <i data-feather="download" class="icons"></i> 导出问答对
|
|
|
|
+ </el-button>
|
|
</div>
|
|
</div>
|
|
<div class="selection-control" v-if="selectedRows.length > 0">
|
|
<div class="selection-control" v-if="selectedRows.length > 0">
|
|
<el-alert
|
|
<el-alert
|
|
@@ -155,18 +158,22 @@
|
|
effect="dark"
|
|
effect="dark"
|
|
placement="top"
|
|
placement="top"
|
|
:disabled="
|
|
:disabled="
|
|
- Number(scope.row.run) !== 1 && Number(scope.row.run) !== 4
|
|
|
|
|
|
+ ![1, 4, 7].includes(Number(scope.row.run))
|
|
"
|
|
"
|
|
>
|
|
>
|
|
<template #content>
|
|
<template #content>
|
|
<div style="padding: 5px">
|
|
<div style="padding: 5px">
|
|
<div style="margin-top: 5px; font-size: 12px">
|
|
<div style="margin-top: 5px; font-size: 12px">
|
|
- {{ scope.row.progress_msg || "正在解析中..." }}
|
|
|
|
|
|
+ {{
|
|
|
|
+ Number(scope.row.run) === 7
|
|
|
|
+ ? (scope.row.progress_msg || "正在生成问答对...")
|
|
|
|
+ : (scope.row.progress_msg || "正在解析中...")
|
|
|
|
+ }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
<div class="status-wrapper">
|
|
<div class="status-wrapper">
|
|
- <template v-if="Number(scope.row.run) === 1">
|
|
|
|
|
|
+ <template v-if="Number(scope.row.run) === 1||Number(scope.row.run) === 6">
|
|
<div class="progress-wrapper">
|
|
<div class="progress-wrapper">
|
|
<el-progress
|
|
<el-progress
|
|
type="circle"
|
|
type="circle"
|
|
@@ -272,6 +279,21 @@
|
|
>
|
|
>
|
|
</el-button>
|
|
</el-button>
|
|
</el-tooltip>
|
|
</el-tooltip>
|
|
|
|
+ <el-tooltip
|
|
|
|
+ class="item"
|
|
|
|
+ effect="dark"
|
|
|
|
+ content="查看问答对"
|
|
|
|
+ placement="top"
|
|
|
|
+ >
|
|
|
|
+ <el-button
|
|
|
|
+ type="text"
|
|
|
|
+ size="small"
|
|
|
|
+ circle
|
|
|
|
+ icon="el-icon-receiving"
|
|
|
|
+ @click="getQa(scope.row.id)"
|
|
|
|
+ style="font-size: 15px"
|
|
|
|
+ ></el-button>
|
|
|
|
+ </el-tooltip>
|
|
<el-tooltip
|
|
<el-tooltip
|
|
class="item"
|
|
class="item"
|
|
effect="dark"
|
|
effect="dark"
|
|
@@ -463,6 +485,66 @@
|
|
>
|
|
>
|
|
</span>
|
|
</span>
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
|
+ <!-- 问答对弹窗 -->
|
|
|
|
+ <el-dialog
|
|
|
|
+ title="问答对"
|
|
|
|
+ :visible.sync="qaDialogVisible"
|
|
|
|
+ width="80%"
|
|
|
|
+ :before-close="handleQaDialogClose"
|
|
|
|
+ >
|
|
|
|
+ <div class="qa-dialog-content">
|
|
|
|
+ <div class="qa-dialog-header">
|
|
|
|
+ <el-tag>文档ID: {{ currentDocumentId }}</el-tag>
|
|
|
|
+ <el-tag type="success" v-if="qaList.length">
|
|
|
|
+ 共 {{ qaList.length }} 个问答对
|
|
|
|
+ </el-tag>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div class="qa-content" v-loading="qaLoading">
|
|
|
|
+ <div v-if="qaList.length === 0 && !qaLoading" class="empty-state">
|
|
|
|
+ <i class="el-icon-document"></i>
|
|
|
|
+ <p>暂无问答对数据</p>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div v-else class="qa-list">
|
|
|
|
+ <div
|
|
|
|
+ v-for="(item, index) in qaList"
|
|
|
|
+ :key="index"
|
|
|
|
+ class="qa-item"
|
|
|
|
+ >
|
|
|
|
+ <div class="qa-question">
|
|
|
|
+ <div class="qa-label">问:</div>
|
|
|
|
+ <div class="qa-text">{{ item.question }}</div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="qa-answer">
|
|
|
|
+ <div class="qa-label">答:</div>
|
|
|
|
+ <div class="qa-text">{{ item.answer }}</div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="qa-meta" v-if="item.confidence || item.source">
|
|
|
|
+ <el-tag size="mini" v-if="item.confidence">
|
|
|
|
+ 置信度: {{ item.confidence }}
|
|
|
|
+ </el-tag>
|
|
|
|
+ <el-tag size="mini" type="info" v-if="item.source">
|
|
|
|
+ 来源: {{ item.source }}
|
|
|
|
+ </el-tag>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <span slot="footer" class="dialog-footer">
|
|
|
|
+ <el-button
|
|
|
|
+ type="primary"
|
|
|
|
+ icon="el-icon-refresh"
|
|
|
|
+ @click="fetchQAData"
|
|
|
|
+ :loading="qaLoading"
|
|
|
|
+ >
|
|
|
|
+ 刷新数据
|
|
|
|
+ </el-button>
|
|
|
|
+ <el-button @click="handleQaDialogClose">关闭</el-button>
|
|
|
|
+ </span>
|
|
|
|
+ </el-dialog>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@@ -492,6 +574,10 @@ import {
|
|
resultTask,
|
|
resultTask,
|
|
endClear,
|
|
endClear,
|
|
} from "@/api/knowledge";
|
|
} from "@/api/knowledge";
|
|
|
|
+
|
|
|
|
+import { exportQaToExcel,queryDocumentContent } from "@/api/document";
|
|
|
|
+import { validateExportParams, logJSON, checkJSONSize } from "@/utils/data-validator";
|
|
|
|
+
|
|
export default {
|
|
export default {
|
|
components: {
|
|
components: {
|
|
dataSearch,
|
|
dataSearch,
|
|
@@ -574,6 +660,11 @@ export default {
|
|
selectedRows: [], // 已选择的行
|
|
selectedRows: [], // 已选择的行
|
|
allSelectedRows: new Map(), // 存储所有选中的行
|
|
allSelectedRows: new Map(), // 存储所有选中的行
|
|
isAllDataSelected: false, // 是否选中所有数据
|
|
isAllDataSelected: false, // 是否选中所有数据
|
|
|
|
+ /* 问答对弹窗 */
|
|
|
|
+ qaDialogVisible: false,
|
|
|
|
+ currentDocumentId: null,
|
|
|
|
+ qaList: [],
|
|
|
|
+ qaLoading: false,
|
|
};
|
|
};
|
|
},
|
|
},
|
|
mounted() {
|
|
mounted() {
|
|
@@ -589,6 +680,158 @@ export default {
|
|
Object.values(this.analysisStatusCheckers).forEach(clearTimeout);
|
|
Object.values(this.analysisStatusCheckers).forEach(clearTimeout);
|
|
},
|
|
},
|
|
methods: {
|
|
methods: {
|
|
|
|
+ /* 导出 */
|
|
|
|
+ async exportData() {
|
|
|
|
+ try {
|
|
|
|
+ // 显示加载状态
|
|
|
|
+ const loading = this.$loading({
|
|
|
|
+ lock: true,
|
|
|
|
+ text: '正在导出,请稍候...',
|
|
|
|
+ spinner: 'el-icon-loading',
|
|
|
|
+ background: 'rgba(0, 0, 0, 0.7)'
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // 准备导出参数
|
|
|
|
+ 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表示全部
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // 如果有选中的文档,只导出选中的
|
|
|
|
+ if (this.selectedRows.length > 0) {
|
|
|
|
+ exportParams.document_ids = this.selectedRows.map(row => row.id);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 验证和清理导出参数
|
|
|
|
+ const validation = validateExportParams(exportParams);
|
|
|
|
+
|
|
|
|
+ if (!validation.isValid) {
|
|
|
|
+ loading.close();
|
|
|
|
+ this.$message.error(`参数验证失败: ${validation.errors.join(', ')}`);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (validation.warnings.length > 0) {
|
|
|
|
+ console.warn('参数警告:', validation.warnings);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 使用清理后的参数
|
|
|
|
+ const finalParams = validation.cleanedParams;
|
|
|
|
+
|
|
|
|
+ // 检查JSON数据大小
|
|
|
|
+ const sizeInfo = checkJSONSize(finalParams);
|
|
|
|
+ if (sizeInfo.isLarge) {
|
|
|
|
+ console.warn(`导出数据较大: ${sizeInfo.kb}KB`);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 日志输出
|
|
|
|
+ logJSON(finalParams, '最终导出参数');
|
|
|
|
+
|
|
|
|
+ // 调用导出接口
|
|
|
|
+ const response = await exportQaToExcel(finalParams);
|
|
|
|
+ console.log(response);
|
|
|
|
+
|
|
|
|
+ // 检查响应格式
|
|
|
|
+ if (response.status === 200) {
|
|
|
|
+ const { data } = response;
|
|
|
|
+ const { message, data: exportData } = data;
|
|
|
|
+
|
|
|
|
+ // 如果有下载链接,直接使用浏览器下载
|
|
|
|
+ if (exportData && exportData.download_url) {
|
|
|
|
+ // 直接打开新窗口下载
|
|
|
|
+ window.open(exportData.download_url, '_blank');
|
|
|
|
+ loading.close();
|
|
|
|
+ this.$message.success(message || '导出成功!');
|
|
|
|
+ } else {
|
|
|
|
+ loading.close();
|
|
|
|
+ this.$message.error('获取下载链接失败');
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ loading.close();
|
|
|
|
+ this.$message.error('导出请求失败');
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('导出失败:', error);
|
|
|
|
+ this.$message.error('导出失败,请稍后重试');
|
|
|
|
+ if (loading) loading.close();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ // 下载文件的通用方法
|
|
|
|
+ downloadFile(downloadUrl, fileName) {
|
|
|
|
+ try {
|
|
|
|
+ const link = document.createElement('a');
|
|
|
|
+ link.href = downloadUrl;
|
|
|
|
+ link.download = fileName || `问答对导出_${new Date().toISOString().slice(0, 10)}.xlsx`;
|
|
|
|
+ link.target = '_blank'; // 在新窗口打开,避免跨域问题
|
|
|
|
+
|
|
|
|
+ // 触发下载
|
|
|
|
+ document.body.appendChild(link);
|
|
|
|
+ link.click();
|
|
|
|
+ document.body.removeChild(link);
|
|
|
|
+
|
|
|
|
+ this.$message.success('文件下载已开始!');
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('下载失败:', error);
|
|
|
|
+ this.$message.error('文件下载失败,请稍后重试');
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ /* 查看问答对 */
|
|
|
|
+ getQa(id) {
|
|
|
|
+ this.currentDocumentId = id;
|
|
|
|
+ this.qaDialogVisible = true;
|
|
|
|
+ this.fetchQAData();
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /* 获取问答对数据 */
|
|
|
|
+ async fetchQAData() {
|
|
|
|
+ if (!this.currentDocumentId) return;
|
|
|
|
+
|
|
|
|
+ this.qaLoading = true;
|
|
|
|
+ try {
|
|
|
|
+ const response = await queryDocumentContent({
|
|
|
|
+ document_id: this.currentDocumentId
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ if (response.status === 200 ) {
|
|
|
|
+ // 根据接口返回的数据结构调整
|
|
|
|
+ this.qaList = response.data[0].qa_pairs || response.result || [];
|
|
|
|
+
|
|
|
|
+ // 如果接口返回的不是数组格式,进行处理
|
|
|
|
+ if (!Array.isArray(this.qaList)) {
|
|
|
|
+ if (this.qaList.items) {
|
|
|
|
+ this.qaList = this.qaList.items;
|
|
|
|
+ } else if (this.qaList.qa_pairs) {
|
|
|
|
+ this.qaList = this.qaList.qa_pairs;
|
|
|
|
+ console.log(this.qaList);
|
|
|
|
+ } else {
|
|
|
|
+ this.qaList = [];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (this.qaList.length === 0) {
|
|
|
|
+ this.$message.info('该文档暂无问答对数据');
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ this.$message.error(response.message || '获取问答对数据失败');
|
|
|
|
+ this.qaList = [];
|
|
|
|
+ }
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error('获取问答对数据失败:', error);
|
|
|
|
+ this.$message.error('获取问答对数据失败,请稍后重试');
|
|
|
|
+ this.qaList = [];
|
|
|
|
+ } finally {
|
|
|
|
+ this.qaLoading = false;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ /* 关闭问答对弹窗 */
|
|
|
|
+ handleQaDialogClose() {
|
|
|
|
+ this.qaDialogVisible = false;
|
|
|
|
+ this.currentDocumentId = null;
|
|
|
|
+ this.qaList = [];
|
|
|
|
+ },
|
|
// 获取行的唯一标识
|
|
// 获取行的唯一标识
|
|
getRowKey(row) {
|
|
getRowKey(row) {
|
|
return row.id;
|
|
return row.id;
|
|
@@ -635,12 +878,13 @@ export default {
|
|
/* 状态展示 */
|
|
/* 状态展示 */
|
|
getStatusType(status) {
|
|
getStatusType(status) {
|
|
const statusMap = {
|
|
const statusMap = {
|
|
- 0: "info", // 未解析
|
|
|
|
|
|
+ 0: "info", // 未解析
|
|
1: "warning", // 解析中
|
|
1: "warning", // 解析中
|
|
- 3: "success", // 成功
|
|
|
|
- 4: "danger", // 失败
|
|
|
|
- 5: "info", // 待解析
|
|
|
|
- 6: "danger", // 文件异常
|
|
|
|
|
|
+ 3: "success", // 解析成功,问答对生成成功
|
|
|
|
+ 4: "danger", // 解析失败
|
|
|
|
+ 5: "info", // 待解析
|
|
|
|
+ 6: "warning", // 待生成问答对
|
|
|
|
+ 7: "danger" // 解析成功,问答对生成失败
|
|
};
|
|
};
|
|
return statusMap[status] || "info";
|
|
return statusMap[status] || "info";
|
|
},
|
|
},
|
|
@@ -649,10 +893,11 @@ export default {
|
|
const statusMap = {
|
|
const statusMap = {
|
|
0: "未解析",
|
|
0: "未解析",
|
|
1: "解析中",
|
|
1: "解析中",
|
|
- 3: "解析成功",
|
|
|
|
|
|
+ 3: "处理成功",
|
|
4: "解析失败",
|
|
4: "解析失败",
|
|
- 5: "待解析",
|
|
|
|
- 6: "文件异常",
|
|
|
|
|
|
+ 5: "待解析",
|
|
|
|
+ 6: "待生成问答对",
|
|
|
|
+ 7: "处理失败"
|
|
};
|
|
};
|
|
return statusMap[status] || "未知状态";
|
|
return statusMap[status] || "未知状态";
|
|
},
|
|
},
|
|
@@ -1124,7 +1369,7 @@ export default {
|
|
},
|
|
},
|
|
/* 解析 */
|
|
/* 解析 */
|
|
analysis(row) {
|
|
analysis(row) {
|
|
- if (row.run == 1 || row.run == 5) return;
|
|
|
|
|
|
+ if (row.run == 1 || row.run == 5|| row.run == 6) return;
|
|
|
|
|
|
// Set the status to "解析中" (1) immediately
|
|
// Set the status to "解析中" (1) immediately
|
|
this.$set(row, "run", 1);
|
|
this.$set(row, "run", 1);
|
|
@@ -1165,71 +1410,50 @@ export default {
|
|
if (this.analysisStatusCheckers[row.id]) {
|
|
if (this.analysisStatusCheckers[row.id]) {
|
|
clearTimeout(this.analysisStatusCheckers[row.id]);
|
|
clearTimeout(this.analysisStatusCheckers[row.id]);
|
|
}
|
|
}
|
|
- /* 获取token数 */
|
|
|
|
- /* const checkStatus = () => {
|
|
|
|
- getdocpro({ document_id: row.id })
|
|
|
|
- .then((res) => {
|
|
|
|
- if (res.status === 200) {
|
|
|
|
- const newStatus = Number(res.data.status);
|
|
|
|
- const newProgress = Number(res.data.total_tasks);
|
|
|
|
- this.$set(row, "run", newStatus);
|
|
|
|
- this.$set(row, "progress", newProgress);
|
|
|
|
-
|
|
|
|
- if (newStatus === 3) {
|
|
|
|
- this.$message.success("解析成功");
|
|
|
|
- delete this.analysisStatusCheckers[row.id];
|
|
|
|
- // 在这里添加刷新列表的逻辑
|
|
|
|
- this.refreshCurrentList();
|
|
|
|
- } else if (newStatus === 4) {
|
|
|
|
- this.$message.error("解析失败");
|
|
|
|
- delete this.analysisStatusCheckers[row.id];
|
|
|
|
- } else if (newStatus === 1 || newStatus === 5) {
|
|
|
|
- // Continue checking
|
|
|
|
- this.analysisStatusCheckers[row.id] = setTimeout(
|
|
|
|
- checkStatus,
|
|
|
|
- 15000
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- this.$message.error("获取解析状态失败");
|
|
|
|
- delete this.analysisStatusCheckers[row.id];
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
- .catch((error) => {
|
|
|
|
- console.error("获取解析状态错误:", error);
|
|
|
|
- this.$message.error("获取解析状态时出现错误");
|
|
|
|
- delete this.analysisStatusCheckers[row.id];
|
|
|
|
- });
|
|
|
|
- }; */
|
|
|
|
/* 监控任务 */
|
|
/* 监控任务 */
|
|
const checkStatus = () => {
|
|
const checkStatus = () => {
|
|
resultTask(row.id)
|
|
resultTask(row.id)
|
|
.then((res) => {
|
|
.then((res) => {
|
|
if (res.status === 200) {
|
|
if (res.status === 200) {
|
|
const newStatus = Number(res.data.document_status);
|
|
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;
|
|
const newProgressMsg = res.data.progress_msg;
|
|
|
|
+ // 更新状态和进度
|
|
this.$set(row, "run", newStatus);
|
|
this.$set(row, "run", newStatus);
|
|
this.$set(row, "progress", newProgress);
|
|
this.$set(row, "progress", newProgress);
|
|
this.$set(row, "progress_msg", newProgressMsg);
|
|
this.$set(row, "progress_msg", newProgressMsg);
|
|
|
|
|
|
- if (newStatus === 3) {
|
|
|
|
- this.$message.success("解析成功");
|
|
|
|
- delete this.analysisStatusCheckers[row.id];
|
|
|
|
- // 在这里添加刷新列表的逻辑
|
|
|
|
- this.refreshCurrentList();
|
|
|
|
- } else if (newStatus === 4) {
|
|
|
|
- this.$message.error("解析失败");
|
|
|
|
- delete this.analysisStatusCheckers[row.id];
|
|
|
|
- } else if (newStatus === 1 || newStatus === 5) {
|
|
|
|
- // Continue checking
|
|
|
|
- this.analysisStatusCheckers[row.id] = setTimeout(
|
|
|
|
- checkStatus,
|
|
|
|
- 15000
|
|
|
|
- );
|
|
|
|
|
|
+ // 根据不同状态处理
|
|
|
|
+ switch (newStatus) {
|
|
|
|
+ case 3: // 解析成功
|
|
|
|
+ this.$message.success("解析成功");
|
|
|
|
+ delete this.analysisStatusCheckers[row.id];
|
|
|
|
+ this.refreshCurrentList();
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case 4: // 解析失败
|
|
|
|
+ this.$message.error(newProgressMsg || "解析失败");
|
|
|
|
+ delete this.analysisStatusCheckers[row.id];
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case 1: // 解析中
|
|
|
|
+ case 5: // 待解析
|
|
|
|
+ case 6: // 待生成问答对
|
|
|
|
+ case 7: // 解析成功,问答对生成失败
|
|
|
|
+ // 设置检查间隔
|
|
|
|
+ const checkInterval = newStatus === 6 ? 5000 : 15000;
|
|
|
|
+
|
|
|
|
+ // 更新进度信息
|
|
|
|
+ if (newStatus === 6) {
|
|
|
|
+ this.$set(row, "progress_msg", "正在生成问答对...");
|
|
|
|
+ } else if (newStatus === 7) {
|
|
|
|
+ const progressMsg = res.data.Result?.message || "问答对生成失败";
|
|
|
|
+ this.$set(row, "progress_msg", progressMsg);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 继续检查状态
|
|
|
|
+ this.analysisStatusCheckers[row.id] = setTimeout(checkStatus, checkInterval);
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
this.$message.error("获取解析状态失败");
|
|
this.$message.error("获取解析状态失败");
|
|
@@ -1466,7 +1690,7 @@ export default {
|
|
|
|
|
|
// Initialize the analysis status for each row
|
|
// Initialize the analysis status for each row
|
|
_this.dataList.forEach((row) => {
|
|
_this.dataList.forEach((row) => {
|
|
- if (row.run == 1 || row.run == 5) {
|
|
|
|
|
|
+ if (row.run == 1 || row.run == 5|| row.run == 6) {
|
|
_this.startAnalysisStatusChecker(row);
|
|
_this.startAnalysisStatusChecker(row);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
@@ -1723,5 +1947,95 @@ export default {
|
|
padding: 8px 16px;
|
|
padding: 8px 16px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+/* 问答对弹窗样式 */
|
|
|
|
+.qa-dialog-content {
|
|
|
|
+ padding: 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.qa-dialog-header {
|
|
|
|
+ margin-bottom: 20px;
|
|
|
|
+ padding-bottom: 12px;
|
|
|
|
+ border-bottom: 1px solid #e8e8e8;
|
|
|
|
+ display: flex;
|
|
|
|
+ gap: 8px;
|
|
|
|
+ align-items: center;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.qa-content {
|
|
|
|
+ min-height: 300px;
|
|
|
|
+ max-height: 500px;
|
|
|
|
+ overflow-y: auto;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.empty-state {
|
|
|
|
+ text-align: center;
|
|
|
|
+ padding: 60px 0;
|
|
|
|
+ color: #999;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.empty-state i {
|
|
|
|
+ font-size: 48px;
|
|
|
|
+ color: #ddd;
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
+ display: block;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.empty-state p {
|
|
|
|
+ margin: 0;
|
|
|
|
+ font-size: 16px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.qa-list {
|
|
|
|
+ space-y: 20px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.qa-item {
|
|
|
|
+ background: #f8f9fa;
|
|
|
|
+ border-radius: 8px;
|
|
|
|
+ padding: 20px;
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
+ border-left: 4px solid #409eff;
|
|
|
|
+ transition: all 0.3s ease;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.qa-item:hover {
|
|
|
|
+ box-shadow: 0 2px 12px rgba(64, 158, 255, 0.1);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.qa-question, .qa-answer {
|
|
|
|
+ display: flex;
|
|
|
|
+ margin-bottom: 12px;
|
|
|
|
+ align-items: flex-start;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.qa-answer {
|
|
|
|
+ margin-bottom: 16px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.qa-label {
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
+ width: 40px;
|
|
|
|
+ font-weight: bold;
|
|
|
|
+ color: #409eff;
|
|
|
|
+ margin-right: 8px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.qa-question .qa-label {
|
|
|
|
+ color: #e6a23c;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.qa-text {
|
|
|
|
+ flex: 1;
|
|
|
|
+ line-height: 1.6;
|
|
|
|
+ color: #333;
|
|
|
|
+ word-break: break-word;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.qa-meta {
|
|
|
|
+ display: flex;
|
|
|
|
+ gap: 8px;
|
|
|
|
+ padding-top: 8px;
|
|
|
|
+ border-top: 1px solid #eee;
|
|
|
|
+}
|
|
</style>
|
|
</style>
|
|
|
|
|