feat: 调整知识库模块

This commit is contained in:
ageerle
2025-04-09 17:41:29 +08:00
parent be6d027cad
commit 3be9005f95
424 changed files with 1584 additions and 10005 deletions

View File

@@ -0,0 +1,37 @@
package org.ruoyi.chain.loader;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.chain.split.TextSplitter;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
@Component
@AllArgsConstructor
@Slf4j
public class CodeFileLoader implements ResourceLoader {
private final TextSplitter textSplitter;
@Override
public String getContent(InputStream inputStream) {
StringBuffer stringBuffer = new StringBuffer();
try (InputStreamReader reader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(reader)){
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuffer.append(line).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}
return stringBuffer.toString();
}
@Override
public List<String> getChunkList(String content, String kid){
return textSplitter.split(content, kid);
}
}

View File

@@ -0,0 +1,18 @@
package org.ruoyi.chain.loader;
import org.ruoyi.chain.loader.ResourceLoader;
import java.io.InputStream;
import java.util.List;
public class CsvFileLoader implements ResourceLoader {
@Override
public String getContent(InputStream inputStream) {
return null;
}
@Override
public List<String> getChunkList(String content, String kid) {
return null;
}
}

View File

@@ -0,0 +1,16 @@
package org.ruoyi.chain.loader;
import java.io.InputStream;
import java.util.List;
public class FolderLoader implements ResourceLoader{
@Override
public String getContent(InputStream inputStream) {
return null;
}
@Override
public List<String> getChunkList(String content, String kid) {
return null;
}
}

View File

@@ -0,0 +1,18 @@
package org.ruoyi.chain.loader;
import org.ruoyi.chain.loader.ResourceLoader;
import java.io.InputStream;
import java.util.List;
public class GithubLoader implements ResourceLoader {
@Override
public String getContent(InputStream inputStream) {
return null;
}
@Override
public List<String> getChunkList(String content, String kid) {
return null;
}
}

View File

@@ -0,0 +1,18 @@
package org.ruoyi.chain.loader;
import org.ruoyi.chain.loader.ResourceLoader;
import java.io.InputStream;
import java.util.List;
public class JsonFileLoader implements ResourceLoader {
@Override
public String getContent(InputStream inputStream) {
return null;
}
@Override
public List<String> getChunkList(String content, String kid) {
return null;
}
}

View File

@@ -0,0 +1,38 @@
package org.ruoyi.chain.loader;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.chain.loader.ResourceLoader;
import org.ruoyi.chain.split.TextSplitter;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
@Component
@AllArgsConstructor
@Slf4j
public class MarkDownFileLoader implements ResourceLoader {
private final TextSplitter textSplitter;
@Override
public String getContent(InputStream inputStream) {
StringBuffer stringBuffer = new StringBuffer();
try (InputStreamReader reader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(reader)){
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuffer.append(line).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}
return stringBuffer.toString();
}
@Override
public List<String> getChunkList(String content, String kid){
return textSplitter.split(content, kid);
}
}

View File

@@ -0,0 +1,35 @@
package org.ruoyi.chain.loader;
import lombok.AllArgsConstructor;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.ruoyi.chain.loader.ResourceLoader;
import org.ruoyi.chain.split.TextSplitter;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
@Component
@AllArgsConstructor
public class PdfFileLoader implements ResourceLoader {
private final TextSplitter characterTextSplitter;
@Override
public String getContent(InputStream inputStream) {
PDDocument document = null;
try {
document = PDDocument.load(inputStream);
PDFTextStripper textStripper = new PDFTextStripper();
String content = textStripper.getText(document);
return content;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public List<String> getChunkList(String content, String kid) {
return characterTextSplitter.split(content, kid);
}
}

View File

@@ -0,0 +1,14 @@
package org.ruoyi.chain.loader;
import java.io.InputStream;
import java.util.List;
/**
* 资源载入
*/
public interface ResourceLoader {
String getContent(InputStream inputStream);
List<String> getChunkList(String content, String kid);
}

View File

@@ -0,0 +1,35 @@
package org.ruoyi.chain.loader;
import lombok.AllArgsConstructor;
import org.ruoyi.chain.loader.ResourceLoader;
import org.ruoyi.chain.loader.TextFileLoader;
import org.ruoyi.chain.split.CharacterTextSplitter;
import org.ruoyi.chain.split.CodeTextSplitter;
import org.ruoyi.chain.split.MarkdownTextSplitter;
import org.ruoyi.chain.split.TokenTextSplitter;
import org.ruoyi.knowledge.constant.FileType;
import org.springframework.stereotype.Component;
@AllArgsConstructor
@Component
public class ResourceLoaderFactory {
private final CharacterTextSplitter characterTextSplitter;
private final CodeTextSplitter codeTextSplitter;
private final MarkdownTextSplitter markdownTextSplitter;
private final TokenTextSplitter tokenTextSplitter;
public ResourceLoader getLoaderByFileType(String fileType){
if (FileType.isTextFile(fileType)){
return new TextFileLoader(characterTextSplitter);
} else if (FileType.isWord(fileType)) {
return new WordLoader(characterTextSplitter);
} else if (FileType.isPdf(fileType)) {
return new PdfFileLoader(characterTextSplitter);
} else if (FileType.isMdFile(fileType)) {
return new MarkDownFileLoader(markdownTextSplitter);
}else if (FileType.isCodeFile(fileType)) {
return new CodeFileLoader(codeTextSplitter);
}else {
return new TextFileLoader(characterTextSplitter);
}
}
}

View File

@@ -0,0 +1,37 @@
package org.ruoyi.chain.loader;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.chain.split.TextSplitter;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
@Component
@AllArgsConstructor
@Slf4j
public class TextFileLoader implements ResourceLoader{
private final TextSplitter textSplitter;
@Override
public String getContent(InputStream inputStream) {
StringBuffer stringBuffer = new StringBuffer();
try (InputStreamReader reader = new InputStreamReader(inputStream, "UTF-8");
BufferedReader bufferedReader = new BufferedReader(reader)){
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuffer.append(line).append("\n");
}
} catch (IOException e) {
e.printStackTrace();
}
return stringBuffer.toString();
}
@Override
public List<String> getChunkList(String content, String kid){
return textSplitter.split(content, kid);
}
}

View File

@@ -0,0 +1,38 @@
package org.ruoyi.chain.loader;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.ruoyi.chain.loader.ResourceLoader;
import org.ruoyi.chain.split.TextSplitter;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
@Component
@AllArgsConstructor
@Slf4j
public class WordLoader implements ResourceLoader {
private final TextSplitter textSplitter;
@Override
public String getContent(InputStream inputStream) {
XWPFDocument document = null;
try {
document = new XWPFDocument(inputStream);
XWPFWordExtractor extractor = new XWPFWordExtractor(document);
String content = extractor.getText();
return content;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public List<String> getChunkList(String content, String kid) {
return textSplitter.split(content, kid);
}
}

View File

@@ -0,0 +1,64 @@
package org.ruoyi.chain.split;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.chain.split.TextSplitter;
import org.ruoyi.domain.vo.KnowledgeInfoVo;
import org.ruoyi.service.IKnowledgeInfoService;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Component
@Slf4j
@Primary
public class CharacterTextSplitter implements TextSplitter {
@Lazy
@Resource
private IKnowledgeInfoService knowledgeInfoService;
@Override
public List<String> split(String content, String kid) {
// 从知识库表中获取配置
KnowledgeInfoVo knowledgeInfoVo = knowledgeInfoService.queryById(Long.valueOf(kid));
String knowledgeSeparator = knowledgeInfoVo.getKnowledgeSeparator();
int textBlockSize = knowledgeInfoVo.getTextBlockSize();
int overlapChar = knowledgeInfoVo.getOverlapChar();
List<String> chunkList = new ArrayList<>();
if (content.contains(knowledgeSeparator) && StringUtils.isNotBlank(knowledgeSeparator)) {
// 按自定义分隔符切分
String[] chunks = content.split(knowledgeSeparator);
chunkList.addAll(Arrays.asList(chunks));
} else {
int indexMin = 0;
int len = content.length();
int i = 0;
int right = 0;
while (true) {
if (len > right) {
int begin = i * textBlockSize - overlapChar;
if (begin < indexMin) {
begin = indexMin;
}
int end = textBlockSize * (i + 1) + overlapChar;
if (end > len) {
end = len;
}
String chunk = content.substring(begin, end);
chunkList.add(chunk);
i++;
right = right + textBlockSize;
} else {
break;
}
}
}
return chunkList;
}
}

View File

@@ -0,0 +1,18 @@
package org.ruoyi.chain.split;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.chain.split.TextSplitter;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@AllArgsConstructor
@Slf4j
public class CodeTextSplitter implements TextSplitter {
@Override
public List<String> split(String content, String kid) {
return null;
}
}

View File

@@ -0,0 +1,17 @@
package org.ruoyi.chain.split;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@AllArgsConstructor
@Slf4j
public class MarkdownTextSplitter implements TextSplitter{
@Override
public List<String> split(String content, String kid) {
return null;
}
}

View File

@@ -0,0 +1,18 @@
package org.ruoyi.chain.split;
import java.util.List;
/**
* 文本切分
*/
public interface TextSplitter {
/**
* 文本切分
*
* @param content 文本内容
* @param kid 知识库id
* @return 切分后的文本列表
*/
List<String> split(String content, String kid);
}

View File

@@ -0,0 +1,18 @@
package org.ruoyi.chain.split;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.chain.split.TextSplitter;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@AllArgsConstructor
@Slf4j
public class TokenTextSplitter implements TextSplitter {
@Override
public List<String> split(String content, String kid) {
return null;
}
}

View File

@@ -0,0 +1,91 @@
package org.ruoyi.constant;
public class FileType {
public static final String TXT = "txt";
public static final String CSV = "csv";
public static final String MD = "md";
public static final String DOC = "doc";
public static final String DOCX = "docx";
public static final String PDF = "pdf";
public static final String LOG = "log";
public static final String XML = "xml";
public static final String JAVA = "java";
public static final String HTML = "html";
public static final String HTM = "htm";
public static final String CSS = "css";
public static final String JS = "js";
public static final String PY = "py";
public static final String CPP = "cpp";
public static final String SQL = "sql";
public static final String PHP = "php";
public static final String RUBY = "ruby";
public static final String C = "c";
public static final String H = "h";
public static final String HPP = "hpp";
public static final String SWIFT = "swift";
public static final String TS = "ts";
public static final String RUST = "rs";
public static final String PERL = "perl";
public static final String SHELL = "shell";
public static final String BAT = "bat";
public static final String CMD = "cmd";
public static final String PROPERTIES = "properties";
public static final String INI = "ini";
public static final String YAML = "yaml";
public static final String YML = "yml";
public static boolean isTextFile(String type){
if (type.equalsIgnoreCase(TXT) || type.equalsIgnoreCase(CSV) || type.equalsIgnoreCase(PROPERTIES)
|| type.equalsIgnoreCase(INI) || type.equalsIgnoreCase(YAML) || type.equalsIgnoreCase(YML)
|| type.equalsIgnoreCase(LOG) || type.equalsIgnoreCase(XML)){
return true;
}
else {
return false;
}
}
public static boolean isCodeFile(String type){
if (type.equalsIgnoreCase(JAVA) || type.equalsIgnoreCase(HTML) || type.equalsIgnoreCase(HTM) || type.equalsIgnoreCase(JS) || type.equalsIgnoreCase(PY)
|| type.equalsIgnoreCase(CPP) || type.equalsIgnoreCase(SQL) || type.equalsIgnoreCase(PHP) || type.equalsIgnoreCase(RUBY)
|| type.equalsIgnoreCase(C) || type.equalsIgnoreCase(H) || type.equalsIgnoreCase(HPP) || type.equalsIgnoreCase(SWIFT)
|| type.equalsIgnoreCase(TS) || type.equalsIgnoreCase(RUST) || type.equalsIgnoreCase(PERL) || type.equalsIgnoreCase(SHELL)
|| type.equalsIgnoreCase(BAT) || type.equalsIgnoreCase(CMD) || type.equalsIgnoreCase(CSS)){
return true;
}
else {
return false;
}
}
public static boolean isMdFile(String type){
if (type.equalsIgnoreCase(MD)){
return true;
}
else {
return false;
}
}
public static boolean isWord(String type){
if (type.equalsIgnoreCase(DOC) || type.equalsIgnoreCase(DOCX)){
return true;
}
else {
return false;
}
}
public static boolean isPdf(String type){
if (type.equalsIgnoreCase(PDF)){
return true;
}
else {
return false;
}
}
}

View File

@@ -0,0 +1,61 @@
package org.ruoyi.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
/**
* 知识库附件对象 knowledge_attach
*
* @author ageerle
* @date 2025-04-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("knowledge_attach")
public class KnowledgeAttach extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
*
*/
@TableId(value = "id")
private Long id;
/**
* 知识库ID
*/
private String kid;
/**
* 文档ID
*/
private String docId;
/**
* 文档名称
*/
private String docName;
/**
* 文档类型
*/
private String docType;
/**
* 文档内容
*/
private String content;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,61 @@
package org.ruoyi.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
/**
* 知识片段对象 knowledge_fragment
*
* @author ageerle
* @date 2025-04-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("knowledge_fragment")
public class KnowledgeFragment extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
*
*/
@TableId(value = "id")
private Long id;
/**
* 知识库ID
*/
private String kid;
/**
* 文档ID
*/
private String docId;
/**
* 知识片段ID
*/
private String fid;
/**
* 片段索引下标
*/
private Long idx;
/**
* 文档内容
*/
private String content;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,96 @@
package org.ruoyi.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import java.io.Serial;
/**
* 知识库对象 knowledge_info
*
* @author ageerle
* @date 2025-04-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("knowledge_info")
public class KnowledgeInfo extends BaseEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
*
*/
@TableId(value = "id")
private Long id;
/**
* 知识库ID
*/
private String kid;
/**
* 用户ID
*/
private Long uid;
/**
* 知识库名称
*/
private String kname;
/**
* 是否公开知识库0 否 1是
*/
private Integer share;
/**
* 描述
*/
private String description;
/**
* 知识分隔符
*/
private String knowledgeSeparator;
/**
* 提问分隔符
*/
private String questionSeparator;
/**
* 重叠字符数
*/
private Long overlapChar;
/**
* 知识库中检索的条数
*/
private Long retrieveLimit;
/**
* 文本块大小
*/
private Long textBlockSize;
/**
* 向量库
*/
private String vector;
/**
* 向量模型
*/
private String vectorModel;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,66 @@
package org.ruoyi.domain.bo;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.domain.KnowledgeAttach;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
/**
* 知识库附件业务对象 knowledge_attach
*
* @author ageerle
* @date 2025-04-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = KnowledgeAttach.class, reverseConvertGenerate = false)
public class KnowledgeAttachBo extends BaseEntity {
/**
*
*/
@NotNull(message = "不能为空", groups = { EditGroup.class })
private Long id;
/**
* 知识库ID
*/
@NotBlank(message = "知识库ID不能为空", groups = { AddGroup.class, EditGroup.class })
private String kid;
/**
* 文档ID
*/
@NotBlank(message = "文档ID不能为空", groups = { AddGroup.class, EditGroup.class })
private String docId;
/**
* 文档名称
*/
@NotBlank(message = "文档名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String docName;
/**
* 文档类型
*/
@NotBlank(message = "文档类型不能为空", groups = { AddGroup.class, EditGroup.class })
private String docType;
/**
* 文档内容
*/
@NotBlank(message = "文档内容不能为空", groups = { AddGroup.class, EditGroup.class })
private String content;
/**
* 备注
*/
@NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
private String remark;
}

View File

@@ -0,0 +1,66 @@
package org.ruoyi.domain.bo;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.domain.KnowledgeFragment;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
/**
* 知识片段业务对象 knowledge_fragment
*
* @author ageerle
* @date 2025-04-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = KnowledgeFragment.class, reverseConvertGenerate = false)
public class KnowledgeFragmentBo extends BaseEntity {
/**
*
*/
@NotNull(message = "不能为空", groups = { EditGroup.class })
private Long id;
/**
* 知识库ID
*/
@NotBlank(message = "知识库ID不能为空", groups = { AddGroup.class, EditGroup.class })
private String kid;
/**
* 文档ID
*/
@NotBlank(message = "文档ID不能为空", groups = { AddGroup.class, EditGroup.class })
private String docId;
/**
* 知识片段ID
*/
@NotBlank(message = "知识片段ID不能为空", groups = { AddGroup.class, EditGroup.class })
private String fid;
/**
* 片段索引下标
*/
@NotNull(message = "片段索引下标不能为空", groups = { AddGroup.class, EditGroup.class })
private Long idx;
/**
* 文档内容
*/
@NotBlank(message = "文档内容不能为空", groups = { AddGroup.class, EditGroup.class })
private String content;
/**
* 备注
*/
@NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
private String remark;
}

View File

@@ -0,0 +1,108 @@
package org.ruoyi.domain.bo;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.domain.KnowledgeInfo;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
/**
* 知识库业务对象 knowledge_info
*
* @author ageerle
* @date 2025-04-08
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = KnowledgeInfo.class, reverseConvertGenerate = false)
public class KnowledgeInfoBo extends BaseEntity {
/**
*
*/
@NotNull(message = "不能为空", groups = { EditGroup.class })
private Long id;
/**
* 知识库ID
*/
@NotBlank(message = "知识库ID不能为空", groups = { AddGroup.class, EditGroup.class })
private String kid;
/**
* 用户ID
*/
@NotNull(message = "用户ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long uid;
/**
* 知识库名称
*/
@NotBlank(message = "知识库名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String kname;
/**
* 是否公开知识库0 否 1是
*/
@NotNull(message = "是否公开知识库0 否 1是不能为空", groups = { AddGroup.class, EditGroup.class })
private Integer share;
/**
* 描述
*/
@NotBlank(message = "描述不能为空", groups = { AddGroup.class, EditGroup.class })
private String description;
/**
* 知识分隔符
*/
@NotBlank(message = "知识分隔符不能为空", groups = { AddGroup.class, EditGroup.class })
private String knowledgeSeparator;
/**
* 提问分隔符
*/
@NotBlank(message = "提问分隔符不能为空", groups = { AddGroup.class, EditGroup.class })
private String questionSeparator;
/**
* 重叠字符数
*/
@NotNull(message = "重叠字符数不能为空", groups = { AddGroup.class, EditGroup.class })
private Long overlapChar;
/**
* 知识库中检索的条数
*/
@NotNull(message = "知识库中检索的条数不能为空", groups = { AddGroup.class, EditGroup.class })
private Long retrieveLimit;
/**
* 文本块大小
*/
@NotNull(message = "文本块大小不能为空", groups = { AddGroup.class, EditGroup.class })
private Long textBlockSize;
/**
* 向量库
*/
@NotBlank(message = "向量库不能为空", groups = { AddGroup.class, EditGroup.class })
private String vector;
/**
* 向量模型
*/
@NotBlank(message = "向量模型不能为空", groups = { AddGroup.class, EditGroup.class })
private String vectorModel;
/**
* 备注
*/
@NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
private String remark;
}

View File

@@ -0,0 +1,72 @@
package org.ruoyi.domain.vo;
import org.ruoyi.domain.KnowledgeAttach;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 知识库附件视图对象 knowledge_attach
*
* @author ageerle
* @date 2025-04-08
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = KnowledgeAttach.class)
public class KnowledgeAttachVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
*
*/
@ExcelProperty(value = "")
private Long id;
/**
* 知识库ID
*/
@ExcelProperty(value = "知识库ID")
private String kid;
/**
* 文档ID
*/
@ExcelProperty(value = "文档ID")
private String docId;
/**
* 文档名称
*/
@ExcelProperty(value = "文档名称")
private String docName;
/**
* 文档类型
*/
@ExcelProperty(value = "文档类型")
private String docType;
/**
* 文档内容
*/
@ExcelProperty(value = "文档内容")
private String content;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
}

View File

@@ -0,0 +1,74 @@
package org.ruoyi.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.ruoyi.domain.KnowledgeFragment;
import java.io.Serial;
import java.io.Serializable;
/**
* 知识片段视图对象 knowledge_fragment
*
* @author ageerle
* @date 2025-04-08
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = KnowledgeFragment.class)
public class KnowledgeFragmentVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
*
*/
@ExcelProperty(value = "")
private Long id;
/**
* 知识库ID
*/
@ExcelProperty(value = "知识库ID")
private String kid;
/**
* 文档ID
*/
@ExcelProperty(value = "文档ID")
private String docId;
/**
* 知识片段ID
*/
@ExcelProperty(value = "知识片段ID")
private String fid;
/**
* 片段索引下标
*/
@ExcelProperty(value = "片段索引下标")
private Long idx;
/**
* 文档内容
*/
@ExcelProperty(value = "文档内容")
private String content;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
}

View File

@@ -0,0 +1,119 @@
package org.ruoyi.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.ruoyi.common.excel.annotation.ExcelDictFormat;
import org.ruoyi.common.excel.convert.ExcelDictConvert;
import org.ruoyi.domain.KnowledgeInfo;
import java.io.Serial;
import java.io.Serializable;
/**
* 知识库视图对象 knowledge_info
*
* @author ageerle
* @date 2025-04-08
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = KnowledgeInfo.class)
public class KnowledgeInfoVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
*
*/
@ExcelProperty(value = "")
private Long id;
/**
* 知识库ID
*/
@ExcelProperty(value = "知识库ID")
private String kid;
/**
* 用户ID
*/
@ExcelProperty(value = "用户ID")
private Long uid;
/**
* 知识库名称
*/
@ExcelProperty(value = "知识库名称")
private String kname;
/**
* 是否公开知识库0 否 1是
*/
@ExcelProperty(value = "是否公开知识库", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "0=,否=,1=是")
private Integer share;
/**
* 描述
*/
@ExcelProperty(value = "描述")
private String description;
/**
* 知识分隔符
*/
@ExcelProperty(value = "知识分隔符")
private String knowledgeSeparator;
/**
* 提问分隔符
*/
@ExcelProperty(value = "提问分隔符")
private String questionSeparator;
/**
* 重叠字符数
*/
@ExcelProperty(value = "重叠字符数")
private Integer overlapChar;
/**
* 知识库中检索的条数
*/
@ExcelProperty(value = "知识库中检索的条数")
private Integer retrieveLimit;
/**
* 文本块大小
*/
@ExcelProperty(value = "文本块大小")
private Integer textBlockSize;
/**
* 向量库
*/
@ExcelProperty(value = "向量库")
private String vector;
/**
* 向量模型
*/
@ExcelProperty(value = "向量模型")
private String vectorModel;
/**
* 备注
*/
@ExcelProperty(value = "备注")
private String remark;
}

View File

@@ -0,0 +1,16 @@
package org.ruoyi.mapper;
import org.ruoyi.domain.KnowledgeAttach;
import org.ruoyi.domain.vo.KnowledgeAttachVo;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 知识库附件Mapper接口
*
* @author ageerle
* @date 2025-04-08
*/
public interface KnowledgeAttachMapper extends BaseMapperPlus<KnowledgeAttach, KnowledgeAttachVo> {
}

View File

@@ -0,0 +1,16 @@
package org.ruoyi.mapper;
import org.ruoyi.domain.KnowledgeFragment;
import org.ruoyi.domain.vo.KnowledgeFragmentVo;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 知识片段Mapper接口
*
* @author ageerle
* @date 2025-04-08
*/
public interface KnowledgeFragmentMapper extends BaseMapperPlus<KnowledgeFragment, KnowledgeFragmentVo> {
}

View File

@@ -0,0 +1,16 @@
package org.ruoyi.mapper;
import org.ruoyi.domain.KnowledgeInfo;
import org.ruoyi.domain.vo.KnowledgeInfoVo;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 知识库Mapper接口
*
* @author ageerle
* @date 2025-04-08
*/
public interface KnowledgeInfoMapper extends BaseMapperPlus<KnowledgeInfo, KnowledgeInfoVo> {
}

View File

@@ -0,0 +1,20 @@
package org.ruoyi.service;
import java.util.List;
public interface EmbeddingService {
void storeEmbeddings(List<String> chunkList, String kid, String docId,List<String> fidList);
void removeByDocId(String kid,String docId);
void removeByKid(String kid);
List<Double> getQueryVector(String query, String kid);
void createSchema(String kid);
void removeByKidAndFid(String kid, String fid);
void saveFragment(String kid, String docId, String fid, String content);
}

View File

@@ -0,0 +1,49 @@
package org.ruoyi.service;
import org.ruoyi.domain.bo.KnowledgeAttachBo;
import org.ruoyi.domain.vo.KnowledgeAttachVo;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 知识库附件Service接口
*
* @author ageerle
* @date 2025-04-08
*/
public interface IKnowledgeAttachService {
/**
* 查询知识库附件
*/
KnowledgeAttachVo queryById(Long id);
/**
* 查询知识库附件列表
*/
TableDataInfo<KnowledgeAttachVo> queryPageList(KnowledgeAttachBo bo, PageQuery pageQuery);
/**
* 查询知识库附件列表
*/
List<KnowledgeAttachVo> queryList(KnowledgeAttachBo bo);
/**
* 新增知识库附件
*/
Boolean insertByBo(KnowledgeAttachBo bo);
/**
* 修改知识库附件
*/
Boolean updateByBo(KnowledgeAttachBo bo);
/**
* 校验并批量删除知识库附件信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,49 @@
package org.ruoyi.service;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.domain.bo.KnowledgeFragmentBo;
import org.ruoyi.domain.vo.KnowledgeFragmentVo;
import java.util.Collection;
import java.util.List;
/**
* 知识片段Service接口
*
* @author ageerle
* @date 2025-04-08
*/
public interface IKnowledgeFragmentService {
/**
* 查询知识片段
*/
KnowledgeFragmentVo queryById(Long id);
/**
* 查询知识片段列表
*/
TableDataInfo<KnowledgeFragmentVo> queryPageList(KnowledgeFragmentBo bo, PageQuery pageQuery);
/**
* 查询知识片段列表
*/
List<KnowledgeFragmentVo> queryList(KnowledgeFragmentBo bo);
/**
* 新增知识片段
*/
Boolean insertByBo(KnowledgeFragmentBo bo);
/**
* 修改知识片段
*/
Boolean updateByBo(KnowledgeFragmentBo bo);
/**
* 校验并批量删除知识片段信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,49 @@
package org.ruoyi.service;
import org.ruoyi.domain.bo.KnowledgeInfoBo;
import org.ruoyi.domain.vo.KnowledgeInfoVo;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 知识库Service接口
*
* @author ageerle
* @date 2025-04-08
*/
public interface IKnowledgeInfoService {
/**
* 查询知识库
*/
KnowledgeInfoVo queryById(Long id);
/**
* 查询知识库列表
*/
TableDataInfo<KnowledgeInfoVo> queryPageList(KnowledgeInfoBo bo, PageQuery pageQuery);
/**
* 查询知识库列表
*/
List<KnowledgeInfoVo> queryList(KnowledgeInfoBo bo);
/**
* 新增知识库
*/
Boolean insertByBo(KnowledgeInfoBo bo);
/**
* 修改知识库
*/
Boolean updateByBo(KnowledgeInfoBo bo);
/**
* 校验并批量删除知识库信息
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@@ -0,0 +1,23 @@
package org.ruoyi.service;
import java.util.List;
/**
* 向量存储
*/
public interface VectorStoreService {
void storeEmbeddings(List<String> chunkList, List<List<Double>> vectorList, String kid, String docId, List<String> fidList);
void removeByDocId(String kid, String docId);
void removeByKid(String kid);
List<String> nearest(List<Double> queryVector, String kid);
List<String> nearest(String query, String kid);
void newSchema(String kid);
void removeByKidAndFid(String kid, String fid);
}

View File

@@ -0,0 +1,13 @@
package org.ruoyi.service;
import java.util.List;
/**
* 文本向量化
*/
public interface VectorizationService {
List<List<Double>> batchVectorization(List<String> chunkList, String kid);
List<Double> singleVectorization(String chunk, String kid);
}

View File

@@ -0,0 +1,64 @@
package org.ruoyi.service.impl;
import lombok.AllArgsConstructor;
import org.ruoyi.service.EmbeddingService;
import org.ruoyi.service.VectorStoreService;
import org.ruoyi.service.VectorizationService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
@AllArgsConstructor
public class EmbeddingServiceImpl implements EmbeddingService {
private final VectorStoreService vectorStore;
private final VectorizationService vectorization;
/**
* 保存向量数据库
* @param chunkList 文档按行切分的片段
* @param kid 知识库ID
* @param docId 文档ID
*/
@Override
public void storeEmbeddings(List<String> chunkList, String kid, String docId,List<String> fidList) {
List<List<Double>> vectorList = vectorization.batchVectorization(chunkList, kid);
vectorStore.storeEmbeddings(chunkList,vectorList,kid,docId,fidList);
}
@Override
public void removeByDocId(String kid,String docId) {
vectorStore.removeByDocId(kid,docId);
}
@Override
public void removeByKid(String kid) {
vectorStore.removeByKid(kid);
}
@Override
public List<Double> getQueryVector(String query, String kid) {
return vectorization.singleVectorization(query,kid);
}
@Override
public void createSchema(String kid) {
vectorStore.newSchema(kid);
}
@Override
public void removeByKidAndFid(String kid, String fid) {
vectorStore.removeByKidAndFid(kid,fid);
}
@Override
public void saveFragment(String kid, String docId, String fid, String content) {
List<String> chunkList = new ArrayList<>();
List<String> fidList = new ArrayList<>();
chunkList.add(content);
fidList.add(fid);
storeEmbeddings(chunkList,kid,docId,fidList);
}
}

View File

@@ -0,0 +1,114 @@
package org.ruoyi.service.impl;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.ruoyi.domain.vo.KnowledgeAttachVo;
import org.springframework.stereotype.Service;
import org.ruoyi.domain.bo.KnowledgeAttachBo;
import org.ruoyi.domain.KnowledgeAttach;
import org.ruoyi.mapper.KnowledgeAttachMapper;
import org.ruoyi.service.IKnowledgeAttachService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 知识库附件Service业务层处理
*
* @author ageerle
* @date 2025-04-08
*/
@RequiredArgsConstructor
@Service
public class KnowledgeAttachServiceImpl implements IKnowledgeAttachService {
private final KnowledgeAttachMapper baseMapper;
/**
* 查询知识库附件
*/
@Override
public KnowledgeAttachVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 查询知识库附件列表
*/
@Override
public TableDataInfo<KnowledgeAttachVo> queryPageList(KnowledgeAttachBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<KnowledgeAttach> lqw = buildQueryWrapper(bo);
Page<KnowledgeAttachVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询知识库附件列表
*/
@Override
public List<KnowledgeAttachVo> queryList(KnowledgeAttachBo bo) {
LambdaQueryWrapper<KnowledgeAttach> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<KnowledgeAttach> buildQueryWrapper(KnowledgeAttachBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<KnowledgeAttach> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getKid()), KnowledgeAttach::getKid, bo.getKid());
lqw.eq(StringUtils.isNotBlank(bo.getDocId()), KnowledgeAttach::getDocId, bo.getDocId());
lqw.like(StringUtils.isNotBlank(bo.getDocName()), KnowledgeAttach::getDocName, bo.getDocName());
lqw.eq(StringUtils.isNotBlank(bo.getDocType()), KnowledgeAttach::getDocType, bo.getDocType());
lqw.eq(StringUtils.isNotBlank(bo.getContent()), KnowledgeAttach::getContent, bo.getContent());
return lqw;
}
/**
* 新增知识库附件
*/
@Override
public Boolean insertByBo(KnowledgeAttachBo bo) {
KnowledgeAttach add = MapstructUtils.convert(bo, KnowledgeAttach.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改知识库附件
*/
@Override
public Boolean updateByBo(KnowledgeAttachBo bo) {
KnowledgeAttach update = MapstructUtils.convert(bo, KnowledgeAttach.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(KnowledgeAttach entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除知识库附件
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@@ -0,0 +1,113 @@
package org.ruoyi.service.impl;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.ruoyi.domain.vo.KnowledgeFragmentVo;
import org.springframework.stereotype.Service;
import org.ruoyi.domain.bo.KnowledgeFragmentBo;
import org.ruoyi.domain.KnowledgeFragment;
import org.ruoyi.mapper.KnowledgeFragmentMapper;
import org.ruoyi.service.IKnowledgeFragmentService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 知识片段Service业务层处理
*
* @author ageerle
* @date 2025-04-08
*/
@RequiredArgsConstructor
@Service
public class KnowledgeFragmentServiceImpl implements IKnowledgeFragmentService {
private final KnowledgeFragmentMapper baseMapper;
/**
* 查询知识片段
*/
@Override
public KnowledgeFragmentVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 查询知识片段列表
*/
@Override
public TableDataInfo<KnowledgeFragmentVo> queryPageList(KnowledgeFragmentBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<KnowledgeFragment> lqw = buildQueryWrapper(bo);
Page<KnowledgeFragmentVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询知识片段列表
*/
@Override
public List<KnowledgeFragmentVo> queryList(KnowledgeFragmentBo bo) {
LambdaQueryWrapper<KnowledgeFragment> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<KnowledgeFragment> buildQueryWrapper(KnowledgeFragmentBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<KnowledgeFragment> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getKid()), KnowledgeFragment::getKid, bo.getKid());
lqw.eq(StringUtils.isNotBlank(bo.getDocId()), KnowledgeFragment::getDocId, bo.getDocId());
lqw.eq(StringUtils.isNotBlank(bo.getFid()), KnowledgeFragment::getFid, bo.getFid());
lqw.eq(bo.getIdx() != null, KnowledgeFragment::getIdx, bo.getIdx());
lqw.eq(StringUtils.isNotBlank(bo.getContent()), KnowledgeFragment::getContent, bo.getContent());
return lqw;
}
/**
* 新增知识片段
*/
@Override
public Boolean insertByBo(KnowledgeFragmentBo bo) {
KnowledgeFragment add = MapstructUtils.convert(bo, KnowledgeFragment.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改知识片段
*/
@Override
public Boolean updateByBo(KnowledgeFragmentBo bo) {
KnowledgeFragment update = MapstructUtils.convert(bo, KnowledgeFragment.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(KnowledgeFragment entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除知识片段
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}

View File

@@ -0,0 +1,120 @@
package org.ruoyi.service.impl;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.ruoyi.domain.vo.KnowledgeInfoVo;
import org.springframework.stereotype.Service;
import org.ruoyi.domain.bo.KnowledgeInfoBo;
import org.ruoyi.domain.KnowledgeInfo;
import org.ruoyi.mapper.KnowledgeInfoMapper;
import org.ruoyi.service.IKnowledgeInfoService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 知识库Service业务层处理
*
* @author ageerle
* @date 2025-04-08
*/
@RequiredArgsConstructor
@Service
public class KnowledgeInfoServiceImpl implements IKnowledgeInfoService {
private final KnowledgeInfoMapper baseMapper;
/**
* 查询知识库
*/
@Override
public KnowledgeInfoVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 查询知识库列表
*/
@Override
public TableDataInfo<KnowledgeInfoVo> queryPageList(KnowledgeInfoBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<KnowledgeInfo> lqw = buildQueryWrapper(bo);
Page<KnowledgeInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询知识库列表
*/
@Override
public List<KnowledgeInfoVo> queryList(KnowledgeInfoBo bo) {
LambdaQueryWrapper<KnowledgeInfo> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<KnowledgeInfo> buildQueryWrapper(KnowledgeInfoBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<KnowledgeInfo> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getKid()), KnowledgeInfo::getKid, bo.getKid());
lqw.eq(bo.getUid() != null, KnowledgeInfo::getUid, bo.getUid());
lqw.like(StringUtils.isNotBlank(bo.getKname()), KnowledgeInfo::getKname, bo.getKname());
lqw.eq(bo.getShare() != null, KnowledgeInfo::getShare, bo.getShare());
lqw.eq(StringUtils.isNotBlank(bo.getDescription()), KnowledgeInfo::getDescription, bo.getDescription());
lqw.eq(StringUtils.isNotBlank(bo.getKnowledgeSeparator()), KnowledgeInfo::getKnowledgeSeparator, bo.getKnowledgeSeparator());
lqw.eq(StringUtils.isNotBlank(bo.getQuestionSeparator()), KnowledgeInfo::getQuestionSeparator, bo.getQuestionSeparator());
lqw.eq(bo.getOverlapChar() != null, KnowledgeInfo::getOverlapChar, bo.getOverlapChar());
lqw.eq(bo.getRetrieveLimit() != null, KnowledgeInfo::getRetrieveLimit, bo.getRetrieveLimit());
lqw.eq(bo.getTextBlockSize() != null, KnowledgeInfo::getTextBlockSize, bo.getTextBlockSize());
lqw.eq(StringUtils.isNotBlank(bo.getVector()), KnowledgeInfo::getVector, bo.getVector());
lqw.eq(StringUtils.isNotBlank(bo.getVectorModel()), KnowledgeInfo::getVectorModel, bo.getVectorModel());
return lqw;
}
/**
* 新增知识库
*/
@Override
public Boolean insertByBo(KnowledgeInfoBo bo) {
KnowledgeInfo add = MapstructUtils.convert(bo, KnowledgeInfo.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改知识库
*/
@Override
public Boolean updateByBo(KnowledgeInfoBo bo) {
KnowledgeInfo update = MapstructUtils.convert(bo, KnowledgeInfo.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(KnowledgeInfo entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 批量删除知识库
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
}