From f2d004a07d198d6d483f93228005506ae5c70ed2 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 09 六月 2026 16:43:04 +0800
Subject: [PATCH] feat(collaborativeApproval): 添加知识库RAG向量检索问答功能
---
src/views/collaborativeApproval/knowledgeBase/index.vue | 133 ++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 127 insertions(+), 6 deletions(-)
diff --git a/src/views/collaborativeApproval/knowledgeBase/index.vue b/src/views/collaborativeApproval/knowledgeBase/index.vue
index 8d625cf..907e51f 100644
--- a/src/views/collaborativeApproval/knowledgeBase/index.vue
+++ b/src/views/collaborativeApproval/knowledgeBase/index.vue
@@ -259,6 +259,22 @@
>
淇濆瓨鏂囦欢鍏宠仈
</el-button>
+ <el-button
+ v-if="uploadedBlobIds.length > 0"
+ type="text"
+ @click="clearUploadedFiles"
+ style="margin-left: 10px"
+ >
+ 娓呯┖寰呬繚瀛樺垪琛�
+ </el-button>
+ </div>
+
+ <!-- 寰呬繚瀛樼殑鏂囦欢鍒楄〃 -->
+ <div v-if="uploadedBlobIds.length > 0" class="uploaded-list">
+ <div class="uploaded-tip">
+ <el-icon style="color: #409eff"><InfoFilled /></el-icon>
+ <span>宸蹭笂浼� {{ uploadedBlobIds.length }} 涓枃浠�,璇风偣鍑�"淇濆瓨鏂囦欢鍏宠仈"鎸夐挳瑙﹀彂鍚戦噺鍖栧鐞�</span>
+ </div>
</div>
<!-- 鏂囦欢鍒楄〃涓庡悜閲忓寲鐘舵�� -->
@@ -273,6 +289,12 @@
</template>
</el-table-column>
<el-table-column prop="chunkCount" label="鍒囩墖鏁�" width="100" align="center" />
+ <el-table-column label="閿欒淇℃伅" width="200" show-overflow-tooltip>
+ <template #default="{ row }">
+ <span v-if="row.vectorError" style="color: #f56c6c">{{ row.vectorError }}</span>
+ <span v-else style="color: #909399">-</span>
+ </template>
+ </el-table-column>
<el-table-column prop="createTime" label="涓婁紶鏃堕棿" width="180" />
<el-table-column label="鎿嶄綔" width="150" align="center">
<template #default="{ row }">
@@ -326,7 +348,7 @@
<div class="chat-input">
<el-input
v-model="inputQuestion"
- placeholder="璇疯緭鍏ラ棶棰橈紝鎸夊洖杞﹀彂閫�"
+ placeholder="璇疯緭鍏ラ棶棰�,鎸夊洖杞﹀彂閫�(Ctrl+Enter蹇嵎鍙戦��)"
@keyup.enter="sendMessage"
:disabled="chatLoading"
>
@@ -334,6 +356,9 @@
<el-button @click="sendMessage" :loading="chatLoading">鍙戦��</el-button>
</template>
</el-input>
+ <div class="chat-actions">
+ <el-button type="text" size="small" @click="clearMessages">娓呯┖瀵硅瘽</el-button>
+ </div>
</div>
</div>
</FormDialog>
@@ -341,7 +366,7 @@
</template>
<script setup>
-import { Search } from "@element-plus/icons-vue";
+import { Search, InfoFilled } from "@element-plus/icons-vue";
import { onMounted, ref, reactive, toRefs, getCurrentInstance, computed, watch, nextTick } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import PIMTable from "@/components/PIMTable/PIMTable.vue";
@@ -412,6 +437,7 @@
fileList: [],
uploadedBlobIds: [],
savingFiles: false,
+ vectorStatusTimer: null, // 鍚戦噺鍖栫姸鎬佽疆璇㈠畾鏃跺櫒
chatDialogVisible: false,
messages: [],
inputQuestion: "",
@@ -436,6 +462,7 @@
fileList,
uploadedBlobIds,
savingFiles,
+ vectorStatusTimer,
chatDialogVisible,
messages,
inputQuestion,
@@ -872,9 +899,45 @@
try {
const res = await getVectorStatus(currentKnowledgeBase.value.id);
fileList.value = res.data || [];
+
+ // 妫�鏌ユ槸鍚︽湁澶勭悊涓殑鏂囦欢,濡傛灉鏈夊垯鍚姩杞
+ const hasProcessing = res.data.some(item => item.vectorStatus === 1);
+ if (hasProcessing && !vectorStatusTimer.value) {
+ startVectorStatusPolling();
+ } else if (!hasProcessing && vectorStatusTimer.value) {
+ stopVectorStatusPolling();
+ }
} catch (error) {
console.error("鍔犺浇鏂囦欢鍒楄〃澶辫触:", error);
ElMessage.error("鍔犺浇鏂囦欢鍒楄〃澶辫触");
+ }
+};
+
+// 寮�濮嬭疆璇㈠悜閲忓寲鐘舵��
+const startVectorStatusPolling = () => {
+ vectorStatusTimer.value = setInterval(async () => {
+ try {
+ const res = await getVectorStatus(currentKnowledgeBase.value.id);
+ fileList.value = res.data || [];
+
+ // 妫�鏌ユ槸鍚﹁繕鏈夊鐞嗕腑鐨勬枃浠�
+ const hasProcessing = res.data.some(item => item.vectorStatus === 1);
+ if (!hasProcessing) {
+ stopVectorStatusPolling();
+ ElMessage.success("鎵�鏈夋枃浠跺悜閲忓寲澶勭悊瀹屾垚");
+ }
+ } catch (error) {
+ console.error("杞鍚戦噺鍖栫姸鎬佸け璐�:", error);
+ stopVectorStatusPolling();
+ }
+ }, 3000); // 姣�3绉掕疆璇竴娆�
+};
+
+// 鍋滄杞鍚戦噺鍖栫姸鎬�
+const stopVectorStatusPolling = () => {
+ if (vectorStatusTimer.value) {
+ clearInterval(vectorStatusTimer.value);
+ vectorStatusTimer.value = null;
}
};
@@ -957,6 +1020,12 @@
}
};
+// 娓呯┖寰呬繚瀛樼殑鏂囦欢鍒楄〃
+const clearUploadedFiles = () => {
+ uploadedBlobIds.value = [];
+ ElMessage.success("宸叉竻绌哄緟淇濆瓨鏂囦欢鍒楄〃");
+};
+
// 鍒犻櫎鏂囦欢
const deleteFile = async (row) => {
try {
@@ -1009,7 +1078,8 @@
currentKnowledgeBase.value = null;
fileList.value = [];
uploadedBlobIds.value = [];
- getList(); // 鍒锋柊涓诲垪琛紝鏇存柊鏂囦欢鏁伴噺
+ stopVectorStatusPolling(); // 鍋滄杞
+ getList(); // 鍒锋柊涓诲垪琛�,鏇存柊鏂囦欢鏁伴噺
};
// ============ 鐭ヨ瘑搴撻棶绛旂浉鍏� ============
@@ -1027,6 +1097,11 @@
const sendMessage = async () => {
if (!inputQuestion.value.trim()) {
ElMessage.warning("璇疯緭鍏ラ棶棰�");
+ return;
+ }
+
+ if (!currentKnowledgeBase.value?.id) {
+ ElMessage.error("鐭ヨ瘑搴撲俊鎭紓甯�");
return;
}
@@ -1061,7 +1136,8 @@
});
if (!response.ok) {
- throw new Error('璇锋眰澶辫触');
+ const errorText = await response.text();
+ throw new Error(errorText || '璇锋眰澶辫触');
}
// 澶勭悊SSE娴佸紡鍝嶅簲
@@ -1083,16 +1159,40 @@
await nextTick();
scrollToBottom();
}
+
+ // 濡傛灉AI杩斿洖绌哄唴瀹�,鏄剧ず鎻愮ず
+ if (!aiContent.trim()) {
+ messages.value[messages.value.length - 1].content = '鎶辨瓑,鐭ヨ瘑搴撲腑鏈壘鍒扮浉鍏冲唴瀹�,璇峰皾璇曞叾浠栭棶棰樸��';
+ }
} catch (error) {
console.error("闂瓟璇锋眰澶辫触:", error);
- ElMessage.error("闂瓟璇锋眰澶辫触锛岃绋嶅悗閲嶈瘯");
+ ElMessage.error("闂瓟璇锋眰澶辫触,璇风◢鍚庨噸璇�");
messages.value.push({
role: 'assistant',
- content: '鎶辨瓑锛屽彂鐢熶簡閿欒锛岃绋嶅悗閲嶈瘯'
+ content: '鎶辨瓑,鍙戠敓浜嗛敊璇�,璇风◢鍚庨噸璇�'
});
} finally {
chatLoading.value = false;
}
+};
+
+// 娓呯┖瀵硅瘽
+const clearMessages = () => {
+ ElMessageBox.confirm(
+ "纭畾瑕佹竻绌烘墍鏈夊璇濊褰曞悧?",
+ "娓呯┖纭",
+ {
+ confirmButtonText: "纭畾",
+ cancelButtonText: "鍙栨秷",
+ type: "warning"
+ }
+ ).then(() => {
+ messages.value = [];
+ memoryId.value = crypto.randomUUID(); // 閲嶆柊鐢熸垚浼氳瘽ID
+ ElMessage.success("瀵硅瘽宸叉竻绌�");
+ }).catch(() => {
+ // 鐢ㄦ埛鍙栨秷
+ });
};
// 婊氬姩鍒板簳閮�
@@ -1195,6 +1295,22 @@
align-items: center;
}
+.uploaded-list {
+ margin-top: 16px;
+ padding: 12px;
+ background: #f0f9ff;
+ border-radius: 6px;
+ border: 1px solid #b3d8ff;
+}
+
+.uploaded-tip {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ color: #409eff;
+ font-size: 14px;
+}
+
/* 鐭ヨ瘑搴撻棶绛旀牱寮� */
.knowledge-chat {
display: flex;
@@ -1272,4 +1388,9 @@
margin-top: auto;
}
+.chat-actions {
+ margin-top: 8px;
+ text-align: right;
+}
+
</style>
--
Gitblit v1.9.3