mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-23 07:41:53 +08:00
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
This commit is contained in:
commit
aaf1599f7a
@ -3,17 +3,23 @@ package cn.iocoder.yudao.module.ai;
|
||||
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
|
||||
|
||||
/**
|
||||
* System 错误码枚举类
|
||||
* AI 错误码枚举类
|
||||
*
|
||||
* system 系统,使用 1-002-000-000 段
|
||||
* ai 系统,使用 1-040-000-000 段
|
||||
*/
|
||||
public interface ErrorCodeConstants {
|
||||
|
||||
// ========== 模块 ai 错误码区间 [1-022-000-000 ~ 1-023-000-000) ==========
|
||||
// ========== API 密钥 1-040-000-000 ==========
|
||||
ErrorCode API_KEY_NOT_EXISTS = new ErrorCode(1_040_000_000, "AI API 密钥不存在");
|
||||
ErrorCode API_KEY_DISABLE = new ErrorCode(1_040_000_001, "AI API 密钥已禁用!");
|
||||
|
||||
// chat
|
||||
// ========== API 聊天模型 1-040-001-000 ==========
|
||||
|
||||
ErrorCode AI_MODULE_NOT_SUPPORTED = new ErrorCode(1_022_000_000, "AI 模型暂不支持!");
|
||||
ErrorCode CHAT_MODAL_NOT_EXIST = new ErrorCode(1_040_001_000, "AI 模型不存在!");
|
||||
ErrorCode CHAT_MODAL_DISABLE = new ErrorCode(1_040_001_001, "AI 模型({})已禁用!");
|
||||
|
||||
// ErrorCode AI_MODAL_CONFIG_PARAMS_INCORRECT = new ErrorCode(1_022_000_081, "AI 模型 config 参数不正确! {} ");
|
||||
// ErrorCode AI_MODAL_PLATFORM_PARAMS_INCORRECT = new ErrorCode(1_022_000_083, "AI 平台参数不正确! {} ");
|
||||
|
||||
// conversation
|
||||
|
||||
@ -30,11 +36,5 @@ public interface ErrorCodeConstants {
|
||||
ErrorCode AI_CHAT_ROLE_NOT_EXIST = new ErrorCode(1_022_000_060, "AI 角色不存在!");
|
||||
ErrorCode AI_CHAT_ROLE_NOT_PUBLIC = new ErrorCode(1_022_000_060, "AI 角色未公开!");
|
||||
|
||||
// modal
|
||||
|
||||
ErrorCode AI_MODAL_NOT_EXIST = new ErrorCode(1_022_000_080, "AI 模型不存在!");
|
||||
ErrorCode AI_MODAL_CONFIG_PARAMS_INCORRECT = new ErrorCode(1_022_000_081, "AI 模型 config 参数不正确! {} ");
|
||||
ErrorCode AI_MODAL_PLATFORM_PARAMS_INCORRECT = new ErrorCode(1_022_000_083, "AI 平台参数不正确! {} ");
|
||||
ErrorCode AI_MODAL_DISABLE_NOT_USED = new ErrorCode(1_022_000_084, "AI 模型禁用不能使用!");
|
||||
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
/**
|
||||
* author: fansili
|
||||
* time: 2024/3/3 18:14
|
||||
*/
|
||||
package cn.iocoder.yudao.module.ai;
|
@ -0,0 +1,72 @@
|
||||
package cn.iocoder.yudao.module.ai.controller.admin.model;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeyPageReqVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeyRespVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeySaveReqVO;
|
||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO;
|
||||
import cn.iocoder.yudao.module.ai.service.model.AiApiKeyService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "管理后台 - AI API 密钥")
|
||||
@RestController
|
||||
@RequestMapping("/ai/api-key")
|
||||
@Validated
|
||||
public class AiApiKeyController {
|
||||
|
||||
@Resource
|
||||
private AiApiKeyService apiKeyService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建 API 密钥")
|
||||
@PreAuthorize("@ss.hasPermission('ai:api-key:create')")
|
||||
public CommonResult<Long> createApiKey(@Valid @RequestBody AiApiKeySaveReqVO createReqVO) {
|
||||
return success(apiKeyService.createApiKey(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新 API 密钥")
|
||||
@PreAuthorize("@ss.hasPermission('ai:api-key:update')")
|
||||
public CommonResult<Boolean> updateApiKey(@Valid @RequestBody AiApiKeySaveReqVO updateReqVO) {
|
||||
apiKeyService.updateApiKey(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除 API 密钥")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('ai:api-key:delete')")
|
||||
public CommonResult<Boolean> deleteApiKey(@RequestParam("id") Long id) {
|
||||
apiKeyService.deleteApiKey(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得 API 密钥")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('ai:api-key:query')")
|
||||
public CommonResult<AiApiKeyRespVO> getApiKey(@RequestParam("id") Long id) {
|
||||
AiApiKeyDO apiKey = apiKeyService.getApiKey(id);
|
||||
return success(BeanUtils.toBean(apiKey, AiApiKeyRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得 API 密钥分页")
|
||||
@PreAuthorize("@ss.hasPermission('ai:api-key:query')")
|
||||
public CommonResult<PageResult<AiApiKeyRespVO>> getApiKeyPage(@Valid AiApiKeyPageReqVO pageReqVO) {
|
||||
PageResult<AiApiKeyDO> pageResult = apiKeyService.getApiKeyPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, AiApiKeyRespVO.class));
|
||||
}
|
||||
|
||||
}
|
@ -2,60 +2,71 @@ package cn.iocoder.yudao.module.ai.controller.admin.model;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelAddReqVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelListReqVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelListRespVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.ai.service.AiChatModelService;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelPageReqVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelRespVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelSaveReqVO;
|
||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
|
||||
import cn.iocoder.yudao.module.ai.service.model.AiChatModelService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
// TODO @fan:调整下接口;相关 vo 的命名等等;modal => model
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
/**
|
||||
* ai 模型
|
||||
*
|
||||
* @author fansili
|
||||
* @time 2024/4/24 19:42
|
||||
* @since 1.0
|
||||
*/
|
||||
@Tag(name = "A6-AI模型")
|
||||
@Tag(name = "管理后台 - AI 聊天模型")
|
||||
@RestController
|
||||
@RequestMapping("/ai/chat/model")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/ai/chat-model")
|
||||
@Validated
|
||||
public class AiChatModelController {
|
||||
|
||||
private final AiChatModelService aiChatModelService;
|
||||
@Resource
|
||||
private AiChatModelService chatModelService;
|
||||
|
||||
@Operation(summary = "ai模型 - 模型列表")
|
||||
@GetMapping("/list")
|
||||
public PageResult<AiChatModelListRespVO> list(@ModelAttribute AiChatModelListReqVO req) {
|
||||
return aiChatModelService.list(req);
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建聊天模型")
|
||||
@PreAuthorize("@ss.hasPermission('ai:chat-model:create')")
|
||||
public CommonResult<Long> createChatModel(@Valid @RequestBody AiChatModelSaveReqVO createReqVO) {
|
||||
return success(chatModelService.createChatModel(createReqVO));
|
||||
}
|
||||
|
||||
@Operation(summary = "ai模型 - 添加")
|
||||
@PutMapping("/add")
|
||||
public CommonResult<Void> add(@RequestBody @Validated AiChatModelAddReqVO req) {
|
||||
aiChatModelService.add(req);
|
||||
return CommonResult.success(null);
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新聊天模型")
|
||||
@PreAuthorize("@ss.hasPermission('ai:chat-model:update')")
|
||||
public CommonResult<Boolean> updateChatModel(@Valid @RequestBody AiChatModelSaveReqVO updateReqVO) {
|
||||
chatModelService.updateChatModel(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@Operation(summary = "ai模型 - 修改")
|
||||
@PostMapping("/update")
|
||||
public CommonResult<Void> update(@RequestBody @Validated AiChatModelUpdateReqVO req) {
|
||||
aiChatModelService.update(req);
|
||||
return CommonResult.success(null);
|
||||
}
|
||||
|
||||
@Operation(summary = "ai模型 - 删除")
|
||||
@DeleteMapping("/delete")
|
||||
public CommonResult<Void> delete(@RequestParam("id") Long id) {
|
||||
aiChatModelService.delete(id);
|
||||
return CommonResult.success(null);
|
||||
@Operation(summary = "删除聊天模型")
|
||||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('ai:chat-model:delete')")
|
||||
public CommonResult<Boolean> deleteChatModel(@RequestParam("id") Long id) {
|
||||
chatModelService.deleteChatModel(id);
|
||||
return success(true);
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "获得聊天模型")
|
||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('ai:chat-model:query')")
|
||||
public CommonResult<AiChatModelRespVO> getChatModel(@RequestParam("id") Long id) {
|
||||
AiChatModelDO chatModel = chatModelService.getChatModel(id);
|
||||
return success(BeanUtils.toBean(chatModel, AiChatModelRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/page")
|
||||
@Operation(summary = "获得聊天模型分页")
|
||||
@PreAuthorize("@ss.hasPermission('ai:chat-model:query')")
|
||||
public CommonResult<PageResult<AiChatModelRespVO>> getChatModelPage(@Valid AiChatModelPageReqVO pageReqVO) {
|
||||
PageResult<AiChatModelDO> pageResult = chatModelService.getChatModelPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, AiChatModelRespVO.class));
|
||||
}
|
||||
|
||||
}
|
@ -6,26 +6,20 @@ import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.*;
|
||||
import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
// TODO @fan:调整下接口;相关 vo 的命名等等;modal => model
|
||||
/**
|
||||
* ai chat 角色
|
||||
*
|
||||
* @fansili
|
||||
* @since v1.0
|
||||
*/
|
||||
@Tag(name = "A4-chat角色")
|
||||
@Tag(name = "管理后台 - AI 聊天角色")
|
||||
@RestController
|
||||
@RequestMapping("/ai/chat/role")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/ai/chat-role")
|
||||
@Validated
|
||||
public class AiChatRoleController {
|
||||
|
||||
private final AiChatRoleService chatRoleService;
|
||||
@Resource
|
||||
private AiChatRoleService chatRoleService;
|
||||
|
||||
@Operation(summary = "chat角色 - 角色列表")
|
||||
@GetMapping("/list")
|
||||
@ -60,4 +54,9 @@ public class AiChatRoleController {
|
||||
chatRoleService.delete(id);
|
||||
return CommonResult.success(null);
|
||||
}
|
||||
|
||||
// ========== 角色管理 ==========
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
@Schema(description = "管理后台 - AI API 密钥分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AiApiKeyPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "名称", example = "文心一言")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "平台", example = "OpenAI")
|
||||
private String platform;
|
||||
|
||||
@Schema(description = "状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
|
||||
@Schema(description = "管理后台 - AI API 密钥 Response VO")
|
||||
@Data
|
||||
public class AiApiKeyRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23538")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "文心一言")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "密钥", requiredMode = Schema.RequiredMode.REQUIRED, example = "ABC")
|
||||
private String apiKey;
|
||||
|
||||
@Schema(description = "平台", requiredMode = Schema.RequiredMode.REQUIRED, example = "OpenAI")
|
||||
private String platform;
|
||||
|
||||
@Schema(description = "自定义 API 地址", example = "https://aip.baidubce.com")
|
||||
private String url;
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer status;
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
@Schema(description = "管理后台 - AI API 密钥新增/修改 Request VO")
|
||||
@Data
|
||||
public class AiApiKeySaveReqVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23538")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "文心一言")
|
||||
@NotEmpty(message = "名称不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "密钥", requiredMode = Schema.RequiredMode.REQUIRED, example = "ABC")
|
||||
@NotEmpty(message = "密钥不能为空")
|
||||
private String apiKey;
|
||||
|
||||
@Schema(description = "平台", requiredMode = Schema.RequiredMode.REQUIRED, example = "OpenAI")
|
||||
@NotEmpty(message = "平台不能为空")
|
||||
private String platform;
|
||||
|
||||
@Schema(description = "自定义 API 地址", example = "https://aip.baidubce.com")
|
||||
private String url;
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel;
|
||||
|
||||
import lombok.*;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
|
||||
@Schema(description = "管理后台 - API 聊天模型分页 Request VO")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ToString(callSuper = true)
|
||||
public class AiChatModelPageReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "模型名字", example = "张三")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "模型标识", example = "gpt-3.5-turbo-0125")
|
||||
private String model;
|
||||
|
||||
@Schema(description = "模型平台", example = "OpenAI")
|
||||
private String platform;
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - AI 聊天模型 Response VO")
|
||||
@Data
|
||||
public class AiChatModelRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2630")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "API 秘钥编号", example = "22042")
|
||||
private Long keyId;
|
||||
|
||||
@Schema(description = "模型名字", example = "张三")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "模型标识", example = "gpt-3.5-turbo-0125")
|
||||
private String model;
|
||||
|
||||
@Schema(description = "模型平台", example = "OpenAI")
|
||||
private String platform;
|
||||
|
||||
@Schema(description = "排序", example = "1")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "状态", example = "2")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "温度参数", example = "1")
|
||||
private Double temperature;
|
||||
|
||||
@Schema(description = "单条回复的最大 Token 数量", example = "4096")
|
||||
private Integer maxTokens;
|
||||
|
||||
@Schema(description = "上下文的最大 Message 数量", example = "8192")
|
||||
private Integer maxContexts;
|
||||
|
||||
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import jakarta.validation.constraints.*;
|
||||
|
||||
@Schema(description = "管理后台 - API 聊天模型新增/修改 Request VO")
|
||||
@Data
|
||||
public class AiChatModelSaveReqVO {
|
||||
|
||||
@Schema(description = "编号", example = "2630")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "API 秘钥编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22042")
|
||||
@NotNull(message = "API 秘钥编号不能为空")
|
||||
private Long keyId;
|
||||
|
||||
@Schema(description = "模型名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
|
||||
@NotEmpty(message = "模型名字不能为空")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "模型标识", requiredMode = Schema.RequiredMode.REQUIRED, example = "gpt-3.5-turbo-0125")
|
||||
@NotEmpty(message = "模型标识不能为空")
|
||||
private String model;
|
||||
|
||||
@Schema(description = "模型平台", requiredMode = Schema.RequiredMode.REQUIRED, example = "OpenAI")
|
||||
@NotEmpty(message = "模型平台不能为空")
|
||||
private String platform;
|
||||
|
||||
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "排序不能为空")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@InEnum(CommonStatusEnum.class)
|
||||
@NotNull(message = "状态不能为空")
|
||||
private Integer status;
|
||||
|
||||
@Schema(description = "温度参数", example = "1")
|
||||
private Double temperature;
|
||||
|
||||
@Schema(description = "单条回复的最大 Token 数量", example = "4096")
|
||||
private Integer maxTokens;
|
||||
|
||||
@Schema(description = "上下文的最大 Message 数量", example = "8192")
|
||||
private Integer maxContexts;
|
||||
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* modal list
|
||||
*
|
||||
* @author fansili
|
||||
* @time 2024/4/24 19:56
|
||||
* @since 1.0
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AiChatModalRespVO {
|
||||
|
||||
@Schema(description = "编号")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "API 秘钥编号")
|
||||
private Long keyId;
|
||||
|
||||
@Schema(description = "模型名字")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "模型类型(qianwen、yiyan、xinghuo、openai)")
|
||||
private String model;
|
||||
|
||||
@Size(max = 32, message = "模型平台最大32个字符")
|
||||
private String platform;
|
||||
|
||||
@Schema(description = "排序")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "状态")
|
||||
private Integer status;
|
||||
|
||||
// ========== 会话配置 ==========
|
||||
|
||||
@Schema(description = "温度参数")
|
||||
private Integer temperature;
|
||||
|
||||
@Schema(description = "单条回复的最大 Token 数量")
|
||||
private Integer maxTokens;
|
||||
|
||||
@Schema(description = "上下文的最大 Message 数量")
|
||||
private Integer maxContexts;
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* ai chat modal
|
||||
*
|
||||
* @author fansili
|
||||
* @time 2024/4/24 19:47
|
||||
* @since 1.0
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AiChatModalUpdateReqVO {
|
||||
|
||||
@Schema(description = "编号")
|
||||
@Size(max = 32, message = "编号最大32个字符")
|
||||
@NotNull(message = "编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "API 秘钥编号")
|
||||
@Size(max = 32, message = "API 秘钥编号最大32个字符")
|
||||
@NotNull(message = "API 秘钥编号不能为空!")
|
||||
private Long keyId;
|
||||
|
||||
@Schema(description = "模型名字")
|
||||
@Size(max = 60, message = "模型名字最大60个字符")
|
||||
@NotNull(message = "模型名字不能为空!")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "模型类型(qianwen、yiyan、xinghuo、openai)")
|
||||
@Size(max = 32, message = "模型类型最大32个字符")
|
||||
@NotNull(message = "model模型不能为空!")
|
||||
private String model;
|
||||
|
||||
@Size(max = 32, message = "模型平台最大32个字符")
|
||||
@Schema(description = "模型平台 参考 AiPlatformEnum")
|
||||
@NotNull(message = "平台不能为空!")
|
||||
private String platform;
|
||||
|
||||
@Schema(description = "排序")
|
||||
@NotNull(message = "sort排序不能为空!")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "状态")
|
||||
@NotNull(message = "状态不能为空!")
|
||||
private Integer status;
|
||||
|
||||
// ========== 会话配置 ==========
|
||||
|
||||
@Schema(description = "温度参数")
|
||||
private Integer temperature;
|
||||
|
||||
@Schema(description = "单条回复的最大 Token 数量")
|
||||
private Integer maxTokens;
|
||||
|
||||
@Schema(description = "上下文的最大 Message 数量")
|
||||
private Integer maxContexts;
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* ai chat modal
|
||||
*
|
||||
* @author fansili
|
||||
* @time 2024/4/24 19:47
|
||||
* @since 1.0
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AiChatModelAddReqVO {
|
||||
|
||||
@Schema(description = "API 秘钥编号")
|
||||
@NotNull(message = "API 秘钥编号不能为空!")
|
||||
private Long keyId;
|
||||
|
||||
@Schema(description = "模型名字")
|
||||
@Size(max = 60, message = "模型名字最大60个字符")
|
||||
@NotNull(message = "模型名字不能为空!")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "模型类型(qianwen、yiyan、xinghuo、openai)")
|
||||
@Size(max = 32, message = "模型类型最大32个字符")
|
||||
@NotNull(message = "model模型不能为空!")
|
||||
private String model;
|
||||
|
||||
@Size(max = 32, message = "模型平台最大32个字符")
|
||||
@Schema(description = "模型平台 参考 AiPlatformEnum")
|
||||
@NotNull(message = "平台不能为空!")
|
||||
private String platform;
|
||||
|
||||
@Schema(description = "排序")
|
||||
@NotNull(message = "sort排序不能为空!")
|
||||
private Integer sort;
|
||||
|
||||
// ========== 会话配置 ==========
|
||||
|
||||
@Schema(description = "温度参数")
|
||||
private Integer temperature;
|
||||
|
||||
@Schema(description = "单条回复的最大 Token 数量")
|
||||
private Integer maxTokens;
|
||||
|
||||
@Schema(description = "上下文的最大 Message 数量")
|
||||
private Integer maxContexts;
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* modal list
|
||||
*
|
||||
* @author fansili
|
||||
* @time 2024/4/24 19:56
|
||||
* @since 1.0
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AiChatModelListReqVO extends PageParam {
|
||||
|
||||
@Schema(description = "名字搜搜")
|
||||
private String search;
|
||||
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
|
||||
|
||||
import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* modal list
|
||||
*
|
||||
* @author fansili
|
||||
* @time 2024/4/24 19:56
|
||||
* @since 1.0
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AiChatModelListRespVO {
|
||||
|
||||
@Schema(description = "编号")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "API 秘钥编号")
|
||||
private Long keyId;
|
||||
|
||||
@Schema(description = "模型名称")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "模型标志")
|
||||
private String model;
|
||||
|
||||
@Schema(description = "平台")
|
||||
private String platform;
|
||||
|
||||
@Schema(description = "排序值")
|
||||
private Integer sort;
|
||||
|
||||
@Schema(description = "状态")
|
||||
private Integer status;
|
||||
|
||||
// ========== 会话配置 ==========
|
||||
|
||||
@Schema(description = "温度参数")
|
||||
private Double temperature;
|
||||
|
||||
@Schema(description = "单条回复的最大 Token 数量")
|
||||
private Integer maxTokens;
|
||||
|
||||
@Schema(description = "上下文的最大 Message 数量")
|
||||
private Integer maxContexts;
|
||||
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.model;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* ai chat modal
|
||||
*
|
||||
* @author fansili
|
||||
* @time 2024/4/24 19:47
|
||||
* @since 1.0
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AiChatModelUpdateReqVO {
|
||||
|
||||
@Schema(description = "编号")
|
||||
@NotNull(message = "编号不能为空")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "API 秘钥编号")
|
||||
@NotNull(message = "API 秘钥编号不能为空!")
|
||||
private Long keyId;
|
||||
|
||||
@Schema(description = "模型名字")
|
||||
@Size(max = 60, message = "模型名字最大60个字符")
|
||||
@NotNull(message = "模型名字不能为空!")
|
||||
private String name;
|
||||
|
||||
@Schema(description = "模型类型(qianwen、yiyan、xinghuo、openai)")
|
||||
@Size(max = 32, message = "模型类型最大32个字符")
|
||||
@NotNull(message = "model模型不能为空!")
|
||||
private String model;
|
||||
|
||||
@Size(max = 32, message = "模型平台最大32个字符")
|
||||
@Schema(description = "模型平台 参考 AiPlatformEnum")
|
||||
@NotNull(message = "平台不能为空!")
|
||||
private String platform;
|
||||
|
||||
@Schema(description = "排序")
|
||||
@NotNull(message = "sort排序不能为空!")
|
||||
private Integer sort;
|
||||
|
||||
// ========== 会话配置 ==========
|
||||
|
||||
@Schema(description = "温度参数")
|
||||
private Integer temperature;
|
||||
|
||||
@Schema(description = "单条回复的最大 Token 数量")
|
||||
private Integer maxTokens;
|
||||
|
||||
@Schema(description = "上下文的最大 Message 数量")
|
||||
private Integer maxContexts;
|
||||
}
|
@ -19,14 +19,6 @@ public interface AiChatMessageConvert {
|
||||
|
||||
AiChatMessageConvert INSTANCE = Mappers.getMapper(AiChatMessageConvert.class);
|
||||
|
||||
/**
|
||||
* 转换 ChatMessageListRes
|
||||
*
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
List<AiChatMessageRespVO> convert(List<AiChatMessageDO> list);
|
||||
|
||||
/**
|
||||
* 转换 AiChatMessageRespVO
|
||||
*
|
||||
|
@ -1,57 +0,0 @@
|
||||
package cn.iocoder.yudao.module.ai.convert;
|
||||
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModalRespVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelAddReqVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelListRespVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModelUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 聊天 modal
|
||||
*
|
||||
* @author fansili
|
||||
* @time 2024/4/18 16:39
|
||||
* @since 1.0
|
||||
*/
|
||||
@Mapper
|
||||
public interface AiChatModelConvert {
|
||||
|
||||
AiChatModelConvert INSTANCE = Mappers.getMapper(AiChatModelConvert.class);
|
||||
|
||||
/**
|
||||
* 转换 - AiChatModalListRes
|
||||
*
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
List<AiChatModelListRespVO> convertAiChatModalListRes(List<AiChatModelDO> list);
|
||||
|
||||
/**
|
||||
* 转换 - AiChatModalDO
|
||||
*
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
AiChatModelDO convertAiChatModalDO(AiChatModelAddReqVO req);
|
||||
|
||||
/**
|
||||
* 转换 - AiChatModalDO
|
||||
*
|
||||
* @param req
|
||||
* @return
|
||||
*/
|
||||
AiChatModelDO convertAiChatModalDO(AiChatModelUpdateReqVO req);
|
||||
|
||||
/**
|
||||
* 转换 - AiChatModalRes
|
||||
*
|
||||
* @param aiChatModalDO
|
||||
* @return
|
||||
*/
|
||||
AiChatModalRespVO convertAiChatModalRes(AiChatModelDO aiChatModalDO);
|
||||
|
||||
}
|
@ -49,8 +49,8 @@ public class AiImageDO extends BaseDO {
|
||||
|
||||
// ============ mj 需要字段
|
||||
|
||||
@Schema(description = "用户操作的消息编号(MJ返回)")
|
||||
private String mjMessageId;
|
||||
@Schema(description = "用户操作的Nonce编号(MJ返回)")
|
||||
private String mjNonceId;
|
||||
|
||||
@Schema(description = "用户操作的操作编号(MJ返回)")
|
||||
private String mjOperationId;
|
||||
|
@ -31,18 +31,16 @@ public class AiApiKeyDO extends BaseDO {
|
||||
* 名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 密钥
|
||||
*/
|
||||
private String apiKey;
|
||||
/**
|
||||
* 平台
|
||||
*
|
||||
* 枚举 {@link AiPlatformEnum}
|
||||
*/
|
||||
private String platform;
|
||||
/**
|
||||
* 用途
|
||||
*
|
||||
* TODO 芋艿:枚举;chat、image
|
||||
*/
|
||||
private Integer type;
|
||||
/**
|
||||
* API 地址
|
||||
*/
|
||||
@ -54,6 +52,4 @@ public class AiApiKeyDO extends BaseDO {
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
// TODO 芋艿:proxyUrl 代理地址
|
||||
|
||||
}
|
||||
|
@ -5,25 +5,23 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelPageReqVO;
|
||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* chat modal
|
||||
* API 聊天模型 Mapper
|
||||
*
|
||||
* @author fansili
|
||||
* @time 2024/4/24 19:41
|
||||
* @since 1.0
|
||||
*/
|
||||
@Repository
|
||||
@Mapper
|
||||
public interface AiChatModelMapper extends BaseMapperX<AiChatModelDO> {
|
||||
|
||||
// TODO 芋艿:要搞一下
|
||||
/**
|
||||
* 查询 - 第一个modal
|
||||
*
|
||||
@ -46,5 +44,16 @@ public interface AiChatModelMapper extends BaseMapperX<AiChatModelDO> {
|
||||
* @param modalIds
|
||||
* @return
|
||||
*/
|
||||
List<AiChatModelDO> selectByIds(Collection<Long> modalIds);
|
||||
default List<AiChatModelDO> selectByIds(Collection<Long> modalIds) {
|
||||
return this.selectList(new LambdaQueryWrapperX<AiChatModelDO>().eq(AiChatModelDO::getId, modalIds));
|
||||
}
|
||||
|
||||
|
||||
default PageResult<AiChatModelDO> selectPage(AiChatModelPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<AiChatModelDO>()
|
||||
.likeIfPresent(AiChatModelDO::getName, reqVO.getName())
|
||||
.eqIfPresent(AiChatModelDO::getModel, reqVO.getModel())
|
||||
.eqIfPresent(AiChatModelDO::getPlatform, reqVO.getPlatform())
|
||||
.orderByDesc(AiChatModelDO::getId));
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.iocoder.yudao.module.ai.dal.mysql;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.ai.dal.dataobject.image.AiImageDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
@ -17,4 +18,13 @@ import org.springframework.stereotype.Repository;
|
||||
public interface AiImageMapper extends BaseMapperX<AiImageDO> {
|
||||
|
||||
|
||||
/**
|
||||
* 更新 - 根据 messageId
|
||||
*
|
||||
* @param mjNonceId
|
||||
* @param aiImageDO
|
||||
*/
|
||||
default void updateByMjNonce(Long mjNonceId, AiImageDO aiImageDO) {
|
||||
this.update(aiImageDO, new LambdaQueryWrapperX<AiImageDO>().eq(AiImageDO::getMjNonceId, mjNonceId));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
package cn.iocoder.yudao.module.ai.dal.mysql.model;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeyPageReqVO;
|
||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* AI API 密钥 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface AiApiKeyMapper extends BaseMapperX<AiApiKeyDO> {
|
||||
|
||||
default PageResult<AiApiKeyDO> selectPage(AiApiKeyPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<AiApiKeyDO>()
|
||||
.likeIfPresent(AiApiKeyDO::getName, reqVO.getName())
|
||||
.eqIfPresent(AiApiKeyDO::getPlatform, reqVO.getPlatform())
|
||||
.eqIfPresent(AiApiKeyDO::getStatus, reqVO.getStatus())
|
||||
.orderByDesc(AiApiKeyDO::getId));
|
||||
}
|
||||
|
||||
}
|
@ -75,5 +75,4 @@ public interface AiChatModelService {
|
||||
* @return
|
||||
*/
|
||||
List<AiChatModelDO> getModalByIds(Set<Long> modalIds);
|
||||
|
||||
}
|
||||
|
@ -72,4 +72,5 @@ public interface AiChatRoleService {
|
||||
* @param aiChatRoleDO
|
||||
*/
|
||||
void validateIsPublic(AiChatRoleDO aiChatRoleDO);
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ import cn.iocoder.yudao.module.ai.service.AiChatModelService;
|
||||
import jakarta.validation.ConstraintViolation;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.mybatis.spring.annotation.MapperScannerRegistrar;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
@ -36,7 +35,6 @@ import java.util.Set;
|
||||
public class AiChatModalServiceImpl implements AiChatModelService {
|
||||
|
||||
private final AiChatModelMapper aiChatModelMapper;
|
||||
private final MapperScannerRegistrar mapperScannerRegistrar;
|
||||
|
||||
@Override
|
||||
public PageResult<AiChatModelListRespVO> list(AiChatModelListReqVO req) {
|
||||
|
@ -12,7 +12,7 @@ import cn.iocoder.yudao.module.ai.convert.AiChatRoleConvert;
|
||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
|
||||
import cn.iocoder.yudao.module.ai.dal.mysql.AiChatRoleMapper;
|
||||
import cn.iocoder.yudao.module.ai.enums.AiChatRoleCategoryEnum;
|
||||
import cn.iocoder.yudao.module.ai.service.AiChatModelService;
|
||||
import cn.iocoder.yudao.module.ai.service.model.AiChatModelService;
|
||||
import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -57,8 +57,8 @@ public class AiChatRoleServiceImpl implements AiChatRoleService {
|
||||
public void add(AiChatRoleAddReqVO req) {
|
||||
// 转换enum,并校验enum
|
||||
AiChatRoleCategoryEnum.valueOfCategory(req.getCategory());
|
||||
// 校验模型是否存在
|
||||
aiChatModalService.validateExists(req.getModelId());
|
||||
// 校验模型是否存在 TODO
|
||||
// aiChatModalService.validateExists(req.getModelId());
|
||||
// 转换do
|
||||
AiChatRoleDO insertAiChatRoleDO = AiChatRoleConvert.INSTANCE.convertAiChatRoleDO(req);
|
||||
insertAiChatRoleDO.setUserId(SecurityFrameworkUtils.getLoginUserId());
|
||||
@ -73,8 +73,8 @@ public class AiChatRoleServiceImpl implements AiChatRoleService {
|
||||
validateExists(req.getId());
|
||||
// 转换enum,并校验enum
|
||||
AiChatRoleCategoryEnum.valueOfCategory(req.getCategory());
|
||||
// 校验模型是否存在
|
||||
aiChatModalService.validateExists(req.getModelId());
|
||||
// 校验模型是否存在 TODO
|
||||
// aiChatModalService.validateExists(req.getModelId());
|
||||
// 转换do
|
||||
AiChatRoleDO updateChatRole = AiChatRoleConvert.INSTANCE.convertAiChatRoleDO(req);
|
||||
updateChatRole.setId(req.getId());
|
||||
|
@ -12,7 +12,6 @@ import cn.iocoder.yudao.module.ai.config.AiChatClientFactory;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationRespVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageRespVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModalRespVO;
|
||||
import cn.iocoder.yudao.module.ai.convert.AiChatMessageConvert;
|
||||
import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO;
|
||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
|
||||
@ -20,7 +19,7 @@ import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
|
||||
import cn.iocoder.yudao.module.ai.dal.mysql.AiChatConversationMapper;
|
||||
import cn.iocoder.yudao.module.ai.dal.mysql.AiChatMessageMapper;
|
||||
import cn.iocoder.yudao.module.ai.service.AiChatConversationService;
|
||||
import cn.iocoder.yudao.module.ai.service.AiChatModelService;
|
||||
import cn.iocoder.yudao.module.ai.service.model.AiChatModelService;
|
||||
import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
|
||||
import cn.iocoder.yudao.module.ai.service.AiChatService;
|
||||
import lombok.AllArgsConstructor;
|
||||
@ -61,9 +60,7 @@ public class AiChatServiceImpl implements AiChatService {
|
||||
// 查询对话
|
||||
AiChatConversationRespVO conversation = chatConversationService.getConversationOfValidate(req.getConversationId());
|
||||
// 获取对话模型
|
||||
AiChatModalRespVO chatModal = aiChatModalService.getChatModalOfValidate(conversation.getModelId());
|
||||
// 对话模型是否可用
|
||||
aiChatModalService.validateAvailable(chatModal);
|
||||
AiChatModelDO chatModel = aiChatModalService.validateChatModel(conversation.getModelId());
|
||||
// 获取角色信息
|
||||
AiChatRoleDO aiChatRoleDO = null;
|
||||
if (conversation.getRoleId() != null) {
|
||||
@ -72,10 +69,10 @@ public class AiChatServiceImpl implements AiChatService {
|
||||
// 校验角色是否公开
|
||||
aiChatRoleService.validateIsPublic(aiChatRoleDO);
|
||||
// 获取 client 类型
|
||||
AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(chatModal.getPlatform());
|
||||
AiPlatformEnum platformEnum = AiPlatformEnum.validatePlatform(chatModel.getPlatform());
|
||||
// 保存 chat message
|
||||
insertChatMessage(conversation.getId(), MessageType.USER, loginUserId, conversation.getRoleId(),
|
||||
chatModal.getModel(), chatModal.getId(), req.getContent(),
|
||||
chatModel.getModel(), chatModel.getId(), req.getContent(),
|
||||
null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
|
||||
String content = null;
|
||||
int tokens = 0;
|
||||
@ -97,7 +94,7 @@ public class AiChatServiceImpl implements AiChatService {
|
||||
} finally {
|
||||
// 保存 chat message
|
||||
insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(),
|
||||
chatModal.getModel(), chatModal.getId(), content,
|
||||
chatModel.getModel(), chatModel.getId(), content,
|
||||
tokens, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
|
||||
}
|
||||
return new AiChatMessageRespVO().setContent(content);
|
||||
@ -132,9 +129,7 @@ public class AiChatServiceImpl implements AiChatService {
|
||||
// 查询对话
|
||||
AiChatConversationRespVO conversation = chatConversationService.getConversationOfValidate(req.getConversationId());
|
||||
// 获取对话模型
|
||||
AiChatModalRespVO chatModal = aiChatModalService.getChatModalOfValidate(conversation.getModelId());
|
||||
// 对话模型是否可用
|
||||
aiChatModalService.validateAvailable(chatModal);
|
||||
AiChatModelDO chatModel = aiChatModalService.validateChatModel(conversation.getModelId());
|
||||
// 获取角色信息
|
||||
AiChatRoleDO aiChatRoleDO = null;
|
||||
if (conversation.getRoleId() != null) {
|
||||
@ -149,10 +144,10 @@ public class AiChatServiceImpl implements AiChatService {
|
||||
// req.setTemperature(req.getTemperature());
|
||||
// 保存 chat message
|
||||
insertChatMessage(conversation.getId(), MessageType.USER, loginUserId, conversation.getRoleId(),
|
||||
chatModal.getModel(), chatModal.getId(), req.getContent(),
|
||||
chatModel.getModel(), chatModel.getId(), req.getContent(),
|
||||
null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
|
||||
// 获取 client 类型
|
||||
AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(chatModal.getPlatform());
|
||||
AiPlatformEnum platformEnum = AiPlatformEnum.validatePlatform(chatModel.getPlatform());
|
||||
StreamingChatClient streamingChatClient = aiChatClientFactory.getStreamingChatClient(platformEnum);
|
||||
Flux<ChatResponse> streamResponse = streamingChatClient.stream(prompt);
|
||||
// 转换 flex AiChatMessageRespVO
|
||||
@ -171,7 +166,7 @@ public class AiChatServiceImpl implements AiChatService {
|
||||
log.info("发送完成!");
|
||||
// 保存 chat message
|
||||
insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(),
|
||||
chatModal.getModel(), chatModal.getId(), contentBuffer.toString(),
|
||||
chatModel.getModel(), chatModel.getId(), contentBuffer.toString(),
|
||||
tokens.get(), conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
|
||||
}
|
||||
}).doOnError(new Consumer<Throwable>() {
|
||||
@ -180,7 +175,7 @@ public class AiChatServiceImpl implements AiChatService {
|
||||
log.error("发送错误 {}!", throwable.getMessage());
|
||||
// 保存 chat message
|
||||
insertChatMessage(conversation.getId(), MessageType.SYSTEM, loginUserId, conversation.getRoleId(),
|
||||
chatModal.getModel(), chatModal.getId(), throwable.getMessage(),
|
||||
chatModel.getModel(), chatModel.getId(), throwable.getMessage(),
|
||||
tokens.get(), conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());
|
||||
}
|
||||
});
|
||||
|
@ -145,7 +145,7 @@ public class AiImageServiceImpl implements AiImageService {
|
||||
// 校验 OperateId 是否存在
|
||||
AiImageMidjourneyOperationsVO midjourneyOperationsVO = validateMidjourneyOperationsExists(midjourneyOperations, req.getOperateId());
|
||||
// 校验 messageId
|
||||
validateMessageId(aiImageDO.getMjMessageId(), req.getMessageId());
|
||||
validateMessageId(aiImageDO.getMjNonceId(), req.getMessageId());
|
||||
// 获取 mjOperationName
|
||||
String mjOperationName = midjourneyOperationsVO.getLabel();
|
||||
// 保存一个 image 任务记录
|
||||
@ -222,7 +222,7 @@ public class AiImageServiceImpl implements AiImageService {
|
||||
aiImageDO.setDrawingImageUrl(drawingImageUrl);
|
||||
aiImageDO.setDrawingErrorMessage(drawingErrorMessage);
|
||||
//
|
||||
aiImageDO.setMjMessageId(mjMessageId);
|
||||
aiImageDO.setMjNonceId(mjMessageId);
|
||||
aiImageDO.setMjOperationId(mjOperationId);
|
||||
aiImageDO.setMjOperationName(mjOperationName);
|
||||
aiImageMapper.insert(aiImageDO);
|
||||
|
@ -62,12 +62,11 @@ public class YuDaoMidjourneyMessageHandler implements MidjourneyMessageHandler {
|
||||
|
||||
private void errorHandler(MidjourneyMessage midjourneyMessage) {
|
||||
// image 编号
|
||||
Long aiImageId = Long.valueOf(midjourneyMessage.getNonce());
|
||||
Long nonceId = Long.valueOf(midjourneyMessage.getNonce());
|
||||
// 获取 error message
|
||||
String errorMessage = getErrorMessage(midjourneyMessage);
|
||||
aiImageMapper.updateById(
|
||||
aiImageMapper.updateByMjNonce(nonceId,
|
||||
new AiImageDO()
|
||||
.setId(aiImageId)
|
||||
.setDrawingErrorMessage(errorMessage)
|
||||
.setDrawingStatus(AiImageDrawingStatusEnum.FAIL.getStatus())
|
||||
);
|
||||
@ -83,7 +82,8 @@ public class YuDaoMidjourneyMessageHandler implements MidjourneyMessageHandler {
|
||||
|
||||
private void successHandler(MidjourneyMessage midjourneyMessage) {
|
||||
// 获取id
|
||||
Long aiImageId = Long.valueOf(midjourneyMessage.getNonce());
|
||||
Long nonceId = Long.valueOf(midjourneyMessage.getNonce());
|
||||
// TODO @芋艿 这个地方有问题,不能根据 nonce来更新,不返回这个信息(别人获取了 image-xxx-xx 后面一段hash,由于没有mj账号测试,暂不清楚。)
|
||||
// 获取生成 url
|
||||
String imageUrl = null;
|
||||
if (CollUtil.isNotEmpty(midjourneyMessage.getAttachments())) {
|
||||
@ -102,12 +102,11 @@ public class YuDaoMidjourneyMessageHandler implements MidjourneyMessageHandler {
|
||||
// 获取 midjourneyOperations
|
||||
List<AiImageMidjourneyOperationsVO> midjourneyOperations = getMidjourneyOperationsList(midjourneyMessage);
|
||||
// 更新数据库
|
||||
aiImageMapper.updateById(
|
||||
aiImageMapper.updateByMjNonce(nonceId,
|
||||
new AiImageDO()
|
||||
.setId(aiImageId)
|
||||
.setDrawingImageUrl(imageUrl)
|
||||
.setDrawingStatus(drawingStatusEnum == null ? null : drawingStatusEnum.getStatus())
|
||||
.setMjMessageId(midjourneyMessage.getId())
|
||||
.setMjNonceId(midjourneyMessage.getId())
|
||||
.setMjOperations(JsonUtils.toJsonString(midjourneyOperations))
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,62 @@
|
||||
package cn.iocoder.yudao.module.ai.service.model;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeyPageReqVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeySaveReqVO;
|
||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
/**
|
||||
* AI API 密钥 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface AiApiKeyService {
|
||||
|
||||
/**
|
||||
* 创建 API 密钥
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createApiKey(@Valid AiApiKeySaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新 API 密钥
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateApiKey(@Valid AiApiKeySaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除 API 密钥
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteApiKey(Long id);
|
||||
|
||||
/**
|
||||
* 获得 API 密钥
|
||||
*
|
||||
* @param id 编号
|
||||
* @return API 密钥
|
||||
*/
|
||||
AiApiKeyDO getApiKey(Long id);
|
||||
|
||||
/**
|
||||
* 校验 API 密钥
|
||||
*
|
||||
* @param id 比那好
|
||||
* @return API 密钥
|
||||
*/
|
||||
AiApiKeyDO validateApiKey(Long id);
|
||||
|
||||
/**
|
||||
* 获得 API 密钥分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return API 密钥分页
|
||||
*/
|
||||
PageResult<AiApiKeyDO> getApiKeyPage(AiApiKeyPageReqVO pageReqVO);
|
||||
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package cn.iocoder.yudao.module.ai.service.model;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeyPageReqVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.apikey.AiApiKeySaveReqVO;
|
||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiApiKeyDO;
|
||||
import cn.iocoder.yudao.module.ai.dal.mysql.model.AiApiKeyMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* AI API 密钥 Service 实现类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class AiApiKeyServiceImpl implements AiApiKeyService {
|
||||
|
||||
@Resource
|
||||
private AiApiKeyMapper apiKeyMapper;
|
||||
|
||||
@Override
|
||||
public Long createApiKey(AiApiKeySaveReqVO createReqVO) {
|
||||
// 插入
|
||||
AiApiKeyDO apiKey = BeanUtils.toBean(createReqVO, AiApiKeyDO.class);
|
||||
apiKeyMapper.insert(apiKey);
|
||||
// 返回
|
||||
return apiKey.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateApiKey(AiApiKeySaveReqVO updateReqVO) {
|
||||
// 校验存在
|
||||
validateApiKeyExists(updateReqVO.getId());
|
||||
// 更新
|
||||
AiApiKeyDO updateObj = BeanUtils.toBean(updateReqVO, AiApiKeyDO.class);
|
||||
apiKeyMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteApiKey(Long id) {
|
||||
// 校验存在
|
||||
validateApiKeyExists(id);
|
||||
// 删除
|
||||
apiKeyMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private AiApiKeyDO validateApiKeyExists(Long id) {
|
||||
AiApiKeyDO apiKey = apiKeyMapper.selectById(id);
|
||||
if (apiKey == null) {
|
||||
throw exception(API_KEY_NOT_EXISTS);
|
||||
}
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AiApiKeyDO getApiKey(Long id) {
|
||||
return apiKeyMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AiApiKeyDO validateApiKey(Long id) {
|
||||
AiApiKeyDO apiKey = validateApiKeyExists(id);
|
||||
if (CommonStatusEnum.isDisable(apiKey.getStatus())) {
|
||||
throw exception(API_KEY_DISABLE);
|
||||
}
|
||||
return apiKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<AiApiKeyDO> getApiKeyPage(AiApiKeyPageReqVO pageReqVO) {
|
||||
return apiKeyMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package cn.iocoder.yudao.module.ai.service.impl;
|
||||
package cn.iocoder.yudao.module.ai.service.model;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
|
||||
@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.ai.ErrorCodeConstants;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationCreateReqVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationRespVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.model.AiChatModalRespVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.AiChatRoleRespVO;
|
||||
import cn.iocoder.yudao.module.ai.convert.AiChatConversationConvert;
|
||||
import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatConversationDO;
|
||||
@ -15,7 +14,6 @@ import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
|
||||
import cn.iocoder.yudao.module.ai.dal.mysql.AiChatConversationMapper;
|
||||
import cn.iocoder.yudao.module.ai.dal.mysql.AiChatModelMapper;
|
||||
import cn.iocoder.yudao.module.ai.service.AiChatConversationService;
|
||||
import cn.iocoder.yudao.module.ai.service.AiChatModelService;
|
||||
import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -87,9 +85,7 @@ public class AiChatConversationServiceImpl implements AiChatConversationService
|
||||
// 校验对话是否存在
|
||||
validateExists(updateReqVO.getId());
|
||||
// 获取模型信息并验证
|
||||
AiChatModalRespVO chatModal = aiChatModalService.getChatModalOfValidate(updateReqVO.getModelId());
|
||||
// 校验modal是否可用
|
||||
aiChatModalService.validateAvailable(chatModal);
|
||||
aiChatModalService.validateChatModel(updateReqVO.getModelId());
|
||||
// 更新对话信息
|
||||
AiChatConversationDO updateAiChatConversationDO
|
||||
= AiChatConversationConvert.INSTANCE.convertAiChatConversationDO(updateReqVO);
|
@ -0,0 +1,63 @@
|
||||
package cn.iocoder.yudao.module.ai.service.model;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelPageReqVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelSaveReqVO;
|
||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
/**
|
||||
* AI 聊天模型 Service 接口
|
||||
*
|
||||
* @author fansili
|
||||
* @since 2024/4/24 19:42
|
||||
*/
|
||||
public interface AiChatModelService {
|
||||
|
||||
/**
|
||||
* 创建聊天模型
|
||||
*
|
||||
* @param createReqVO 创建信息
|
||||
* @return 编号
|
||||
*/
|
||||
Long createChatModel(@Valid AiChatModelSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新聊天模型
|
||||
*
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateChatModel(@Valid AiChatModelSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除聊天模型
|
||||
*
|
||||
* @param id 编号
|
||||
*/
|
||||
void deleteChatModel(Long id);
|
||||
|
||||
/**
|
||||
* 获得聊天模型
|
||||
*
|
||||
* @param id 编号
|
||||
* @return API 聊天模型
|
||||
*/
|
||||
AiChatModelDO getChatModel(Long id);
|
||||
|
||||
/**
|
||||
* 获得聊天模型分页
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @return API 聊天模型分页
|
||||
*/
|
||||
PageResult<AiChatModelDO> getChatModelPage(AiChatModelPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 校验聊天模型
|
||||
*
|
||||
* @param id 编号
|
||||
* @return 聊天模型
|
||||
*/
|
||||
AiChatModelDO validateChatModel(Long id);
|
||||
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
package cn.iocoder.yudao.module.ai.service.model;
|
||||
|
||||
import cn.iocoder.yudao.framework.ai.AiPlatformEnum;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelPageReqVO;
|
||||
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatModel.AiChatModelSaveReqVO;
|
||||
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
|
||||
import cn.iocoder.yudao.module.ai.dal.mysql.AiChatModelMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.*;
|
||||
|
||||
/**
|
||||
* AI 聊天模型 Service 实现类
|
||||
*
|
||||
* @author fansili
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class AiChatModelServiceImpl implements AiChatModelService {
|
||||
|
||||
@Resource
|
||||
private AiApiKeyService apiKeyService;
|
||||
|
||||
@Resource
|
||||
private AiChatModelMapper chatModelMapper;
|
||||
|
||||
@Override
|
||||
public Long createChatModel(AiChatModelSaveReqVO createReqVO) {
|
||||
// 1. 校验
|
||||
AiPlatformEnum.validatePlatform(createReqVO.getPlatform());
|
||||
apiKeyService.validateApiKey(createReqVO.getKeyId());
|
||||
|
||||
// 2. 插入
|
||||
AiChatModelDO chatModel = BeanUtils.toBean(createReqVO, AiChatModelDO.class);
|
||||
chatModelMapper.insert(chatModel);
|
||||
return chatModel.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateChatModel(AiChatModelSaveReqVO updateReqVO) {
|
||||
// 1. 校验
|
||||
validateChatModelExists(updateReqVO.getId());
|
||||
AiPlatformEnum.validatePlatform(updateReqVO.getPlatform());
|
||||
apiKeyService.validateApiKey(updateReqVO.getKeyId());
|
||||
|
||||
// 2. 更新
|
||||
AiChatModelDO updateObj = BeanUtils.toBean(updateReqVO, AiChatModelDO.class);
|
||||
chatModelMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteChatModel(Long id) {
|
||||
// 校验存在
|
||||
validateChatModelExists(id);
|
||||
// 删除
|
||||
chatModelMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private AiChatModelDO validateChatModelExists(Long id) {
|
||||
AiChatModelDO model = chatModelMapper.selectById(id);
|
||||
if (chatModelMapper.selectById(id) == null) {
|
||||
throw exception(CHAT_MODAL_NOT_EXIST);
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AiChatModelDO getChatModel(Long id) {
|
||||
return chatModelMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<AiChatModelDO> getChatModelPage(AiChatModelPageReqVO pageReqVO) {
|
||||
return chatModelMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AiChatModelDO validateChatModel(Long id) {
|
||||
AiChatModelDO model = validateChatModelExists(id);
|
||||
if (CommonStatusEnum.isDisable(model.getStatus())) {
|
||||
throw exception(CHAT_MODAL_DISABLE);
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
}
|
@ -20,5 +20,5 @@ Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
"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"
|
||||
"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."
|
||||
}
|
@ -6,6 +6,7 @@ import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
// TODO 芋艿:这块,看看要不要调整下;
|
||||
/**
|
||||
* ai 模型平台
|
||||
*
|
||||
@ -16,11 +17,10 @@ import java.util.List;
|
||||
@AllArgsConstructor
|
||||
public enum AiPlatformEnum {
|
||||
|
||||
|
||||
YI_YAN("yiyan", "一言"),
|
||||
QIAN_WEN("qianwen", "千问"),
|
||||
XING_HUO("xinghuo", "星火"),
|
||||
OPEN_AI("openai", "openAi"),
|
||||
OPEN_AI("openai", "openAi"), // TODO 芋艿:OpenAI
|
||||
OPEN_AI_DALL("dall", "dall"),
|
||||
MIDJOURNEY("midjourney", "midjourney"),
|
||||
|
||||
@ -41,7 +41,7 @@ public enum AiPlatformEnum {
|
||||
AiPlatformEnum.MIDJOURNEY
|
||||
);
|
||||
|
||||
public static AiPlatformEnum valueOfPlatform(String platform) {
|
||||
public static AiPlatformEnum validatePlatform(String platform) {
|
||||
for (AiPlatformEnum itemEnum : AiPlatformEnum.values()) {
|
||||
if (itemEnum.getPlatform().equals(platform)) {
|
||||
return itemEnum;
|
||||
|
@ -6,7 +6,7 @@
|
||||
"session_id": "$session_id",
|
||||
"nonce": "$nonce",
|
||||
"data": {
|
||||
"version": "1166847114203123795",
|
||||
"version": "1237876415471554623",
|
||||
"id": "938956540159881230",
|
||||
"name": "imagine",
|
||||
"type": 1,
|
||||
|
@ -0,0 +1,54 @@
|
||||
{
|
||||
"type": 2,
|
||||
"application_id": "936929561302675456",
|
||||
"guild_id": "1237948819677904956",
|
||||
"channel_id": "1237948819677904960",
|
||||
"session_id": "4bdb0c32158f625bbd7f0a54bfbb54aa",
|
||||
"data": {
|
||||
"version": "1237876415471554623",
|
||||
"id": "938956540159881230",
|
||||
"name": "imagine",
|
||||
"type": 1,
|
||||
"options": [
|
||||
{
|
||||
"type": 3,
|
||||
"name": "prompt",
|
||||
"value": "哈哈哈"
|
||||
}
|
||||
],
|
||||
"application_command": {
|
||||
"id": "938956540159881230",
|
||||
"type": 1,
|
||||
"application_id": "936929561302675456",
|
||||
"version": "1237876415471554623",
|
||||
"name": "imagine",
|
||||
"description": "Create images with Midjourney",
|
||||
"options": [
|
||||
{
|
||||
"type": 3,
|
||||
"name": "prompt",
|
||||
"description": "The prompt to imagine",
|
||||
"required": true,
|
||||
"description_localized": "The prompt to imagine",
|
||||
"name_localized": "prompt"
|
||||
}
|
||||
],
|
||||
"dm_permission": true,
|
||||
"contexts": [
|
||||
0,
|
||||
1,
|
||||
2
|
||||
],
|
||||
"integration_types": [
|
||||
0,
|
||||
1
|
||||
],
|
||||
"global_popularity_rank": 1,
|
||||
"description_localized": "Create images with Midjourney",
|
||||
"name_localized": "imagine"
|
||||
},
|
||||
"attachments": []
|
||||
},
|
||||
"nonce": "1238062212925358080",
|
||||
"analytics_location": "slash_ui"
|
||||
}
|
@ -52,7 +52,7 @@ spring:
|
||||
# url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8 # SQLServer 连接的示例
|
||||
# url: jdbc:dm://127.0.0.1:5236?schema=RUOYI_VUE_PRO # DM 连接的示例
|
||||
username: root
|
||||
password: 123456
|
||||
password: root
|
||||
# username: sa # SQL Server 连接的示例
|
||||
# password: Yudao@2024 # SQL Server 连接的示例
|
||||
# username: SYSDBA # DM 连接的示例
|
||||
@ -61,7 +61,7 @@ spring:
|
||||
lazy: true # 开启懒加载,保证启动速度
|
||||
url: jdbc:mysql://127.0.0.1:3306/ruoyi-vue-pro?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
|
||||
username: root
|
||||
password: 123456
|
||||
password: root
|
||||
|
||||
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
|
||||
data:
|
||||
@ -248,9 +248,9 @@ yudao:
|
||||
style: vivid
|
||||
midjourney:
|
||||
enable: true
|
||||
token: OTc1MzcyNDg1OTcxMzEyNzAw.G2iiSo.OqW9vToC5dokiyb1QOWnCwRPsYpOjLyNcf9--M
|
||||
guild-id: 1234355413420347402
|
||||
channel-id: 1234380679576424448
|
||||
token: MTE4MjE3MjY2MjkxNTY3ODIzOA.GEV1SG.c49F8lZoGCUHwsj8O0UdodmM6nyQHvuD2fXflw
|
||||
guild-id: 1237948819677904956
|
||||
channel-id: 1237948819677904960
|
||||
captcha:
|
||||
enable: false # 本地环境,暂时关闭图片验证码,方便登录等接口的测试;
|
||||
security:
|
||||
@ -267,6 +267,8 @@ yudao:
|
||||
enable: false
|
||||
demo: false # 关闭演示模式
|
||||
tencent-lbs-key: TVDBZ-TDILD-4ON4B-PFDZA-RNLKH-VVF6E # QQ 地图的密钥 https://lbs.qq.com/service/staticV2/staticGuide/staticDoc
|
||||
tenant:
|
||||
enable: false
|
||||
|
||||
justauth:
|
||||
enabled: true
|
||||
|
Loading…
Reference in New Issue
Block a user