feat(model-provider): 完成模型服务商路由与RAG向量接入后端实现

This commit is contained in:
2026-05-27 22:14:13 +08:00
parent cc745cad47
commit 5d7ca5b31f
57 changed files with 2922 additions and 1 deletions

View File

@@ -3,6 +3,13 @@ package com.bruce.common.enumconfig;
import com.bruce.common.enums.CommonStatusEnum;
import com.bruce.common.enums.EnableStatusEnum;
import com.bruce.common.enums.PersistableSysEnumDefinition;
import com.bruce.modelprovider.enums.ModelCallStatusEnum;
import com.bruce.modelprovider.enums.ModelHealthStatusEnum;
import com.bruce.modelprovider.enums.ModelProtocolTypeEnum;
import com.bruce.modelprovider.enums.ModelProviderTypeEnum;
import com.bruce.modelprovider.enums.ModelRouteStrategyEnum;
import com.bruce.modelprovider.enums.ModelTaskTypeEnum;
import com.bruce.modelprovider.enums.ModelTypeEnum;
import com.bruce.rag.enums.RagChunkStrategyEnum;
import com.bruce.rag.enums.RagIndexStatusEnum;
import com.bruce.rag.enums.RagParseStatusEnum;
@@ -14,6 +21,9 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
class EnumDefinitionTests {
@Test
/**
* 方法 enumValuesShouldBeStable用于执行业务逻辑处理。
*/
void enumValuesShouldBeStable() {
assertEquals(1, EnableStatusEnum.ENABLED.getValue());
assertEquals(0, EnableStatusEnum.DISABLED.getValue());
@@ -30,9 +40,19 @@ class EnumDefinitionTests {
assertEquals(1, RagChunkStrategyEnum.FIXED_LENGTH.getValue());
assertEquals(5, RagChunkStrategyEnum.DELIMITER.getValue());
assertEquals(6, RagChunkStrategyEnum.SEMANTIC.getValue());
assertEquals(1, ModelProviderTypeEnum.OLLAMA.getValue());
assertEquals(1, ModelProtocolTypeEnum.OPENAI_COMPATIBLE.getValue());
assertEquals(2, ModelTypeEnum.EMBEDDING.getValue());
assertEquals(1, ModelTaskTypeEnum.RAG_EMBEDDING.getValue());
assertEquals(4, ModelRouteStrategyEnum.MANUAL.getValue());
assertEquals(1, ModelCallStatusEnum.SUCCESS.getValue());
assertEquals(2, ModelHealthStatusEnum.HEALTHY.getValue());
}
@Test
/**
* 方法 enumNamesShouldBeStable用于执行业务逻辑处理。
*/
void enumNamesShouldBeStable() {
assertEquals("启用", EnableStatusEnum.ENABLED.getLabel());
assertEquals("禁用", EnableStatusEnum.DISABLED.getLabel());
@@ -47,9 +67,19 @@ class EnumDefinitionTests {
assertEquals("固定长度切片", RagChunkStrategyEnum.FIXED_LENGTH.getLabel());
assertEquals("按分隔符切片", RagChunkStrategyEnum.DELIMITER.getLabel());
assertEquals("语义切片", RagChunkStrategyEnum.SEMANTIC.getLabel());
assertEquals("Ollama", ModelProviderTypeEnum.OLLAMA.getLabel());
assertEquals("OpenAI兼容协议", ModelProtocolTypeEnum.OPENAI_COMPATIBLE.getLabel());
assertEquals("向量模型", ModelTypeEnum.EMBEDDING.getLabel());
assertEquals("RAG文档向量化", ModelTaskTypeEnum.RAG_EMBEDDING.getLabel());
assertEquals("手工指定", ModelRouteStrategyEnum.MANUAL.getLabel());
assertEquals("成功", ModelCallStatusEnum.SUCCESS.getLabel());
assertEquals("健康", ModelHealthStatusEnum.HEALTHY.getLabel());
}
@Test
/**
* 方法 enumsShouldExposeStableSysEnumMetadata用于执行业务逻辑处理。
*/
void enumsShouldExposeStableSysEnumMetadata() {
PersistableSysEnumDefinition chunkStrategy = RagChunkStrategyEnum.DELIMITER;
PersistableSysEnumDefinition parseStatus = RagParseStatusEnum.PARSED;
@@ -69,12 +99,22 @@ class EnumDefinitionTests {
assertEquals("common", enableStatus.getCatalog());
assertEquals("enable_status", enableStatus.getType());
assertEquals("启用", enableStatus.getName());
PersistableSysEnumDefinition providerType = ModelProviderTypeEnum.OLLAMA;
assertEquals("model_provider", providerType.getCatalog());
assertEquals("provider_type", providerType.getType());
assertEquals("Ollama", providerType.getName());
}
@Test
/**
* 方法 ragChunkStrategyShouldResolveByIntegerValue用于执行业务逻辑处理。
*/
void ragChunkStrategyShouldResolveByIntegerValue() {
assertEquals(RagChunkStrategyEnum.FIXED_LENGTH, RagChunkStrategyEnum.fromValue(1));
assertEquals(RagChunkStrategyEnum.DELIMITER, RagChunkStrategyEnum.fromValue(5));
assertThrows(IllegalArgumentException.class, () -> RagChunkStrategyEnum.fromValue(999));
}
}

View File

@@ -5,6 +5,13 @@ import com.bruce.common.domain.entity.SysEnum;
import com.bruce.common.enums.PersistableSysEnumDefinition;
import com.bruce.common.enums.CommonStatusEnum;
import com.bruce.common.enums.EnableStatusEnum;
import com.bruce.modelprovider.enums.ModelCallStatusEnum;
import com.bruce.modelprovider.enums.ModelHealthStatusEnum;
import com.bruce.modelprovider.enums.ModelProtocolTypeEnum;
import com.bruce.modelprovider.enums.ModelProviderTypeEnum;
import com.bruce.modelprovider.enums.ModelRouteStrategyEnum;
import com.bruce.modelprovider.enums.ModelTaskTypeEnum;
import com.bruce.modelprovider.enums.ModelTypeEnum;
import com.bruce.common.service.ISysEnumService;
import com.bruce.rag.enums.RagChunkStrategyEnum;
import com.bruce.rag.enums.RagIndexStatusEnum;
@@ -24,13 +31,23 @@ class SysEnumDataInitTests {
private ISysEnumService sysEnumService;
@Test
/**
* 方法 initDefaultEnums用于执行业务逻辑处理。
*/
public void initDefaultEnums() {
List<SysEnumDefinitionSyncSupport.EnumGroup> groups = List.of(
buildGroup(EnableStatusEnum.values()),
buildGroup(CommonStatusEnum.values()),
buildGroup(RagParseStatusEnum.values()),
buildGroup(RagIndexStatusEnum.values()),
buildGroup(RagChunkStrategyEnum.values())
buildGroup(RagChunkStrategyEnum.values()),
buildGroup(ModelProviderTypeEnum.values()),
buildGroup(ModelProtocolTypeEnum.values()),
buildGroup(ModelTypeEnum.values()),
buildGroup(ModelTaskTypeEnum.values()),
buildGroup(ModelRouteStrategyEnum.values()),
buildGroup(ModelCallStatusEnum.values()),
buildGroup(ModelHealthStatusEnum.values())
);
SysEnumDefinitionSyncSupport.validateUniqueGroupKeys(groups);
@@ -40,7 +57,12 @@ class SysEnumDataInitTests {
}
}
/**
* 方法 buildGroup用于执行业务逻辑处理。
*/
private SysEnumDefinitionSyncSupport.EnumGroup buildGroup(PersistableSysEnumDefinition[] definitions) {
return SysEnumDefinitionSyncSupport.groupOf(List.of(definitions));
}
}

View File

@@ -0,0 +1,100 @@
package com.bruce.modelprovider;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bruce.common.domain.model.RequestResult;
import com.bruce.modelprovider.controller.ModelCallLogController;
import com.bruce.modelprovider.controller.ModelConfigController;
import com.bruce.modelprovider.controller.ModelProviderController;
import com.bruce.modelprovider.controller.ModelRouteRuleController;
import com.bruce.modelprovider.dto.response.ModelProviderResponse;
import com.bruce.modelprovider.entity.ModelCallLog;
import com.bruce.modelprovider.entity.ModelConfig;
import com.bruce.modelprovider.entity.ModelProvider;
import com.bruce.modelprovider.entity.ModelRouteRule;
import com.bruce.modelprovider.entity.RagStoreModelConfig;
import com.bruce.modelprovider.mapper.ModelCallLogMapper;
import com.bruce.modelprovider.mapper.ModelConfigMapper;
import com.bruce.modelprovider.mapper.ModelProviderMapper;
import com.bruce.modelprovider.mapper.ModelRouteRuleMapper;
import com.bruce.modelprovider.mapper.RagStoreModelConfigMapper;
import com.bruce.modelprovider.service.IModelCallLogService;
import com.bruce.modelprovider.service.IModelConfigService;
import com.bruce.modelprovider.service.IModelProviderService;
import com.bruce.modelprovider.service.IModelRouteRuleService;
import com.bruce.modelprovider.service.IRagStoreModelConfigService;
import com.bruce.modelprovider.service.impl.ModelCallLogServiceImpl;
import com.bruce.modelprovider.service.impl.ModelConfigServiceImpl;
import com.bruce.modelprovider.service.impl.ModelProviderServiceImpl;
import com.bruce.modelprovider.service.impl.ModelRouteRuleServiceImpl;
import com.bruce.modelprovider.service.impl.RagStoreModelConfigServiceImpl;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Method;
import static org.junit.jupiter.api.Assertions.*;
class ModelProviderComponentStructureTests {
@Test
/**
* 方法 modelProviderComponentsShouldReuseMybatisPlusBaseTypes用于执行业务逻辑处理。
*/
void modelProviderComponentsShouldReuseMybatisPlusBaseTypes() {
assertTrue(BaseMapper.class.isAssignableFrom(ModelProviderMapper.class));
assertTrue(BaseMapper.class.isAssignableFrom(ModelConfigMapper.class));
assertTrue(BaseMapper.class.isAssignableFrom(ModelRouteRuleMapper.class));
assertTrue(BaseMapper.class.isAssignableFrom(ModelCallLogMapper.class));
assertTrue(BaseMapper.class.isAssignableFrom(RagStoreModelConfigMapper.class));
assertTrue(IService.class.isAssignableFrom(IModelProviderService.class));
assertTrue(IService.class.isAssignableFrom(IModelConfigService.class));
assertTrue(IService.class.isAssignableFrom(IModelRouteRuleService.class));
assertTrue(IService.class.isAssignableFrom(IModelCallLogService.class));
assertTrue(IService.class.isAssignableFrom(IRagStoreModelConfigService.class));
assertTrue(ServiceImpl.class.isAssignableFrom(ModelProviderServiceImpl.class));
assertTrue(ServiceImpl.class.isAssignableFrom(ModelConfigServiceImpl.class));
assertTrue(ServiceImpl.class.isAssignableFrom(ModelRouteRuleServiceImpl.class));
assertTrue(ServiceImpl.class.isAssignableFrom(ModelCallLogServiceImpl.class));
assertTrue(ServiceImpl.class.isAssignableFrom(RagStoreModelConfigServiceImpl.class));
}
@Test
void controllersShouldExposeRequestResult() throws NoSuchMethodException {
Method providerQuery = ModelProviderController.class.getMethod("query");
Method configQuery = ModelConfigController.class.getMethod("query");
Method routeQuery = ModelRouteRuleController.class.getMethod("query");
Method logQuery = ModelCallLogController.class.getMethod("query", com.bruce.modelprovider.dto.request.ModelCallLogQueryRequest.class);
assertEquals(RequestResult.class, providerQuery.getReturnType());
assertEquals(RequestResult.class, configQuery.getReturnType());
assertEquals(RequestResult.class, routeQuery.getReturnType());
assertEquals(RequestResult.class, logQuery.getReturnType());
}
@Test
/**
* 方法 modelProviderResponseShouldHideApiKeyCipher用于执行业务逻辑处理。
*/
void modelProviderResponseShouldHideApiKeyCipher() {
ModelProvider provider = new ModelProvider();
provider.setProviderCode("sf");
provider.setApiKeyCipher("secret");
ModelProviderResponse response = ModelProviderResponse.fromEntity(provider);
assertTrue(response.getHasApiKey());
}
@Test
void entitiesShouldMapCoreFields() throws NoSuchFieldException {
assertEquals(String.class, ModelProvider.class.getDeclaredField("providerCode").getType());
assertEquals(String.class, ModelConfig.class.getDeclaredField("modelCode").getType());
assertEquals(Long.class, ModelRouteRule.class.getDeclaredField("primaryModelId").getType());
assertEquals(String.class, ModelCallLog.class.getDeclaredField("requestId").getType());
assertEquals(Long.class, RagStoreModelConfig.class.getDeclaredField("embeddingModelId").getType());
}
}