chore: initialize qiming workspace repository

This commit is contained in:
Codex
2026-05-29 14:22:48 +08:00
commit bfd67a0f2c
10750 changed files with 1885711 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.xspaceagi</groupId>
<artifactId>app-platform-knowledge</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>app-platform-knowledge-api</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.xspaceagi</groupId>
<artifactId>app-platform-knowledge-core-application</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,224 @@
package com.xspaceagi.knowledge.api;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.xspaceagi.knowledge.assembler.KnowledgeModelApiAssembler;
import com.xspaceagi.knowledge.core.application.service.IKnowledgeConfigApplicationService;
import com.xspaceagi.knowledge.core.application.vo.KnowledgeConfigApplicationRequestVo;
import com.xspaceagi.knowledge.core.infra.dao.entity.KnowledgeConfig;
import com.xspaceagi.knowledge.core.infra.dao.service.KnowledgeConfigService;
import com.xspaceagi.knowledge.core.infra.translator.IKnowledgeConfigTranslator;
import com.xspaceagi.knowledge.domain.model.KnowledgeConfigModel;
import com.xspaceagi.knowledge.domain.repository.IKnowledgeConfigRepository;
import com.xspaceagi.knowledge.domain.service.IKnowledgeConfigDomainService;
import com.xspaceagi.knowledge.sdk.request.KnowledgeConfigRequestVo;
import com.xspaceagi.knowledge.sdk.request.KnowledgeCreateRequestVo;
import com.xspaceagi.knowledge.sdk.response.KnowledgeConfigResponseVo;
import com.xspaceagi.knowledge.sdk.response.KnowledgeConfigVo;
import com.xspaceagi.knowledge.sdk.sevice.IKnowledgeConfigRpcService;
import com.xspaceagi.system.application.dto.permission.BindRestrictionTargetsDto;
import com.xspaceagi.system.application.service.SysSubjectPermissionApplicationService;
import com.xspaceagi.system.domain.log.LogRecordPrint;
import com.xspaceagi.system.sdk.server.IUserRpcService;
import com.xspaceagi.system.spec.common.UserContext;
import com.xspaceagi.system.spec.enums.PermissionSubjectTypeEnum;
import com.xspaceagi.system.spec.enums.ErrorCodeEnum;
import com.xspaceagi.system.spec.exception.BizException;
import com.xspaceagi.system.spec.exception.BizExceptionCodeEnum;
import com.xspaceagi.system.spec.page.PageQueryVo;
import com.xspaceagi.system.spec.page.SuperPage;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Slf4j
@Service
public class KnowledgeConfigRpcService implements IKnowledgeConfigRpcService {
@Resource
private IKnowledgeConfigApplicationService knowledgeConfigApplicationService;
@Resource
private IKnowledgeConfigDomainService knowledgeConfigDomainService;
@Resource
private KnowledgeConfigService knowledgeConfigService;
@Resource
private IKnowledgeConfigTranslator iKnowledgeConfigTranslator;
@Resource
private IUserRpcService userRpcService;
@Resource
private SysSubjectPermissionApplicationService sysSubjectPermissionApplicationService;
@Resource
private IKnowledgeConfigRepository knowledgeConfigRepository;
@Override
public KnowledgeConfigResponseVo queryListKnowledgeConfig(KnowledgeConfigRequestVo knowledgeConfigRequestVo) {
PageQueryVo<KnowledgeConfigApplicationRequestVo> pageQueryVo = new PageQueryVo<>();
var current = 1L;
if (Objects.nonNull(knowledgeConfigRequestVo.getPage())) {
current = knowledgeConfigRequestVo.getPage();
}
var pageSize = 100L;
if (Objects.nonNull(knowledgeConfigRequestVo.getPageSize())) {
pageSize = knowledgeConfigRequestVo.getPageSize();
}
pageQueryVo.setCurrent(current);
pageQueryVo.setPageSize(pageSize);
KnowledgeConfigApplicationRequestVo knowledgeConfigApplicationRequestVo = KnowledgeConfigApplicationRequestVo
.convert(knowledgeConfigRequestVo);
pageQueryVo.setQueryFilter(knowledgeConfigApplicationRequestVo);
var modelPage = knowledgeConfigApplicationService.querySearchConfigs(pageQueryVo);
//新增开始
if(current == 1L) {
List<KnowledgeConfigModel> extKnowledgeConfigModel = knowledgeConfigRepository.queryListByIds(knowledgeConfigRequestVo.getKnowledgeIds());
modelPage.getRecords().addAll(extKnowledgeConfigModel);
}
//新增结束
var voList = modelPage.getRecords().stream()
.map(KnowledgeConfigModel::convertFromModel)
.toList();
// 补充用户信息,比如:昵称
var userIds = modelPage.getRecords().stream()
.map(KnowledgeConfigModel::getCreatorId)
.filter(Objects::nonNull)
.toList();
var userList = this.userRpcService.queryUserListByIds(userIds);
var userMap = userList.stream()
.collect(Collectors.toMap(UserContext::getUserId, userContext -> userContext));
voList.forEach(item -> {
UserContext userContext = userMap.get(item.getCreatorId());
if (userContext != null) {
item.setCreatorName(userContext.getUserName());
item.setCreatorNickName(userContext.getNickName());
item.setCreatorAvatar(userContext.getAvatar());
}
});
SuperPage<KnowledgeConfigVo> iPage = SuperPage.build(modelPage, voList);
iPage.setCurrent(pageQueryVo.getCurrent());
iPage.setSize(pageQueryVo.getPageSize());
var response = new KnowledgeConfigResponseVo();
response.setConfigPage(iPage);
return response;
}
@LogRecordPrint(content = "[知识库文档]-创建知识库")
@Override
public Long createKnowledgeConfig(KnowledgeCreateRequestVo createRequestVo) {
var model = KnowledgeModelApiAssembler.convertFromVo(createRequestVo);
// 补充用户信息,比如:昵称
var userId = createRequestVo.getUserId();
var userIds = Lists.newArrayList(userId);
var userList = this.userRpcService.queryUserListByIds(userIds);
var userContext = userList.stream()
.findFirst()
.orElse(UserContext.builder()
.userId(userId)
.userName("未知用户")
.nickName("未知用户")
.build());
model.setCreatorName(userContext.getUserName());
model.setCreatorId(userId);
var dataId = this.knowledgeConfigDomainService.addInfo(model, userContext);
return dataId;
}
@Override
public KnowledgeConfigVo queryKnowledgeConfigById(Long id) {
var model = this.knowledgeConfigDomainService.queryOneInfoById(id);
return KnowledgeConfigModel.convertFromModel(model);
}
@Override
public Long countTotalKnowledge(Long userId) {
return knowledgeConfigDomainService.countTotalKnowledge(userId);
}
@Override
public IPage<KnowledgeConfigVo> queryListForManage(Integer pageNo, Integer pageSize, String name,
java.util.List<Long> creatorIds, Long spaceId, Integer accessControl) {
LambdaQueryWrapper<KnowledgeConfig> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(StringUtils.isNotBlank(name), KnowledgeConfig::getName, name);
queryWrapper.eq(spaceId != null, KnowledgeConfig::getSpaceId, spaceId);
queryWrapper.in(creatorIds != null && !creatorIds.isEmpty(), KnowledgeConfig::getCreatorId, creatorIds);
queryWrapper.eq(accessControl != null, KnowledgeConfig::getAccessControl, accessControl);
queryWrapper.inSql(KnowledgeConfig::getSpaceId, "SELECT id FROM space where yn=0 ");
queryWrapper.orderByDesc(KnowledgeConfig::getId);
return knowledgeConfigService.page(new Page<>(pageNo, pageSize), queryWrapper).convert(knowledgeConfig -> {
return KnowledgeConfigModel.convertFromModel(iKnowledgeConfigTranslator.convertToModel(knowledgeConfig));
});
}
@Override
public void deleteForManage(Long id) {
// 调用领域服务删除
var model = knowledgeConfigDomainService.queryOneInfoById(id);
if (model != null) {
knowledgeConfigDomainService.deleteById(id, com.xspaceagi.system.spec.common.UserContext.builder()
.userId(0L)
.userName("admin")
.tenantId(model.getTenantId())
.build());
}
}
@Override
public List<KnowledgeConfigVo> listByIds(List<Long> ids) {
List<KnowledgeConfigModel> modelList = knowledgeConfigDomainService.queryListByIds(ids);
if (CollectionUtils.isEmpty(modelList)) {
return List.of();
}
return modelList.stream().map(KnowledgeConfigModel::convertFromModel).toList();
}
@Override
public void updateAccessControlStatus(Long id, Integer status, UserContext userContext) {
var model = knowledgeConfigDomainService.queryOneInfoById(id);
if (model == null) {
throw BizException.of(ErrorCodeEnum.INVALID_PARAM, BizExceptionCodeEnum.knowledgeNotFoundSimple);
}
int oldStatus = model.getAccessControl() != null ? model.getAccessControl() : 0;
int newStatus = status == null ? 0 : status;
model.setAccessControl(status);
knowledgeConfigDomainService.updateInfo(model, userContext);
// 如果从受限(1)切换为不受限(0),需要删除原有主体访问权限绑定并清除缓存
if (oldStatus == 1 && newStatus == 0) {
// 不设置 roleIds 和 groupIds内部会按空集合处理表示清空所有绑定
sysSubjectPermissionApplicationService.bindRestrictionTargets(
PermissionSubjectTypeEnum.KNOWLEDGE,
id,
new BindRestrictionTargetsDto(),
userContext
);
}
}
}

View File

@@ -0,0 +1,33 @@
package com.xspaceagi.knowledge.api;
import com.xspaceagi.knowledge.domain.model.KnowledgeDocumentModel;
import com.xspaceagi.knowledge.domain.service.IKnowledgeDocumentDomainService;
import com.xspaceagi.knowledge.sdk.request.KnowledgeDocumentRequestVo;
import com.xspaceagi.knowledge.sdk.response.KnowledgeDocumentResponseVo;
import com.xspaceagi.knowledge.sdk.sevice.IKnowledgeDocumentSearchRpcService;
import com.xspaceagi.system.domain.log.LogRecordPrint;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class KnowledgeDocumentSearchRpcService implements IKnowledgeDocumentSearchRpcService {
@Resource
private IKnowledgeDocumentDomainService knowledgeDocumentDomainService;
@LogRecordPrint(content = "[知识库文档]-根据知识库id查询文档")
@Override
public KnowledgeDocumentResponseVo documentSearch(KnowledgeDocumentRequestVo requestVo) {
var docList = this.knowledgeDocumentDomainService.queryDocByKbId(requestVo.getKbId());
var ans = docList.stream()
.map(KnowledgeDocumentModel::convertFromModel)
.toList();
KnowledgeDocumentResponseVo responseVo = new KnowledgeDocumentResponseVo();
responseVo.setDocumentVoList(ans);
return responseVo;
}
}

View File

@@ -0,0 +1,85 @@
package com.xspaceagi.knowledge.api;
import com.xspaceagi.knowledge.core.infra.rpc.SearchRpcService;
import com.xspaceagi.knowledge.core.infra.rpc.vo.KnowledgeSearchDocument;
import com.xspaceagi.knowledge.sdk.request.KnowledgeFullTextSearchRequestVo;
import com.xspaceagi.knowledge.sdk.response.KnowledgeFullTextSearchResponseVo;
import com.xspaceagi.knowledge.sdk.response.KnowledgeFullTextSearchResultVo;
import com.xspaceagi.knowledge.sdk.sevice.IKnowledgeFullTextSearchRpcService;
import com.xspaceagi.log.sdk.request.DocumentSearchRequest;
import com.xspaceagi.log.sdk.vo.SearchResult;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 知识库全文检索 RPC 服务实现
*
* @author system
* @date 2025-03-31
*/
@Slf4j
@Service
public class KnowledgeFullTextSearchRpcService implements IKnowledgeFullTextSearchRpcService {
@Resource
private SearchRpcService searchRpcService;
@Override
public KnowledgeFullTextSearchResponseVo search(KnowledgeFullTextSearchRequestVo requestVo) {
long startTime = System.currentTimeMillis();
log.info("全文检索RPC请求: tenantId={}, kbIds={}, queryText={}, topK={}",
requestVo.getTenantId(), requestVo.getKbIds(), requestVo.getQueryText(), requestVo.getTopK());
List<Map<String, Object>> filterFieldsAndValues = new ArrayList<>();
filterFieldsAndValues.add(Map.of("tenantId", requestVo.getTenantId()));
if (requestVo.getDocIds() != null && requestVo.getDocIds().size() > 0) {
filterFieldsAndValues.add(Map.of("docId", requestVo.getDocIds()));
}
if (requestVo.getKbIds() != null && requestVo.getKbIds().size() > 0) {
filterFieldsAndValues.add(Map.of("kbId", requestVo.getKbIds()));
}
DocumentSearchRequest documentSearchRequest = DocumentSearchRequest.builder()
.searchDocumentClazz(KnowledgeSearchDocument.class)
.searchFields(List.of("rawText"))
.keyword(requestVo.getQueryText()).filterFieldsAndValues(filterFieldsAndValues).build();
SearchResult search = searchRpcService.search(documentSearchRequest);
// 3. 转换返回结果
KnowledgeFullTextSearchResponseVo response = new KnowledgeFullTextSearchResponseVo();
response.setResults(search.getItems().stream()
.map(this::convertToVo)
.collect(Collectors.toList()));
response.setCostTimeMs(System.currentTimeMillis() - startTime);
log.info("全文检索RPC完成: kbIds={}, resultCount={}, costTimeMs={}",
requestVo.getKbIds(), response.getResults().size(), response.getCostTimeMs());
return response;
}
/**
* 转换 Domain Model 为 SDK VO
*/
private KnowledgeFullTextSearchResultVo convertToVo(SearchResult.SearchResultItem item) {
KnowledgeSearchDocument knowledgeSearchDocument = (KnowledgeSearchDocument) item.getDocument();
KnowledgeFullTextSearchResultVo vo = new KnowledgeFullTextSearchResultVo();
vo.setRawSegmentId(Long.parseLong(knowledgeSearchDocument.getId()));
vo.setDocId(knowledgeSearchDocument.getDocId());
vo.setKbId(knowledgeSearchDocument.getKbId());
vo.setRawText(knowledgeSearchDocument.getRawText());
vo.setScore(item.getScore().floatValue());
vo.setDocumentName(knowledgeSearchDocument.getDocumentName());
return vo;
}
}

View File

@@ -0,0 +1,41 @@
package com.xspaceagi.knowledge.api;
import com.xspaceagi.knowledge.core.application.service.IKnowledgeQaSegmentApplicationService;
import com.xspaceagi.knowledge.domain.dto.qa.QAQueryDto;
import com.xspaceagi.knowledge.domain.dto.qa.QAResDto;
import com.xspaceagi.knowledge.sdk.request.KnowledgeQaRequestVo;
import com.xspaceagi.knowledge.sdk.response.KnowledgeQaResponseVo;
import com.xspaceagi.knowledge.sdk.sevice.IKnowledgeQaSearchRpcService;
import com.xspaceagi.system.domain.log.LogRecordPrint;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
@Slf4j
@Service
public class KnowledgeQaSearchRpcService implements IKnowledgeQaSearchRpcService {
@Resource
private IKnowledgeQaSegmentApplicationService knowledgeQaSegmentApplicationService;
@LogRecordPrint(content = "[知识库文档]-知识库问答查询搜索")
@Override
public KnowledgeQaResponseVo search(KnowledgeQaRequestVo requestVo) {
QAQueryDto qaQueryDto = QAQueryDto.convertToDto(requestVo);
List<QAResDto> dataList = this.knowledgeQaSegmentApplicationService.search(qaQueryDto, requestVo.isIgnoreDocStatus());
var response = dataList.stream()
.map(QAResDto::convertToVo)
.toList();
KnowledgeQaResponseVo knowledgeQaResponseVo = new KnowledgeQaResponseVo();
knowledgeQaResponseVo.setQaVoList(response);
return knowledgeQaResponseVo;
}
}

View File

@@ -0,0 +1,46 @@
package com.xspaceagi.knowledge.api.task;
import com.xspaceagi.knowledge.domain.service.IKnowledgeTaskArchiveAndRetryDomainService;
import com.xspaceagi.system.sdk.service.AbstractTaskExecuteService;
import com.xspaceagi.system.sdk.service.ScheduleTaskApiService;
import com.xspaceagi.system.sdk.service.dto.ScheduleTaskDto;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Map;
@Slf4j
@Component("knowledgeAutoArchiveTask")
public class KnowledgeAutoArchiveTask extends AbstractTaskExecuteService {
@Resource
private ScheduleTaskApiService scheduleTaskApiService;
@Resource
private IKnowledgeTaskArchiveAndRetryDomainService knowledgeTaskArchiveAndRetryDomainService;
@PostConstruct
public void init() {
scheduleTaskApiService.start(ScheduleTaskDto.builder()
.taskId("knowledgeAutoArchiveTask")
.beanId("knowledgeAutoArchiveTask")
.maxExecTimes(Long.MAX_VALUE)
.cron(ScheduleTaskDto.Cron.EVERYDAY_0_2.getCron())
.params(Map.of())
.build());
}
@Override
protected boolean execute(ScheduleTaskDto scheduleTaskDto) {
log.info("knowledgeAutoArchiveTask 自动运行任务开始执行");
try {
this.knowledgeTaskArchiveAndRetryDomainService.archiveTask(15);
log.info("knowledgeAutoArchiveTask 自动运行任务执行结束");
} catch (Exception e) {
log.error("Auto-run task failed", e);
}
return false;//false会一直循环执行
}
}

View File

@@ -0,0 +1,68 @@
package com.xspaceagi.knowledge.api.task;
import com.xspaceagi.knowledge.core.application.service.IKnowledgeQaSegmentApplicationService;
import com.xspaceagi.system.sdk.service.AbstractTaskExecuteService;
import com.xspaceagi.system.sdk.service.ScheduleTaskApiService;
import com.xspaceagi.system.sdk.service.dto.ScheduleTaskDto;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
@Slf4j
@Component("knowledgeAutoGenerateQaEmbeddingsTask")
public class KnowledgeAutoGenerateQaEmbeddingsTask extends AbstractTaskExecuteService {
@Resource
private ScheduleTaskApiService scheduleTaskApiService;
@Resource
private IKnowledgeQaSegmentApplicationService knowledgeQaSegmentApplicationService;
@PostConstruct
public void init() {
scheduleTaskApiService.start(ScheduleTaskDto.builder()
.taskId("knowledgeAutoGenerateQaEmbeddingsTask")
.beanId("knowledgeAutoGenerateQaEmbeddingsTask")
.maxExecTimes(Long.MAX_VALUE)
.cron(ScheduleTaskDto.Cron.EVERY_5_MINUTE.getCron())
.params(Map.of())
.build());
}
@Override
protected boolean execute(ScheduleTaskDto scheduleTaskDto) {
log.info("knowledgeAutoGenerateQaEmbeddingsTask 自动运行任务开始执行");
try {
this.autoGenerateQaEmbeddings();
log.info("knowledgeAutoGenerateQaEmbeddingsTask 自动运行任务执行结束");
} catch (Exception e) {
log.error("Auto-run task failed", e);
}
return false;//false会一直循环执行
}
public void autoGenerateQaEmbeddings() {
Integer reqId = ThreadLocalRandom.current().nextInt(100, 999999);
MDC.put("tid", reqId + "" + Instant.now().toEpochMilli());
// 分页查询,直到没有数据为止
int pageNum = 1;
int pageSize = 500;
while (true) {
var dataList = this.knowledgeQaSegmentApplicationService.queryListForEmbeddingQaAndEmbeddings(1,
pageSize,
pageNum);
if (dataList.isEmpty()) {
break;
}
pageNum++;
}
}
}

View File

@@ -0,0 +1,69 @@
package com.xspaceagi.knowledge.api.task;
import com.xspaceagi.knowledge.core.application.service.IKnowledgeRawSegmentApplicationService;
import com.xspaceagi.system.sdk.service.AbstractTaskExecuteService;
import com.xspaceagi.system.sdk.service.ScheduleTaskApiService;
import com.xspaceagi.system.sdk.service.dto.ScheduleTaskDto;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import java.time.Instant;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
@Slf4j
@Component("knowledgeAutoGenerateQaTask")
public class KnowledgeAutoGenerateQaTask extends AbstractTaskExecuteService {
@Resource
private ScheduleTaskApiService scheduleTaskApiService;
@Resource
private IKnowledgeRawSegmentApplicationService knowledgeRawSegmentApplicationService;
@PostConstruct
public void init() {
scheduleTaskApiService.start(ScheduleTaskDto.builder()
.taskId("knowledgeAutoGenerateQaTask")
.beanId("knowledgeAutoGenerateQaTask")
.maxExecTimes(Long.MAX_VALUE)
.cron(ScheduleTaskDto.Cron.EVERY_5_MINUTE.getCron())
.params(Map.of())
.build());
}
@Override
protected boolean execute(ScheduleTaskDto scheduleTaskDto) {
log.info("knowledgeAutoGenerateQaTask 自动运行任务开始执行");
try {
this.autoGenerateQa();
log.info("knowledgeAutoGenerateQaTask 自动运行任务执行结束");
} catch (Exception e) {
log.error("Auto-run task failed", e);
}
return false;//false会一直循环执行
}
private void autoGenerateQa() {
Integer reqId = ThreadLocalRandom.current().nextInt(100, 999999);
MDC.put("tid", reqId + "" + Instant.now().toEpochMilli());
// 分页查询,直到没有数据为止
int pageNum = 1;
int pageSize = 500;
while (true) {
var dataList = this.knowledgeRawSegmentApplicationService.queryListForPendingQaAndGenerateQa(1,
pageSize,
pageNum);
if (dataList.isEmpty()) {
break;
}
pageNum++;
}
}
}

View File

@@ -0,0 +1,46 @@
package com.xspaceagi.knowledge.api.task;
import com.xspaceagi.knowledge.domain.service.IKnowledgeTaskArchiveAndRetryDomainService;
import com.xspaceagi.system.sdk.service.AbstractTaskExecuteService;
import com.xspaceagi.system.sdk.service.ScheduleTaskApiService;
import com.xspaceagi.system.sdk.service.dto.ScheduleTaskDto;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Map;
@Slf4j
@Component("knowledgeAutoQaRunTask")
public class KnowledgeAutoQaRunTask extends AbstractTaskExecuteService {
@Resource
private ScheduleTaskApiService scheduleTaskApiService;
@Resource
private IKnowledgeTaskArchiveAndRetryDomainService knowledgeTaskArchiveAndRetryDomainService;
@PostConstruct
public void init() {
scheduleTaskApiService.start(ScheduleTaskDto.builder()
.taskId("knowledgeAutoQaRunTask")
.beanId("knowledgeAutoQaRunTask")
.maxExecTimes(Long.MAX_VALUE)
.cron(ScheduleTaskDto.Cron.EVERY_10_MINUTE.getCron())
.params(Map.of())
.build());
}
@Override
protected boolean execute(ScheduleTaskDto scheduleTaskDto) {
log.info("knowledgeAutoQaRunTask 自动运行任务开始执行");
try {
this.knowledgeTaskArchiveAndRetryDomainService.autoQaRunTask(7);
log.info("knowledgeAutoQaRunTask 自动运行任务执行结束");
} catch (Exception e) {
log.error("Auto-run task failed", e);
}
return false;//false会一直循环执行
}
}

View File

@@ -0,0 +1,46 @@
package com.xspaceagi.knowledge.api.task;
import com.xspaceagi.knowledge.domain.service.IKnowledgeTaskArchiveAndRetryDomainService;
import com.xspaceagi.system.sdk.service.AbstractTaskExecuteService;
import com.xspaceagi.system.sdk.service.ScheduleTaskApiService;
import com.xspaceagi.system.sdk.service.dto.ScheduleTaskDto;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Map;
@Slf4j
@Component("knowledgeAutoRunTask")
public class KnowledgeAutoRunTask extends AbstractTaskExecuteService {
@Resource
private ScheduleTaskApiService scheduleTaskApiService;
@Resource
private IKnowledgeTaskArchiveAndRetryDomainService knowledgeTaskArchiveAndRetryDomainService;
@PostConstruct
public void init() {
scheduleTaskApiService.start(ScheduleTaskDto.builder()
.taskId("knowledgeAutoRunTask")
.beanId("knowledgeAutoRunTask")
.maxExecTimes(Long.MAX_VALUE)
.cron(ScheduleTaskDto.Cron.EVERY_5_MINUTE.getCron())
.params(Map.of())
.build());
}
@Override
protected boolean execute(ScheduleTaskDto scheduleTaskDto) {
log.info("KnowledgeAutoRunTask 自动运行任务开始执行");
try {
this.knowledgeTaskArchiveAndRetryDomainService.autoRunTask(7);
log.info("KnowledgeAutoRunTask 自动运行任务执行结束");
} catch (Exception e) {
log.error("Auto-run task failed", e);
}
return false;//false会一直循环执行
}
}

View File

@@ -0,0 +1,112 @@
package com.xspaceagi.knowledge.api.task;
import com.xspaceagi.knowledge.core.application.service.IKnowledgeFullTextBatchSyncService;
import com.xspaceagi.system.domain.service.UserDomainService;
import com.xspaceagi.system.infra.dao.entity.Tenant;
import com.xspaceagi.system.sdk.service.AbstractTaskExecuteService;
import com.xspaceagi.system.sdk.service.ScheduleTaskApiService;
import com.xspaceagi.system.sdk.service.dto.ScheduleTaskDto;
import com.xspaceagi.system.spec.common.RequestContext;
import com.xspaceagi.system.spec.common.UserContext;
import com.xspaceagi.system.spec.enums.TenantStatus;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
* 全文检索定时同步任务
*
* <p>每隔30分钟检查所有启用租户的知识库分段数据是否存在未同步记录
* 并将其同步到 Quickwit 全文检索服务。</p>
*/
@Slf4j
@Component("knowledgeFullTextPeriodicSyncTask")
public class KnowledgeFullTextPeriodicSyncTask extends AbstractTaskExecuteService {
@Resource
private ScheduleTaskApiService scheduleTaskApiService;
@Resource
private IKnowledgeFullTextBatchSyncService batchSyncService;
@Resource
private UserDomainService userDomainService;
@PostConstruct
public void init() {
scheduleTaskApiService.start(ScheduleTaskDto.builder()
.taskId("knowledgeFullTextPeriodicSyncTask")
.beanId("knowledgeFullTextPeriodicSyncTask")
.maxExecTimes(Long.MAX_VALUE)
.cron(ScheduleTaskDto.Cron.EVERY_30_MINUTE.getCron())
.params(Map.of())
.build());
}
@Override
protected boolean execute(ScheduleTaskDto scheduleTaskDto) {
try {
this.periodicSyncUnsyncedKnowledgeBases();
} catch (Exception e) {
log.error("Scheduled task failed", e);
}
return false;
}
public void periodicSyncUnsyncedKnowledgeBases() {
log.info("========== 定时任务触发,检查未同步知识库分段数据并同步到全文检索 ==========");
try {
List<Tenant> tenants = userDomainService.queryTenantsByStatus(TenantStatus.Enabled);
log.info("定时任务找到 {} 个启用的租户", tenants.size());
int totalSuccess = 0;
int totalFail = 0;
for (Tenant tenant : tenants) {
try {
log.debug("定时任务开始处理租户: tenantId={}, tenantName={}", tenant.getId(), tenant.getName());
// 构造系统用户上下文
UserContext userContext = UserContext.builder()
.userId(0L)
.userName("system")
.tenantId(tenant.getId())
.tenantName(tenant.getName())
.build();
// 设置请求上下文
RequestContext<UserContext> requestContext = new RequestContext<>();
requestContext.setTenantId(tenant.getId());
requestContext.setUserContext(userContext);
RequestContext.set(requestContext);
try {
// 同步该租户的所有未同步知识库
batchSyncService.syncAllUnsyncedKnowledgeBasesToQuickwit(tenant.getId());
log.debug("定时任务租户同步成功: tenantId={}, tenantName={}", tenant.getId(), tenant.getName());
totalSuccess++;
} catch (Exception e) {
log.error("定时任务租户同步失败: tenantId={}, tenantName={}", tenant.getId(), tenant.getName(), e);
totalFail++;
} finally {
// 清除上下文
RequestContext.remove();
}
} catch (Exception e) {
log.error("定时任务处理租户异常: tenantId={}, tenantName={}", tenant.getId(), tenant.getName(), e);
totalFail++;
}
}
log.info("========== 定时任务完成: 总租户数={}, 成功={}, 失败={} ==========",
tenants.size(), totalSuccess, totalFail);
} catch (Exception e) {
log.error("Scheduled task failed", e);
}
}
}

View File

@@ -0,0 +1,36 @@
package com.xspaceagi.knowledge.assembler;
import org.springframework.stereotype.Service;
import com.xspaceagi.knowledge.domain.model.KnowledgeConfigModel;
import com.xspaceagi.knowledge.sdk.request.KnowledgeCreateRequestVo;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class KnowledgeModelApiAssembler {
public static KnowledgeConfigModel convertFromVo(KnowledgeCreateRequestVo vo) {
KnowledgeConfigModel knowledgeConfigModel = new KnowledgeConfigModel();
knowledgeConfigModel.setId(null);
knowledgeConfigModel.setName(vo.getName());
knowledgeConfigModel.setDescription(vo.getDescription());
knowledgeConfigModel.setPubStatus(null);
knowledgeConfigModel.setDataType(vo.getDataType());
knowledgeConfigModel.setEmbeddingModelId(null);
knowledgeConfigModel.setChatModelId(null);
knowledgeConfigModel.setSpaceId(vo.getSpaceId());
knowledgeConfigModel.setIcon(vo.getIcon());
knowledgeConfigModel.setFileSize(null);
knowledgeConfigModel.setCreated(null);
knowledgeConfigModel.setCreatorId(vo.getUserId());
knowledgeConfigModel.setCreatorName(null);
knowledgeConfigModel.setModified(null);
knowledgeConfigModel.setModifiedId(null);
knowledgeConfigModel.setModifiedName(null);
return knowledgeConfigModel;
}
}