Commit b9deba889c64e5e24fa068c8ab70e44beaaa8e7b

Authored by YunaiV
1 parent caca47b6

【新增】AI:API 模型管理

Showing 27 changed files with 406 additions and 662 deletions
yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/ErrorCodeConstants.java
... ... @@ -11,10 +11,15 @@ public interface ErrorCodeConstants {
11 11  
12 12 // ========== API 密钥 1-040-000-000 ==========
13 13 ErrorCode API_KEY_NOT_EXISTS = new ErrorCode(1_040_000_000, "AI API 密钥不存在");
  14 + ErrorCode API_KEY_DISABLE = new ErrorCode(1_040_000_001, "AI API 密钥已禁用!");
14 15  
15   - // chat
  16 + // ========== API 聊天模型 1-040-001-000 ==========
16 17  
17   - ErrorCode AI_MODULE_NOT_SUPPORTED = new ErrorCode(1_022_000_000, "AI 模型暂不支持!");
  18 + ErrorCode CHAT_MODAL_NOT_EXIST = new ErrorCode(1_040_001_000, "AI 模型不存在!");
  19 + ErrorCode CHAT_MODAL_DISABLE = new ErrorCode(1_040_001_001, "AI 模型({})已禁用!");
  20 +
  21 + // ErrorCode AI_MODAL_CONFIG_PARAMS_INCORRECT = new ErrorCode(1_022_000_081, "AI 模型 config 参数不正确! {} ");
  22 +// ErrorCode AI_MODAL_PLATFORM_PARAMS_INCORRECT = new ErrorCode(1_022_000_083, "AI 平台参数不正确! {} ");
18 23  
19 24 // conversation
20 25  
... ... @@ -31,12 +36,5 @@ public interface ErrorCodeConstants {
31 36 ErrorCode AI_CHAT_ROLE_NOT_EXIST = new ErrorCode(1_022_000_060, "AI 角色不存在!");
32 37 ErrorCode AI_CHAT_ROLE_NOT_PUBLIC = new ErrorCode(1_022_000_060, "AI 角色未公开!");
33 38  
34   - // modal
35   -
36   - ErrorCode AI_MODAL_NOT_EXIST = new ErrorCode(1_022_000_080, "AI 模型不存在!");
37   - ErrorCode AI_MODAL_CONFIG_PARAMS_INCORRECT = new ErrorCode(1_022_000_081, "AI 模型 config 参数不正确! {} ");
38   - ErrorCode AI_MODAL_PLATFORM_PARAMS_INCORRECT = new ErrorCode(1_022_000_083, "AI 平台参数不正确! {} ");
39   - ErrorCode AI_MODAL_DISABLE_NOT_USED = new ErrorCode(1_022_000_084, "AI 模型禁用不能使用!");
40   -
41 39  
42 40 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/AiApiKeyController.java
... ... @@ -29,14 +29,14 @@ public class AiApiKeyController {
29 29 private AiApiKeyService apiKeyService;
30 30  
31 31 @PostMapping("/create")
32   - @Operation(summary = "创建AI API 密钥")
  32 + @Operation(summary = "创建 API 密钥")
33 33 @PreAuthorize("@ss.hasPermission('ai:api-key:create')")
34 34 public CommonResult<Long> createApiKey(@Valid @RequestBody AiApiKeySaveReqVO createReqVO) {
35 35 return success(apiKeyService.createApiKey(createReqVO));
36 36 }
37 37  
38 38 @PutMapping("/update")
39   - @Operation(summary = "更新AI API 密钥")
  39 + @Operation(summary = "更新 API 密钥")
40 40 @PreAuthorize("@ss.hasPermission('ai:api-key:update')")
41 41 public CommonResult<Boolean> updateApiKey(@Valid @RequestBody AiApiKeySaveReqVO updateReqVO) {
42 42 apiKeyService.updateApiKey(updateReqVO);
... ... @@ -44,7 +44,7 @@ public class AiApiKeyController {
44 44 }
45 45  
46 46 @DeleteMapping("/delete")
47   - @Operation(summary = "删除AI API 密钥")
  47 + @Operation(summary = "删除 API 密钥")
48 48 @Parameter(name = "id", description = "编号", required = true)
49 49 @PreAuthorize("@ss.hasPermission('ai:api-key:delete')")
50 50 public CommonResult<Boolean> deleteApiKey(@RequestParam("id") Long id) {
... ... @@ -53,7 +53,7 @@ public class AiApiKeyController {
53 53 }
54 54  
55 55 @GetMapping("/get")
56   - @Operation(summary = "获得AI API 密钥")
  56 + @Operation(summary = "获得 API 密钥")
57 57 @Parameter(name = "id", description = "编号", required = true, example = "1024")
58 58 @PreAuthorize("@ss.hasPermission('ai:api-key:query')")
59 59 public CommonResult<AiApiKeyRespVO> getApiKey(@RequestParam("id") Long id) {
... ... @@ -62,7 +62,7 @@ public class AiApiKeyController {
62 62 }
63 63  
64 64 @GetMapping("/page")
65   - @Operation(summary = "获得AI API 密钥分页")
  65 + @Operation(summary = "获得 API 密钥分页")
66 66 @PreAuthorize("@ss.hasPermission('ai:api-key:query')")
67 67 public CommonResult<PageResult<AiApiKeyRespVO>> getApiKeyPage(@Valid AiApiKeyPageReqVO pageReqVO) {
68 68 PageResult<AiApiKeyDO> pageResult = apiKeyService.getApiKeyPage(pageReqVO);
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/AiChatModelController.java
... ... @@ -2,60 +2,71 @@ package cn.iocoder.yudao.module.ai.controller.admin.model;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5   -import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelAddReqVO;
6   -import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelListReqVO;
7   -import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelListRespVO;
8   -import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelUpdateReqVO;
9   -import cn.iocoder.yudao.module.ai.service.AiChatModelService;
  5 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  6 +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelPageReqVO;
  7 +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelRespVO;
  8 +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelSaveReqVO;
  9 +import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
  10 +import cn.iocoder.yudao.module.ai.service.model.AiChatModelService;
10 11 import io.swagger.v3.oas.annotations.Operation;
  12 +import io.swagger.v3.oas.annotations.Parameter;
11 13 import io.swagger.v3.oas.annotations.tags.Tag;
12   -import lombok.AllArgsConstructor;
13   -import lombok.extern.slf4j.Slf4j;
  14 +import jakarta.annotation.Resource;
  15 +import jakarta.validation.Valid;
  16 +import org.springframework.security.access.prepost.PreAuthorize;
14 17 import org.springframework.validation.annotation.Validated;
15 18 import org.springframework.web.bind.annotation.*;
16 19  
17   -// TODO @fan:调整下接口;相关 vo 的命名等等;modal => model
  20 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
18 21  
19   -/**
20   - * ai 模型
21   - *
22   - * @author fansili
23   - * @time 2024/4/24 19:42
24   - * @since 1.0
25   - */
26   -@Tag(name = "A6-AI模型")
  22 +@Tag(name = "管理后台 - AI 聊天模型")
27 23 @RestController
28   -@RequestMapping("/ai/chat/model")
29   -@Slf4j
30   -@AllArgsConstructor
  24 +@RequestMapping("/ai/chat-model")
  25 +@Validated
31 26 public class AiChatModelController {
32 27  
33   - private final AiChatModelService aiChatModelService;
  28 + @Resource
  29 + private AiChatModelService chatModelService;
34 30  
35   - @Operation(summary = "ai模型 - 模型列表")
36   - @GetMapping("/list")
37   - public PageResult<AiChatModelListRespVO> list(@ModelAttribute AiChatModelListReqVO req) {
38   - return aiChatModelService.list(req);
  31 + @PostMapping("/create")
  32 + @Operation(summary = "创建聊天模型")
  33 + @PreAuthorize("@ss.hasPermission('ai:chat-model:create')")
  34 + public CommonResult<Long> createChatModel(@Valid @RequestBody AiChatModelSaveReqVO createReqVO) {
  35 + return success(chatModelService.createChatModel(createReqVO));
39 36 }
40 37  
41   - @Operation(summary = "ai模型 - 添加")
42   - @PutMapping("/add")
43   - public CommonResult<Void> add(@RequestBody @Validated AiChatModelAddReqVO req) {
44   - aiChatModelService.add(req);
45   - return CommonResult.success(null);
  38 + @PutMapping("/update")
  39 + @Operation(summary = "更新聊天模型")
  40 + @PreAuthorize("@ss.hasPermission('ai:chat-model:update')")
  41 + public CommonResult<Boolean> updateChatModel(@Valid @RequestBody AiChatModelSaveReqVO updateReqVO) {
  42 + chatModelService.updateChatModel(updateReqVO);
  43 + return success(true);
46 44 }
47 45  
48   - @Operation(summary = "ai模型 - 修改")
49   - @PostMapping("/update")
50   - public CommonResult<Void> update(@RequestBody @Validated AiChatModelUpdateReqVO req) {
51   - aiChatModelService.update(req);
52   - return CommonResult.success(null);
  46 + @DeleteMapping("/delete")
  47 + @Operation(summary = "删除聊天模型")
  48 + @Parameter(name = "id", description = "编号", required = true)
  49 + @PreAuthorize("@ss.hasPermission('ai:chat-model:delete')")
  50 + public CommonResult<Boolean> deleteChatModel(@RequestParam("id") Long id) {
  51 + chatModelService.deleteChatModel(id);
  52 + return success(true);
53 53 }
54 54  
55   - @Operation(summary = "ai模型 - 删除")
56   - @DeleteMapping("/delete")
57   - public CommonResult<Void> delete(@RequestParam("id") Long id) {
58   - aiChatModelService.delete(id);
59   - return CommonResult.success(null);
  55 + @GetMapping("/get")
  56 + @Operation(summary = "获得聊天模型")
  57 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  58 + @PreAuthorize("@ss.hasPermission('ai:chat-model:query')")
  59 + public CommonResult<AiChatModelRespVO> getChatModel(@RequestParam("id") Long id) {
  60 + AiChatModelDO chatModel = chatModelService.getChatModel(id);
  61 + return success(BeanUtils.toBean(chatModel, AiChatModelRespVO.class));
60 62 }
61   -}
  63 +
  64 + @GetMapping("/page")
  65 + @Operation(summary = "获得聊天模型分页")
  66 + @PreAuthorize("@ss.hasPermission('ai:chat-model:query')")
  67 + public CommonResult<PageResult<AiChatModelRespVO>> getChatModelPage(@Valid AiChatModelPageReqVO pageReqVO) {
  68 + PageResult<AiChatModelDO> pageResult = chatModelService.getChatModelPage(pageReqVO);
  69 + return success(BeanUtils.toBean(pageResult, AiChatModelRespVO.class));
  70 + }
  71 +
  72 +}
62 73 \ No newline at end of file
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/AiChatRoleController.java
... ... @@ -6,26 +6,20 @@ import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.*;
6 6 import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
7 7 import io.swagger.v3.oas.annotations.Operation;
8 8 import io.swagger.v3.oas.annotations.tags.Tag;
  9 +import jakarta.annotation.Resource;
9 10 import lombok.AllArgsConstructor;
10 11 import lombok.extern.slf4j.Slf4j;
11 12 import org.springframework.validation.annotation.Validated;
12 13 import org.springframework.web.bind.annotation.*;
13 14  
14   -// TODO @fan:调整下接口;相关 vo 的命名等等;modal => model
15   -/**
16   - * ai chat 角色
17   - *
18   - * @fansili
19   - * @since v1.0
20   - */
21   -@Tag(name = "A4-chat角色")
  15 +@Tag(name = "管理后台 - AI 聊天角色")
22 16 @RestController
23   -@RequestMapping("/ai/chat/role")
24   -@Slf4j
25   -@AllArgsConstructor
  17 +@RequestMapping("/ai/chat-role")
  18 +@Validated
26 19 public class AiChatRoleController {
27 20  
28   - private final AiChatRoleService chatRoleService;
  21 + @Resource
  22 + private AiChatRoleService chatRoleService;
29 23  
30 24 @Operation(summary = "chat角色 - 角色列表")
31 25 @GetMapping("/list")
... ... @@ -60,4 +54,9 @@ public class AiChatRoleController {
60 54 chatRoleService.delete(id);
61 55 return CommonResult.success(null);
62 56 }
  57 +
  58 + // ========== 角色管理 ==========
  59 +
  60 +
  61 +
63 62 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/chatModel/AiChatModelPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel;
  2 +
  3 +import lombok.*;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  6 +
  7 +@Schema(description = "管理后台 - API 聊天模型分页 Request VO")
  8 +@Data
  9 +@EqualsAndHashCode(callSuper = true)
  10 +@ToString(callSuper = true)
  11 +public class AiChatModelPageReqVO extends PageParam {
  12 +
  13 + @Schema(description = "模型名字", example = "张三")
  14 + private String name;
  15 +
  16 + @Schema(description = "模型标识", example = "gpt-3.5-turbo-0125")
  17 + private String model;
  18 +
  19 + @Schema(description = "模型平台", example = "OpenAI")
  20 + private String platform;
  21 +
  22 +}
0 23 \ No newline at end of file
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/chatModel/AiChatModelRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +@Schema(description = "管理后台 - AI 聊天模型 Response VO")
  9 +@Data
  10 +public class AiChatModelRespVO {
  11 +
  12 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2630")
  13 + private Long id;
  14 +
  15 + @Schema(description = "API 秘钥编号", example = "22042")
  16 + private Long keyId;
  17 +
  18 + @Schema(description = "模型名字", example = "张三")
  19 + private String name;
  20 +
  21 + @Schema(description = "模型标识", example = "gpt-3.5-turbo-0125")
  22 + private String model;
  23 +
  24 + @Schema(description = "模型平台", example = "OpenAI")
  25 + private String platform;
  26 +
  27 + @Schema(description = "排序", example = "1")
  28 + private Integer sort;
  29 +
  30 + @Schema(description = "状态", example = "2")
  31 + private Integer status;
  32 +
  33 + @Schema(description = "温度参数", example = "1")
  34 + private Double temperature;
  35 +
  36 + @Schema(description = "单条回复的最大 Token 数量", example = "4096")
  37 + private Integer maxTokens;
  38 +
  39 + @Schema(description = "上下文的最大 Message 数量", example = "8192")
  40 + private Integer maxContexts;
  41 +
  42 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  43 + private LocalDateTime createTime;
  44 +
  45 +}
0 46 \ No newline at end of file
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/chatModel/AiChatModelSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import lombok.*;
  7 +import jakarta.validation.constraints.*;
  8 +
  9 +@Schema(description = "管理后台 - API 聊天模型新增/修改 Request VO")
  10 +@Data
  11 +public class AiChatModelSaveReqVO {
  12 +
  13 + @Schema(description = "编号", example = "2630")
  14 + private Long id;
  15 +
  16 + @Schema(description = "API 秘钥编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22042")
  17 + @NotNull(message = "API 秘钥编号不能为空")
  18 + private Long keyId;
  19 +
  20 + @Schema(description = "模型名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
  21 + @NotEmpty(message = "模型名字不能为空")
  22 + private String name;
  23 +
  24 + @Schema(description = "模型标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "gpt-3.5-turbo-0125")
  25 + @NotEmpty(message = "模型标识不能为空")
  26 + private String model;
  27 +
  28 + @Schema(description = "模型平台", requiredMode = Schema.RequiredMode.REQUIRED, example = "OpenAI")
  29 + @NotEmpty(message = "模型平台不能为空")
  30 + private String platform;
  31 +
  32 + @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  33 + @NotNull(message = "排序不能为空")
  34 + private Integer sort;
  35 +
  36 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  37 + @InEnum(CommonStatusEnum.class)
  38 + @NotNull(message = "状态不能为空")
  39 + private Integer status;
  40 +
  41 + @Schema(description = "温度参数", example = "1")
  42 + private Double temperature;
  43 +
  44 + @Schema(description = "单条回复的最大 Token 数量", example = "4096")
  45 + private Integer maxTokens;
  46 +
  47 + @Schema(description = "上下文的最大 Message 数量", example = "8192")
  48 + private Integer maxContexts;
  49 +
  50 +}
0 51 \ No newline at end of file
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/model/AiChatModalRespVO.java deleted
1   -package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
2   -
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -import jakarta.validation.constraints.Size;
5   -import lombok.Data;
6   -import lombok.experimental.Accessors;
7   -
8   -/**
9   - * modal list
10   - *
11   - * @author fansili
12   - * @time 2024/4/24 19:56
13   - * @since 1.0
14   - */
15   -@Data
16   -@Accessors(chain = true)
17   -public class AiChatModalRespVO {
18   -
19   - @Schema(description = "编号")
20   - private Long id;
21   -
22   - @Schema(description = "API 秘钥编号")
23   - private Long keyId;
24   -
25   - @Schema(description = "模型名字")
26   - private String name;
27   -
28   - @Schema(description = "模型类型(qianwen、yiyan、xinghuo、openai)")
29   - private String model;
30   -
31   - @Size(max = 32, message = "模型平台最大32个字符")
32   - private String platform;
33   -
34   - @Schema(description = "排序")
35   - private Integer sort;
36   -
37   - @Schema(description = "状态")
38   - private Integer status;
39   -
40   - // ========== 会话配置 ==========
41   -
42   - @Schema(description = "温度参数")
43   - private Integer temperature;
44   -
45   - @Schema(description = "单条回复的最大 Token 数量")
46   - private Integer maxTokens;
47   -
48   - @Schema(description = "上下文的最大 Message 数量")
49   - private Integer maxContexts;
50   -}
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/model/AiChatModalUpdateReqVO.java deleted
1   -package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
2   -
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -import jakarta.validation.constraints.NotNull;
5   -import jakarta.validation.constraints.Size;
6   -import lombok.Data;
7   -import lombok.experimental.Accessors;
8   -
9   -/**
10   - * ai chat modal
11   - *
12   - * @author fansili
13   - * @time 2024/4/24 19:47
14   - * @since 1.0
15   - */
16   -@Data
17   -@Accessors(chain = true)
18   -public class AiChatModalUpdateReqVO {
19   -
20   - @Schema(description = "编号")
21   - @Size(max = 32, message = "编号最大32个字符")
22   - @NotNull(message = "编号不能为空")
23   - private Long id;
24   -
25   - @Schema(description = "API 秘钥编号")
26   - @Size(max = 32, message = "API 秘钥编号最大32个字符")
27   - @NotNull(message = "API 秘钥编号不能为空!")
28   - private Long keyId;
29   -
30   - @Schema(description = "模型名字")
31   - @Size(max = 60, message = "模型名字最大60个字符")
32   - @NotNull(message = "模型名字不能为空!")
33   - private String name;
34   -
35   - @Schema(description = "模型类型(qianwen、yiyan、xinghuo、openai)")
36   - @Size(max = 32, message = "模型类型最大32个字符")
37   - @NotNull(message = "model模型不能为空!")
38   - private String model;
39   -
40   - @Size(max = 32, message = "模型平台最大32个字符")
41   - @Schema(description = "模型平台 参考 AiPlatformEnum")
42   - @NotNull(message = "平台不能为空!")
43   - private String platform;
44   -
45   - @Schema(description = "排序")
46   - @NotNull(message = "sort排序不能为空!")
47   - private Integer sort;
48   -
49   - @Schema(description = "状态")
50   - @NotNull(message = "状态不能为空!")
51   - private Integer status;
52   -
53   - // ========== 会话配置 ==========
54   -
55   - @Schema(description = "温度参数")
56   - private Integer temperature;
57   -
58   - @Schema(description = "单条回复的最大 Token 数量")
59   - private Integer maxTokens;
60   -
61   - @Schema(description = "上下文的最大 Message 数量")
62   - private Integer maxContexts;
63   -}
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/model/AiChatModelAddReqVO.java deleted
1   -package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
2   -
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -import jakarta.validation.constraints.NotNull;
5   -import jakarta.validation.constraints.Size;
6   -import lombok.Data;
7   -import lombok.experimental.Accessors;
8   -
9   -/**
10   - * ai chat modal
11   - *
12   - * @author fansili
13   - * @time 2024/4/24 19:47
14   - * @since 1.0
15   - */
16   -@Data
17   -@Accessors(chain = true)
18   -public class AiChatModelAddReqVO {
19   -
20   - @Schema(description = "API 秘钥编号")
21   - @NotNull(message = "API 秘钥编号不能为空!")
22   - private Long keyId;
23   -
24   - @Schema(description = "模型名字")
25   - @Size(max = 60, message = "模型名字最大60个字符")
26   - @NotNull(message = "模型名字不能为空!")
27   - private String name;
28   -
29   - @Schema(description = "模型类型(qianwen、yiyan、xinghuo、openai)")
30   - @Size(max = 32, message = "模型类型最大32个字符")
31   - @NotNull(message = "model模型不能为空!")
32   - private String model;
33   -
34   - @Size(max = 32, message = "模型平台最大32个字符")
35   - @Schema(description = "模型平台 参考 AiPlatformEnum")
36   - @NotNull(message = "平台不能为空!")
37   - private String platform;
38   -
39   - @Schema(description = "排序")
40   - @NotNull(message = "sort排序不能为空!")
41   - private Integer sort;
42   -
43   - // ========== 会话配置 ==========
44   -
45   - @Schema(description = "温度参数")
46   - private Integer temperature;
47   -
48   - @Schema(description = "单条回复的最大 Token 数量")
49   - private Integer maxTokens;
50   -
51   - @Schema(description = "上下文的最大 Message 数量")
52   - private Integer maxContexts;
53   -}
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/model/AiChatModelListReqVO.java deleted
1   -package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
2   -
3   -import cn.iocoder.yudao.framework.common.pojo.PageParam;
4   -import io.swagger.v3.oas.annotations.media.Schema;
5   -import lombok.Data;
6   -import lombok.experimental.Accessors;
7   -
8   -/**
9   - * modal list
10   - *
11   - * @author fansili
12   - * @time 2024/4/24 19:56
13   - * @since 1.0
14   - */
15   -@Data
16   -@Accessors(chain = true)
17   -public class AiChatModelListReqVO extends PageParam {
18   -
19   - @Schema(description = "名字搜搜")
20   - private String search;
21   -
22   -}
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/model/AiChatModelListRespVO.java deleted
1   -package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
2   -
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -import lombok.Data;
5   -import lombok.experimental.Accessors;
6   -
7   -/**
8   - * modal list
9   - *
10   - * @author fansili
11   - * @time 2024/4/24 19:56
12   - * @since 1.0
13   - */
14   -@Data
15   -@Accessors(chain = true)
16   -public class AiChatModelListRespVO {
17   -
18   - @Schema(description = "编号")
19   - private Long id;
20   -
21   - @Schema(description = "API 秘钥编号")
22   - private Long keyId;
23   -
24   - @Schema(description = "模型名称")
25   - private String name;
26   -
27   - @Schema(description = "模型标志")
28   - private String model;
29   -
30   - @Schema(description = "平台")
31   - private String platform;
32   -
33   - @Schema(description = "排序值")
34   - private Integer sort;
35   -
36   - @Schema(description = "状态")
37   - private Integer status;
38   -
39   - // ========== 会话配置 ==========
40   -
41   - @Schema(description = "温度参数")
42   - private Double temperature;
43   -
44   - @Schema(description = "单条回复的最大 Token 数量")
45   - private Integer maxTokens;
46   -
47   - @Schema(description = "上下文的最大 Message 数量")
48   - private Integer maxContexts;
49   -
50   -}
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/model/AiChatModelUpdateReqVO.java deleted
1   -package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
2   -
3   -import io.swagger.v3.oas.annotations.media.Schema;
4   -import jakarta.validation.constraints.NotNull;
5   -import jakarta.validation.constraints.Size;
6   -import lombok.Data;
7   -import lombok.experimental.Accessors;
8   -
9   -/**
10   - * ai chat modal
11   - *
12   - * @author fansili
13   - * @time 2024/4/24 19:47
14   - * @since 1.0
15   - */
16   -@Data
17   -@Accessors(chain = true)
18   -public class AiChatModelUpdateReqVO {
19   -
20   - @Schema(description = "编号")
21   - @NotNull(message = "编号不能为空")
22   - private Long id;
23   -
24   - @Schema(description = "API 秘钥编号")
25   - @NotNull(message = "API 秘钥编号不能为空!")
26   - private Long keyId;
27   -
28   - @Schema(description = "模型名字")
29   - @Size(max = 60, message = "模型名字最大60个字符")
30   - @NotNull(message = "模型名字不能为空!")
31   - private String name;
32   -
33   - @Schema(description = "模型类型(qianwen、yiyan、xinghuo、openai)")
34   - @Size(max = 32, message = "模型类型最大32个字符")
35   - @NotNull(message = "model模型不能为空!")
36   - private String model;
37   -
38   - @Size(max = 32, message = "模型平台最大32个字符")
39   - @Schema(description = "模型平台 参考 AiPlatformEnum")
40   - @NotNull(message = "平台不能为空!")
41   - private String platform;
42   -
43   - @Schema(description = "排序")
44   - @NotNull(message = "sort排序不能为空!")
45   - private Integer sort;
46   -
47   - // ========== 会话配置 ==========
48   -
49   - @Schema(description = "温度参数")
50   - private Integer temperature;
51   -
52   - @Schema(description = "单条回复的最大 Token 数量")
53   - private Integer maxTokens;
54   -
55   - @Schema(description = "上下文的最大 Message 数量")
56   - private Integer maxContexts;
57   -}
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/convert/AiChatMessageConvert.java
... ... @@ -20,14 +20,6 @@ public interface AiChatMessageConvert {
20 20 AiChatMessageConvert INSTANCE = Mappers.getMapper(AiChatMessageConvert.class);
21 21  
22 22 /**
23   - * 转换 ChatMessageListRes
24   - *
25   - * @param list
26   - * @return
27   - */
28   - List<AiChatMessageRespVO> convert(List<AiChatMessageDO> list);
29   -
30   - /**
31 23 * 转换 AiChatMessageRespVO
32 24 *
33 25 * @param aiChatMessageDOList
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/convert/AiChatModelConvert.java deleted
1   -package cn.iocoder.yudao.module.ai.convert;
2   -
3   -import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModalRespVO;
4   -import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelAddReqVO;
5   -import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelListRespVO;
6   -import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelUpdateReqVO;
7   -import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
8   -import org.mapstruct.Mapper;
9   -import org.mapstruct.factory.Mappers;
10   -
11   -import java.util.List;
12   -
13   -/**
14   - * 聊天 modal
15   - *
16   - * @author fansili
17   - * @time 2024/4/18 16:39
18   - * @since 1.0
19   - */
20   -@Mapper
21   -public interface AiChatModelConvert {
22   -
23   - AiChatModelConvert INSTANCE = Mappers.getMapper(AiChatModelConvert.class);
24   -
25   - /**
26   - * 转换 - AiChatModalListRes
27   - *
28   - * @param list
29   - * @return
30   - */
31   - List<AiChatModelListRespVO> convertAiChatModalListRes(List<AiChatModelDO> list);
32   -
33   - /**
34   - * 转换 - AiChatModalDO
35   - *
36   - * @param req
37   - * @return
38   - */
39   - AiChatModelDO convertAiChatModalDO(AiChatModelAddReqVO req);
40   -
41   - /**
42   - * 转换 - AiChatModalDO
43   - *
44   - * @param req
45   - * @return
46   - */
47   - AiChatModelDO convertAiChatModalDO(AiChatModelUpdateReqVO req);
48   -
49   - /**
50   - * 转换 - AiChatModalRes
51   - *
52   - * @param aiChatModalDO
53   - * @return
54   - */
55   - AiChatModalRespVO convertAiChatModalRes(AiChatModelDO aiChatModalDO);
56   -
57   -}
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/AiChatModelMapper.java
... ... @@ -5,21 +5,19 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
5 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
7 7 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  8 +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelPageReqVO;
8 9 import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
9 10 import org.apache.ibatis.annotations.Mapper;
10   -import org.springframework.stereotype.Repository;
11 11  
12 12 /**
13   - * chat modal
  13 + * API 聊天模型 Mapper
14 14 *
15 15 * @author fansili
16   - * @time 2024/4/24 19:41
17   - * @since 1.0
18 16 */
19   -@Repository
20 17 @Mapper
21 18 public interface AiChatModelMapper extends BaseMapperX<AiChatModelDO> {
22 19  
  20 + // TODO 芋艿:要搞一下
23 21 /**
24 22 * 查询 - 第一个modal
25 23 *
... ... @@ -36,5 +34,12 @@ public interface AiChatModelMapper extends BaseMapperX&lt;AiChatModelDO&gt; {
36 34 return pageResult.getList().get(0);
37 35 }
38 36  
  37 + default PageResult<AiChatModelDO> selectPage(AiChatModelPageReqVO reqVO) {
  38 + return selectPage(reqVO, new LambdaQueryWrapperX<AiChatModelDO>()
  39 + .likeIfPresent(AiChatModelDO::getName, reqVO.getName())
  40 + .eqIfPresent(AiChatModelDO::getModel, reqVO.getModel())
  41 + .eqIfPresent(AiChatModelDO::getPlatform, reqVO.getPlatform())
  42 + .orderByDesc(AiChatModelDO::getId));
  43 + }
39 44  
40 45 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/AiChatModelService.java deleted
1   -package cn.iocoder.yudao.module.ai.service;
2   -
3   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.*;
5   -import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
6   -
7   -/**
8   - * ai modal
9   - *
10   - * @author fansili
11   - * @time 2024/4/24 19:42
12   - * @since 1.0
13   - */
14   -public interface AiChatModelService {
15   -
16   - /**
17   - * ai modal - 列表
18   - *
19   - * @param req
20   - * @return
21   - */
22   - PageResult<AiChatModelListRespVO> list(AiChatModelListReqVO req);
23   -
24   - /**
25   - * ai modal - 添加
26   - *
27   - * @param req
28   - */
29   - void add(AiChatModelAddReqVO req);
30   -
31   - /**
32   - * ai modal - 更新
33   - *
34   - * @param req
35   - */
36   - void update(AiChatModelUpdateReqVO req);
37   -
38   - /**
39   - * ai modal - 删除
40   - *
41   - * @param id
42   - */
43   - void delete(Long id);
44   -
45   - /**
46   - * 获取 - 获取 modal
47   - *
48   - * @param modalId
49   - * @return
50   - */
51   - AiChatModalRespVO getChatModalOfValidate(Long modalId);
52   -
53   - /**
54   - * 校验 - 是否存在
55   - *
56   - * @param id
57   - * @return
58   - */
59   - AiChatModelDO validateExists(Long id);
60   -
61   - /**
62   - * 校验 - 校验是否可用
63   - *
64   - * @param chatModal
65   - */
66   - void validateAvailable(AiChatModalRespVO chatModal);
67   -}
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/AiChatRoleService.java
... ... @@ -72,4 +72,5 @@ public interface AiChatRoleService {
72 72 * @param aiChatRoleDO
73 73 */
74 74 void validateIsPublic(AiChatRoleDO aiChatRoleDO);
  75 +
75 76 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatModalServiceImpl.java deleted
1   -package cn.iocoder.yudao.module.ai.service.impl;
2   -
3   -import cn.hutool.core.util.StrUtil;
4   -import cn.hutool.extra.validation.ValidationUtil;
5   -import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
6   -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
7   -import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
8   -import cn.iocoder.yudao.framework.common.pojo.PageResult;
9   -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
10   -import cn.iocoder.yudao.module.ai.ErrorCodeConstants;
11   -import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.*;
12   -import cn.iocoder.yudao.module.ai.convert.AiChatModelConvert;
13   -import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
14   -import cn.iocoder.yudao.module.ai.dal.mysql.AiChatModelMapper;
15   -import cn.iocoder.yudao.module.ai.dal.vo.AiChatModalConfigVO;
16   -import cn.iocoder.yudao.module.ai.service.AiChatModelService;
17   -import jakarta.validation.ConstraintViolation;
18   -import lombok.AllArgsConstructor;
19   -import lombok.extern.slf4j.Slf4j;
20   -import org.springframework.stereotype.Service;
21   -
22   -import java.util.List;
23   -import java.util.Set;
24   -
25   -/**
26   - * ai 模型
27   - *
28   - * @author fansili
29   - * @time 2024/4/24 19:42
30   - * @since 1.0
31   - */
32   -@AllArgsConstructor
33   -@Service
34   -@Slf4j
35   -public class AiChatModalServiceImpl implements AiChatModelService {
36   -
37   - private final AiChatModelMapper aiChatModelMapper;
38   -
39   - @Override
40   - public PageResult<AiChatModelListRespVO> list(AiChatModelListReqVO req) {
41   - LambdaQueryWrapperX<AiChatModelDO> queryWrapperX = new LambdaQueryWrapperX<>();
42   - // 查询的都是未禁用的模型
43   - queryWrapperX.eq(AiChatModelDO::getStatus, CommonStatusEnum.ENABLE.getStatus());
44   - // search
45   - if (!StrUtil.isBlank(req.getSearch())) {
46   - queryWrapperX.like(AiChatModelDO::getName, req.getSearch().trim());
47   - }
48   - // 默认排序
49   - queryWrapperX.orderByAsc(AiChatModelDO::getSort);
50   - // 查询
51   - PageResult<AiChatModelDO> aiChatModalDOPageResult = aiChatModelMapper.selectPage(req, queryWrapperX);
52   - // 转换 res
53   - List<AiChatModelListRespVO> resList = AiChatModelConvert.INSTANCE.convertAiChatModalListRes(aiChatModalDOPageResult.getList());
54   - return new PageResult<>(resList, aiChatModalDOPageResult.getTotal());
55   - }
56   -
57   - @Override
58   - public void add(AiChatModelAddReqVO req) {
59   - // 校验 platform、type
60   - validatePlatform(req.getPlatform());
61   - // 转换 do
62   - AiChatModelDO insertChatModalDO = AiChatModelConvert.INSTANCE.convertAiChatModalDO(req);
63   - // 设置默认属性
64   - insertChatModalDO.setStatus(CommonStatusEnum.ENABLE.getStatus());
65   - // 保存数据库
66   - aiChatModelMapper.insert(insertChatModalDO);
67   - }
68   -
69   - @Override
70   - public void update(AiChatModelUpdateReqVO req) {
71   - // 校验 platform
72   - validatePlatform(req.getPlatform());
73   - // 校验模型是否存在
74   - validateExists(req.getId());
75   - // 转换 updateChatModalDO
76   - AiChatModelDO updateChatModalDO = AiChatModelConvert.INSTANCE.convertAiChatModalDO(req);
77   - updateChatModalDO.setId(req.getId());
78   - // 更新数据库
79   - aiChatModelMapper.updateById(updateChatModalDO);
80   - }
81   -
82   - @Override
83   - public void delete(Long id) {
84   - // 检查 modal 是否存在
85   - validateExists(id);
86   - // 删除 delete
87   - aiChatModelMapper.deleteById(id);
88   - }
89   -
90   - @Override
91   - public AiChatModalRespVO getChatModalOfValidate(Long modalId) {
92   - // 检查 modal 是否存在
93   - AiChatModelDO aiChatModalDO = validateExists(modalId);
94   - return AiChatModelConvert.INSTANCE.convertAiChatModalRes(aiChatModalDO);
95   - }
96   -
97   - @Override
98   - public void validateAvailable(AiChatModalRespVO chatModal) {
99   - // 对话模型是否可用
100   - if (!CommonStatusEnum.ENABLE.getStatus().equals(chatModal.getStatus())) {
101   - throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_DISABLE_NOT_USED);
102   - }
103   - }
104   -
105   - public AiChatModelDO validateExists(Long id) {
106   - AiChatModelDO aiChatModalDO = aiChatModelMapper.selectById(id);
107   - if (aiChatModalDO == null) {
108   - throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_NOT_EXIST);
109   - }
110   - return aiChatModalDO;
111   - }
112   -
113   - private void validatePlatform(String platform) {
114   - try {
115   - AiPlatformEnum.valueOfPlatform(platform);
116   - } catch (IllegalArgumentException e) {
117   - throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_PLATFORM_PARAMS_INCORRECT, e.getMessage());
118   - }
119   - }
120   -
121   - private void validateModalConfig(AiChatModalConfigVO aiChatModalConfigVO) {
122   - Set<ConstraintViolation<AiChatModalConfigVO>> validate = ValidationUtil.validate(aiChatModalConfigVO);
123   - for (ConstraintViolation<AiChatModalConfigVO> constraintViolation : validate) {
124   - throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_CONFIG_PARAMS_INCORRECT, constraintViolation.getMessage());
125   - }
126   - }
127   -}
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatRoleServiceImpl.java
... ... @@ -12,7 +12,7 @@ import cn.iocoder.yudao.module.ai.convert.AiChatRoleConvert;
12 12 import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
13 13 import cn.iocoder.yudao.module.ai.dal.mysql.AiChatRoleMapper;
14 14 import cn.iocoder.yudao.module.ai.enums.AiChatRoleCategoryEnum;
15   -import cn.iocoder.yudao.module.ai.service.AiChatModelService;
  15 +import cn.iocoder.yudao.module.ai.service.model.AiChatModelService;
16 16 import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
17 17 import lombok.AllArgsConstructor;
18 18 import lombok.extern.slf4j.Slf4j;
... ... @@ -57,8 +57,8 @@ public class AiChatRoleServiceImpl implements AiChatRoleService {
57 57 public void add(AiChatRoleAddReqVO req) {
58 58 // 转换enum,并校验enum
59 59 AiChatRoleCategoryEnum.valueOfCategory(req.getCategory());
60   - // 校验模型是否存在
61   - aiChatModalService.validateExists(req.getModelId());
  60 + // 校验模型是否存在 TODO
  61 +// aiChatModalService.validateExists(req.getModelId());
62 62 // 转换do
63 63 AiChatRoleDO insertAiChatRoleDO = AiChatRoleConvert.INSTANCE.convertAiChatRoleDO(req);
64 64 insertAiChatRoleDO.setUserId(SecurityFrameworkUtils.getLoginUserId());
... ... @@ -73,8 +73,8 @@ public class AiChatRoleServiceImpl implements AiChatRoleService {
73 73 validateExists(req.getId());
74 74 // 转换enum,并校验enum
75 75 AiChatRoleCategoryEnum.valueOfCategory(req.getCategory());
76   - // 校验模型是否存在
77   - aiChatModalService.validateExists(req.getModelId());
  76 + // 校验模型是否存在 TODO
  77 +// aiChatModalService.validateExists(req.getModelId());
78 78 // 转换do
79 79 AiChatRoleDO updateChatRole = AiChatRoleConvert.INSTANCE.convertAiChatRoleDO(req);
80 80 updateChatRole.setId(req.getId());
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatServiceImpl.java
... ... @@ -12,14 +12,14 @@ import cn.iocoder.yudao.module.ai.config.AiChatClientFactory;
12 12 import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationRespVO;
13 13 import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageRespVO;
14 14 import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO;
15   -import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModalRespVO;
16 15 import cn.iocoder.yudao.module.ai.convert.AiChatMessageConvert;
17 16 import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO;
  17 +import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
18 18 import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
19 19 import cn.iocoder.yudao.module.ai.dal.mysql.AiChatConversationMapper;
20 20 import cn.iocoder.yudao.module.ai.dal.mysql.AiChatMessageMapper;
21 21 import cn.iocoder.yudao.module.ai.service.AiChatConversationService;
22   -import cn.iocoder.yudao.module.ai.service.AiChatModelService;
  22 +import cn.iocoder.yudao.module.ai.service.model.AiChatModelService;
23 23 import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
24 24 import cn.iocoder.yudao.module.ai.service.AiChatService;
25 25 import lombok.AllArgsConstructor;
... ... @@ -57,9 +57,7 @@ public class AiChatServiceImpl implements AiChatService {
57 57 // 查询对话
58 58 AiChatConversationRespVO conversation = chatConversationService.getConversationOfValidate(req.getConversationId());
59 59 // 获取对话模型
60   - AiChatModalRespVO chatModal = aiChatModalService.getChatModalOfValidate(conversation.getModelId());
61   - // 对话模型是否可用
62   - aiChatModalService.validateAvailable(chatModal);
  60 + AiChatModelDO chatModel = aiChatModalService.validateChatModel(conversation.getModelId());
63 61 // 获取角色信息
64 62 AiChatRoleDO aiChatRoleDO = null;
65 63 if (conversation.getRoleId() != null) {
... ... @@ -68,10 +66,10 @@ public class AiChatServiceImpl implements AiChatService {
68 66 // 校验角色是否公开
69 67 aiChatRoleService.validateIsPublic(aiChatRoleDO);
70 68 // 获取 client 类型
71   - AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(chatModal.getPlatform());
  69 + AiPlatformEnum platformEnum = AiPlatformEnum.validatePlatform(chatModel.getPlatform());
72 70 // 保存 chat message
73 71 insertChatMessage(conversation.getId(), MessageType.USER, loginUserId, conversation.getRoleId(),
74   - chatModal.getModel(), chatModal.getId(), req.getContent(),
  72 + chatModel.getModel(), chatModel.getId(), req.getContent(),
75 73 null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
76 74 String content = null;
77 75 int tokens = 0;
... ... @@ -93,7 +91,7 @@ public class AiChatServiceImpl implements AiChatService {
93 91 } finally {
94 92 // 保存 chat message
95 93 insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(),
96   - chatModal.getModel(), chatModal.getId(), content,
  94 + chatModel.getModel(), chatModel.getId(), content,
97 95 tokens, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
98 96 }
99 97 return new AiChatMessageRespVO().setContent(content);
... ... @@ -128,9 +126,7 @@ public class AiChatServiceImpl implements AiChatService {
128 126 // 查询对话
129 127 AiChatConversationRespVO conversation = chatConversationService.getConversationOfValidate(req.getConversationId());
130 128 // 获取对话模型
131   - AiChatModalRespVO chatModal = aiChatModalService.getChatModalOfValidate(conversation.getModelId());
132   - // 对话模型是否可用
133   - aiChatModalService.validateAvailable(chatModal);
  129 + AiChatModelDO chatModel = aiChatModalService.validateChatModel(conversation.getModelId());
134 130 // 获取角色信息
135 131 AiChatRoleDO aiChatRoleDO = null;
136 132 if (conversation.getRoleId() != null) {
... ... @@ -145,10 +141,10 @@ public class AiChatServiceImpl implements AiChatService {
145 141 // req.setTemperature(req.getTemperature());
146 142 // 保存 chat message
147 143 insertChatMessage(conversation.getId(), MessageType.USER, loginUserId, conversation.getRoleId(),
148   - chatModal.getModel(), chatModal.getId(), req.getContent(),
  144 + chatModel.getModel(), chatModel.getId(), req.getContent(),
149 145 null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
150 146 // 获取 client 类型
151   - AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(chatModal.getPlatform());
  147 + AiPlatformEnum platformEnum = AiPlatformEnum.validatePlatform(chatModel.getPlatform());
152 148 StreamingChatClient streamingChatClient = aiChatClientFactory.getStreamingChatClient(platformEnum);
153 149 Flux<ChatResponse> streamResponse = streamingChatClient.stream(prompt);
154 150 // 转换 flex AiChatMessageRespVO
... ... @@ -167,7 +163,7 @@ public class AiChatServiceImpl implements AiChatService {
167 163 log.info("发送完成!");
168 164 // 保存 chat message
169 165 insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(),
170   - chatModal.getModel(), chatModal.getId(), contentBuffer.toString(),
  166 + chatModel.getModel(), chatModel.getId(), contentBuffer.toString(),
171 167 tokens.get(), conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
172 168 }
173 169 }).doOnError(new Consumer<Throwable>() {
... ... @@ -176,7 +172,7 @@ public class AiChatServiceImpl implements AiChatService {
176 172 log.error("发送错误 {}!", throwable.getMessage());
177 173 // 保存 chat message
178 174 insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(),
179   - chatModal.getModel(), chatModal.getId(), throwable.getMessage(),
  175 + chatModel.getModel(), chatModel.getId(), throwable.getMessage(),
180 176 tokens.get(), conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
181 177 }
182 178 });
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiApiKeyService.java
... ... @@ -14,7 +14,7 @@ import jakarta.validation.Valid;
14 14 public interface AiApiKeyService {
15 15  
16 16 /**
17   - * 创建AI API 密钥
  17 + * 创建 API 密钥
18 18 *
19 19 * @param createReqVO 创建信息
20 20 * @return 编号
... ... @@ -22,32 +22,40 @@ public interface AiApiKeyService {
22 22 Long createApiKey(@Valid AiApiKeySaveReqVO createReqVO);
23 23  
24 24 /**
25   - * 更新AI API 密钥
  25 + * 更新 API 密钥
26 26 *
27 27 * @param updateReqVO 更新信息
28 28 */
29 29 void updateApiKey(@Valid AiApiKeySaveReqVO updateReqVO);
30 30  
31 31 /**
32   - * 删除AI API 密钥
  32 + * 删除 API 密钥
33 33 *
34 34 * @param id 编号
35 35 */
36 36 void deleteApiKey(Long id);
37 37  
38 38 /**
39   - * 获得AI API 密钥
  39 + * 获得 API 密钥
40 40 *
41 41 * @param id 编号
42   - * @return AI API 密钥
  42 + * @return API 密钥
43 43 */
44 44 AiApiKeyDO getApiKey(Long id);
45 45  
46 46 /**
47   - * 获得AI API 密钥分页
  47 + * 校验 API 密钥
  48 + *
  49 + * @param id 比那好
  50 + * @return API 密钥
  51 + */
  52 + AiApiKeyDO validateApiKey(Long id);
  53 +
  54 + /**
  55 + * 获得 API 密钥分页
48 56 *
49 57 * @param pageReqVO 分页查询
50   - * @return AI API 密钥分页
  58 + * @return API 密钥分页
51 59 */
52 60 PageResult<AiApiKeyDO> getApiKeyPage(AiApiKeyPageReqVO pageReqVO);
53 61  
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiApiKeyServiceImpl.java
1 1 package cn.iocoder.yudao.module.ai.service.model;
2 2  
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 6 import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeyPageReqVO;
... ... @@ -11,7 +12,7 @@ import org.springframework.stereotype.Service;
11 12 import org.springframework.validation.annotation.Validated;
12 13  
13 14 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
14   -import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.API_KEY_NOT_EXISTS;
  15 +import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.*;
15 16  
16 17 /**
17 18 * AI API 密钥 Service 实现类
... ... @@ -51,10 +52,12 @@ public class AiApiKeyServiceImpl implements AiApiKeyService {
51 52 apiKeyMapper.deleteById(id);
52 53 }
53 54  
54   - private void validateApiKeyExists(Long id) {
55   - if (apiKeyMapper.selectById(id) == null) {
  55 + private AiApiKeyDO validateApiKeyExists(Long id) {
  56 + AiApiKeyDO apiKey = apiKeyMapper.selectById(id);
  57 + if (apiKey == null) {
56 58 throw exception(API_KEY_NOT_EXISTS);
57 59 }
  60 + return apiKey;
58 61 }
59 62  
60 63 @Override
... ... @@ -63,6 +66,15 @@ public class AiApiKeyServiceImpl implements AiApiKeyService {
63 66 }
64 67  
65 68 @Override
  69 + public AiApiKeyDO validateApiKey(Long id) {
  70 + AiApiKeyDO apiKey = validateApiKeyExists(id);
  71 + if (CommonStatusEnum.isDisable(apiKey.getStatus())) {
  72 + throw exception(API_KEY_DISABLE);
  73 + }
  74 + return apiKey;
  75 + }
  76 +
  77 + @Override
66 78 public PageResult<AiApiKeyDO> getApiKeyPage(AiApiKeyPageReqVO pageReqVO) {
67 79 return apiKeyMapper.selectPage(pageReqVO);
68 80 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatConversationServiceImpl.java renamed to yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiChatConversationServiceImpl.java
1   -package cn.iocoder.yudao.module.ai.service.impl;
  1 +package cn.iocoder.yudao.module.ai.service.model;
2 2  
3 3 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
4 4 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
... ... @@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.ai.ErrorCodeConstants;
7 7 import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationCreateReqVO;
8 8 import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationRespVO;
9 9 import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationUpdateReqVO;
10   -import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModalRespVO;
11 10 import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.AiChatRoleRespVO;
12 11 import cn.iocoder.yudao.module.ai.convert.AiChatConversationConvert;
13 12 import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatConversationDO;
... ... @@ -15,7 +14,6 @@ import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
15 14 import cn.iocoder.yudao.module.ai.dal.mysql.AiChatConversationMapper;
16 15 import cn.iocoder.yudao.module.ai.dal.mysql.AiChatModelMapper;
17 16 import cn.iocoder.yudao.module.ai.service.AiChatConversationService;
18   -import cn.iocoder.yudao.module.ai.service.AiChatModelService;
19 17 import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
20 18 import lombok.AllArgsConstructor;
21 19 import lombok.extern.slf4j.Slf4j;
... ... @@ -87,9 +85,7 @@ public class AiChatConversationServiceImpl implements AiChatConversationService
87 85 // 校验对话是否存在
88 86 validateExists(updateReqVO.getId());
89 87 // 获取模型信息并验证
90   - AiChatModalRespVO chatModal = aiChatModalService.getChatModalOfValidate(updateReqVO.getModelId());
91   - // 校验modal是否可用
92   - aiChatModalService.validateAvailable(chatModal);
  88 + aiChatModalService.validateChatModel(updateReqVO.getModelId());
93 89 // 更新对话信息
94 90 AiChatConversationDO updateAiChatConversationDO
95 91 = AiChatConversationConvert.INSTANCE.convertAiChatConversationDO(updateReqVO);
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiChatModelService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.service.model;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelPageReqVO;
  5 +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelSaveReqVO;
  6 +import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
  7 +import jakarta.validation.Valid;
  8 +
  9 +/**
  10 + * AI 聊天模型 Service 接口
  11 + *
  12 + * @author fansili
  13 + * @since 2024/4/24 19:42
  14 + */
  15 +public interface AiChatModelService {
  16 +
  17 + /**
  18 + * 创建聊天模型
  19 + *
  20 + * @param createReqVO 创建信息
  21 + * @return 编号
  22 + */
  23 + Long createChatModel(@Valid AiChatModelSaveReqVO createReqVO);
  24 +
  25 + /**
  26 + * 更新聊天模型
  27 + *
  28 + * @param updateReqVO 更新信息
  29 + */
  30 + void updateChatModel(@Valid AiChatModelSaveReqVO updateReqVO);
  31 +
  32 + /**
  33 + * 删除聊天模型
  34 + *
  35 + * @param id 编号
  36 + */
  37 + void deleteChatModel(Long id);
  38 +
  39 + /**
  40 + * 获得聊天模型
  41 + *
  42 + * @param id 编号
  43 + * @return API 聊天模型
  44 + */
  45 + AiChatModelDO getChatModel(Long id);
  46 +
  47 + /**
  48 + * 获得聊天模型分页
  49 + *
  50 + * @param pageReqVO 分页查询
  51 + * @return API 聊天模型分页
  52 + */
  53 + PageResult<AiChatModelDO> getChatModelPage(AiChatModelPageReqVO pageReqVO);
  54 +
  55 + /**
  56 + * 校验聊天模型
  57 + *
  58 + * @param id 编号
  59 + * @return 聊天模型
  60 + */
  61 + AiChatModelDO validateChatModel(Long id);
  62 +
  63 +}
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiChatModelServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.service.model;
  2 +
  3 +import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  7 +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelPageReqVO;
  8 +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelSaveReqVO;
  9 +import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
  10 +import cn.iocoder.yudao.module.ai.dal.mysql.AiChatModelMapper;
  11 +import jakarta.annotation.Resource;
  12 +import org.springframework.stereotype.Service;
  13 +import org.springframework.validation.annotation.Validated;
  14 +
  15 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  16 +import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.*;
  17 +
  18 +/**
  19 + * AI 聊天模型 Service 实现类
  20 + *
  21 + * @author fansili
  22 + */
  23 +@Service
  24 +@Validated
  25 +public class AiChatModelServiceImpl implements AiChatModelService {
  26 +
  27 + @Resource
  28 + private AiApiKeyService apiKeyService;
  29 +
  30 + @Resource
  31 + private AiChatModelMapper chatModelMapper;
  32 +
  33 + @Override
  34 + public Long createChatModel(AiChatModelSaveReqVO createReqVO) {
  35 + // 1. 校验
  36 + AiPlatformEnum.validatePlatform(createReqVO.getPlatform());
  37 + apiKeyService.validateApiKey(createReqVO.getKeyId());
  38 +
  39 + // 2. 插入
  40 + AiChatModelDO chatModel = BeanUtils.toBean(createReqVO, AiChatModelDO.class);
  41 + chatModelMapper.insert(chatModel);
  42 + return chatModel.getId();
  43 + }
  44 +
  45 + @Override
  46 + public void updateChatModel(AiChatModelSaveReqVO updateReqVO) {
  47 + // 1. 校验
  48 + validateChatModelExists(updateReqVO.getId());
  49 + AiPlatformEnum.validatePlatform(updateReqVO.getPlatform());
  50 + apiKeyService.validateApiKey(updateReqVO.getKeyId());
  51 +
  52 + // 2. 更新
  53 + AiChatModelDO updateObj = BeanUtils.toBean(updateReqVO, AiChatModelDO.class);
  54 + chatModelMapper.updateById(updateObj);
  55 + }
  56 +
  57 + @Override
  58 + public void deleteChatModel(Long id) {
  59 + // 校验存在
  60 + validateChatModelExists(id);
  61 + // 删除
  62 + chatModelMapper.deleteById(id);
  63 + }
  64 +
  65 + private AiChatModelDO validateChatModelExists(Long id) {
  66 + AiChatModelDO model = chatModelMapper.selectById(id);
  67 + if (chatModelMapper.selectById(id) == null) {
  68 + throw exception(CHAT_MODAL_NOT_EXIST);
  69 + }
  70 + return model;
  71 + }
  72 +
  73 + @Override
  74 + public AiChatModelDO getChatModel(Long id) {
  75 + return chatModelMapper.selectById(id);
  76 + }
  77 +
  78 + @Override
  79 + public PageResult<AiChatModelDO> getChatModelPage(AiChatModelPageReqVO pageReqVO) {
  80 + return chatModelMapper.selectPage(pageReqVO);
  81 + }
  82 +
  83 + @Override
  84 + public AiChatModelDO validateChatModel(Long id) {
  85 + AiChatModelDO model = validateChatModelExists(id);
  86 + if (CommonStatusEnum.isDisable(model.getStatus())) {
  87 + throw exception(CHAT_MODAL_DISABLE);
  88 + }
  89 + return model;
  90 + }
  91 +
  92 +}
0 93 \ No newline at end of file
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/AiPlatformEnum.java
... ... @@ -41,7 +41,7 @@ public enum AiPlatformEnum {
41 41 AiPlatformEnum.MIDJOURNEY
42 42 );
43 43  
44   - public static AiPlatformEnum valueOfPlatform(String platform) {
  44 + public static AiPlatformEnum validatePlatform(String platform) {
45 45 for (AiPlatformEnum itemEnum : AiPlatformEnum.values()) {
46 46 if (itemEnum.getPlatform().equals(platform)) {
47 47 return itemEnum;
... ...