feat(knowledge): 完善知识库及附件统计功能并修复分块数统计问题

This commit is contained in:
RobustH
2026-04-12 18:37:52 +08:00
parent 3071bfd0f9
commit 28ad29d6ed
7 changed files with 110 additions and 1 deletions

View File

@@ -0,0 +1,20 @@
package org.ruoyi.domain.vo.knowledge;
import lombok.Data;
/**
* 文档分块数统计 VO用于 GROUP BY 查询结果接收)
*/
@Data
public class DocFragmentCountVo {
/**
* 文档ID关联 knowledge_attach.doc_id
*/
private String docId;
/**
* 该文档下的分块数量
*/
private Integer fragmentCount;
}

View File

@@ -8,6 +8,7 @@ import org.ruoyi.domain.entity.knowledge.KnowledgeAttach;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date;
@@ -68,5 +69,16 @@ public class KnowledgeAttachVo implements Serializable {
@ExcelProperty(value = "备注") @ExcelProperty(value = "备注")
private String remark; private String remark;
/**
* 上传时间(来自 BaseEntity.createTime
*/
@ExcelProperty(value = "上传时间")
private Date createTime;
/**
* 分块数(统计字段,非数据库列)
*/
private Integer fragmentCount;
} }

View File

@@ -100,5 +100,10 @@ public class KnowledgeInfoVo implements Serializable {
@ExcelProperty(value = "备注") @ExcelProperty(value = "备注")
private String remark; private String remark;
/**
* 文档数(统计字段,非数据库列)
*/
private Integer documentCount;
} }

View File

@@ -1,5 +1,7 @@
package org.ruoyi.mapper.knowledge; package org.ruoyi.mapper.knowledge;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.ruoyi.domain.entity.knowledge.KnowledgeAttach; import org.ruoyi.domain.entity.knowledge.KnowledgeAttach;
import org.ruoyi.domain.vo.knowledge.KnowledgeAttachVo; import org.ruoyi.domain.vo.knowledge.KnowledgeAttachVo;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus; import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
@@ -12,4 +14,9 @@ import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
*/ */
public interface KnowledgeAttachMapper extends BaseMapperPlus<KnowledgeAttach, KnowledgeAttachVo> { public interface KnowledgeAttachMapper extends BaseMapperPlus<KnowledgeAttach, KnowledgeAttachVo> {
/**
* 统计指定知识库下的文档数量
*/
@Select("SELECT COUNT(*) FROM knowledge_attach WHERE knowledge_id = #{knowledgeId}")
int countByKnowledgeId(@Param("knowledgeId") Long knowledgeId);
} }

View File

@@ -1,9 +1,14 @@
package org.ruoyi.mapper.knowledge; package org.ruoyi.mapper.knowledge;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.ruoyi.domain.entity.knowledge.KnowledgeFragment; import org.ruoyi.domain.entity.knowledge.KnowledgeFragment;
import org.ruoyi.domain.vo.knowledge.DocFragmentCountVo;
import org.ruoyi.domain.vo.knowledge.KnowledgeFragmentVo; import org.ruoyi.domain.vo.knowledge.KnowledgeFragmentVo;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus; import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import java.util.List;
/** /**
* 知识片段Mapper接口 * 知识片段Mapper接口
* *
@@ -12,4 +17,18 @@ import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
*/ */
public interface KnowledgeFragmentMapper extends BaseMapperPlus<KnowledgeFragment, KnowledgeFragmentVo> { public interface KnowledgeFragmentMapper extends BaseMapperPlus<KnowledgeFragment, KnowledgeFragmentVo> {
/**
* 批量统计各文档的分块数(强类型接收,避免 Map key 大小写问题)
*
* @param docIds 文档 ID 列表
* @return 每个 docId 对应的分块数列表
*/
@Select("<script>" +
"SELECT doc_id AS docId, COUNT(*) AS fragmentCount " +
"FROM knowledge_fragment " +
"WHERE doc_id IN " +
"<foreach collection='docIds' item='id' open='(' separator=',' close=')'>#{id}</foreach> " +
"GROUP BY doc_id" +
"</script>")
List<DocFragmentCountVo> selectFragmentCountByDocIds(@Param("docIds") List<String> docIds);
} }

View File

@@ -20,6 +20,7 @@ import org.ruoyi.domain.bo.knowledge.KnowledgeInfoUploadBo;
import org.ruoyi.domain.bo.vector.StoreEmbeddingBo; import org.ruoyi.domain.bo.vector.StoreEmbeddingBo;
import org.ruoyi.domain.entity.knowledge.KnowledgeAttach; import org.ruoyi.domain.entity.knowledge.KnowledgeAttach;
import org.ruoyi.domain.entity.knowledge.KnowledgeFragment; import org.ruoyi.domain.entity.knowledge.KnowledgeFragment;
import org.ruoyi.domain.vo.knowledge.DocFragmentCountVo;
import org.ruoyi.domain.vo.knowledge.KnowledgeAttachVo; import org.ruoyi.domain.vo.knowledge.KnowledgeAttachVo;
import org.ruoyi.domain.vo.knowledge.KnowledgeInfoVo; import org.ruoyi.domain.vo.knowledge.KnowledgeInfoVo;
import org.ruoyi.factory.ResourceLoaderFactory; import org.ruoyi.factory.ResourceLoaderFactory;
@@ -81,6 +82,9 @@ public class KnowledgeAttachServiceImpl implements IKnowledgeAttachService {
public TableDataInfo<KnowledgeAttachVo> queryPageList(KnowledgeAttachBo bo, PageQuery pageQuery) { public TableDataInfo<KnowledgeAttachVo> queryPageList(KnowledgeAttachBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<KnowledgeAttach> lqw = buildQueryWrapper(bo); LambdaQueryWrapper<KnowledgeAttach> lqw = buildQueryWrapper(bo);
Page<KnowledgeAttachVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); Page<KnowledgeAttachVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
// 批量填充分块数
List<KnowledgeAttachVo> records = result.getRecords();
fillFragmentCount(records);
return TableDataInfo.build(result); return TableDataInfo.build(result);
} }
@@ -93,7 +97,33 @@ public class KnowledgeAttachServiceImpl implements IKnowledgeAttachService {
@Override @Override
public List<KnowledgeAttachVo> queryList(KnowledgeAttachBo bo) { public List<KnowledgeAttachVo> queryList(KnowledgeAttachBo bo) {
LambdaQueryWrapper<KnowledgeAttach> lqw = buildQueryWrapper(bo); LambdaQueryWrapper<KnowledgeAttach> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw); List<KnowledgeAttachVo> list = baseMapper.selectVoList(lqw);
fillFragmentCount(list);
return list;
}
/**
* 批量填充每个附件记录的分块数fragmentCount
*/
private void fillFragmentCount(List<KnowledgeAttachVo> records) {
if (records == null || records.isEmpty()) return;
List<String> docIds = records.stream()
.map(KnowledgeAttachVo::getDocId)
.filter(docId -> docId != null && !docId.isEmpty())
.distinct()
.collect(java.util.stream.Collectors.toList());
if (docIds.isEmpty()) return;
List<DocFragmentCountVo> countList =
knowledgeFragmentMapper.selectFragmentCountByDocIds(docIds);
Map<String, Integer> countMap = new java.util.HashMap<>();
for (DocFragmentCountVo item : countList) {
if (item.getDocId() != null) {
countMap.put(item.getDocId(), item.getFragmentCount());
}
}
for (KnowledgeAttachVo vo : records) {
vo.setFragmentCount(countMap.getOrDefault(vo.getDocId(), 0));
}
} }
private LambdaQueryWrapper<KnowledgeAttach> buildQueryWrapper(KnowledgeAttachBo bo) { private LambdaQueryWrapper<KnowledgeAttach> buildQueryWrapper(KnowledgeAttachBo bo) {

View File

@@ -12,6 +12,7 @@ import lombok.extern.slf4j.Slf4j;
import org.ruoyi.domain.bo.knowledge.KnowledgeInfoBo; import org.ruoyi.domain.bo.knowledge.KnowledgeInfoBo;
import org.ruoyi.domain.entity.knowledge.KnowledgeInfo; import org.ruoyi.domain.entity.knowledge.KnowledgeInfo;
import org.ruoyi.domain.vo.knowledge.KnowledgeInfoVo; import org.ruoyi.domain.vo.knowledge.KnowledgeInfoVo;
import org.ruoyi.mapper.knowledge.KnowledgeAttachMapper;
import org.ruoyi.mapper.knowledge.KnowledgeInfoMapper; import org.ruoyi.mapper.knowledge.KnowledgeInfoMapper;
import org.ruoyi.service.knowledge.IKnowledgeInfoService; import org.ruoyi.service.knowledge.IKnowledgeInfoService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -33,6 +34,8 @@ public class KnowledgeInfoServiceImpl implements IKnowledgeInfoService {
private final KnowledgeInfoMapper baseMapper; private final KnowledgeInfoMapper baseMapper;
private final KnowledgeAttachMapper knowledgeAttachMapper;
/** /**
* 查询知识库 * 查询知识库
* *
@@ -55,6 +58,8 @@ public class KnowledgeInfoServiceImpl implements IKnowledgeInfoService {
public TableDataInfo<KnowledgeInfoVo> queryPageList(KnowledgeInfoBo bo, PageQuery pageQuery) { public TableDataInfo<KnowledgeInfoVo> queryPageList(KnowledgeInfoBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<KnowledgeInfo> lqw = buildQueryWrapper(bo); LambdaQueryWrapper<KnowledgeInfo> lqw = buildQueryWrapper(bo);
Page<KnowledgeInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); Page<KnowledgeInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
// 批量填充文档数
fillDocumentCount(result.getRecords());
return TableDataInfo.build(result); return TableDataInfo.build(result);
} }
@@ -87,6 +92,17 @@ public class KnowledgeInfoServiceImpl implements IKnowledgeInfoService {
return lqw; return lqw;
} }
/**
* 批量填充知识库列表每一条记录的文档数documentCount
*/
private void fillDocumentCount(List<KnowledgeInfoVo> records) {
if (records == null || records.isEmpty()) return;
for (KnowledgeInfoVo vo : records) {
int count = knowledgeAttachMapper.countByKnowledgeId(vo.getId());
vo.setDocumentCount(count);
}
}
/** /**
* 新增知识库 * 新增知识库
* *