Commit aaf1599f7a771f6aaaa43a3ece914325d72135ec

Authored by cherishsince
2 parents 79bd7899 ba1333bd

Merge remote-tracking branch 'origin/master-jdk21-ai' into master-jdk21-ai

# Conflicts:
#	yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/AiChatModelMapper.java
#	yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/AiChatModelService.java
#	yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatModalServiceImpl.java
Showing 41 changed files with 799 additions and 496 deletions
yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/ErrorCodeConstants.java
... ... @@ -3,17 +3,23 @@ package cn.iocoder.yudao.module.ai;
3 3 import cn.iocoder.yudao.framework.common.exception.ErrorCode;
4 4  
5 5 /**
6   - * System 错误码枚举类
  6 + * AI 错误码枚举类
7 7 *
8   - * system 系统,使用 1-002-000-000 段
  8 + * ai 系统,使用 1-040-000-000 段
9 9 */
10 10 public interface ErrorCodeConstants {
11 11  
12   - // ========== 模块 ai 错误码区间 [1-022-000-000 ~ 1-023-000-000) ==========
  12 + // ========== API 密钥 1-040-000-000 ==========
  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 密钥已禁用!");
13 15  
14   - // chat
  16 + // ========== API 聊天模型 1-040-001-000 ==========
15 17  
16   - 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 平台参数不正确! {} ");
17 23  
18 24 // conversation
19 25  
... ... @@ -30,11 +36,5 @@ public interface ErrorCodeConstants {
30 36 ErrorCode AI_CHAT_ROLE_NOT_EXIST = new ErrorCode(1_022_000_060, "AI 角色不存在!");
31 37 ErrorCode AI_CHAT_ROLE_NOT_PUBLIC = new ErrorCode(1_022_000_060, "AI 角色未公开!");
32 38  
33   - // modal
34   -
35   - ErrorCode AI_MODAL_NOT_EXIST = new ErrorCode(1_022_000_080, "AI 模型不存在!");
36   - ErrorCode AI_MODAL_CONFIG_PARAMS_INCORRECT = new ErrorCode(1_022_000_081, "AI 模型 config 参数不正确! {} ");
37   - ErrorCode AI_MODAL_PLATFORM_PARAMS_INCORRECT = new ErrorCode(1_022_000_083, "AI 平台参数不正确! {} ");
38   - ErrorCode AI_MODAL_DISABLE_NOT_USED = new ErrorCode(1_022_000_084, "AI 模型禁用不能使用!");
39 39  
40 40 }
... ...
yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/package-info.java deleted
1   -/**
2   - * author: fansili
3   - * time: 2024/3/3 18:14
4   - */
5   -package cn.iocoder.yudao.module.ai;
6 0 \ No newline at end of file
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/AiApiKeyController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.controller.admin.model;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  6 +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeyPageReqVO;
  7 +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeyRespVO;
  8 +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeySaveReqVO;
  9 +import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO;
  10 +import cn.iocoder.yudao.module.ai.service.model.AiApiKeyService;
  11 +import io.swagger.v3.oas.annotations.Operation;
  12 +import io.swagger.v3.oas.annotations.Parameter;
  13 +import io.swagger.v3.oas.annotations.tags.Tag;
  14 +import jakarta.annotation.Resource;
  15 +import jakarta.validation.Valid;
  16 +import org.springframework.security.access.prepost.PreAuthorize;
  17 +import org.springframework.validation.annotation.Validated;
  18 +import org.springframework.web.bind.annotation.*;
  19 +
  20 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  21 +
  22 +@Tag(name = "管理后台 - AI API 密钥")
  23 +@RestController
  24 +@RequestMapping("/ai/api-key")
  25 +@Validated
  26 +public class AiApiKeyController {
  27 +
  28 + @Resource
  29 + private AiApiKeyService apiKeyService;
  30 +
  31 + @PostMapping("/create")
  32 + @Operation(summary = "创建 API 密钥")
  33 + @PreAuthorize("@ss.hasPermission('ai:api-key:create')")
  34 + public CommonResult<Long> createApiKey(@Valid @RequestBody AiApiKeySaveReqVO createReqVO) {
  35 + return success(apiKeyService.createApiKey(createReqVO));
  36 + }
  37 +
  38 + @PutMapping("/update")
  39 + @Operation(summary = "更新 API 密钥")
  40 + @PreAuthorize("@ss.hasPermission('ai:api-key:update')")
  41 + public CommonResult<Boolean> updateApiKey(@Valid @RequestBody AiApiKeySaveReqVO updateReqVO) {
  42 + apiKeyService.updateApiKey(updateReqVO);
  43 + return success(true);
  44 + }
  45 +
  46 + @DeleteMapping("/delete")
  47 + @Operation(summary = "删除 API 密钥")
  48 + @Parameter(name = "id", description = "编号", required = true)
  49 + @PreAuthorize("@ss.hasPermission('ai:api-key:delete')")
  50 + public CommonResult<Boolean> deleteApiKey(@RequestParam("id") Long id) {
  51 + apiKeyService.deleteApiKey(id);
  52 + return success(true);
  53 + }
  54 +
  55 + @GetMapping("/get")
  56 + @Operation(summary = "获得 API 密钥")
  57 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  58 + @PreAuthorize("@ss.hasPermission('ai:api-key:query')")
  59 + public CommonResult<AiApiKeyRespVO> getApiKey(@RequestParam("id") Long id) {
  60 + AiApiKeyDO apiKey = apiKeyService.getApiKey(id);
  61 + return success(BeanUtils.toBean(apiKey, AiApiKeyRespVO.class));
  62 + }
  63 +
  64 + @GetMapping("/page")
  65 + @Operation(summary = "获得 API 密钥分页")
  66 + @PreAuthorize("@ss.hasPermission('ai:api-key:query')")
  67 + public CommonResult<PageResult<AiApiKeyRespVO>> getApiKeyPage(@Valid AiApiKeyPageReqVO pageReqVO) {
  68 + PageResult<AiApiKeyDO> pageResult = apiKeyService.getApiKeyPage(pageReqVO);
  69 + return success(BeanUtils.toBean(pageResult, AiApiKeyRespVO.class));
  70 + }
  71 +
  72 +}
0 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/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/apikey/AiApiKeyPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  7 +import org.springframework.format.annotation.DateTimeFormat;
  8 +import java.time.LocalDateTime;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +@Schema(description = "管理后台 - AI API 密钥分页 Request VO")
  13 +@Data
  14 +@EqualsAndHashCode(callSuper = true)
  15 +@ToString(callSuper = true)
  16 +public class AiApiKeyPageReqVO extends PageParam {
  17 +
  18 + @Schema(description = "名称", example = "文心一言")
  19 + private String name;
  20 +
  21 + @Schema(description = "平台", example = "OpenAI")
  22 + private String platform;
  23 +
  24 + @Schema(description = "状态", example = "1")
  25 + private Integer status;
  26 +
  27 +}
0 28 \ 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/apikey/AiApiKeyRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.*;
  5 +
  6 +@Schema(description = "管理后台 - AI API 密钥 Response VO")
  7 +@Data
  8 +public class AiApiKeyRespVO {
  9 +
  10 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23538")
  11 + private Long id;
  12 +
  13 + @Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "文心一言")
  14 + private String name;
  15 +
  16 + @Schema(description = "密钥", requiredMode = Schema.RequiredMode.REQUIRED, example = "ABC")
  17 + private String apiKey;
  18 +
  19 + @Schema(description = "平台", requiredMode = Schema.RequiredMode.REQUIRED, example = "OpenAI")
  20 + private String platform;
  21 +
  22 + @Schema(description = "自定义 API 地址", example = "https://aip.baidubce.com")
  23 + private String url;
  24 +
  25 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  26 + private Integer status;
  27 +
  28 +}
0 29 \ 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/apikey/AiApiKeySaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.*;
  5 +import java.util.*;
  6 +import jakarta.validation.constraints.*;
  7 +
  8 +@Schema(description = "管理后台 - AI API 密钥新增/修改 Request VO")
  9 +@Data
  10 +public class AiApiKeySaveReqVO {
  11 +
  12 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23538")
  13 + private Long id;
  14 +
  15 + @Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "文心一言")
  16 + @NotEmpty(message = "名称不能为空")
  17 + private String name;
  18 +
  19 + @Schema(description = "密钥", requiredMode = Schema.RequiredMode.REQUIRED, example = "ABC")
  20 + @NotEmpty(message = "密钥不能为空")
  21 + private String apiKey;
  22 +
  23 + @Schema(description = "平台", requiredMode = Schema.RequiredMode.REQUIRED, example = "OpenAI")
  24 + @NotEmpty(message = "平台不能为空")
  25 + private String platform;
  26 +
  27 + @Schema(description = "自定义 API 地址", example = "https://aip.baidubce.com")
  28 + private String url;
  29 +
  30 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  31 + @NotNull(message = "状态不能为空")
  32 + private Integer status;
  33 +
  34 +}
0 35 \ 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/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 cn.iocoder.yudao.framework.ai.AiPlatformEnum;
4   -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5   -import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO;
6   -import com.baomidou.mybatisplus.annotation.TableId;
7   -import io.swagger.v3.oas.annotations.media.Schema;
8   -import lombok.Data;
9   -import lombok.experimental.Accessors;
10   -
11   -/**
12   - * modal list
13   - *
14   - * @author fansili
15   - * @time 2024/4/24 19:56
16   - * @since 1.0
17   - */
18   -@Data
19   -@Accessors(chain = true)
20   -public class AiChatModelListRespVO {
21   -
22   - @Schema(description = "编号")
23   - private Long id;
24   -
25   - @Schema(description = "API 秘钥编号")
26   - private Long keyId;
27   -
28   - @Schema(description = "模型名称")
29   - private String name;
30   -
31   - @Schema(description = "模型标志")
32   - private String model;
33   -
34   - @Schema(description = "平台")
35   - private String platform;
36   -
37   - @Schema(description = "排序值")
38   - private Integer sort;
39   -
40   - @Schema(description = "状态")
41   - private Integer status;
42   -
43   - // ========== 会话配置 ==========
44   -
45   - @Schema(description = "温度参数")
46   - private Double temperature;
47   -
48   - @Schema(description = "单条回复的最大 Token 数量")
49   - private Integer maxTokens;
50   -
51   - @Schema(description = "上下文的最大 Message 数量")
52   - private Integer maxContexts;
53   -
54   -}
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/dataobject/image/AiImageDO.java
... ... @@ -49,8 +49,8 @@ public class AiImageDO extends BaseDO {
49 49  
50 50 // ============ mj 需要字段
51 51  
52   - @Schema(description = "用户操作的消息编号(MJ返回)")
53   - private String mjMessageId;
  52 + @Schema(description = "用户操作的Nonce编号(MJ返回)")
  53 + private String mjNonceId;
54 54  
55 55 @Schema(description = "用户操作的操作编号(MJ返回)")
56 56 private String mjOperationId;
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/model/AiApiKeyDO.java
... ... @@ -32,18 +32,16 @@ public class AiApiKeyDO extends BaseDO {
32 32 */
33 33 private String name;
34 34 /**
  35 + * 密钥
  36 + */
  37 + private String apiKey;
  38 + /**
35 39 * 平台
36 40 *
37 41 * 枚举 {@link AiPlatformEnum}
38 42 */
39 43 private String platform;
40 44 /**
41   - * 用途
42   - *
43   - * TODO 芋艿:枚举;chat、image
44   - */
45   - private Integer type;
46   - /**
47 45 * API 地址
48 46 */
49 47 private String url;
... ... @@ -54,6 +52,4 @@ public class AiApiKeyDO extends BaseDO {
54 52 */
55 53 private Integer status;
56 54  
57   - // TODO 芋艿:proxyUrl 代理地址
58   -
59 55 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/AiChatModelMapper.java
... ... @@ -5,25 +5,23 @@ 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 import java.util.Collection;
13 13 import java.util.List;
14 14 import java.util.Set;
15 15  
16 16 /**
17   - * chat modal
  17 + * API 聊天模型 Mapper
18 18 *
19 19 * @author fansili
20   - * @time 2024/4/24 19:41
21   - * @since 1.0
22 20 */
23   -@Repository
24 21 @Mapper
25 22 public interface AiChatModelMapper extends BaseMapperX<AiChatModelDO> {
26 23  
  24 + // TODO 芋艿:要搞一下
27 25 /**
28 26 * 查询 - 第一个modal
29 27 *
... ... @@ -46,5 +44,16 @@ public interface AiChatModelMapper extends BaseMapperX&lt;AiChatModelDO&gt; {
46 44 * @param modalIds
47 45 * @return
48 46 */
49   - List<AiChatModelDO> selectByIds(Collection<Long> modalIds);
  47 + default List<AiChatModelDO> selectByIds(Collection<Long> modalIds) {
  48 + return this.selectList(new LambdaQueryWrapperX<AiChatModelDO>().eq(AiChatModelDO::getId, modalIds));
  49 + }
  50 +
  51 +
  52 + default PageResult<AiChatModelDO> selectPage(AiChatModelPageReqVO reqVO) {
  53 + return selectPage(reqVO, new LambdaQueryWrapperX<AiChatModelDO>()
  54 + .likeIfPresent(AiChatModelDO::getName, reqVO.getName())
  55 + .eqIfPresent(AiChatModelDO::getModel, reqVO.getModel())
  56 + .eqIfPresent(AiChatModelDO::getPlatform, reqVO.getPlatform())
  57 + .orderByDesc(AiChatModelDO::getId));
  58 + }
50 59 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/AiImageMapper.java
1 1 package cn.iocoder.yudao.module.ai.dal.mysql;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
4 5 import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO;
5 6 import org.apache.ibatis.annotations.Mapper;
6 7 import org.springframework.stereotype.Repository;
... ... @@ -17,4 +18,13 @@ import org.springframework.stereotype.Repository;
17 18 public interface AiImageMapper extends BaseMapperX<AiImageDO> {
18 19  
19 20  
  21 + /**
  22 + * 更新 - 根据 messageId
  23 + *
  24 + * @param mjNonceId
  25 + * @param aiImageDO
  26 + */
  27 + default void updateByMjNonce(Long mjNonceId, AiImageDO aiImageDO) {
  28 + this.update(aiImageDO, new LambdaQueryWrapperX<AiImageDO>().eq(AiImageDO::getMjNonceId, mjNonceId));
  29 + }
20 30 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/model/AiApiKeyMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.dal.mysql.model;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeyPageReqVO;
  7 +import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +/**
  11 + * AI API 密钥 Mapper
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Mapper
  16 +public interface AiApiKeyMapper extends BaseMapperX<AiApiKeyDO> {
  17 +
  18 + default PageResult<AiApiKeyDO> selectPage(AiApiKeyPageReqVO reqVO) {
  19 + return selectPage(reqVO, new LambdaQueryWrapperX<AiApiKeyDO>()
  20 + .likeIfPresent(AiApiKeyDO::getName, reqVO.getName())
  21 + .eqIfPresent(AiApiKeyDO::getPlatform, reqVO.getPlatform())
  22 + .eqIfPresent(AiApiKeyDO::getStatus, reqVO.getStatus())
  23 + .orderByDesc(AiApiKeyDO::getId));
  24 + }
  25 +
  26 +}
0 27 \ No newline at end of file
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/AiChatModelService.java
... ... @@ -75,5 +75,4 @@ public interface AiChatModelService {
75 75 * @return
76 76 */
77 77 List<AiChatModelDO> getModalByIds(Set<Long> modalIds);
78   -
79 78 }
... ...
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
... ... @@ -17,7 +17,6 @@ import cn.iocoder.yudao.module.ai.service.AiChatModelService;
17 17 import jakarta.validation.ConstraintViolation;
18 18 import lombok.AllArgsConstructor;
19 19 import lombok.extern.slf4j.Slf4j;
20   -import org.mybatis.spring.annotation.MapperScannerRegistrar;
21 20 import org.springframework.stereotype.Service;
22 21  
23 22 import java.util.List;
... ... @@ -36,7 +35,6 @@ import java.util.Set;
36 35 public class AiChatModalServiceImpl implements AiChatModelService {
37 36  
38 37 private final AiChatModelMapper aiChatModelMapper;
39   - private final MapperScannerRegistrar mapperScannerRegistrar;
40 38  
41 39 @Override
42 40 public PageResult<AiChatModelListRespVO> list(AiChatModelListReqVO req) {
... ...
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,7 +12,6 @@ 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;
18 17 import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
... ... @@ -20,7 +19,7 @@ import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
20 19 import cn.iocoder.yudao.module.ai.dal.mysql.AiChatConversationMapper;
21 20 import cn.iocoder.yudao.module.ai.dal.mysql.AiChatMessageMapper;
22 21 import cn.iocoder.yudao.module.ai.service.AiChatConversationService;
23   -import cn.iocoder.yudao.module.ai.service.AiChatModelService;
  22 +import cn.iocoder.yudao.module.ai.service.model.AiChatModelService;
24 23 import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
25 24 import cn.iocoder.yudao.module.ai.service.AiChatService;
26 25 import lombok.AllArgsConstructor;
... ... @@ -61,9 +60,7 @@ public class AiChatServiceImpl implements AiChatService {
61 60 // 查询对话
62 61 AiChatConversationRespVO conversation = chatConversationService.getConversationOfValidate(req.getConversationId());
63 62 // 获取对话模型
64   - AiChatModalRespVO chatModal = aiChatModalService.getChatModalOfValidate(conversation.getModelId());
65   - // 对话模型是否可用
66   - aiChatModalService.validateAvailable(chatModal);
  63 + AiChatModelDO chatModel = aiChatModalService.validateChatModel(conversation.getModelId());
67 64 // 获取角色信息
68 65 AiChatRoleDO aiChatRoleDO = null;
69 66 if (conversation.getRoleId() != null) {
... ... @@ -72,10 +69,10 @@ public class AiChatServiceImpl implements AiChatService {
72 69 // 校验角色是否公开
73 70 aiChatRoleService.validateIsPublic(aiChatRoleDO);
74 71 // 获取 client 类型
75   - AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(chatModal.getPlatform());
  72 + AiPlatformEnum platformEnum = AiPlatformEnum.validatePlatform(chatModel.getPlatform());
76 73 // 保存 chat message
77 74 insertChatMessage(conversation.getId(), MessageType.USER, loginUserId, conversation.getRoleId(),
78   - chatModal.getModel(), chatModal.getId(), req.getContent(),
  75 + chatModel.getModel(), chatModel.getId(), req.getContent(),
79 76 null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
80 77 String content = null;
81 78 int tokens = 0;
... ... @@ -97,7 +94,7 @@ public class AiChatServiceImpl implements AiChatService {
97 94 } finally {
98 95 // 保存 chat message
99 96 insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(),
100   - chatModal.getModel(), chatModal.getId(), content,
  97 + chatModel.getModel(), chatModel.getId(), content,
101 98 tokens, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
102 99 }
103 100 return new AiChatMessageRespVO().setContent(content);
... ... @@ -132,9 +129,7 @@ public class AiChatServiceImpl implements AiChatService {
132 129 // 查询对话
133 130 AiChatConversationRespVO conversation = chatConversationService.getConversationOfValidate(req.getConversationId());
134 131 // 获取对话模型
135   - AiChatModalRespVO chatModal = aiChatModalService.getChatModalOfValidate(conversation.getModelId());
136   - // 对话模型是否可用
137   - aiChatModalService.validateAvailable(chatModal);
  132 + AiChatModelDO chatModel = aiChatModalService.validateChatModel(conversation.getModelId());
138 133 // 获取角色信息
139 134 AiChatRoleDO aiChatRoleDO = null;
140 135 if (conversation.getRoleId() != null) {
... ... @@ -149,10 +144,10 @@ public class AiChatServiceImpl implements AiChatService {
149 144 // req.setTemperature(req.getTemperature());
150 145 // 保存 chat message
151 146 insertChatMessage(conversation.getId(), MessageType.USER, loginUserId, conversation.getRoleId(),
152   - chatModal.getModel(), chatModal.getId(), req.getContent(),
  147 + chatModel.getModel(), chatModel.getId(), req.getContent(),
153 148 null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
154 149 // 获取 client 类型
155   - AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(chatModal.getPlatform());
  150 + AiPlatformEnum platformEnum = AiPlatformEnum.validatePlatform(chatModel.getPlatform());
156 151 StreamingChatClient streamingChatClient = aiChatClientFactory.getStreamingChatClient(platformEnum);
157 152 Flux<ChatResponse> streamResponse = streamingChatClient.stream(prompt);
158 153 // 转换 flex AiChatMessageRespVO
... ... @@ -171,7 +166,7 @@ public class AiChatServiceImpl implements AiChatService {
171 166 log.info("发送完成!");
172 167 // 保存 chat message
173 168 insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(),
174   - chatModal.getModel(), chatModal.getId(), contentBuffer.toString(),
  169 + chatModel.getModel(), chatModel.getId(), contentBuffer.toString(),
175 170 tokens.get(), conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
176 171 }
177 172 }).doOnError(new Consumer<Throwable>() {
... ... @@ -180,7 +175,7 @@ public class AiChatServiceImpl implements AiChatService {
180 175 log.error("发送错误 {}!", throwable.getMessage());
181 176 // 保存 chat message
182 177 insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(),
183   - chatModal.getModel(), chatModal.getId(), throwable.getMessage(),
  178 + chatModel.getModel(), chatModel.getId(), throwable.getMessage(),
184 179 tokens.get(), conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
185 180 }
186 181 });
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiImageServiceImpl.java
... ... @@ -145,7 +145,7 @@ public class AiImageServiceImpl implements AiImageService {
145 145 // 校验 OperateId 是否存在
146 146 AiImageMidjourneyOperationsVO midjourneyOperationsVO = validateMidjourneyOperationsExists(midjourneyOperations, req.getOperateId());
147 147 // 校验 messageId
148   - validateMessageId(aiImageDO.getMjMessageId(), req.getMessageId());
  148 + validateMessageId(aiImageDO.getMjNonceId(), req.getMessageId());
149 149 // 获取 mjOperationName
150 150 String mjOperationName = midjourneyOperationsVO.getLabel();
151 151 // 保存一个 image 任务记录
... ... @@ -222,7 +222,7 @@ public class AiImageServiceImpl implements AiImageService {
222 222 aiImageDO.setDrawingImageUrl(drawingImageUrl);
223 223 aiImageDO.setDrawingErrorMessage(drawingErrorMessage);
224 224 //
225   - aiImageDO.setMjMessageId(mjMessageId);
  225 + aiImageDO.setMjNonceId(mjMessageId);
226 226 aiImageDO.setMjOperationId(mjOperationId);
227 227 aiImageDO.setMjOperationName(mjOperationName);
228 228 aiImageMapper.insert(aiImageDO);
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/midjourneyHandler/YuDaoMidjourneyMessageHandler.java
... ... @@ -62,12 +62,11 @@ public class YuDaoMidjourneyMessageHandler implements MidjourneyMessageHandler {
62 62  
63 63 private void errorHandler(MidjourneyMessage midjourneyMessage) {
64 64 // image 编号
65   - Long aiImageId = Long.valueOf(midjourneyMessage.getNonce());
  65 + Long nonceId = Long.valueOf(midjourneyMessage.getNonce());
66 66 // 获取 error message
67 67 String errorMessage = getErrorMessage(midjourneyMessage);
68   - aiImageMapper.updateById(
  68 + aiImageMapper.updateByMjNonce(nonceId,
69 69 new AiImageDO()
70   - .setId(aiImageId)
71 70 .setDrawingErrorMessage(errorMessage)
72 71 .setDrawingStatus(AiImageDrawingStatusEnum.FAIL.getStatus())
73 72 );
... ... @@ -83,7 +82,8 @@ public class YuDaoMidjourneyMessageHandler implements MidjourneyMessageHandler {
83 82  
84 83 private void successHandler(MidjourneyMessage midjourneyMessage) {
85 84 // 获取id
86   - Long aiImageId = Long.valueOf(midjourneyMessage.getNonce());
  85 + Long nonceId = Long.valueOf(midjourneyMessage.getNonce());
  86 + // TODO @芋艿 这个地方有问题,不能根据 nonce来更新,不返回这个信息(别人获取了 image-xxx-xx 后面一段hash,由于没有mj账号测试,暂不清楚。)
87 87 // 获取生成 url
88 88 String imageUrl = null;
89 89 if (CollUtil.isNotEmpty(midjourneyMessage.getAttachments())) {
... ... @@ -102,12 +102,11 @@ public class YuDaoMidjourneyMessageHandler implements MidjourneyMessageHandler {
102 102 // 获取 midjourneyOperations
103 103 List<AiImageMidjourneyOperationsVO> midjourneyOperations = getMidjourneyOperationsList(midjourneyMessage);
104 104 // 更新数据库
105   - aiImageMapper.updateById(
  105 + aiImageMapper.updateByMjNonce(nonceId,
106 106 new AiImageDO()
107   - .setId(aiImageId)
108 107 .setDrawingImageUrl(imageUrl)
109 108 .setDrawingStatus(drawingStatusEnum == null ? null : drawingStatusEnum.getStatus())
110   - .setMjMessageId(midjourneyMessage.getId())
  109 + .setMjNonceId(midjourneyMessage.getId())
111 110 .setMjOperations(JsonUtils.toJsonString(midjourneyOperations))
112 111 );
113 112 }
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiApiKeyService.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.apikey.AiApiKeyPageReqVO;
  5 +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeySaveReqVO;
  6 +import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO;
  7 +import jakarta.validation.Valid;
  8 +
  9 +/**
  10 + * AI API 密钥 Service 接口
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +public interface AiApiKeyService {
  15 +
  16 + /**
  17 + * 创建 API 密钥
  18 + *
  19 + * @param createReqVO 创建信息
  20 + * @return 编号
  21 + */
  22 + Long createApiKey(@Valid AiApiKeySaveReqVO createReqVO);
  23 +
  24 + /**
  25 + * 更新 API 密钥
  26 + *
  27 + * @param updateReqVO 更新信息
  28 + */
  29 + void updateApiKey(@Valid AiApiKeySaveReqVO updateReqVO);
  30 +
  31 + /**
  32 + * 删除 API 密钥
  33 + *
  34 + * @param id 编号
  35 + */
  36 + void deleteApiKey(Long id);
  37 +
  38 + /**
  39 + * 获得 API 密钥
  40 + *
  41 + * @param id 编号
  42 + * @return API 密钥
  43 + */
  44 + AiApiKeyDO getApiKey(Long id);
  45 +
  46 + /**
  47 + * 校验 API 密钥
  48 + *
  49 + * @param id 比那好
  50 + * @return API 密钥
  51 + */
  52 + AiApiKeyDO validateApiKey(Long id);
  53 +
  54 + /**
  55 + * 获得 API 密钥分页
  56 + *
  57 + * @param pageReqVO 分页查询
  58 + * @return API 密钥分页
  59 + */
  60 + PageResult<AiApiKeyDO> getApiKeyPage(AiApiKeyPageReqVO pageReqVO);
  61 +
  62 +}
0 63 \ No newline at end of file
... ...
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiApiKeyServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.ai.service.model;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  6 +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeyPageReqVO;
  7 +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeySaveReqVO;
  8 +import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO;
  9 +import cn.iocoder.yudao.module.ai.dal.mysql.model.AiApiKeyMapper;
  10 +import jakarta.annotation.Resource;
  11 +import org.springframework.stereotype.Service;
  12 +import org.springframework.validation.annotation.Validated;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  15 +import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.*;
  16 +
  17 +/**
  18 + * AI API 密钥 Service 实现类
  19 + *
  20 + * @author 芋道源码
  21 + */
  22 +@Service
  23 +@Validated
  24 +public class AiApiKeyServiceImpl implements AiApiKeyService {
  25 +
  26 + @Resource
  27 + private AiApiKeyMapper apiKeyMapper;
  28 +
  29 + @Override
  30 + public Long createApiKey(AiApiKeySaveReqVO createReqVO) {
  31 + // 插入
  32 + AiApiKeyDO apiKey = BeanUtils.toBean(createReqVO, AiApiKeyDO.class);
  33 + apiKeyMapper.insert(apiKey);
  34 + // 返回
  35 + return apiKey.getId();
  36 + }
  37 +
  38 + @Override
  39 + public void updateApiKey(AiApiKeySaveReqVO updateReqVO) {
  40 + // 校验存在
  41 + validateApiKeyExists(updateReqVO.getId());
  42 + // 更新
  43 + AiApiKeyDO updateObj = BeanUtils.toBean(updateReqVO, AiApiKeyDO.class);
  44 + apiKeyMapper.updateById(updateObj);
  45 + }
  46 +
  47 + @Override
  48 + public void deleteApiKey(Long id) {
  49 + // 校验存在
  50 + validateApiKeyExists(id);
  51 + // 删除
  52 + apiKeyMapper.deleteById(id);
  53 + }
  54 +
  55 + private AiApiKeyDO validateApiKeyExists(Long id) {
  56 + AiApiKeyDO apiKey = apiKeyMapper.selectById(id);
  57 + if (apiKey == null) {
  58 + throw exception(API_KEY_NOT_EXISTS);
  59 + }
  60 + return apiKey;
  61 + }
  62 +
  63 + @Override
  64 + public AiApiKeyDO getApiKey(Long id) {
  65 + return apiKeyMapper.selectById(id);
  66 + }
  67 +
  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
  78 + public PageResult<AiApiKeyDO> getApiKeyPage(AiApiKeyPageReqVO pageReqVO) {
  79 + return apiKeyMapper.selectPage(pageReqVO);
  80 + }
  81 +
  82 +}
0 83 \ No newline at end of file
... ...
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-module-ai-biz/src/main/resources/http/image.http
... ... @@ -20,5 +20,5 @@ Content-Type: application/json
20 20 Authorization: {{token}}
21 21  
22 22 {
23   - "prompt": "Cute cartoon style mobile game scene, a colorful camping car with an outdoor table and chairs next to it on the road in a spring forest, the simple structure of the camper van, soft lighting, C4D rendering, 3d model in the style of a cartoon, cute shape, a pastel color scheme, closeup view from the side angle, high resolution, bright colors, a happy atmosphere. --ar 1:2 --v 6.0"
  23 + "prompt": "Cute cartoon style mobile game scene, a colorful camping car with an outdoor table and chairs next to it on the road in a spring forest, the simple structure of the camper van, soft lighting, C4D rendering, 3d model in the style of a cartoon, cute shape, a pastel color scheme, closeup view from the side angle, high resolution, bright colors, a happy atmosphere."
24 24 }
25 25 \ No newline at end of file
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/AiPlatformEnum.java
... ... @@ -6,6 +6,7 @@ import lombok.Getter;
6 6  
7 7 import java.util.List;
8 8  
  9 +// TODO 芋艿:这块,看看要不要调整下;
9 10 /**
10 11 * ai 模型平台
11 12 *
... ... @@ -16,11 +17,10 @@ import java.util.List;
16 17 @AllArgsConstructor
17 18 public enum AiPlatformEnum {
18 19  
19   -
20 20 YI_YAN("yiyan", "一言"),
21 21 QIAN_WEN("qianwen", "千问"),
22 22 XING_HUO("xinghuo", "星火"),
23   - OPEN_AI("openai", "openAi"),
  23 + OPEN_AI("openai", "openAi"), // TODO 芋艿:OpenAI
24 24 OPEN_AI_DALL("dall", "dall"),
25 25 MIDJOURNEY("midjourney", "midjourney"),
26 26  
... ... @@ -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;
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/resources/http-body/imagine.json
... ... @@ -6,7 +6,7 @@
6 6 "session_id": "$session_id",
7 7 "nonce": "$nonce",
8 8 "data": {
9   - "version": "1166847114203123795",
  9 + "version": "1237876415471554623",
10 10 "id": "938956540159881230",
11 11 "name": "imagine",
12 12 "type": 1,
... ...
yudao-module-ai/yudao-spring-boot-starter-ai/src/main/resources/requestTestJson/imageGenerationProcess/test2.json 0 → 100644
  1 +{
  2 + "type": 2,
  3 + "application_id": "936929561302675456",
  4 + "guild_id": "1237948819677904956",
  5 + "channel_id": "1237948819677904960",
  6 + "session_id": "4bdb0c32158f625bbd7f0a54bfbb54aa",
  7 + "data": {
  8 + "version": "1237876415471554623",
  9 + "id": "938956540159881230",
  10 + "name": "imagine",
  11 + "type": 1,
  12 + "options": [
  13 + {
  14 + "type": 3,
  15 + "name": "prompt",
  16 + "value": "哈哈哈"
  17 + }
  18 + ],
  19 + "application_command": {
  20 + "id": "938956540159881230",
  21 + "type": 1,
  22 + "application_id": "936929561302675456",
  23 + "version": "1237876415471554623",
  24 + "name": "imagine",
  25 + "description": "Create images with Midjourney",
  26 + "options": [
  27 + {
  28 + "type": 3,
  29 + "name": "prompt",
  30 + "description": "The prompt to imagine",
  31 + "required": true,
  32 + "description_localized": "The prompt to imagine",
  33 + "name_localized": "prompt"
  34 + }
  35 + ],
  36 + "dm_permission": true,
  37 + "contexts": [
  38 + 0,
  39 + 1,
  40 + 2
  41 + ],
  42 + "integration_types": [
  43 + 0,
  44 + 1
  45 + ],
  46 + "global_popularity_rank": 1,
  47 + "description_localized": "Create images with Midjourney",
  48 + "name_localized": "imagine"
  49 + },
  50 + "attachments": []
  51 + },
  52 + "nonce": "1238062212925358080",
  53 + "analytics_location": "slash_ui"
  54 +}
0 55 \ No newline at end of file
... ...
yudao-server/src/main/resources/application-local.yaml
... ... @@ -52,7 +52,7 @@ spring:
52 52 # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8 # SQLServer 连接的示例
53 53 # url: jdbc:dm://127.0.0.1:5236?schema=RUOYI_VUE_PRO # DM 连接的示例
54 54 username: root
55   - password: 123456
  55 + password: root
56 56 # username: sa # SQL Server 连接的示例
57 57 # password: Yudao@2024 # SQL Server 连接的示例
58 58 # username: SYSDBA # DM 连接的示例
... ... @@ -61,7 +61,7 @@ spring:
61 61 lazy: true # 开启懒加载,保证启动速度
62 62 url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
63 63 username: root
64   - password: 123456
  64 + password: root
65 65  
66 66 # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
67 67 data:
... ... @@ -248,9 +248,9 @@ yudao:
248 248 style: vivid
249 249 midjourney:
250 250 enable: true
251   - token: OTc1MzcyNDg1OTcxMzEyNzAw.G2iiSo.OqW9vToC5dokiyb1QOWnCwRPsYpOjLyNcf9--M
252   - guild-id: 1234355413420347402
253   - channel-id: 1234380679576424448
  251 + token: MTE4MjE3MjY2MjkxNTY3ODIzOA.GEV1SG.c49F8lZoGCUHwsj8O0UdodmM6nyQHvuD2fXflw
  252 + guild-id: 1237948819677904956
  253 + channel-id: 1237948819677904960
254 254 captcha:
255 255 enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试;
256 256 security:
... ... @@ -267,6 +267,8 @@ yudao:
267 267 enable: false
268 268 demo: false # 关闭演示模式
269 269 tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc
  270 + tenant:
  271 + enable: false
270 272  
271 273 justauth:
272 274 enabled: true
... ...