listUserModels(String userId);
/**
* 根据用户标识获取默认用户模型关系。
*
- * @param userId 表示用户标识。
- * @return 默认的用户模型关系。
+ * @param userId 表示用户标识的 {@link String}。
+ * @return 默认的用户模型关系的 {@link UserModelPo}。
*/
UserModelPo getDefault(String userId);
+
+ /**
+ * 判断指定用户是否已绑定默认模型。
+ *
+ * @param userId 表示用户标识的 {@link String}。
+ * @return 若已绑定默认模型则返回 {@code true},否则返回 {@code false}。
+ */
+ boolean hasDefaultModel(String userId);
+
+ /**
+ * 插入用户模型绑定关系。
+ *
+ * @param userModel 表示待插入的用户模型关系对象的 {@link UserModelPo}。
+ */
+ void insertUserModel(UserModelPo userModel);
+
+ /**
+ * 根据模型标识删除对应的用户模型绑定关系。
+ *
+ * @param modelId 表示模型标识的 {@link String}。
+ */
+ void deleteByModelId(String modelId);
+
+ /**
+ * 查找指定用户最新创建的模型绑定记录(按创建时间降序,取第一条)。
+ *
+ * @param userId 表示用户标识的 {@link String}。
+ * @return 最新的用户模型关系的 {@link UserModelPo}。
+ */
+ UserModelPo findLatestUserModel(String userId);
+
+ /**
+ * 更新指定用户的所有模型绑定记录的默认状态。
+ * 若记录中的模型标识与传入的 {@code modelId} 一致,则设置为默认(1),否则设为非默认(0)。
+ *
+ * @param userId 表示用户标识的 {@link String}。
+ * @param modelId 表示需设为默认的模型标识的 {@link String}。
+ * @return 成功更新的记录条数的 {@code int}。
+ */
+ int setDefault(@Param("userId") String userId, @Param("modelId") String modelId);
}
diff --git a/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/po/ModelPo.java b/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/po/ModelPo.java
index 8f702b20db..096a0d66c1 100644
--- a/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/po/ModelPo.java
+++ b/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/po/ModelPo.java
@@ -6,10 +6,11 @@
package modelengine.fit.jade.aipp.model.po;
-import lombok.AllArgsConstructor;
import lombok.Data;
import modelengine.jade.common.po.BasePo;
+import java.time.LocalDateTime;
+
/**
* 模型信息 ORM 对象。
*
@@ -17,11 +18,145 @@
* @since 2025/3/11
*/
@Data
-@AllArgsConstructor
public class ModelPo extends BasePo {
private String modelId;
private String name;
private String tag;
private String baseUrl;
private String type;
+
+ /**
+ * 用于构建 {@link ModelPo} 实例的构建器类。
+ */
+ public static class Builder {
+ private final ModelPo instance = new ModelPo();
+
+ /**
+ * 设置模型标识符。
+ *
+ * @param modelId 表示模型唯一标识的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder modelId(String modelId) {
+ this.instance.setModelId(modelId);
+ return this;
+ }
+
+ /**
+ * 设置模型名称。
+ *
+ * @param name 表示模型名称的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder name(String name) {
+ this.instance.setName(name);
+ return this;
+ }
+
+ /**
+ * 设置模型标签。
+ *
+ * @param tag 表示模型所属标签的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder tag(String tag) {
+ this.instance.setTag(tag);
+ return this;
+ }
+
+ /**
+ * 设置模型基础地址。
+ *
+ * @param baseUrl 表示模型服务访问基础地址的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder baseUrl(String baseUrl) {
+ this.instance.setBaseUrl(baseUrl);
+ return this;
+ }
+
+ /**
+ * 设置模型类型。
+ *
+ * @param type 表示模型类型的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder type(String type) {
+ this.instance.setType(type);
+ return this;
+ }
+
+ /**
+ * 设置数据库主键标识。
+ *
+ * @param id 表示模型数据的唯一数据库主键的 {@link Long}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder id(Long id) {
+ this.instance.setId(id);
+ return this;
+ }
+
+ /**
+ * 设置创建时间。
+ *
+ * @param createdAt 表示模型创建时间的 {@link LocalDateTime}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder createdAt(LocalDateTime createdAt) {
+ this.instance.setCreatedAt(createdAt);
+ return this;
+ }
+
+ /**
+ * 设置更新时间。
+ *
+ * @param updatedAt 表示模型最近更新时间的 {@link LocalDateTime}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder updatedAt(LocalDateTime updatedAt) {
+ this.instance.setUpdatedAt(updatedAt);
+ return this;
+ }
+
+ /**
+ * 设置创建人标识。
+ *
+ * @param createdBy 表示创建该模型记录的用户标识的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder createdBy(String createdBy) {
+ this.instance.setCreatedBy(createdBy);
+ return this;
+ }
+
+ /**
+ * 设置更新人标识。
+ *
+ * @param updatedBy 表示最近更新该模型记录的用户标识的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder updatedBy(String updatedBy) {
+ this.instance.setUpdatedBy(updatedBy);
+ return this;
+ }
+
+ /**
+ * 构建并返回 {@link ModelPo} 实例。
+ *
+ * @return 构建完成的 {@link ModelPo} 实例。
+ */
+ public ModelPo build() {
+ return this.instance;
+ }
+ }
+
+ /**
+ * 创建并返回一个新的 {@link Builder} 构建器实例。
+ *
+ * @return {@link Builder} 实例,用于构建 {@link ModelPo}。
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
}
diff --git a/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/po/UserModelDetailPo.java b/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/po/UserModelDetailPo.java
new file mode 100644
index 0000000000..4c55bfebdb
--- /dev/null
+++ b/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/po/UserModelDetailPo.java
@@ -0,0 +1,181 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
+ * This file is a part of the ModelEngine Project.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+package modelengine.fit.jade.aipp.model.po;
+
+import lombok.Data;
+import modelengine.jade.common.po.BasePo;
+
+import java.time.LocalDateTime;
+
+/**
+ * 用户模型关系信息用于前端表单展示。
+ *
+ * @author 李智超
+ * @since 2025-04-08
+ */
+@Data
+public class UserModelDetailPo extends BasePo {
+ /**
+ * 表示模型标识。
+ */
+ private String modelId;
+
+ /**
+ * 表示用户标识。
+ */
+ private String userId;
+
+ /**
+ * 表示模型名称。
+ */
+ private String modelName;
+
+ /**
+ * 表示模型访问地址。
+ */
+ private String baseUrl;
+
+ /**
+ * 表示是否为默认模型(1 表示默认,0 表示非默认)。
+ */
+ private int isDefault;
+
+ /**
+ * 用于构建 {@link UserModelDetailPo} 实例的构建器类。
+ */
+ public static class Builder {
+ private final UserModelDetailPo instance = new UserModelDetailPo();
+
+ /**
+ * 设置数据库主键标识。
+ *
+ * @param id 表示用户模型记录的唯一数据库主键的 {@link Long}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder id(Long id) {
+ this.instance.setId(id);
+ return this;
+ }
+
+ /**
+ * 设置创建时间。
+ *
+ * @param createdAt 表示该用户模型记录的创建时间的 {@link LocalDateTime}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder createdAt(LocalDateTime createdAt) {
+ this.instance.setCreatedAt(createdAt);
+ return this;
+ }
+
+ /**
+ * 设置更新时间。
+ *
+ * @param updatedAt 表示该用户模型记录的最后更新时间的 {@link LocalDateTime}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder updatedAt(LocalDateTime updatedAt) {
+ this.instance.setUpdatedAt(updatedAt);
+ return this;
+ }
+
+ /**
+ * 设置创建人标识。
+ *
+ * @param createdBy 表示创建该用户模型记录的用户标识的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder createdBy(String createdBy) {
+ this.instance.setCreatedBy(createdBy);
+ return this;
+ }
+
+ /**
+ * 设置更新人标识。
+ *
+ * @param updatedBy 表示最近更新该用户模型记录的用户标识的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder updatedBy(String updatedBy) {
+ this.instance.setUpdatedBy(updatedBy);
+ return this;
+ }
+
+ /**
+ * 设置模型标识。
+ *
+ * @param modelId 表示关联的模型标识的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder modelId(String modelId) {
+ this.instance.setModelId(modelId);
+ return this;
+ }
+
+ /**
+ * 设置用户标识。
+ *
+ * @param userId 表示关联的用户标识的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder userId(String userId) {
+ this.instance.setUserId(userId);
+ return this;
+ }
+
+ /**
+ * 设置模型名称。
+ *
+ * @param modelName 表示模型名称的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder modelName(String modelName) {
+ this.instance.setModelName(modelName);
+ return this;
+ }
+
+ /**
+ * 设置模型访问地址。
+ *
+ * @param baseUrl 表示模型服务访问地址的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder baseUrl(String baseUrl) {
+ this.instance.setBaseUrl(baseUrl);
+ return this;
+ }
+
+ /**
+ * 设置是否为默认模型。
+ *
+ * @param isDefault 表示是否为默认模型的 {@code int}(1 表示默认,0 表示非默认)。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder isDefault(int isDefault) {
+ this.instance.setIsDefault(isDefault);
+ return this;
+ }
+
+ /**
+ * 构建并返回 {@link UserModelDetailPo} 实例。
+ *
+ * @return 构建完成的 {@link UserModelDetailPo} 实例。
+ */
+ public UserModelDetailPo build() {
+ return this.instance;
+ }
+ }
+
+ /**
+ * 创建并返回一个新的 {@link Builder} 构建器实例。
+ *
+ * @return {@link Builder} 实例,用于构建 {@link UserModelDetailPo}。
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+}
\ No newline at end of file
diff --git a/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/po/UserModelPo.java b/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/po/UserModelPo.java
index fedc68af1f..bfce91247a 100644
--- a/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/po/UserModelPo.java
+++ b/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/po/UserModelPo.java
@@ -9,6 +9,8 @@
import lombok.Data;
import modelengine.jade.common.po.BasePo;
+import java.time.LocalDateTime;
+
/**
* 用户模型关系信息 ORM 对象。
*
@@ -21,4 +23,128 @@ public class UserModelPo extends BasePo {
private String modelId;
private String apiKey;
private int isDefault;
-}
+
+ /**
+ * 用于构建 {@link UserModelPo} 实例的构建器类。
+ */
+ public static class Builder {
+ private final UserModelPo instance = new UserModelPo();
+
+ /**
+ * 设置用户标识。
+ *
+ * @param userId 表示用户标识的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder userId(String userId) {
+ this.instance.setUserId(userId);
+ return this;
+ }
+
+ /**
+ * 设置模型标识。
+ *
+ * @param modelId 表示关联的模型标识的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder modelId(String modelId) {
+ this.instance.setModelId(modelId);
+ return this;
+ }
+
+ /**
+ * 设置模型访问所需的访问密钥。
+ *
+ * @param apiKey 表示模型访问密钥的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder apiKey(String apiKey) {
+ this.instance.setApiKey(apiKey);
+ return this;
+ }
+
+ /**
+ * 设置是否为默认模型。
+ *
+ * @param isDefault 表示是否为默认模型的 {@code int}(1 表示默认,0 表示非默认)。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder isDefault(int isDefault) {
+ this.instance.setIsDefault(isDefault);
+ return this;
+ }
+
+ /**
+ * 设置数据库主键 ID。
+ *
+ * @param id 表示用户模型记录的唯一数据库主键的 {@link Long}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder id(Long id) {
+ this.instance.setId(id);
+ return this;
+ }
+
+ /**
+ * 设置创建时间。
+ *
+ * @param createdAt 表示用户模型记录的创建时间的 {@link LocalDateTime}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder createdAt(LocalDateTime createdAt) {
+ this.instance.setCreatedAt(createdAt);
+ return this;
+ }
+
+ /**
+ * 设置更新时间。
+ *
+ * @param updatedAt 表示用户模型记录的最后更新时间的 {@link LocalDateTime}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder updatedAt(LocalDateTime updatedAt) {
+ this.instance.setUpdatedAt(updatedAt);
+ return this;
+ }
+
+ /**
+ * 设置创建人标识。
+ *
+ * @param createdBy 表示创建该记录的用户标识的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder createdBy(String createdBy) {
+ this.instance.setCreatedBy(createdBy);
+ return this;
+ }
+
+ /**
+ * 设置更新人标识。
+ *
+ * @param updatedBy 表示最近更新该记录的用户标识的 {@link String}。
+ * @return {@link Builder} 构建器本身。
+ */
+ public Builder updatedBy(String updatedBy) {
+ this.instance.setUpdatedBy(updatedBy);
+ return this;
+ }
+
+ /**
+ * 构建并返回 {@link UserModelPo} 实例。
+ *
+ * @return 构建完成的 {@link UserModelPo} 实例。
+ */
+ public UserModelPo build() {
+ return this.instance;
+ }
+ }
+
+ /**
+ * 创建并返回一个新的 {@link Builder} 构建器实例。
+ *
+ * @return {@link Builder} 实例,用于构建 {@link UserModelPo}。
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+}
\ No newline at end of file
diff --git a/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/repository/UserModelRepo.java b/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/repository/UserModelRepo.java
index 8fa2e309ed..80bcfd675a 100644
--- a/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/repository/UserModelRepo.java
+++ b/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/repository/UserModelRepo.java
@@ -8,6 +8,7 @@
import modelengine.fit.jade.aipp.model.po.ModelAccessPo;
import modelengine.fit.jade.aipp.model.po.ModelPo;
+import modelengine.fit.jade.aipp.model.po.UserModelPo;
import java.util.List;
@@ -21,26 +22,88 @@ public interface UserModelRepo {
/**
* 根据用户标识来查询该用户可用的模型列表。
*
- * @param userId 表示用户标识。
- * @return 表示该用户可用的模型列表 {@link List}{@code <}{@link ModelPo}{@code >}。
+ * @param userId 表示用户标识的 {@link String}。
+ * @return 该用户可用的模型列表的 {@link List}{@code <}{@link ModelPo}{@code >}。
*/
- List get(String userId);
+ List listModelsByUserId(String userId);
/**
* 查询特定的模型访问信息。
*
- * @param userId 表示用户标识。
- * @param tag 表示模型标签。
- * @param name 表示模型名称。
- * @return 模型访问信息 {@link ModelAccessPo}。
+ * @param userId 表示用户标识的 {@link String}。
+ * @param tag 表示模型标签的 {@link String}。
+ * @param name 表示模型名称的 {@link String}。
+ * @return 模型访问信息的 {@link ModelAccessPo}。
*/
ModelAccessPo getModelAccessInfo(String userId, String tag, String name);
/**
* 获取一个用户的默认模型。
*
- * @param userId 表示用户标识。
- * @return 模型信息 {@link ModelPo}.
+ * @param userId 表示用户标识的 {@link String}。
+ * @return 模型信息的 {@link ModelPo}。
*/
ModelPo getDefaultModel(String userId);
+
+ /**
+ * 根据用户标识来查询该用户可用的用户模型列表。
+ *
+ * @param userId 表示用户标识的 {@link String}。
+ * @return 该用户可用的用户模型列表的 {@link List}{@code <}{@link UserModelPo}{@code >}。
+ */
+ List listUserModelsByUserId(String userId);
+
+ /**
+ * 根据模型标识列表批量查询模型信息。
+ *
+ * @param modelIds 表示模型标识列表的 {@link List}{@code <}{@link String}{@code >}。
+ * @return 模型信息列表的 {@link List}{@code <}{@link ModelPo}{@code >}。
+ */
+ List listModels(List modelIds);
+
+ /**
+ * 查询该用户是否存在默认模型。
+ *
+ * @param userId 表示用户标识的 {@link String}。
+ * @return 是否存在默认模型的 {@code boolean}。
+ */
+ boolean hasDefaultModel(String userId);
+
+ /**
+ * 插入一条模型信息。
+ *
+ * @param modelPo 表示要插入的模型数据的 {@link ModelPo}。
+ */
+ void insertModel(ModelPo modelPo);
+
+ /**
+ * 插入一条用户模型关联信息。
+ *
+ * @param userModelPo 表示要插入的用户模型数据的 {@link UserModelPo}。
+ */
+ void insertUserModel(UserModelPo userModelPo);
+
+ /**
+ * 根据模型标识删除该模型的用户关联信息。
+ *
+ * @param modelId 表示待删除模型标识的 {@link String}。
+ */
+ void deleteByModelId(String modelId);
+
+ /**
+ * 设置某个模型为该用户的默认模型。
+ *
+ * @param userId 表示用户标识的 {@link String}。
+ * @param modelId 表示要设置为默认的模型标识的 {@link String}。
+ * @return 受影响的记录行数的 {@code int}。
+ */
+ int switchDefaultUserModel(String userId, String modelId);
+
+ /**
+ * 根据模型标识查询模型信息。
+ *
+ * @param modelId 表示模型标识的 {@link String}。
+ * @return 模型信息的 {@link ModelPo}。
+ */
+ ModelPo getModel(String modelId);
}
diff --git a/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/repository/impl/UserModelRepoImpl.java b/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/repository/impl/UserModelRepoImpl.java
index 8c00db9d12..6f79168212 100644
--- a/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/repository/impl/UserModelRepoImpl.java
+++ b/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/repository/impl/UserModelRepoImpl.java
@@ -37,7 +37,7 @@ public UserModelRepoImpl(ModelMapper modelMapper, UserModelMapper userModelMappe
}
@Override
- public List get(String userId) {
+ public List listModelsByUserId(String userId) {
return this.getModelPos(this.userModelMapper.listUserModels(userId));
}
@@ -75,6 +75,47 @@ public ModelPo getDefaultModel(String userId) {
if (defaultModel == null) {
return null;
}
- return this.modelMapper.get(defaultModel.getModelId());
+ return this.modelMapper.getModel(defaultModel.getModelId());
+ }
+
+ @Override
+ public List listUserModelsByUserId(String userId) {
+ return this.userModelMapper.listUserModels(userId);
+ }
+
+ @Override
+ public List listModels(List modelIds) {
+ return this.modelMapper.listModels(modelIds);
+ }
+
+ @Override
+ public boolean hasDefaultModel(String userId) {
+ return this.userModelMapper.hasDefaultModel(userId);
+ }
+
+ @Override
+ public void insertModel(ModelPo modelPo) {
+ this.modelMapper.insertModel(modelPo);
+ }
+
+ @Override
+ public void insertUserModel(UserModelPo userModelPo) {
+ this.userModelMapper.insertUserModel(userModelPo);
+ }
+
+ @Override
+ public void deleteByModelId(String modelId) {
+ this.userModelMapper.deleteByModelId(modelId);
+ this.modelMapper.deleteByModelId(modelId);
+ }
+
+ @Override
+ public int switchDefaultUserModel(String userId, String modelId) {
+ return this.userModelMapper.setDefault(userId, modelId);
+ }
+
+ @Override
+ public ModelPo getModel(String modelId) {
+ return this.modelMapper.getModel(modelId);
}
}
diff --git a/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/service/impl/CustomAippModelCenter.java b/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/service/impl/CustomAippModelCenter.java
index f418b501a0..bd47202d86 100644
--- a/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/service/impl/CustomAippModelCenter.java
+++ b/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/service/impl/CustomAippModelCenter.java
@@ -4,7 +4,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-
package modelengine.fit.jade.aipp.model.service.impl;
import modelengine.fit.jade.aipp.model.dto.ModelAccessInfo;
@@ -51,7 +50,7 @@ public CustomAippModelCenter(UserModelRepo userModelRepo,
@Override
public ModelListDto fetchModelList(String type, String scene, OperationContext context) {
LOG.info("[Custom][fetchModelList] operator={}, type={}, scene={}.", context.getOperator(), type, scene);
- List modelList = this.userModelRepo.get(context.getOperator());
+ List modelList = this.userModelRepo.listModelsByUserId(context.getOperator());
if (CollectionUtils.isEmpty(modelList)) {
return this.defaultModelCenter.fetchModelList(type, scene, context);
}
diff --git a/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/service/impl/UserModelConfigService.java b/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/service/impl/UserModelConfigService.java
new file mode 100644
index 0000000000..2f636f4326
--- /dev/null
+++ b/app-builder/plugins/aipp-custom-model-center/src/main/java/modelengine/fit/jade/aipp/model/service/impl/UserModelConfigService.java
@@ -0,0 +1,181 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) 2025 Huawei Technologies Co., Ltd. All rights reserved.
+ * This file is a part of the ModelEngine Project.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+package modelengine.fit.jade.aipp.model.service.impl;
+
+import modelengine.fit.jade.aipp.model.dto.UserModelDetailDto;
+
+import modelengine.fit.jade.aipp.model.po.ModelPo;
+import modelengine.fit.jade.aipp.model.po.UserModelPo;
+import modelengine.fit.jade.aipp.model.repository.UserModelRepo;
+import modelengine.fit.jade.aipp.model.service.UserModelConfig;
+import modelengine.fitframework.annotation.Component;
+import modelengine.fitframework.annotation.Fitable;
+import modelengine.fitframework.annotation.Property;
+import modelengine.fitframework.log.Logger;
+import modelengine.fitframework.util.CollectionUtils;
+import modelengine.jade.carver.tool.annotation.Attribute;
+import modelengine.jade.carver.tool.annotation.Group;
+import modelengine.jade.carver.tool.annotation.ToolMethod;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * 表示用户模型信息用于插件的持久化层的接口的实现。
+ *
+ * @author 李智超
+ * @since 2025-04-09
+ */
+@Component
+@Group(name = "User_Model_Config_Service")
+public class UserModelConfigService implements UserModelConfig {
+ private static final Logger log = Logger.get(UserModelConfig.class);
+ private static final String FITABLE_ID = "aipp.model.service.impl";
+ private static final String DEFAULT_MODEL_TYPE = "chat_completions";
+ private final UserModelRepo userModelRepo;
+
+ /**
+ * 构造方法。
+ *
+ * @param userModelRepo 表示用于访问用户模型数据的仓储接口的 {@link UserModelRepo}。
+ */
+ public UserModelConfigService(UserModelRepo userModelRepo) {
+ this.userModelRepo = userModelRepo;
+ }
+
+ @Override
+ @Fitable(id = FITABLE_ID)
+ @ToolMethod(name = "获取用户模型列表", description = "根据用户标识来查询该用户可用的模型列表", extensions = {
+ @Attribute(key = "tags", value = "FIT"), @Attribute(key = "tags", value = "MODEL")
+ })
+ @Property(description = "返回该用户可用的模型列表")
+ public List getUserModelList(String userId) {
+ log.info("start get model list for {}.", userId);
+ List userModelPos = this.userModelRepo.listUserModelsByUserId(userId);
+ if (CollectionUtils.isEmpty(userModelPos)) {
+ log.warn("No user model records found for userId={}.", userId);
+ return Collections.emptyList();
+ }
+
+ List modelIds =
+ userModelPos.stream().map(UserModelPo::getModelId).distinct().collect(Collectors.toList());
+ List modelPos = this.userModelRepo.listModels(modelIds);
+
+ // 构建 modelId → ModelPo 映射
+ Map modelMap = modelPos.stream()
+ .map(model -> Map.entry(model.getModelId(), model))
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a));
+
+ return userModelPos.stream().map(userModel -> {
+ ModelPo model = modelMap.get(userModel.getModelId());
+ return UserModelDetailDto.builder()
+ .createdAt(userModel.getCreatedAt())
+ .modelId(userModel.getModelId())
+ .userId(userModel.getUserId())
+ .modelName(model != null ? model.getName() : null)
+ .baseUrl(model != null ? model.getBaseUrl() : null)
+ .isDefault(userModel.getIsDefault())
+ .build();
+ }).collect(Collectors.toList());
+ }
+
+ @Override
+ @Fitable(id = FITABLE_ID)
+ @ToolMethod(name = "添加模型", description = "为用户添加可用的模型信息", extensions = {
+ @Attribute(key = "tags", value = "FIT"), @Attribute(key = "tags", value = "MODEL")
+ })
+ @Property(description = "为用户添加可用的模型信息")
+ public String addUserModel(String userId, String apiKey, String modelName, String baseUrl) {
+ log.info("start add user model for {}.", userId);
+ String modelId = UUID.randomUUID().toString().replace("-", "");
+ boolean hasDefault = this.userModelRepo.hasDefaultModel(userId);
+
+ ModelPo modelPo = ModelPo.builder()
+ .modelId(modelId)
+ .name(modelName)
+ .tag(modelId)
+ .baseUrl(baseUrl)
+ .type(DEFAULT_MODEL_TYPE)
+ .createdBy(userId)
+ .updatedBy(userId)
+ .build();
+ this.userModelRepo.insertModel(modelPo);
+
+ UserModelPo userModelPo = UserModelPo.builder()
+ .userId(userId)
+ .modelId(modelId)
+ .apiKey(apiKey)
+ .isDefault(hasDefault ? 0 : 1)
+ .createdBy(userId)
+ .updatedBy(userId)
+ .build();
+ this.userModelRepo.insertUserModel(userModelPo);
+ return "添加模型成功。";
+ }
+
+ @Override
+ @Fitable(id = FITABLE_ID)
+ @ToolMethod(name = "删除模型", description = "删除用户绑定的模型信息", extensions = {
+ @Attribute(key = "tags", value = "FIT"), @Attribute(key = "tags", value = "MODEL")
+ })
+ @Property(description = "删除用户绑定的模型信息")
+ public String deleteUserModel(String userId, String modelId) {
+ log.info("start delete user model for {}.", userId);
+ List userModels = this.userModelRepo.listUserModelsByUserId(userId);
+ if (CollectionUtils.isEmpty(userModels)) {
+ return "删除模型失败,当前用户没有任何模型记录。";
+ }
+
+ UserModelPo target = userModels.stream()
+ .filter(m -> Objects.equals(m.getModelId(), modelId))
+ .findFirst()
+ .orElse(null);
+ if (target == null) {
+ return "删除模型失败,该模型不属于当前用户。";
+ }
+ this.userModelRepo.deleteByModelId(modelId);
+ // 如果删除的不是默认模型,直接返回
+ if (target.getIsDefault() != 1) {
+ return "删除模型成功。";
+ }
+ userModels.remove(target);
+ // 如果没有默认模型,但还有其他记录,则设置最新创建的为默认
+ if (CollectionUtils.isNotEmpty(userModels)) {
+ UserModelPo latestUserModel = userModels.stream()
+ .filter(m -> m.getCreatedAt() != null)
+ .max(Comparator.comparing(UserModelPo::getCreatedAt))
+ .orElse(null);
+
+ if (latestUserModel != null) {
+ this.userModelRepo.switchDefaultUserModel(userId, latestUserModel.getModelId());
+ return String.format("删除默认模型成功,已将%s设为默认模型。",
+ this.userModelRepo.getModel(latestUserModel.getModelId()).getName());
+ }
+ }
+ return "删除模型成功,当前无默认模型。";
+ }
+
+ @Override
+ @Fitable(id = FITABLE_ID)
+ @ToolMethod(name = "切换默认模型", description = "将指定模型设置为用户的默认模型", extensions = {
+ @Attribute(key = "tags", value = "FIT"), @Attribute(key = "tags", value = "MODEL")
+ })
+ @Property(description = "将指定模型设置为用户的默认模型")
+ public String switchDefaultModel(String userId, String modelId) {
+ log.info("start switch default model for {}.", userId);
+ int rows = this.userModelRepo.switchDefaultUserModel(userId, modelId);
+ if (rows == 0) {
+ return "未查到对应模型。";
+ }
+ return String.format("已切换%s为默认模型。", this.userModelRepo.getModel(modelId).getName());
+ }
+}
\ No newline at end of file
diff --git a/app-builder/plugins/aipp-custom-model-center/src/main/resources/mapper/ModelMapper.xml b/app-builder/plugins/aipp-custom-model-center/src/main/resources/mapper/ModelMapper.xml
index 61b690d7c5..f492df2bc4 100644
--- a/app-builder/plugins/aipp-custom-model-center/src/main/resources/mapper/ModelMapper.xml
+++ b/app-builder/plugins/aipp-custom-model-center/src/main/resources/mapper/ModelMapper.xml
@@ -14,19 +14,29 @@
model_id, name, tag, base_url, type
-