diff --git a/chat-client/.env.development b/chat-client/.env.development
index 9799822..9c24f36 100644
--- a/chat-client/.env.development
+++ b/chat-client/.env.development
@@ -2,17 +2,17 @@
# 此文件修改后需要重启项目
NODE_ENV=development
#VUE_APP_BASE_URL='/vab-mock-server'
-VUE_APP_BASE_URL='http://localhost:10001'
-VUE_APP_API_BASE_URL='http://localhost:8080'
+# VUE_APP_BASE_URL='http://localhost:10001'
+# VUE_APP_API_BASE_URL='http://localhost:8080'
#北京服务器配置
# VUE_APP_BASE_URL='http://192.168.1.211:80/brichat'
# VUE_APP_API_BASE_URL='http://192.168.1.211:80/brichat'
# #武汉公司服务器
-# VUE_APP_BASE_URL='http://192.168.8.253:80/brichat'
-# VUE_APP_API_BASE_URL='http://192.168.8.253:80/brichat'
+VUE_APP_BASE_URL='http://192.168.8.253:80/brichat'
+VUE_APP_API_BASE_URL='http://192.168.8.253:80/brichat'
#总部服务器配置
# VUE_APP_BASE_URL='http://192.168.0.33:80/brichat'
# VUE_APP_API_BASE_URL='http://192.168.0.33:80/brichat'
-VUE_APP_GITHUB_USER_NAME=test
-VUE_APP_SECRET_KEY=preview
+# VUE_APP_GITHUB_USER_NAME=test
+# VUE_APP_SECRET_KEY=preview
diff --git a/chat-client/.env.production b/chat-client/.env.production
index d6534da..8d5124b 100644
--- a/chat-client/.env.production
+++ b/chat-client/.env.production
@@ -2,18 +2,18 @@
# 此文件修改后需要重启项目
NODE_ENV=production
# VUE_APP_BASE_URL='/vab-mock-server'
-VUE_APP_BASE_URL='http://localhost:10001'
-VUE_APP_API_BASE_URL='http://localhost:10001'
+# VUE_APP_BASE_URL='http://localhost:10001'
+# VUE_APP_API_BASE_URL='http://localhost:10001'
#北京服务器
# VUE_APP_BASE_URL='http://192.168.1.211:80/brichat'
# VUE_APP_API_BASE_URL='http://192.168.1.211:80/brichat'
#武汉公司服务器
-# VUE_APP_BASE_URL='http://192.168.8.253:80/brichat'
-# VUE_APP_API_BASE_URL='http://192.168.8.253:80/brichat'
+VUE_APP_BASE_URL='http://192.168.8.253:80/brichat'
+VUE_APP_API_BASE_URL='http://192.168.8.253:80/brichat'
# 总部服务器
# VUE_APP_BASE_URL='http://192.168.0.33:80/brichat'
# VUE_APP_API_BASE_URL='http://192.168.0.33:80/brichat'
-VUE_APP_GITHUB_USER_NAME=test
-VUE_APP_SECRET_KEY=preview
\ No newline at end of file
+# VUE_APP_GITHUB_USER_NAME=test
+# VUE_APP_SECRET_KEY=preview
\ No newline at end of file
diff --git a/chat-client/src/api/dataset.ts b/chat-client/src/api/dataset.ts
index 8bf0248..c172975 100644
--- a/chat-client/src/api/dataset.ts
+++ b/chat-client/src/api/dataset.ts
@@ -138,4 +138,14 @@ export const deleteDataset = (id: string) => {
datasetId
}
})
+ }
+
+ /**
+ * 获取深度解析任务列表
+ */
+ export const getDeepAnalysisList = () => {
+ return request({
+ url: '/brichat-service/datasetManage/document/deepAnalysisList',
+ method: 'get'
+ })
}
\ No newline at end of file
diff --git a/chat-client/src/locales/en.ts b/chat-client/src/locales/en.ts
index f3967c2..e7c14e5 100644
--- a/chat-client/src/locales/en.ts
+++ b/chat-client/src/locales/en.ts
@@ -295,6 +295,7 @@ export default {
download: 'Download',
rename: 'Rename',
delete: 'Delete',
+ deepAnalysis: 'Deep Analysis',
},
search: {
placeholder: 'Enter keywords to search',
@@ -314,6 +315,8 @@ export default {
segmentation: 'Segmentation Rules',
separatorPlaceholder: 'Separator (default: ###)',
maxTokens: 'Max Tokens',
+ deepAnalysis: 'Deep Analysis',
+ deepAnalysisOption: 'Enable deep analysis to improve document understanding accuracy',
selectFile: 'Select the file',
fileTip:
'Multiple selection supported, max 100MB per file. Accepted formats: TXT, MD, MARKDOWN, MDX, PDF, HTML, HTM, XLSX, XLS, DOCX, CSV, VTT, PROPERTIES',
@@ -331,6 +334,14 @@ export default {
confirm: 'Confirm',
deleteconfirm: 'Delete Confirm',
},
+ deepAnalysisDialog: {
+ title: 'Deep Analysis Task List',
+ noTasks: 'No deep analysis tasks are currently in progress',
+ datasetName: 'Dataset',
+ taskId: 'Task ID',
+ createTime: 'Create Time',
+ close: 'Close',
+ },
messages: {
FilenamecantEmpty: 'Filename cannot be empty',
uploadSuccess: 'Upload successfully',
@@ -359,6 +370,7 @@ export default {
fetchFailed: 'Failed to get document list: ',
previewFailed: 'Preview failed: ',
downloadFailed: 'Download failed: ',
+ fetchDeepAnalysisFailed: 'Failed to get deep analysis task list',
},
},
},
@@ -515,70 +527,35 @@ export default {
Tip: 'Tip',
selectDeleteData: 'Please select the data to be deleted',
confirmDeleteApiKeys: 'This operation will permanently delete selected ',
- confirmDeleteApiKeysEnd: ' API key, are you sure?',
- confirmDeleteApiKeysEndPlural: ' API keys, are you sure?',
+ confirmDeleteApiKeysEnd:' API key, are you sure?',
+ confirmDeleteApiKeysEndPlural:' API keys, are you sure?',
confirmRefreshCache: 'This operation will refresh Redis cache, reloading all API keys, are you sure?',
updateSuccess: 'Update Successfully',
updateFail: 'Update Failed',
addSuccess: 'Add Successfully',
- addFail: 'Add Failed',
+ addFail:'Add Failed'
},
- prologue: {
- title: 'Opening Statement Management',
- query: 'Query',
- save: 'Save',
+ prologue:{
chatType: 'Chat Type',
- chatTypes: {
- '1': 'Fault Diagnosis',
- '2': 'Intelligent Q&A',
- '3': 'Chart Report',
- '4': 'Emergency Assistant Q&A',
- '5': 'Diagnostic Code Lookup',
- },
- openingContent: 'Opening Statement Content',
- addRecommend: 'Add Recommended Question',
- recommendation: 'Recommended Question',
- action: 'Action',
+ selectChatType: 'Select Chat Type',
+ prologueContent: 'Prologue Content',
+ addRecommend: 'Add Recommendation',
+ recommendQuestion: 'Recommended Question',
+ actions: 'Actions',
edit: 'Edit',
delete: 'Delete',
- dialog: {
- addTitle: 'Add Recommended Question',
- editTitle: 'Edit Recommended Question',
- questionContent: 'Recommended Question',
- cancel: 'Cancel',
- confirm: 'Confirm',
- save: 'Save',
- },
- message: {
- loadSuccess: 'Loaded successfully',
- loadFailed: 'Load failed, please try again later',
- loadFailedMess: 'Failed to load recommended questions',
- notFound: 'Opening statement not found',
- saveSuccess: 'Saved successfully',
- saveFailed: 'Save failed, please try again later',
- addSuccess: 'Recommended question added successfully',
- addFailed: 'Failed to add recommended question',
- editSuccess: 'Recommended question edited successfully',
- editFailed: 'Failed to edit recommended question, please try again later',
- deleteSuccess: 'Deleted successfully',
- deleteFailed: 'Deletion failed',
- },
- confirm: {
- save: 'Are you sure you want to save the changes?',
- tips: 'Tips',
- delete: 'Are you sure you want to delete this recommended question?',
- deleteConfirm: 'Delete Confirmation',
- },
- placeholder: {
- selectType: 'Select chat type',
- },
- },
- vabtabs: {
- refresh: 'Refresh',
- closeOthers: 'Close Others',
- closeLeft: 'Close Left',
- closeRight: 'Close Right',
- closeAll: 'Close All',
- },
+ confirmDelete: 'Are you sure you want to delete this recommendation?',
+ confirmSave: 'Are you sure you want to save the changes?',
+ deleteSuccess: 'Deleted successfully',
+ deleteFailure: 'Failed to delete, please try again later',
+ saveSuccess: 'Saved successfully',
+ saveFailure: 'Failed to save, please try again later',
+ loadSuccess: 'Loaded successfully',
+ loadFailure: 'Failed to load, please try again later',
+ noContent: 'No content found',
+ loading: 'Loading...',
+ updateRecommendation: 'Update Recommendation',
+ addRecommendation: 'Add Recommendation',
+ }
},
}
diff --git a/chat-client/src/locales/zh.ts b/chat-client/src/locales/zh.ts
index a417884..36c7cd7 100644
--- a/chat-client/src/locales/zh.ts
+++ b/chat-client/src/locales/zh.ts
@@ -303,6 +303,7 @@ export default {
download: '下载',
rename: '重命名',
delete: '删除',
+ deepAnalysis: '深度解析',
},
search: {
placeholder: '请输入关键词查询',
@@ -322,6 +323,8 @@ export default {
segmentation: '分段规则',
separatorPlaceholder: '分隔符(默认###)',
maxTokens: '最大Token数',
+ deepAnalysis: '深度解析',
+ deepAnalysisOption: '启用深度解析,提高文档理解精度',
selectFile: '选择文件',
fileTip: '支持多选,单个文件不超过100MB,可接受格式:TXT、MD、MARKDOWN、MDX、PDF、HTML、HTM、XLSX、XLS、DOCX、CSV、VTT、PROPERTIES',
cancel: '取消',
@@ -338,6 +341,14 @@ export default {
confirm: '确定',
deleteconfirm: '删除确认',
},
+ deepAnalysisDialog: {
+ title: '深度解析任务列表',
+ noTasks: '当前没有正在进行的深度解析任务',
+ datasetName: '知识库',
+ taskId: '任务ID',
+ createTime: '创建时间',
+ close: '关闭',
+ },
messages: {
FilenamecantEmpty: '文件名不能为空',
uploadSuccess: '上传成功',
@@ -367,6 +378,7 @@ export default {
fetchFailed: '获取文档列表失败: ',
previewFailed: '预览失败: ',
downloadFailed: '下载失败: ',
+ fetchDeepAnalysisFailed: '获取深度解析任务列表失败',
},
},
},
diff --git a/chat-client/src/views/datasets/components/DocumentList.vue b/chat-client/src/views/datasets/components/DocumentList.vue
index a99d9e3..42a5118 100644
--- a/chat-client/src/views/datasets/components/DocumentList.vue
+++ b/chat-client/src/views/datasets/components/DocumentList.vue
@@ -37,6 +37,7 @@
{{t('vabI18n.knowledge.document.buttons.batchDelete', { count: selectedRows.length })}}
{{t('vabI18n.knowledge.document.buttons.refresh')}}
+ {{t('vabI18n.knowledge.document.buttons.deepAnalysis')}}
{{t('vabI18n.knowledge.document.buttons.upload')}}
@@ -186,6 +187,12 @@
+
+
+ {{t('vabI18n.knowledge.document.uploadDialog.deepAnalysisOption')}}
+
+
+
{{t('vabI18n.knowledge.document.renameDialog.confirm')}}
+
+
+
+
+
+ {{t('vabI18n.knowledge.document.buttons.refresh')}}
+ {{t('vabI18n.knowledge.document.deepAnalysisDialog.close')}}
+
+
@@ -274,7 +313,7 @@
import { useRoute } from 'vue-router'
import { ref, reactive } from 'vue'
import VueOfficePdf from '@vue-office/pdf'
-import { getDatasetDocPage, uploadDocument, deleteDocument, downloadDocument, previewDocumentUrl, renameDocument} from '@/api/dataset'
+import { getDatasetDocPage, uploadDocument, deleteDocument, downloadDocument, previewDocumentUrl, renameDocument, getDeepAnalysisList } from '@/api/dataset'
//引入VueOfficeDocx组件
import VueOfficeDocx from '@vue-office/docx'
//引入相关样式
@@ -328,7 +367,8 @@ const uploadForm = reactive({
indexingTechnique: 'high_quality',
preProcessingRules: ['remove_extra_spaces', 'remove_urls_emails'],
segmentSeparator: '###',
- segmentMaxTokens: 500
+ segmentMaxTokens: 500,
+ deepAnalysis: false
})
// 重命名相关
@@ -338,6 +378,21 @@ const renameForm = reactive({
newName: ''
})
+// 深度解析相关
+const deepAnalysisDialogVisible = ref(false)
+const deepAnalysisLoading = ref(false)
+const deepAnalysisList = ref([])
+
+// 定义深度解析任务类型
+interface PdfTask {
+ name: string
+ taskId: string
+ percent: number
+ datasetName: string
+ createTime: number
+
+}
+
const getFileTypeIcon = (fileType: string) => {
// 使用动态导入获取图标路径
// const getIconUrl = (iconName: string) => {
@@ -625,6 +680,7 @@ const handleUpload = async () => {
datasetId: datasetId.value,
indexingTechnique: uploadForm.indexingTechnique,
processRule: processRule,
+ deepAnalysis: uploadForm.deepAnalysis
})], {
type: 'application/json'
}))
@@ -806,6 +862,34 @@ const handleRefresh = () => {
fetchDocuments()
}
+// 深度解析方法
+const handleDeepAnalysis = async () => {
+ deepAnalysisDialogVisible.value = true
+ await fetchDeepAnalysisList()
+}
+
+const fetchDeepAnalysisList = async () => {
+ deepAnalysisLoading.value = true
+ try {
+ const { data } = await getDeepAnalysisList()
+ deepAnalysisList.value = data || []
+ } catch (error) {
+ console.error('获取深度解析任务列表失败:', error)
+ ElNotification({
+ title: t('vabI18n.knowledge.document.errors.fetchDeepAnalysisFailed'),
+ message: error instanceof Error ? error.message : t('vabI18n.knowledge.document.messages.NoKnowError'),
+ type: 'error'
+ })
+ } finally {
+ deepAnalysisLoading.value = false
+ }
+}
+
+const formatTimestampToLocaleString = (timestamp: number): string => {
+ const date = new Date(timestamp * 1000)
+ return date.toLocaleString()
+}
+
// 工具函数
const formatTimestamp = (timestamp: number): string => {
const date = new Date(timestamp * 1000)
@@ -1249,6 +1333,83 @@ const handleSearch = () => {
to { transform: rotate(360deg); }
}
+// 深度解析对话框样式
+.deep-analysis-dialog {
+ ::v-deep .el-dialog__header {
+ background: linear-gradient(135deg, #409eff 0%, #67c23a 100%);
+ color: white;
+ border-radius: 8px 8px 0 0;
+ }
+
+ ::v-deep .el-dialog__title {
+ color: white;
+ font-weight: 600;
+ }
+}
+
+.empty-state {
+ padding: 40px 20px;
+ text-align: center;
+}
+
+.task-list {
+ max-height: 400px;
+ overflow-y: auto;
+ padding: 10px 0;
+}
+
+.task-item {
+ border: 1px solid #ebeef5;
+ border-radius: 8px;
+ margin-bottom: 12px;
+ padding: 16px;
+ background: #fafafa;
+ transition: all 0.3s ease;
+
+ &:hover {
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+ transform: translateY(-2px);
+ }
+}
+
+.task-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ gap: 20px;
+}
+
+.task-info {
+ flex: 1;
+
+ .task-name {
+ margin: 0 0 8px 0;
+ font-size: 16px;
+ font-weight: 600;
+ color: #303133;
+ word-break: break-all;
+ }
+
+ .task-dataset, .task-id, .task-time {
+ margin: 4px 0;
+ font-size: 12px;
+ color: #909399;
+ }
+
+ .task-dataset {
+ color: #67c23a;
+ font-weight: 500;
+ }
+}
+
+.task-progress {
+ flex: 0 0 200px;
+
+ ::v-deep .el-progress__text {
+ font-weight: 600;
+ }
+}
+
// 响应式设计
@media (max-width: 768px) {
.main-container {
@@ -1274,5 +1435,14 @@ const handleSearch = () => {
flex-direction: column;
gap: 4px;
}
+
+ .task-header {
+ flex-direction: column;
+ gap: 12px;
+ }
+
+ .task-progress {
+ flex: 1;
+ }
}
\ No newline at end of file
diff --git a/chat-server/src/main/java/com/bjtds/brichat/service/task/PdfConversionTaskService.java b/chat-server/src/main/java/com/bjtds/brichat/service/task/PdfConversionTaskService.java
new file mode 100644
index 0000000..3dec015
--- /dev/null
+++ b/chat-server/src/main/java/com/bjtds/brichat/service/task/PdfConversionTaskService.java
@@ -0,0 +1,402 @@
+package com.bjtds.brichat.service.task;
+
+import com.bjtds.brichat.entity.dataset.DocumentUploadReq;
+import com.bjtds.brichat.entity.dataset.RetrievalModel;
+import com.bjtds.brichat.entity.dto.PdfTaskDto;
+import com.bjtds.brichat.entity.dto.PdfTaskStatusResponse;
+import com.bjtds.brichat.service.dify.DifyDatasetApiService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * PDF转换任务定时服务
+ */
+@Service
+public class PdfConversionTaskService {
+
+ private static final Logger logger = LoggerFactory.getLogger(PdfConversionTaskService.class);
+ private static final String PDF_TASK_REDIS_KEY = "pdf:conversion:tasks";
+
+ @Autowired
+ private RestTemplate restTemplate;
+
+ @Autowired
+ @Qualifier("redisTemplate")
+ private RedisTemplate redisTemplate;
+
+ @Autowired
+ private DifyDatasetApiService difyDatasetApiService;
+
+ @Value("${pdf.conversion.service.url}")
+ private String pdfConversionServiceUrl;
+
+ /**
+ * 定时任务:每10秒检查一次PDF转换任务状态
+ */
+ @Scheduled(fixedRate = 10000) // 10秒执行一次
+ public void checkPdfConversionTasks() {
+ try {
+ // 获取所有待处理的任务ID
+ List