Merge branch '分段预览'
# Conflicts: # chat-client/src/views/datasets/components/DocumentList.vue
This commit is contained in:
commit
73b332de51
|
|
@ -0,0 +1,9 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
export function getSegmentList(params: { datasetId: string; documentId: string }) {
|
||||
return request({
|
||||
url: '/brichat-service/documentSegment/selectSegments',
|
||||
method: 'get',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
|
@ -243,6 +243,7 @@
|
|||
@success="handleUploadSuccess"
|
||||
/>
|
||||
</el-dialog>
|
||||
<<<<<<< HEAD
|
||||
|
||||
<!-- 文件替换对话框 -->
|
||||
<el-dialog
|
||||
|
|
@ -281,16 +282,42 @@
|
|||
/>
|
||||
</el-dialog>
|
||||
|
||||
=======
|
||||
|
||||
>>>>>>> 分段预览
|
||||
<!-- 预览抽屉 -->
|
||||
|
||||
<el-drawer
|
||||
v-model="previewDrawerVisible"
|
||||
:title="t('vabI18n.knowledge.document.preview.title')"
|
||||
:direction="'rtl'"
|
||||
size="60%"
|
||||
size="80%"
|
||||
class="preview-drawer"
|
||||
:close-on-click-modal="false"
|
||||
@close="handleClose"
|
||||
>
|
||||
<div v-loading="previewLoading">
|
||||
<div v-loading="previewLoading" class="drawer-content-container" style="display: flex; height: 100%;">
|
||||
|
||||
<!-- 左侧分段数据容器 -->
|
||||
<div class="segment-list-container" style="width: 30%; border-right: 1px solid #ebeef5; overflow-y: auto; padding: 10px;">
|
||||
<h3>分段数据</h3>
|
||||
<el-form v-if="segmentList.length > 0">
|
||||
<el-form-item
|
||||
v-for="(segment) in segmentList"
|
||||
:key="segment.id"
|
||||
style="cursor: pointer; margin-bottom: 5px;"
|
||||
>
|
||||
<span>分段{{segment.position}}:</span>
|
||||
<h4>{{segment.content}}</h4>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div v-else>
|
||||
暂无分段数据
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧原预览内容 -->
|
||||
<div class="preview-content-container" style="flex: 1; padding: 10px; overflow-y: auto;">
|
||||
<!-- TXT 文件预览 -->
|
||||
<div v-if="previewFileType === 'txt'" class="text-preview-container">
|
||||
<pre class="text-preview">{{ previewTextContent }}</pre>
|
||||
|
|
@ -324,8 +351,10 @@
|
|||
@error="errorHandler"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
||||
|
||||
<!-- 重命名对话框 -->
|
||||
<el-dialog
|
||||
v-model="renameDialogVisible"
|
||||
|
|
@ -456,7 +485,8 @@
|
|||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
|
||||
import VueOfficePdf from '@vue-office/pdf'
|
||||
import { getDatasetDocPage, uploadDocument, deleteDocument, downloadDocument, previewDocumentUrl, renameDocument, createFolder, CreateFolderReq } from '@/api/dataset'
|
||||
import { getDatasetDocPage, uploadDocument, deleteDocument, downloadDocument, previewDocumentUrl, renameDocument, createFolder, CreateFolderReq} from '@/api/dataset'
|
||||
import {getSegmentList} from "@/api/Segment"
|
||||
import DocUpload from './DocUpload.vue'
|
||||
//引入VueOfficeDocx组件
|
||||
import VueOfficeDocx from '@vue-office/docx'
|
||||
|
|
@ -467,6 +497,7 @@ import VueOfficeExcel from '@vue-office/excel'
|
|||
//引入相关样式
|
||||
import '@vue-office/excel/lib/index.css'
|
||||
|
||||
|
||||
import VueOfficePptx from '@vue-office/pptx'
|
||||
|
||||
// 引入 markdown 解析器和代码高亮
|
||||
|
|
@ -539,7 +570,7 @@ folderName: [
|
|||
{ pattern: /^[^<>:"/\\|?*]+$/, message: t('vabI18n.knowledge.document.createFolderDialog.rules.namePattern', '文件夹名称不能包含特殊字符'), trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
const segmentList= ref([])
|
||||
// 右键菜单相关
|
||||
const contextMenuVisible = ref(false)
|
||||
const contextMenuPosition = reactive({
|
||||
|
|
@ -559,7 +590,10 @@ name: string;
|
|||
|
||||
|
||||
|
||||
|
||||
const handleClose = () => {
|
||||
uploadDialogVisible.value = false
|
||||
segmentList.value = []
|
||||
}
|
||||
|
||||
|
||||
// 组件卸载时清理
|
||||
|
|
@ -686,6 +720,10 @@ try {
|
|||
}
|
||||
)
|
||||
|
||||
const handleClose = () => {
|
||||
previewDrawerVisible.value = false,
|
||||
segmentList.value = []
|
||||
}
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: t('vabI18n.knowledge.document.messages.deleteing'),
|
||||
|
|
@ -917,7 +955,6 @@ const handlePreview = async (row: FileItem) => {
|
|||
previewDrawerVisible.value = true
|
||||
previewLoading.value = true
|
||||
|
||||
console.log("row",row)
|
||||
previewFileType.value = row.fileType;
|
||||
|
||||
try {
|
||||
|
|
@ -935,6 +972,13 @@ const handlePreview = async (row: FileItem) => {
|
|||
breaks: true,
|
||||
gfm: true
|
||||
})
|
||||
const resp = await getSegmentList({
|
||||
datasetId:datasetId.value,
|
||||
documentId: row.difyDocId
|
||||
})
|
||||
if (resp.data?.length) {
|
||||
segmentList.value = resp.data
|
||||
}
|
||||
|
||||
previewMarkdownContent.value = marked.parse(content) as string
|
||||
}
|
||||
|
|
@ -2317,4 +2361,82 @@ transform: scale(0.9) translateY(-5px);
|
|||
gap: 4px;
|
||||
}
|
||||
}
|
||||
.segment-list-container {
|
||||
width: 30%;
|
||||
border-right: 1px solid #ebeef5;
|
||||
overflow-y: auto;
|
||||
padding: 16px;
|
||||
background: #f9fafc;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
|
||||
h3 {
|
||||
margin-bottom: 12px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.el-form-item {
|
||||
cursor: pointer;
|
||||
padding: 16px; // 内边距增加
|
||||
border-radius: 8px;
|
||||
background: white;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
|
||||
min-height: 100px; // 增加最小高度,让卡片更高
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center; // 让内容垂直居中
|
||||
|
||||
&:hover {
|
||||
background: #f0f4ff;
|
||||
transform: translateX(2px);
|
||||
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.15);
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
margin-top: 4px;
|
||||
word-break: break-word; // 防止长文本溢出
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-family: "Microsoft YaHei", "微软雅黑", sans-serif; // 设置微软雅黑字体
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #4a4a4a;
|
||||
margin: 0;
|
||||
line-height: 1.6;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 4;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-word;
|
||||
}
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
font-size: 14px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 右侧预览内容保持原有样式 */
|
||||
.preview-content-container {
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
overflow-y: auto;
|
||||
background: #ffffff;
|
||||
border-radius: 0 8px 8px 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package com.bjtds.brichat.controller;
|
||||
|
||||
import com.bjtds.brichat.entity.dto.SegmentDto;
|
||||
import com.bjtds.brichat.service.dify.DocumentSegmentService;
|
||||
import com.bjtds.brichat.util.ResultUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.checkerframework.checker.units.qual.C;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@Slf4j
|
||||
@CrossOrigin(value = "*", maxAge = 3600)
|
||||
@RequestMapping("/documentSegment")
|
||||
public class DocumentSegmentController {
|
||||
@Autowired
|
||||
private DocumentSegmentService documentSegmentService;
|
||||
|
||||
@GetMapping("/selectSegments")
|
||||
public ResultUtils SelectSegments(@RequestParam("documentId") String documentId, @RequestParam("datasetId") String datasetId) {
|
||||
List<SegmentDto> segments = documentSegmentService.SelectSegments(documentId, datasetId);
|
||||
segments.sort(Comparator.comparing(SegmentDto::getPosition));
|
||||
return ResultUtils.success(segments);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.bjtds.brichat.mapper.postgresql;
|
||||
|
||||
|
||||
import com.bjtds.brichat.entity.dto.SegmentDto;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface DifyDocumentSegmentMapper {
|
||||
|
||||
List<SegmentDto> SelectSegmentsByDocumentIdAndDatasetId(String documentId, String datasetId);
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.bjtds.brichat.service.dify;
|
||||
|
||||
import com.bjtds.brichat.entity.dto.SegmentDto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface DocumentSegmentService {
|
||||
|
||||
List<SegmentDto> SelectSegments(String documentId, String datasetId);
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.bjtds.brichat.service.dify.impl;
|
||||
|
||||
import com.bjtds.brichat.entity.dto.SegmentDto;
|
||||
import com.bjtds.brichat.mapper.postgresql.DifyDocumentSegmentMapper;
|
||||
import com.bjtds.brichat.service.dify.DocumentSegmentService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class DocumentSegmentServiceImpl implements DocumentSegmentService {
|
||||
|
||||
@Autowired
|
||||
private DifyDocumentSegmentMapper difyDocumentSegmentMapper;
|
||||
|
||||
@Override
|
||||
public List<SegmentDto> SelectSegments(String documentId, String datasetId) {
|
||||
return difyDocumentSegmentMapper.SelectSegmentsByDocumentIdAndDatasetId(documentId, datasetId);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.bjtds.brichat.mapper.postgresql.DifyDocumentSegmentMapper">
|
||||
<select id="SelectSegmentsByDocumentIdAndDatasetId" resultType="com.bjtds.brichat.entity.dto.SegmentDto">
|
||||
select *
|
||||
from document_segments
|
||||
where
|
||||
<if test="documentId != null">
|
||||
document_id = CAST(#{documentId} as uuid) and
|
||||
</if>
|
||||
<if test="datasetId != null">
|
||||
dataset_id = CAST(#{datasetId} as uuid)
|
||||
</if>
|
||||
</select>
|
||||
</mapper>
|
||||
Loading…
Reference in New Issue