【新增】AI:API 模型管理

This commit is contained in:
YunaiV 2024-05-10 22:48:49 +08:00
parent caca47b6d7
commit b9deba889c
27 changed files with 407 additions and 663 deletions

View File

@ -11,10 +11,15 @@ public interface ErrorCodeConstants {
// ========== API 密钥 1-040-000-000 ==========
ErrorCode API_KEY_NOT_EXISTS = new ErrorCode(1_040_000_000, "AI API 密钥不存在");
ErrorCode API_KEY_DISABLE = new ErrorCode(1_040_000_001, "AI API 密钥已禁用!");
// chat
// ========== API 聊天模型 1-040-001-000 ==========
ErrorCode AI_MODULE_NOT_SUPPORTED = new ErrorCode(1_022_000_000, "AI 模型暂不支持!");
ErrorCode CHAT_MODAL_NOT_EXIST = new ErrorCode(1_040_001_000, "AI 模型不存在!");
ErrorCode CHAT_MODAL_DISABLE = new ErrorCode(1_040_001_001, "AI 模型({})已禁用!");
// ErrorCode AI_MODAL_CONFIG_PARAMS_INCORRECT = new ErrorCode(1_022_000_081, "AI 模型 config 参数不正确! {} ");
// ErrorCode AI_MODAL_PLATFORM_PARAMS_INCORRECT = new ErrorCode(1_022_000_083, "AI 平台参数不正确! {} ");
// conversation
@ -31,12 +36,5 @@ public interface ErrorCodeConstants {
ErrorCode AI_CHAT_ROLE_NOT_EXIST = new ErrorCode(1_022_000_060, "AI 角色不存在!");
ErrorCode AI_CHAT_ROLE_NOT_PUBLIC = new ErrorCode(1_022_000_060, "AI 角色未公开!");
// modal
ErrorCode AI_MODAL_NOT_EXIST = new ErrorCode(1_022_000_080, "AI 模型不存在!");
ErrorCode AI_MODAL_CONFIG_PARAMS_INCORRECT = new ErrorCode(1_022_000_081, "AI 模型 config 参数不正确! {} ");
ErrorCode AI_MODAL_PLATFORM_PARAMS_INCORRECT = new ErrorCode(1_022_000_083, "AI 平台参数不正确! {} ");
ErrorCode AI_MODAL_DISABLE_NOT_USED = new ErrorCode(1_022_000_084, "AI 模型禁用不能使用!");
}

View File

@ -29,14 +29,14 @@ public class AiApiKeyController {
private AiApiKeyService apiKeyService;
@PostMapping("/create")
@Operation(summary = "创建AI API 密钥")
@Operation(summary = "创建 API 密钥")
@PreAuthorize("@ss.hasPermission('ai:api-key:create')")
public CommonResult<Long> createApiKey(@Valid @RequestBody AiApiKeySaveReqVO createReqVO) {
return success(apiKeyService.createApiKey(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新AI API 密钥")
@Operation(summary = "更新 API 密钥")
@PreAuthorize("@ss.hasPermission('ai:api-key:update')")
public CommonResult<Boolean> updateApiKey(@Valid @RequestBody AiApiKeySaveReqVO updateReqVO) {
apiKeyService.updateApiKey(updateReqVO);
@ -44,7 +44,7 @@ public class AiApiKeyController {
}
@DeleteMapping("/delete")
@Operation(summary = "删除AI API 密钥")
@Operation(summary = "删除 API 密钥")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('ai:api-key:delete')")
public CommonResult<Boolean> deleteApiKey(@RequestParam("id") Long id) {
@ -53,7 +53,7 @@ public class AiApiKeyController {
}
@GetMapping("/get")
@Operation(summary = "获得AI API 密钥")
@Operation(summary = "获得 API 密钥")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('ai:api-key:query')")
public CommonResult<AiApiKeyRespVO> getApiKey(@RequestParam("id") Long id) {
@ -62,7 +62,7 @@ public class AiApiKeyController {
}
@GetMapping("/page")
@Operation(summary = "获得AI API 密钥分页")
@Operation(summary = "获得 API 密钥分页")
@PreAuthorize("@ss.hasPermission('ai:api-key:query')")
public CommonResult<PageResult<AiApiKeyRespVO>> getApiKeyPage(@Valid AiApiKeyPageReqVO pageReqVO) {
PageResult<AiApiKeyDO> pageResult = apiKeyService.getApiKeyPage(pageReqVO);

View File

@ -2,60 +2,71 @@ package cn.iocoder.yudao.module.ai.controller.admin.model;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelAddReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelListReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelListRespVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelUpdateReqVO;
import cn.iocoder.yudao.module.ai.service.AiChatModelService;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelPageReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelRespVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelSaveReqVO;
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
import cn.iocoder.yudao.module.ai.service.model.AiChatModelService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
// TODO @fan调整下接口相关 vo 的命名等等modal => model
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
/**
* ai 模型
*
* @author fansili
* @time 2024/4/24 19:42
* @since 1.0
*/
@Tag(name = "A6-AI模型")
@Tag(name = "管理后台 - AI 聊天模型")
@RestController
@RequestMapping("/ai/chat/model")
@Slf4j
@AllArgsConstructor
@RequestMapping("/ai/chat-model")
@Validated
public class AiChatModelController {
private final AiChatModelService aiChatModelService;
@Resource
private AiChatModelService chatModelService;
@Operation(summary = "ai模型 - 模型列表")
@GetMapping("/list")
public PageResult<AiChatModelListRespVO> list(@ModelAttribute AiChatModelListReqVO req) {
return aiChatModelService.list(req);
@PostMapping("/create")
@Operation(summary = "创建聊天模型")
@PreAuthorize("@ss.hasPermission('ai:chat-model:create')")
public CommonResult<Long> createChatModel(@Valid @RequestBody AiChatModelSaveReqVO createReqVO) {
return success(chatModelService.createChatModel(createReqVO));
}
@Operation(summary = "ai模型 - 添加")
@PutMapping("/add")
public CommonResult<Void> add(@RequestBody @Validated AiChatModelAddReqVO req) {
aiChatModelService.add(req);
return CommonResult.success(null);
@PutMapping("/update")
@Operation(summary = "更新聊天模型")
@PreAuthorize("@ss.hasPermission('ai:chat-model:update')")
public CommonResult<Boolean> updateChatModel(@Valid @RequestBody AiChatModelSaveReqVO updateReqVO) {
chatModelService.updateChatModel(updateReqVO);
return success(true);
}
@Operation(summary = "ai模型 - 修改")
@PostMapping("/update")
public CommonResult<Void> update(@RequestBody @Validated AiChatModelUpdateReqVO req) {
aiChatModelService.update(req);
return CommonResult.success(null);
}
@Operation(summary = "ai模型 - 删除")
@DeleteMapping("/delete")
public CommonResult<Void> delete(@RequestParam("id") Long id) {
aiChatModelService.delete(id);
return CommonResult.success(null);
@Operation(summary = "删除聊天模型")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('ai:chat-model:delete')")
public CommonResult<Boolean> deleteChatModel(@RequestParam("id") Long id) {
chatModelService.deleteChatModel(id);
return success(true);
}
}
@GetMapping("/get")
@Operation(summary = "获得聊天模型")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('ai:chat-model:query')")
public CommonResult<AiChatModelRespVO> getChatModel(@RequestParam("id") Long id) {
AiChatModelDO chatModel = chatModelService.getChatModel(id);
return success(BeanUtils.toBean(chatModel, AiChatModelRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得聊天模型分页")
@PreAuthorize("@ss.hasPermission('ai:chat-model:query')")
public CommonResult<PageResult<AiChatModelRespVO>> getChatModelPage(@Valid AiChatModelPageReqVO pageReqVO) {
PageResult<AiChatModelDO> pageResult = chatModelService.getChatModelPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, AiChatModelRespVO.class));
}
}

View File

@ -6,26 +6,20 @@ import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.*;
import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
// TODO @fan调整下接口相关 vo 的命名等等modal => model
/**
* ai chat 角色
*
* @fansili
* @since v1.0
*/
@Tag(name = "A4-chat角色")
@Tag(name = "管理后台 - AI 聊天角色")
@RestController
@RequestMapping("/ai/chat/role")
@Slf4j
@AllArgsConstructor
@RequestMapping("/ai/chat-role")
@Validated
public class AiChatRoleController {
private final AiChatRoleService chatRoleService;
@Resource
private AiChatRoleService chatRoleService;
@Operation(summary = "chat角色 - 角色列表")
@GetMapping("/list")
@ -60,4 +54,9 @@ public class AiChatRoleController {
chatRoleService.delete(id);
return CommonResult.success(null);
}
// ========== 角色管理 ==========
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel;
import lombok.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
@Schema(description = "管理后台 - API 聊天模型分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class AiChatModelPageReqVO extends PageParam {
@Schema(description = "模型名字", example = "张三")
private String name;
@Schema(description = "模型标识", example = "gpt-3.5-turbo-0125")
private String model;
@Schema(description = "模型平台", example = "OpenAI")
private String platform;
}

View File

@ -0,0 +1,45 @@
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - AI 聊天模型 Response VO")
@Data
public class AiChatModelRespVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2630")
private Long id;
@Schema(description = "API 秘钥编号", example = "22042")
private Long keyId;
@Schema(description = "模型名字", example = "张三")
private String name;
@Schema(description = "模型标识", example = "gpt-3.5-turbo-0125")
private String model;
@Schema(description = "模型平台", example = "OpenAI")
private String platform;
@Schema(description = "排序", example = "1")
private Integer sort;
@Schema(description = "状态", example = "2")
private Integer status;
@Schema(description = "温度参数", example = "1")
private Double temperature;
@Schema(description = "单条回复的最大 Token 数量", example = "4096")
private Integer maxTokens;
@Schema(description = "上下文的最大 Message 数量", example = "8192")
private Integer maxContexts;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}

View File

@ -0,0 +1,50 @@
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import jakarta.validation.constraints.*;
@Schema(description = "管理后台 - API 聊天模型新增/修改 Request VO")
@Data
public class AiChatModelSaveReqVO {
@Schema(description = "编号", example = "2630")
private Long id;
@Schema(description = "API 秘钥编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22042")
@NotNull(message = "API 秘钥编号不能为空")
private Long keyId;
@Schema(description = "模型名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
@NotEmpty(message = "模型名字不能为空")
private String name;
@Schema(description = "模型标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "gpt-3.5-turbo-0125")
@NotEmpty(message = "模型标识不能为空")
private String model;
@Schema(description = "模型平台", requiredMode = Schema.RequiredMode.REQUIRED, example = "OpenAI")
@NotEmpty(message = "模型平台不能为空")
private String platform;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "排序不能为空")
private Integer sort;
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@InEnum(CommonStatusEnum.class)
@NotNull(message = "状态不能为空")
private Integer status;
@Schema(description = "温度参数", example = "1")
private Double temperature;
@Schema(description = "单条回复的最大 Token 数量", example = "4096")
private Integer maxTokens;
@Schema(description = "上下文的最大 Message 数量", example = "8192")
private Integer maxContexts;
}

View File

@ -1,50 +0,0 @@
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* modal list
*
* @author fansili
* @time 2024/4/24 19:56
* @since 1.0
*/
@Data
@Accessors(chain = true)
public class AiChatModalRespVO {
@Schema(description = "编号")
private Long id;
@Schema(description = "API 秘钥编号")
private Long keyId;
@Schema(description = "模型名字")
private String name;
@Schema(description = "模型类型(qianwen、yiyan、xinghuo、openai)")
private String model;
@Size(max = 32, message = "模型平台最大32个字符")
private String platform;
@Schema(description = "排序")
private Integer sort;
@Schema(description = "状态")
private Integer status;
// ========== 会话配置 ==========
@Schema(description = "温度参数")
private Integer temperature;
@Schema(description = "单条回复的最大 Token 数量")
private Integer maxTokens;
@Schema(description = "上下文的最大 Message 数量")
private Integer maxContexts;
}

View File

@ -1,63 +0,0 @@
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* ai chat modal
*
* @author fansili
* @time 2024/4/24 19:47
* @since 1.0
*/
@Data
@Accessors(chain = true)
public class AiChatModalUpdateReqVO {
@Schema(description = "编号")
@Size(max = 32, message = "编号最大32个字符")
@NotNull(message = "编号不能为空")
private Long id;
@Schema(description = "API 秘钥编号")
@Size(max = 32, message = "API 秘钥编号最大32个字符")
@NotNull(message = "API 秘钥编号不能为空!")
private Long keyId;
@Schema(description = "模型名字")
@Size(max = 60, message = "模型名字最大60个字符")
@NotNull(message = "模型名字不能为空!")
private String name;
@Schema(description = "模型类型(qianwen、yiyan、xinghuo、openai)")
@Size(max = 32, message = "模型类型最大32个字符")
@NotNull(message = "model模型不能为空!")
private String model;
@Size(max = 32, message = "模型平台最大32个字符")
@Schema(description = "模型平台 参考 AiPlatformEnum")
@NotNull(message = "平台不能为空!")
private String platform;
@Schema(description = "排序")
@NotNull(message = "sort排序不能为空!")
private Integer sort;
@Schema(description = "状态")
@NotNull(message = "状态不能为空!")
private Integer status;
// ========== 会话配置 ==========
@Schema(description = "温度参数")
private Integer temperature;
@Schema(description = "单条回复的最大 Token 数量")
private Integer maxTokens;
@Schema(description = "上下文的最大 Message 数量")
private Integer maxContexts;
}

View File

@ -1,53 +0,0 @@
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* ai chat modal
*
* @author fansili
* @time 2024/4/24 19:47
* @since 1.0
*/
@Data
@Accessors(chain = true)
public class AiChatModelAddReqVO {
@Schema(description = "API 秘钥编号")
@NotNull(message = "API 秘钥编号不能为空!")
private Long keyId;
@Schema(description = "模型名字")
@Size(max = 60, message = "模型名字最大60个字符")
@NotNull(message = "模型名字不能为空!")
private String name;
@Schema(description = "模型类型(qianwen、yiyan、xinghuo、openai)")
@Size(max = 32, message = "模型类型最大32个字符")
@NotNull(message = "model模型不能为空!")
private String model;
@Size(max = 32, message = "模型平台最大32个字符")
@Schema(description = "模型平台 参考 AiPlatformEnum")
@NotNull(message = "平台不能为空!")
private String platform;
@Schema(description = "排序")
@NotNull(message = "sort排序不能为空!")
private Integer sort;
// ========== 会话配置 ==========
@Schema(description = "温度参数")
private Integer temperature;
@Schema(description = "单条回复的最大 Token 数量")
private Integer maxTokens;
@Schema(description = "上下文的最大 Message 数量")
private Integer maxContexts;
}

View File

@ -1,22 +0,0 @@
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* modal list
*
* @author fansili
* @time 2024/4/24 19:56
* @since 1.0
*/
@Data
@Accessors(chain = true)
public class AiChatModelListReqVO extends PageParam {
@Schema(description = "名字搜搜")
private String search;
}

View File

@ -1,50 +0,0 @@
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* modal list
*
* @author fansili
* @time 2024/4/24 19:56
* @since 1.0
*/
@Data
@Accessors(chain = true)
public class AiChatModelListRespVO {
@Schema(description = "编号")
private Long id;
@Schema(description = "API 秘钥编号")
private Long keyId;
@Schema(description = "模型名称")
private String name;
@Schema(description = "模型标志")
private String model;
@Schema(description = "平台")
private String platform;
@Schema(description = "排序值")
private Integer sort;
@Schema(description = "状态")
private Integer status;
// ========== 会话配置 ==========
@Schema(description = "温度参数")
private Double temperature;
@Schema(description = "单条回复的最大 Token 数量")
private Integer maxTokens;
@Schema(description = "上下文的最大 Message 数量")
private Integer maxContexts;
}

View File

@ -1,57 +0,0 @@
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* ai chat modal
*
* @author fansili
* @time 2024/4/24 19:47
* @since 1.0
*/
@Data
@Accessors(chain = true)
public class AiChatModelUpdateReqVO {
@Schema(description = "编号")
@NotNull(message = "编号不能为空")
private Long id;
@Schema(description = "API 秘钥编号")
@NotNull(message = "API 秘钥编号不能为空!")
private Long keyId;
@Schema(description = "模型名字")
@Size(max = 60, message = "模型名字最大60个字符")
@NotNull(message = "模型名字不能为空!")
private String name;
@Schema(description = "模型类型(qianwen、yiyan、xinghuo、openai)")
@Size(max = 32, message = "模型类型最大32个字符")
@NotNull(message = "model模型不能为空!")
private String model;
@Size(max = 32, message = "模型平台最大32个字符")
@Schema(description = "模型平台 参考 AiPlatformEnum")
@NotNull(message = "平台不能为空!")
private String platform;
@Schema(description = "排序")
@NotNull(message = "sort排序不能为空!")
private Integer sort;
// ========== 会话配置 ==========
@Schema(description = "温度参数")
private Integer temperature;
@Schema(description = "单条回复的最大 Token 数量")
private Integer maxTokens;
@Schema(description = "上下文的最大 Message 数量")
private Integer maxContexts;
}

View File

@ -19,14 +19,6 @@ public interface AiChatMessageConvert {
AiChatMessageConvert INSTANCE = Mappers.getMapper(AiChatMessageConvert.class);
/**
* 转换 ChatMessageListRes
*
* @param list
* @return
*/
List<AiChatMessageRespVO> convert(List<AiChatMessageDO> list);
/**
* 转换 AiChatMessageRespVO
*

View File

@ -1,57 +0,0 @@
package cn.iocoder.yudao.module.ai.convert;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModalRespVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelAddReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelListRespVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelUpdateReqVO;
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* 聊天 modal
*
* @author fansili
* @time 2024/4/18 16:39
* @since 1.0
*/
@Mapper
public interface AiChatModelConvert {
AiChatModelConvert INSTANCE = Mappers.getMapper(AiChatModelConvert.class);
/**
* 转换 - AiChatModalListRes
*
* @param list
* @return
*/
List<AiChatModelListRespVO> convertAiChatModalListRes(List<AiChatModelDO> list);
/**
* 转换 - AiChatModalDO
*
* @param req
* @return
*/
AiChatModelDO convertAiChatModalDO(AiChatModelAddReqVO req);
/**
* 转换 - AiChatModalDO
*
* @param req
* @return
*/
AiChatModelDO convertAiChatModalDO(AiChatModelUpdateReqVO req);
/**
* 转换 - AiChatModalRes
*
* @param aiChatModalDO
* @return
*/
AiChatModalRespVO convertAiChatModalRes(AiChatModelDO aiChatModalDO);
}

View File

@ -5,21 +5,19 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelPageReqVO;
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
/**
* chat modal
* API 聊天模型 Mapper
*
* @author fansili
* @time 2024/4/24 19:41
* @since 1.0
*/
@Repository
@Mapper
public interface AiChatModelMapper extends BaseMapperX<AiChatModelDO> {
// TODO 芋艿要搞一下
/**
* 查询 - 第一个modal
*
@ -36,5 +34,12 @@ public interface AiChatModelMapper extends BaseMapperX<AiChatModelDO> {
return pageResult.getList().get(0);
}
default PageResult<AiChatModelDO> selectPage(AiChatModelPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<AiChatModelDO>()
.likeIfPresent(AiChatModelDO::getName, reqVO.getName())
.eqIfPresent(AiChatModelDO::getModel, reqVO.getModel())
.eqIfPresent(AiChatModelDO::getPlatform, reqVO.getPlatform())
.orderByDesc(AiChatModelDO::getId));
}
}

View File

@ -1,67 +0,0 @@
package cn.iocoder.yudao.module.ai.service;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.*;
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
/**
* ai modal
*
* @author fansili
* @time 2024/4/24 19:42
* @since 1.0
*/
public interface AiChatModelService {
/**
* ai modal - 列表
*
* @param req
* @return
*/
PageResult<AiChatModelListRespVO> list(AiChatModelListReqVO req);
/**
* ai modal - 添加
*
* @param req
*/
void add(AiChatModelAddReqVO req);
/**
* ai modal - 更新
*
* @param req
*/
void update(AiChatModelUpdateReqVO req);
/**
* ai modal - 删除
*
* @param id
*/
void delete(Long id);
/**
* 获取 - 获取 modal
*
* @param modalId
* @return
*/
AiChatModalRespVO getChatModalOfValidate(Long modalId);
/**
* 校验 - 是否存在
*
* @param id
* @return
*/
AiChatModelDO validateExists(Long id);
/**
* 校验 - 校验是否可用
*
* @param chatModal
*/
void validateAvailable(AiChatModalRespVO chatModal);
}

View File

@ -72,4 +72,5 @@ public interface AiChatRoleService {
* @param aiChatRoleDO
*/
void validateIsPublic(AiChatRoleDO aiChatRoleDO);
}

View File

@ -1,127 +0,0 @@
package cn.iocoder.yudao.module.ai.service.impl;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.validation.ValidationUtil;
import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.ai.ErrorCodeConstants;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.*;
import cn.iocoder.yudao.module.ai.convert.AiChatModelConvert;
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
import cn.iocoder.yudao.module.ai.dal.mysql.AiChatModelMapper;
import cn.iocoder.yudao.module.ai.dal.vo.AiChatModalConfigVO;
import cn.iocoder.yudao.module.ai.service.AiChatModelService;
import jakarta.validation.ConstraintViolation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Set;
/**
* ai 模型
*
* @author fansili
* @time 2024/4/24 19:42
* @since 1.0
*/
@AllArgsConstructor
@Service
@Slf4j
public class AiChatModalServiceImpl implements AiChatModelService {
private final AiChatModelMapper aiChatModelMapper;
@Override
public PageResult<AiChatModelListRespVO> list(AiChatModelListReqVO req) {
LambdaQueryWrapperX<AiChatModelDO> queryWrapperX = new LambdaQueryWrapperX<>();
// 查询的都是未禁用的模型
queryWrapperX.eq(AiChatModelDO::getStatus, CommonStatusEnum.ENABLE.getStatus());
// search
if (!StrUtil.isBlank(req.getSearch())) {
queryWrapperX.like(AiChatModelDO::getName, req.getSearch().trim());
}
// 默认排序
queryWrapperX.orderByAsc(AiChatModelDO::getSort);
// 查询
PageResult<AiChatModelDO> aiChatModalDOPageResult = aiChatModelMapper.selectPage(req, queryWrapperX);
// 转换 res
List<AiChatModelListRespVO> resList = AiChatModelConvert.INSTANCE.convertAiChatModalListRes(aiChatModalDOPageResult.getList());
return new PageResult<>(resList, aiChatModalDOPageResult.getTotal());
}
@Override
public void add(AiChatModelAddReqVO req) {
// 校验 platformtype
validatePlatform(req.getPlatform());
// 转换 do
AiChatModelDO insertChatModalDO = AiChatModelConvert.INSTANCE.convertAiChatModalDO(req);
// 设置默认属性
insertChatModalDO.setStatus(CommonStatusEnum.ENABLE.getStatus());
// 保存数据库
aiChatModelMapper.insert(insertChatModalDO);
}
@Override
public void update(AiChatModelUpdateReqVO req) {
// 校验 platform
validatePlatform(req.getPlatform());
// 校验模型是否存在
validateExists(req.getId());
// 转换 updateChatModalDO
AiChatModelDO updateChatModalDO = AiChatModelConvert.INSTANCE.convertAiChatModalDO(req);
updateChatModalDO.setId(req.getId());
// 更新数据库
aiChatModelMapper.updateById(updateChatModalDO);
}
@Override
public void delete(Long id) {
// 检查 modal 是否存在
validateExists(id);
// 删除 delete
aiChatModelMapper.deleteById(id);
}
@Override
public AiChatModalRespVO getChatModalOfValidate(Long modalId) {
// 检查 modal 是否存在
AiChatModelDO aiChatModalDO = validateExists(modalId);
return AiChatModelConvert.INSTANCE.convertAiChatModalRes(aiChatModalDO);
}
@Override
public void validateAvailable(AiChatModalRespVO chatModal) {
// 对话模型是否可用
if (!CommonStatusEnum.ENABLE.getStatus().equals(chatModal.getStatus())) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_DISABLE_NOT_USED);
}
}
public AiChatModelDO validateExists(Long id) {
AiChatModelDO aiChatModalDO = aiChatModelMapper.selectById(id);
if (aiChatModalDO == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_NOT_EXIST);
}
return aiChatModalDO;
}
private void validatePlatform(String platform) {
try {
AiPlatformEnum.valueOfPlatform(platform);
} catch (IllegalArgumentException e) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_PLATFORM_PARAMS_INCORRECT, e.getMessage());
}
}
private void validateModalConfig(AiChatModalConfigVO aiChatModalConfigVO) {
Set<ConstraintViolation<AiChatModalConfigVO>> validate = ValidationUtil.validate(aiChatModalConfigVO);
for (ConstraintViolation<AiChatModalConfigVO> constraintViolation : validate) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_CONFIG_PARAMS_INCORRECT, constraintViolation.getMessage());
}
}
}

View File

@ -12,7 +12,7 @@ import cn.iocoder.yudao.module.ai.convert.AiChatRoleConvert;
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
import cn.iocoder.yudao.module.ai.dal.mysql.AiChatRoleMapper;
import cn.iocoder.yudao.module.ai.enums.AiChatRoleCategoryEnum;
import cn.iocoder.yudao.module.ai.service.AiChatModelService;
import cn.iocoder.yudao.module.ai.service.model.AiChatModelService;
import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -57,8 +57,8 @@ public class AiChatRoleServiceImpl implements AiChatRoleService {
public void add(AiChatRoleAddReqVO req) {
// 转换enum并校验enum
AiChatRoleCategoryEnum.valueOfCategory(req.getCategory());
// 校验模型是否存在
aiChatModalService.validateExists(req.getModelId());
// 校验模型是否存在 TODO
// aiChatModalService.validateExists(req.getModelId());
// 转换do
AiChatRoleDO insertAiChatRoleDO = AiChatRoleConvert.INSTANCE.convertAiChatRoleDO(req);
insertAiChatRoleDO.setUserId(SecurityFrameworkUtils.getLoginUserId());
@ -73,8 +73,8 @@ public class AiChatRoleServiceImpl implements AiChatRoleService {
validateExists(req.getId());
// 转换enum并校验enum
AiChatRoleCategoryEnum.valueOfCategory(req.getCategory());
// 校验模型是否存在
aiChatModalService.validateExists(req.getModelId());
// 校验模型是否存在 TODO
// aiChatModalService.validateExists(req.getModelId());
// 转换do
AiChatRoleDO updateChatRole = AiChatRoleConvert.INSTANCE.convertAiChatRoleDO(req);
updateChatRole.setId(req.getId());

View File

@ -12,14 +12,14 @@ import cn.iocoder.yudao.module.ai.config.AiChatClientFactory;
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationRespVO;
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageRespVO;
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModalRespVO;
import cn.iocoder.yudao.module.ai.convert.AiChatMessageConvert;
import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO;
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
import cn.iocoder.yudao.module.ai.dal.mysql.AiChatConversationMapper;
import cn.iocoder.yudao.module.ai.dal.mysql.AiChatMessageMapper;
import cn.iocoder.yudao.module.ai.service.AiChatConversationService;
import cn.iocoder.yudao.module.ai.service.AiChatModelService;
import cn.iocoder.yudao.module.ai.service.model.AiChatModelService;
import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
import cn.iocoder.yudao.module.ai.service.AiChatService;
import lombok.AllArgsConstructor;
@ -57,9 +57,7 @@ public class AiChatServiceImpl implements AiChatService {
// 查询对话
AiChatConversationRespVO conversation = chatConversationService.getConversationOfValidate(req.getConversationId());
// 获取对话模型
AiChatModalRespVO chatModal = aiChatModalService.getChatModalOfValidate(conversation.getModelId());
// 对话模型是否可用
aiChatModalService.validateAvailable(chatModal);
AiChatModelDO chatModel = aiChatModalService.validateChatModel(conversation.getModelId());
// 获取角色信息
AiChatRoleDO aiChatRoleDO = null;
if (conversation.getRoleId() != null) {
@ -68,10 +66,10 @@ public class AiChatServiceImpl implements AiChatService {
// 校验角色是否公开
aiChatRoleService.validateIsPublic(aiChatRoleDO);
// 获取 client 类型
AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(chatModal.getPlatform());
AiPlatformEnum platformEnum = AiPlatformEnum.validatePlatform(chatModel.getPlatform());
// 保存 chat message
insertChatMessage(conversation.getId(), MessageType.USER, loginUserId, conversation.getRoleId(),
chatModal.getModel(), chatModal.getId(), req.getContent(),
chatModel.getModel(), chatModel.getId(), req.getContent(),
null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
String content = null;
int tokens = 0;
@ -93,7 +91,7 @@ public class AiChatServiceImpl implements AiChatService {
} finally {
// 保存 chat message
insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(),
chatModal.getModel(), chatModal.getId(), content,
chatModel.getModel(), chatModel.getId(), content,
tokens, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
}
return new AiChatMessageRespVO().setContent(content);
@ -128,9 +126,7 @@ public class AiChatServiceImpl implements AiChatService {
// 查询对话
AiChatConversationRespVO conversation = chatConversationService.getConversationOfValidate(req.getConversationId());
// 获取对话模型
AiChatModalRespVO chatModal = aiChatModalService.getChatModalOfValidate(conversation.getModelId());
// 对话模型是否可用
aiChatModalService.validateAvailable(chatModal);
AiChatModelDO chatModel = aiChatModalService.validateChatModel(conversation.getModelId());
// 获取角色信息
AiChatRoleDO aiChatRoleDO = null;
if (conversation.getRoleId() != null) {
@ -145,10 +141,10 @@ public class AiChatServiceImpl implements AiChatService {
// req.setTemperature(req.getTemperature());
// 保存 chat message
insertChatMessage(conversation.getId(), MessageType.USER, loginUserId, conversation.getRoleId(),
chatModal.getModel(), chatModal.getId(), req.getContent(),
chatModel.getModel(), chatModel.getId(), req.getContent(),
null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
// 获取 client 类型
AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(chatModal.getPlatform());
AiPlatformEnum platformEnum = AiPlatformEnum.validatePlatform(chatModel.getPlatform());
StreamingChatClient streamingChatClient = aiChatClientFactory.getStreamingChatClient(platformEnum);
Flux<ChatResponse> streamResponse = streamingChatClient.stream(prompt);
// 转换 flex AiChatMessageRespVO
@ -167,7 +163,7 @@ public class AiChatServiceImpl implements AiChatService {
log.info("发送完成!");
// 保存 chat message
insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(),
chatModal.getModel(), chatModal.getId(), contentBuffer.toString(),
chatModel.getModel(), chatModel.getId(), contentBuffer.toString(),
tokens.get(), conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
}
}).doOnError(new Consumer<Throwable>() {
@ -176,7 +172,7 @@ public class AiChatServiceImpl implements AiChatService {
log.error("发送错误 {}!", throwable.getMessage());
// 保存 chat message
insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(),
chatModal.getModel(), chatModal.getId(), throwable.getMessage(),
chatModel.getModel(), chatModel.getId(), throwable.getMessage(),
tokens.get(), conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
}
});

View File

@ -14,7 +14,7 @@ import jakarta.validation.Valid;
public interface AiApiKeyService {
/**
* 创建AI API 密钥
* 创建 API 密钥
*
* @param createReqVO 创建信息
* @return 编号
@ -22,32 +22,40 @@ public interface AiApiKeyService {
Long createApiKey(@Valid AiApiKeySaveReqVO createReqVO);
/**
* 更新AI API 密钥
* 更新 API 密钥
*
* @param updateReqVO 更新信息
*/
void updateApiKey(@Valid AiApiKeySaveReqVO updateReqVO);
/**
* 删除AI API 密钥
* 删除 API 密钥
*
* @param id 编号
*/
void deleteApiKey(Long id);
/**
* 获得AI API 密钥
* 获得 API 密钥
*
* @param id 编号
* @return AI API 密钥
* @return API 密钥
*/
AiApiKeyDO getApiKey(Long id);
/**
* 获得AI API 密钥分页
* 校验 API 密钥
*
* @param id 比那好
* @return API 密钥
*/
AiApiKeyDO validateApiKey(Long id);
/**
* 获得 API 密钥分页
*
* @param pageReqVO 分页查询
* @return AI API 密钥分页
* @return API 密钥分页
*/
PageResult<AiApiKeyDO> getApiKeyPage(AiApiKeyPageReqVO pageReqVO);

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.ai.service.model;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeyPageReqVO;
@ -11,7 +12,7 @@ import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.API_KEY_NOT_EXISTS;
import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.*;
/**
* AI API 密钥 Service 实现类
@ -51,10 +52,12 @@ public class AiApiKeyServiceImpl implements AiApiKeyService {
apiKeyMapper.deleteById(id);
}
private void validateApiKeyExists(Long id) {
if (apiKeyMapper.selectById(id) == null) {
private AiApiKeyDO validateApiKeyExists(Long id) {
AiApiKeyDO apiKey = apiKeyMapper.selectById(id);
if (apiKey == null) {
throw exception(API_KEY_NOT_EXISTS);
}
return apiKey;
}
@Override
@ -62,6 +65,15 @@ public class AiApiKeyServiceImpl implements AiApiKeyService {
return apiKeyMapper.selectById(id);
}
@Override
public AiApiKeyDO validateApiKey(Long id) {
AiApiKeyDO apiKey = validateApiKeyExists(id);
if (CommonStatusEnum.isDisable(apiKey.getStatus())) {
throw exception(API_KEY_DISABLE);
}
return apiKey;
}
@Override
public PageResult<AiApiKeyDO> getApiKeyPage(AiApiKeyPageReqVO pageReqVO) {
return apiKeyMapper.selectPage(pageReqVO);

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.ai.service.impl;
package cn.iocoder.yudao.module.ai.service.model;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.ai.ErrorCodeConstants;
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationCreateReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationRespVO;
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationUpdateReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModalRespVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.AiChatRoleRespVO;
import cn.iocoder.yudao.module.ai.convert.AiChatConversationConvert;
import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatConversationDO;
@ -15,7 +14,6 @@ import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
import cn.iocoder.yudao.module.ai.dal.mysql.AiChatConversationMapper;
import cn.iocoder.yudao.module.ai.dal.mysql.AiChatModelMapper;
import cn.iocoder.yudao.module.ai.service.AiChatConversationService;
import cn.iocoder.yudao.module.ai.service.AiChatModelService;
import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -87,9 +85,7 @@ public class AiChatConversationServiceImpl implements AiChatConversationService
// 校验对话是否存在
validateExists(updateReqVO.getId());
// 获取模型信息并验证
AiChatModalRespVO chatModal = aiChatModalService.getChatModalOfValidate(updateReqVO.getModelId());
// 校验modal是否可用
aiChatModalService.validateAvailable(chatModal);
aiChatModalService.validateChatModel(updateReqVO.getModelId());
// 更新对话信息
AiChatConversationDO updateAiChatConversationDO
= AiChatConversationConvert.INSTANCE.convertAiChatConversationDO(updateReqVO);

View File

@ -0,0 +1,63 @@
package cn.iocoder.yudao.module.ai.service.model;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelPageReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelSaveReqVO;
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
import jakarta.validation.Valid;
/**
* AI 聊天模型 Service 接口
*
* @author fansili
* @since 2024/4/24 19:42
*/
public interface AiChatModelService {
/**
* 创建聊天模型
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createChatModel(@Valid AiChatModelSaveReqVO createReqVO);
/**
* 更新聊天模型
*
* @param updateReqVO 更新信息
*/
void updateChatModel(@Valid AiChatModelSaveReqVO updateReqVO);
/**
* 删除聊天模型
*
* @param id 编号
*/
void deleteChatModel(Long id);
/**
* 获得聊天模型
*
* @param id 编号
* @return API 聊天模型
*/
AiChatModelDO getChatModel(Long id);
/**
* 获得聊天模型分页
*
* @param pageReqVO 分页查询
* @return API 聊天模型分页
*/
PageResult<AiChatModelDO> getChatModelPage(AiChatModelPageReqVO pageReqVO);
/**
* 校验聊天模型
*
* @param id 编号
* @return 聊天模型
*/
AiChatModelDO validateChatModel(Long id);
}

View File

@ -0,0 +1,92 @@
package cn.iocoder.yudao.module.ai.service.model;
import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelPageReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelSaveReqVO;
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
import cn.iocoder.yudao.module.ai.dal.mysql.AiChatModelMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.*;
/**
* AI 聊天模型 Service 实现类
*
* @author fansili
*/
@Service
@Validated
public class AiChatModelServiceImpl implements AiChatModelService {
@Resource
private AiApiKeyService apiKeyService;
@Resource
private AiChatModelMapper chatModelMapper;
@Override
public Long createChatModel(AiChatModelSaveReqVO createReqVO) {
// 1. 校验
AiPlatformEnum.validatePlatform(createReqVO.getPlatform());
apiKeyService.validateApiKey(createReqVO.getKeyId());
// 2. 插入
AiChatModelDO chatModel = BeanUtils.toBean(createReqVO, AiChatModelDO.class);
chatModelMapper.insert(chatModel);
return chatModel.getId();
}
@Override
public void updateChatModel(AiChatModelSaveReqVO updateReqVO) {
// 1. 校验
validateChatModelExists(updateReqVO.getId());
AiPlatformEnum.validatePlatform(updateReqVO.getPlatform());
apiKeyService.validateApiKey(updateReqVO.getKeyId());
// 2. 更新
AiChatModelDO updateObj = BeanUtils.toBean(updateReqVO, AiChatModelDO.class);
chatModelMapper.updateById(updateObj);
}
@Override
public void deleteChatModel(Long id) {
// 校验存在
validateChatModelExists(id);
// 删除
chatModelMapper.deleteById(id);
}
private AiChatModelDO validateChatModelExists(Long id) {
AiChatModelDO model = chatModelMapper.selectById(id);
if (chatModelMapper.selectById(id) == null) {
throw exception(CHAT_MODAL_NOT_EXIST);
}
return model;
}
@Override
public AiChatModelDO getChatModel(Long id) {
return chatModelMapper.selectById(id);
}
@Override
public PageResult<AiChatModelDO> getChatModelPage(AiChatModelPageReqVO pageReqVO) {
return chatModelMapper.selectPage(pageReqVO);
}
@Override
public AiChatModelDO validateChatModel(Long id) {
AiChatModelDO model = validateChatModelExists(id);
if (CommonStatusEnum.isDisable(model.getStatus())) {
throw exception(CHAT_MODAL_DISABLE);
}
return model;
}
}

View File

@ -41,7 +41,7 @@ public enum AiPlatformEnum {
AiPlatformEnum.MIDJOURNEY
);
public static AiPlatformEnum valueOfPlatform(String platform) {
public static AiPlatformEnum validatePlatform(String platform) {
for (AiPlatformEnum itemEnum : AiPlatformEnum.values()) {
if (itemEnum.getPlatform().equals(platform)) {
return itemEnum;