新增可搜索状态字段

This commit is contained in:
luke 2025-06-20 17:13:18 +08:00
parent 4f439361b7
commit f2bd42005a
13 changed files with 76 additions and 6 deletions

View File

@ -88,6 +88,7 @@ CREATE TABLE IF NOT EXISTS oss_upload_record (
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键', id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键',
file_name VARCHAR(255) NOT NULL COMMENT '文件名', file_name VARCHAR(255) NOT NULL COMMENT '文件名',
local_rela_file_path VARCHAR(512) NOT NULL DEFAULT 'UNKNOWN' COMMENT '本地文件相对路径', local_rela_file_path VARCHAR(512) NOT NULL DEFAULT 'UNKNOWN' COMMENT '本地文件相对路径',
searchable_status INT NOT NULL DEFAULT 0 COMMENT '可搜索状态0-初始状态1-可搜索, 2-导入失败, 99-禁止搜索'
bucket_name VARCHAR(128) NOT NULL COMMENT '目标 bucket 名', bucket_name VARCHAR(128) NOT NULL COMMENT '目标 bucket 名',
uploader VARCHAR(128) NOT NULL COMMENT '上传人用户名', uploader VARCHAR(128) NOT NULL COMMENT '上传人用户名',
upload_time DATETIME NOT NULL COMMENT '上传时间', upload_time DATETIME NOT NULL COMMENT '上传时间',

View File

@ -0,0 +1,22 @@
package com.knowledge.base.domain.common.enums;
/**
* @author Luke.ye
* @date 2025/6/20 16:41
*/
public enum SearchableStatusEnum {
INIT(0, "未开始进行导入"),
SUCCESS(1, "成功"),
FAILED(2, "导入失败"),
PROHIBITED(99, "用户禁止文件被检索"),
;
public int code;
private String desc;
SearchableStatusEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
}

View File

@ -9,6 +9,7 @@ public class OSRecordDO {
private Long id; private Long id;
private String fileName; private String fileName;
private String localRelaFilePath; private String localRelaFilePath;
private int searchableStatus;
private String bucketName; private String bucketName;
private String uploader; private String uploader;
private String objectPath; private String objectPath;

View File

@ -25,6 +25,14 @@ public interface OSRecordRepository {
*/ */
Optional<OSRecord> getLatestRecordByRelaPath(String localRelaFilePath); Optional<OSRecord> getLatestRecordByRelaPath(String localRelaFilePath);
/**
* 更新上传记录中文档的可搜索状态
* @param localRelaFilePath
* @param searchableStatus
* @return
*/
boolean updateSearchableStatusByRelaPath(String localRelaFilePath, int searchableStatus);
/** /**
* 批量获取 * 批量获取
* @param recordIds * @param recordIds

View File

@ -14,6 +14,7 @@ public class OSRecord {
private String fileName; private String fileName;
private String localRelaFilePath; private String localRelaFilePath;
private int searchableStatus;
private String bucketName; private String bucketName;
private String uploader; private String uploader;
private String objectPath; private String objectPath;

View File

@ -32,6 +32,14 @@ public interface FileDomainService {
*/ */
Optional<OSRecordDO> getLatestRecordByRelaPath(String localRelaFilePath); Optional<OSRecordDO> getLatestRecordByRelaPath(String localRelaFilePath);
/**
* 更新上传记录中文档的可搜索状态
* @param localRelaFilePath
* @param searchableStatus
* @return
*/
boolean updateSearchableStatusByRelaPath(String localRelaFilePath, int searchableStatus);
/** /**
* 批量获取上传记录 * 批量获取上传记录
* @param recordIds * @param recordIds
@ -45,4 +53,6 @@ public interface FileDomainService {
* @return * @return
*/ */
boolean batchRemoveOSFiles(List<Long> recordIds); boolean batchRemoveOSFiles(List<Long> recordIds);
} }

View File

@ -8,6 +8,7 @@ import cn.hutool.json.JSONUtil;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.knowledge.base.domain.common.enums.DocMetaPropEnum; import com.knowledge.base.domain.common.enums.DocMetaPropEnum;
import com.knowledge.base.domain.common.enums.SearchableStatusEnum;
import com.knowledge.base.domain.doc.model.FileEsField; import com.knowledge.base.domain.doc.model.FileEsField;
import com.knowledge.base.domain.doc.model.FileEsModel; import com.knowledge.base.domain.doc.model.FileEsModel;
import com.knowledge.base.domain.doc.model.OSRecordDO; import com.knowledge.base.domain.doc.model.OSRecordDO;
@ -143,9 +144,10 @@ public abstract class AbstractBaseFileImporter implements DocumentImporter {
// === Step 5: 构建待写入文档 === // === Step 5: 构建待写入文档 ===
FileEsModel fileEsModel = buildDocument(fileNameWithSuffix, localRelaFilePath, content, localMTime, extInfo); FileEsModel fileEsModel = buildDocument(fileNameWithSuffix, localRelaFilePath, content, localMTime, extInfo);
// === Step 6: 写入 Elasticsearch 并更新缓存 === // === Step 6: 写入 Elasticsearch 并更新 导入状态&缓存 ===
esGateway.saveDoc(fileEsModel); boolean saved = esGateway.saveDoc(fileEsModel);
logger.info("导入成功: {}", localRelaFilePath); logger.info("导入结束: relativePah: {}, status: {}", localRelaFilePath, saved);
fileDomainService.updateSearchableStatusByRelaPath(localRelaFilePath, saved ? SearchableStatusEnum.SUCCESS.code : SearchableStatusEnum.FAILED.code);
String metaJson = transToMetaJson(BeanUtil.beanToMap(fileEsModel, false, true)); String metaJson = transToMetaJson(BeanUtil.beanToMap(fileEsModel, false, true));
fileCacheService.cacheMeta(localRelaFilePath, metaJson, ConstantConfig.FILE_META_CACHE_EXPIRED_MINUTES); fileCacheService.cacheMeta(localRelaFilePath, metaJson, ConstantConfig.FILE_META_CACHE_EXPIRED_MINUTES);

View File

@ -78,6 +78,11 @@ public class FileDomainServiceImpl implements FileDomainService {
return Optional.of(BeanConvertUtil.convert(osRecordOpt.get(), OSRecordDO.class)); return Optional.of(BeanConvertUtil.convert(osRecordOpt.get(), OSRecordDO.class));
} }
@Override
public boolean updateSearchableStatusByRelaPath(String localRelaFilePath, int searchableStatus) {
return osRecordRepository.updateSearchableStatusByRelaPath(localRelaFilePath, searchableStatus);
}
@Override @Override
public List<OSRecordDO> batchQueryOSRecord(List<Long> recordIds) { public List<OSRecordDO> batchQueryOSRecord(List<Long> recordIds) {
return BeanConvertUtil.convertList(osRecordRepository.batchQueryOSRecord(recordIds), OSRecordDO.class); return BeanConvertUtil.convertList(osRecordRepository.batchQueryOSRecord(recordIds), OSRecordDO.class);

View File

@ -116,6 +116,7 @@ public class FileQueryController {
item.put("fileName", dto.getFileName()); item.put("fileName", dto.getFileName());
item.put("url", dto.getUrl()); item.put("url", dto.getUrl());
item.put("recordId", dto.getId()); item.put("recordId", dto.getId());
item.put("searchableStatus", dto.getSearchableStatus());
// 格式化上传时间 // 格式化上传时间
if (StrUtil.isNotBlank(dto.getUploadTime())) { if (StrUtil.isNotBlank(dto.getUploadTime())) {

View File

@ -6,6 +6,7 @@ import cn.hutool.core.util.StrUtil;
import com.knowledge.base.application.service.DocAppService; import com.knowledge.base.application.service.DocAppService;
import com.knowledge.base.application.service.UserAppService; import com.knowledge.base.application.service.UserAppService;
import com.knowledge.base.domain.common.enums.DocMetaPropEnum; import com.knowledge.base.domain.common.enums.DocMetaPropEnum;
import com.knowledge.base.domain.common.enums.SearchableStatusEnum;
import com.knowledge.base.domain.doc.service.FileImporterDispatcher; import com.knowledge.base.domain.doc.service.FileImporterDispatcher;
import com.knowledge.base.domain.doc.service.iface.DocumentImporter; import com.knowledge.base.domain.doc.service.iface.DocumentImporter;
import com.knowledge.base.infrastructure.cache.iface.FileCacheService; import com.knowledge.base.infrastructure.cache.iface.FileCacheService;
@ -206,6 +207,7 @@ public class FileWriteController {
OSRecordDTO dto = new OSRecordDTO(); OSRecordDTO dto = new OSRecordDTO();
dto.setFileName(originFileNameWithSuffix); dto.setFileName(originFileNameWithSuffix);
dto.setLocalRelaFilePath(allowSaveToLocal ? localRelaFilePath : ConstantConfig.UNKNOWN_LOCAL_RELA_PATH); dto.setLocalRelaFilePath(allowSaveToLocal ? localRelaFilePath : ConstantConfig.UNKNOWN_LOCAL_RELA_PATH);
dto.setSearchableStatus(allowSaveToLocal ? SearchableStatusEnum.INIT.code : SearchableStatusEnum.PROHIBITED.code);
dto.setUrl(url); dto.setUrl(url);
dto.setUploader(uploader); dto.setUploader(uploader);
dto.setBucketName(bucket); dto.setBucketName(bucket);

View File

@ -8,10 +8,12 @@ public class OSRecordDTO {
private String fileName; private String fileName;
/** /**
* 本地相对路径文件名不为空则文件可搜索 * 本地相对路径文件名
*/ */
private String localRelaFilePath; private String localRelaFilePath;
private int searchableStatus;
private String bucketName; private String bucketName;
private String uploader; private String uploader;
private String objectPath; private String objectPath;

View File

@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.knowledge.base.domain.common.model.PageResult; import com.knowledge.base.domain.common.model.PageResult;
@ -50,6 +51,16 @@ public class OSRecordRepositoryImpl implements OSRecordRepository {
return Optional.ofNullable(fileLatestRecord); return Optional.ofNullable(fileLatestRecord);
} }
@Override
public boolean updateSearchableStatusByRelaPath(String localRelaFilePath, int searchableStatus) {
UpdateWrapper<OSRecord> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("local_rela_file_path", localRelaFilePath)
.set("searchable_status", searchableStatus);
int rows = osRecordMapper.update(null, updateWrapper);
return rows > 0;
}
@Override @Override
public List<OSRecord> batchQueryOSRecord(List<Long> recordIds) { public List<OSRecord> batchQueryOSRecord(List<Long> recordIds) {
if(CollectionUtil.isEmpty(recordIds)) { if(CollectionUtil.isEmpty(recordIds)) {

View File

@ -11,6 +11,7 @@ import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder; import org.elasticsearch.index.query.BoolQueryBuilder;
@ -19,6 +20,7 @@ import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder; import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.reindex.BulkByScrollResponse; import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest; import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchRequest;
@ -180,14 +182,16 @@ public class FileElasticsearchGateway {
/** /**
* 写入/更新文档 * 写入/更新文档
*/ */
public void saveDoc(FileEsModel docModel) { public boolean saveDoc(FileEsModel docModel) {
try { try {
String docId = docModel.buildDocId(); String docId = docModel.buildDocId();
Map<String, Object> source = BeanUtil.beanToMap(docModel, false, true); Map<String, Object> source = BeanUtil.beanToMap(docModel, false, true);
IndexRequest request = new IndexRequest(INDEX_NAME).id(docId).source(source); IndexRequest request = new IndexRequest(INDEX_NAME).id(docId).source(source);
esClient.index(request, RequestOptions.DEFAULT); IndexResponse response = esClient.index(request, RequestOptions.DEFAULT);
return response.status().getStatus() == RestStatus.OK.getStatus();
} catch (Exception e) { } catch (Exception e) {
log.error("ES 写入文档失败: doc={}", docModel, e); log.error("ES 写入文档失败: doc={}", docModel, e);
return false;
} }
} }