Browse Source

【新增】AI:聊天角色管理(50%)

YunaiV 11 months ago
parent
commit
1676f671d8
19 changed files with 353 additions and 572 deletions
  1. 3 9
      yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/ErrorCodeConstants.java
  2. 57 31
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/AiChatRoleController.java
  3. 0 52
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/role/AiChatRoleAddReqVO.java
  4. 0 20
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/role/AiChatRoleListReqVO.java
  5. 0 52
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/role/AiChatRoleListRespVO.java
  6. 27 0
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/role/AiChatRolePageReqVO.java
  7. 35 21
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/role/AiChatRoleRespVO.java
  8. 57 0
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/role/AiChatRoleSaveReqVO.java
  9. 0 27
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/role/AiChatRoleUpdatePublicStatusReqVO.java
  10. 0 62
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/role/AiChatRoleUpdateReqVO.java
  11. 0 56
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/convert/AiChatRoleConvert.java
  12. 4 3
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/model/AiChatRoleDO.java
  13. 14 4
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/AiChatRoleMapper.java
  14. 0 76
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/AiChatRoleService.java
  15. 5 7
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatConversationServiceImpl.java
  16. 0 129
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatRoleServiceImpl.java
  17. 5 23
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatServiceImpl.java
  18. 61 0
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiChatRoleService.java
  19. 85 0
      yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiChatRoleServiceImpl.java

+ 3 - 9
yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/ErrorCodeConstants.java

@@ -18,8 +18,9 @@ public interface ErrorCodeConstants {
     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 平台参数不正确! {} ");
+    // ========== API 聊天模型 1-040-002-000 ==========
+    ErrorCode CHAT_ROLE_NOT_EXISTS = new ErrorCode(1_040_002_000, "AI 聊天角色不存在");
+    ErrorCode CHAT_ROLE_DISABLE = new ErrorCode(1_040_001_001, "AI 聊天角色({})已禁用!");
 
     // conversation
 
@@ -31,14 +32,7 @@ public interface ErrorCodeConstants {
     ErrorCode AI_MIDJOURNEY_OPERATION_NOT_EXISTS = new ErrorCode(1_022_000_040, "midjourney 操作不存在!");
     ErrorCode AI_MIDJOURNEY_MESSAGE_ID_INCORRECT = new ErrorCode(1_022_000_040, "midjourney message id 不正确!");
 
-    // role
-
-    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 角色未公开!");
-
     // chat
-
     ErrorCode AI_CHAT_MESSAGE_NOT_EXIST = new ErrorCode(1_022_000_100, "AI 提问的 MessageId 不存在!");
 
-
 }

+ 57 - 31
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/AiChatRoleController.java

@@ -1,17 +1,30 @@
 package cn.iocoder.yudao.module.ai.controller.admin.model;
 
+import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.*;
-import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.AiChatRolePageReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.AiChatRoleRespVO;
+import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.AiChatRoleSaveReqVO;
+import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
+import cn.iocoder.yudao.module.ai.service.model.AiChatRoleService;
 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 lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.Valid;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import java.io.IOException;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
 @Tag(name = "管理后台 - AI 聊天角色")
 @RestController
 @RequestMapping("/ai/chat-role")
@@ -21,42 +34,55 @@ public class AiChatRoleController {
     @Resource
     private AiChatRoleService chatRoleService;
 
-    @Operation(summary = "chat角色 - 角色列表")
-    @GetMapping("/list")
-    public PageResult<AiChatRoleListRespVO> list(@Validated @ModelAttribute AiChatRoleListReqVO req) {
-        return chatRoleService.list(req);
-    }
+    // TODO 芋艿:我的分页
 
-    @Operation(summary = "chat角色 - 添加")
-    @PutMapping("/add")
-    public CommonResult<Void> add(@Validated @RequestBody AiChatRoleAddReqVO req) {
-        chatRoleService.add(req);
-        return CommonResult.success(null);
-    }
+    // TODO 芋艿:我的新增
+
+    // TODO 芋艿:我的修改
+
+    // TODO 芋艿:我的删除
 
-    @Operation(summary = "chat角色 - 修改")
-    @PostMapping("/update")
-    public CommonResult<Void> update(@Validated @RequestBody AiChatRoleUpdateReqVO req) {
-        chatRoleService.update(req);
-        return CommonResult.success(null);
+    // ========== 角色管理 ==========
+
+    @PostMapping("/create")
+    @Operation(summary = "创建聊天角色")
+    @PreAuthorize("@ss.hasPermission('ai:chat-role:create')")
+    public CommonResult<Long> createChatRole(@Valid @RequestBody AiChatRoleSaveReqVO createReqVO) {
+        return success(chatRoleService.createChatRole(createReqVO));
     }
 
-    @Operation(summary = "chat角色 - 修改可见性")
-    @PostMapping("/update-public-status")
-    public CommonResult<Void> updatePublicStatus(@Validated @RequestBody AiChatRoleUpdatePublicStatusReqVO req) {
-        chatRoleService.updatePublicStatus(req);
-        return CommonResult.success(null);
+    @PutMapping("/update")
+    @Operation(summary = "更新聊天角色")
+    @PreAuthorize("@ss.hasPermission('ai:chat-role:update')")
+    public CommonResult<Boolean> updateChatRole(@Valid @RequestBody AiChatRoleSaveReqVO updateReqVO) {
+        chatRoleService.updateChatRole(updateReqVO);
+        return success(true);
     }
 
-    @Operation(summary = "chat角色 - 删除")
     @DeleteMapping("/delete")
-    public CommonResult<Void> delete(@RequestParam("id") Long id) {
-        chatRoleService.delete(id);
-        return CommonResult.success(null);
+    @Operation(summary = "删除聊天角色")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('ai:chat-role:delete')")
+    public CommonResult<Boolean> deleteChatRole(@RequestParam("id") Long id) {
+        chatRoleService.deleteChatRole(id);
+        return success(true);
     }
 
-    // ========== 角色管理 ==========
-
+    @GetMapping("/get")
+    @Operation(summary = "获得聊天角色")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('ai:chat-role:query')")
+    public CommonResult<AiChatRoleRespVO> getChatRole(@RequestParam("id") Long id) {
+        AiChatRoleDO chatRole = chatRoleService.getChatRole(id);
+        return success(BeanUtils.toBean(chatRole, AiChatRoleRespVO.class));
+    }
 
+    @GetMapping("/page")
+    @Operation(summary = "获得聊天角色分页")
+    @PreAuthorize("@ss.hasPermission('ai:chat-role:query')")
+    public CommonResult<PageResult<AiChatRoleRespVO>> getChatRolePage(@Valid AiChatRolePageReqVO pageReqVO) {
+        PageResult<AiChatRoleDO> pageResult = chatRoleService.getChatRolePage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, AiChatRoleRespVO.class));
+    }
 
 }

+ 0 - 52
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/role/AiChatRoleAddReqVO.java

@@ -1,52 +0,0 @@
-package cn.iocoder.yudao.module.ai.controller.admin.model.vo.role;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-import lombok.experimental.Accessors;
-
-/**
- * chat 角色列表
- *
- * @fansili
- * @since v1.0
- */
-@Data
-@Accessors(chain = true)
-public class AiChatRoleAddReqVO {
-
-    @NotNull
-    @Schema(description = "角色名,角色的显示名称")
-    private String name;
-
-    @Schema(description = "头像")
-    private String avatar;
-
-    @NotNull
-    @Schema(description = "分类,角色所属的类别,如娱乐、创作等")
-    private String category;
-
-    @NotNull
-    @Schema(description = "角色描述")
-    private String description;
-
-    @Schema(description = "角色欢迎语")
-    private String welcomeMessage;
-
-    @NotNull
-    @Schema(description = "角色设定(消息)")
-    private String systemMessage;
-
-    @NotNull
-    @Schema(description = "模型编号")
-    private Long modelId;
-
-    @NotNull
-    @Schema(description = "开启状态 0、open 1、close")
-    private Boolean publicStatus;
-
-    @NotNull
-    @Schema(description = "排序")
-    private Integer sort;
-
-}

+ 0 - 20
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/role/AiChatRoleListReqVO.java

@@ -1,20 +0,0 @@
-package cn.iocoder.yudao.module.ai.controller.admin.model.vo.role;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.experimental.Accessors;
-
-/**
- * chat 角色列表
- *
- * @fansili
- * @since v1.0
- */
-@Data
-@Accessors(chain = true)
-public class AiChatRoleListReqVO extends PageParam {
-
-    @Schema(description = "查询")
-    private String search;
-}

+ 0 - 52
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/role/AiChatRoleListRespVO.java

@@ -1,52 +0,0 @@
-package cn.iocoder.yudao.module.ai.controller.admin.model.vo.role;
-
-import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.Data;
-import lombok.experimental.Accessors;
-
-/**
- * chat 角色列表
- *
- * @fansili
- * @since v1.0
- */
-@Data
-@Accessors(chain = true)
-public class AiChatRoleListRespVO {
-
-    @Schema(description = "编号", example = "1")
-    private Long id;
-
-    @Schema(description = "角色名称", example = "小红书写作")
-    private String name;
-
-    @Schema(description = "角色头像", example = "http://...")
-    private String avatar;
-
-    @Schema(description = "角色分类", example = "writing")
-    private String category;
-
-    @Schema(description = "角色描述", example = "角色描述")
-    private String description;
-
-    @Schema(description = "角色欢迎语", example = "欢迎...")
-    private String welcomeMessage;
-
-    @Schema(description = "角色设定(消息)", example = "你是拥有丰富的小红书写作经验作者xxxx")
-    private String systemMessage;
-
-    @Schema(description = "用户编号", example = "1")
-    private Long userId;
-
-    @Schema(description = "模型编号", example = "1")
-    private Long modelId;
-
-    @Schema(description = "是否公开 true - 公开;false - 私有", example = "true")
-    private Boolean publicStatus;
-
-    @Schema(description = "排序值 asc", example = "1")
-    private Integer sort;
-
-    @Schema(description = "状态 0、开启 1、关闭", example = "1")
-    private Integer status;
-}

+ 27 - 0
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/role/AiChatRolePageReqVO.java

@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.ai.controller.admin.model.vo.role;
+
+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 聊天角色分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class AiChatRolePageReqVO extends PageParam {
+
+    @Schema(description = "角色名称", example = "李四")
+    private String name;
+
+    @Schema(description = "角色类别", example = "创作")
+    private String category;
+
+    @Schema(description = "是否公开", example = "1")
+    private Boolean publicStatus;
+
+}

+ 35 - 21
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/role/AiChatRoleRespVO.java

@@ -2,36 +2,50 @@ package cn.iocoder.yudao.module.ai.controller.admin.model.vo.role;
 
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
-import lombok.experimental.Accessors;
-
-/**
- * chat 角色
- *
- * @fansili
- * @since v1.0
- */
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - AI 聊天角色 Response VO")
 @Data
-@Accessors(chain = true)
 public class AiChatRoleRespVO {
 
-    @Schema(description = "id")
+    @Schema(description = "角色编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32746")
     private Long id;
 
-    @Schema(description = "用户id")
+    @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "9442")
     private Long userId;
 
-    @Schema(description = "角色名字")
+    @Schema(description = "模型编号", example = "17640")
+    private Long modelId;
+
+    @Schema(description = "角色名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
     private String name;
 
-    @Schema(description = "角色介绍,详细描述角色的功能或用途")
-    private String introduce;
+    @Schema(description = "角色头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png")
+    private String avatar;
+
+    @Schema(description = "角色类别", requiredMode = Schema.RequiredMode.REQUIRED, example = "创作")
+    private String category;
+
+    @Schema(description = "角色排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Integer sort;
+
+    @Schema(description = "角色描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "你说的对")
+    private String description;
+
+    @Schema(description = "角色欢迎语", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String welcomeMessage;
+
+    @Schema(description = "角色上下文", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String systemMessage;
+
+    @Schema(description = "是否公开", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    private Boolean publicStatus;
 
-    @Schema(description = "分类,角色所属的类别,如娱乐、创作等")
-    private String classify;
+    @Schema(description = "状态", example = "1")
+    private Integer status;
 
-    @Schema(description = "状态 open、close")
-    private String enable;
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    private LocalDateTime createTime;
 
-    @Schema(description = "角色的使用次数统计")
-    private Integer useCount;
-}
+}

+ 57 - 0
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/role/AiChatRoleSaveReqVO.java

@@ -0,0 +1,57 @@
+package cn.iocoder.yudao.module.ai.controller.admin.model.vo.role;
+
+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 java.util.*;
+import jakarta.validation.constraints.*;
+
+@Schema(description = "管理后台 - AI 聊天角色新增/修改 Request VO")
+@Data
+public class AiChatRoleSaveReqVO {
+
+    @Schema(description = "角色编号", example = "32746")
+    private Long id;
+
+    @Schema(description = "模型编号", example = "17640")
+    private Long modelId;
+
+    @Schema(description = "角色名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
+    @NotEmpty(message = "角色名称不能为空")
+    private String name;
+
+    @Schema(description = "角色头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png")
+    @NotEmpty(message = "角色头像不能为空")
+    private String avatar;
+
+    @Schema(description = "角色类别", requiredMode = Schema.RequiredMode.REQUIRED, example = "创作")
+    @NotEmpty(message = "角色类别不能为空")
+    private String category;
+
+    @Schema(description = "角色排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "角色排序不能为空")
+    private Integer sort;
+
+    @Schema(description = "角色描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "你说的对")
+    @NotEmpty(message = "角色描述不能为空")
+    private String description;
+
+    @Schema(description = "角色欢迎语", requiredMode = Schema.RequiredMode.REQUIRED, example = "Talk is cheap, i will show code")
+    @NotEmpty(message = "角色欢迎语不能为空")
+    private String welcomeMessage;
+
+    @Schema(description = "角色上下文", requiredMode = Schema.RequiredMode.REQUIRED, example = "现在开始你扮演一位程序员,你是一名优秀的程序员,具有很强的逻辑思维能力,总能高效的解决问题")
+    @NotEmpty(message = "角色上下文不能为空")
+    private String systemMessage;
+
+    @Schema(description = "是否公开", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "是否公开不能为空")
+    private Boolean publicStatus;
+
+    @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "状态不能为空")
+    @InEnum(CommonStatusEnum.class)
+    private Integer status;
+
+}

+ 0 - 27
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/role/AiChatRoleUpdatePublicStatusReqVO.java

@@ -1,27 +0,0 @@
-package cn.iocoder.yudao.module.ai.controller.admin.model.vo.role;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-import lombok.experimental.Accessors;
-
-/**
- * chat 角色 - 修改可见性
- *
- * @fansili
- * @since v1.0
- */
-@Data
-@Accessors(chain = true)
-public class AiChatRoleUpdatePublicStatusReqVO extends PageParam {
-
-
-    @NotNull(message = "角色编号不能为空")
-    @Schema(description = "角色编号")
-    private Long id;
-
-    @NotNull(message = "开启状态不能为空")
-    @Schema(description = "开启状态 open、close")
-    private Boolean publicStatus;
-}

+ 0 - 62
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/role/AiChatRoleUpdateReqVO.java

@@ -1,62 +0,0 @@
-package cn.iocoder.yudao.module.ai.controller.admin.model.vo.role;
-
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotNull;
-import lombok.Data;
-import lombok.experimental.Accessors;
-
-/**
- * chat 角色 - 更新
- *
- * @fansili
- * @since v1.0
- */
-@Data
-@Accessors(chain = true)
-public class AiChatRoleUpdateReqVO extends PageParam {
-
-
-    @NotNull(message = "角色编号不能为空")
-    @Schema(description = "角色编号")
-    private Long id;
-
-    @NotNull
-    @Schema(description = "角色名,角色的显示名称")
-    private String name;
-
-    @Schema(description = "头像")
-    private String avatar;
-
-    @NotNull
-    @Schema(description = "分类,角色所属的类别,如娱乐、创作等")
-    private String category;
-
-    @NotNull
-    @Schema(description = "角色描述")
-    private String description;
-
-    @Schema(description = "角色欢迎语")
-    private String welcomeMessage;
-
-    @NotNull
-    @Schema(description = "角色设定(消息)")
-    private String systemMessage;
-
-    @NotNull
-    @Schema(description = "模型编号")
-    private Long modelId;
-
-    @NotNull
-    @Schema(description = "开启状态 open、close")
-    private Boolean publicStatus;
-
-    @NotNull
-    @Schema(description = "排序")
-    private Integer sort;
-
-    @NotNull
-    @Schema(description = "状态")
-    private Integer status;
-
-}

+ 0 - 56
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/convert/AiChatRoleConvert.java

@@ -1,56 +0,0 @@
-package cn.iocoder.yudao.module.ai.convert;
-
-import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
-import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.AiChatRoleAddReqVO;
-import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.AiChatRoleRespVO;
-import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.AiChatRoleUpdateReqVO;
-import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.AiChatRoleListRespVO;
-import org.mapstruct.Mapper;
-import org.mapstruct.factory.Mappers;
-
-import java.util.List;
-
-/**
- * 聊天 对话 convert
- *
- * @author fansili
- * @time 2024/4/18 16:39
- * @since 1.0
- */
-@Mapper
-public interface AiChatRoleConvert {
-
-    AiChatRoleConvert INSTANCE = Mappers.getMapper(AiChatRoleConvert.class);
-
-    /**
-     * 转换 - ChatRoleListRes
-     *
-     * @param roleList
-     * @return
-     */
-    List<AiChatRoleListRespVO> convertChatRoleListRes(List<AiChatRoleDO> roleList);
-
-    /**
-     * 转换 - AiChatRoleDO
-     *
-     * @param req
-     * @return
-     */
-    AiChatRoleDO convertAiChatRoleDO(AiChatRoleAddReqVO req);
-
-    /**
-     * 转换 - AiChatRoleDO
-     *
-     * @param req
-     * @return
-     */
-    AiChatRoleDO convertAiChatRoleDO(AiChatRoleUpdateReqVO req);
-
-    /**
-     * 转换 - AiChatRoleRes
-     *
-     * @param aiChatRoleDO
-     * @return
-     */
-    AiChatRoleRespVO convertAiChatRoleRes(AiChatRoleDO aiChatRoleDO);
-}

+ 4 - 3
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/model/AiChatRoleDO.java

@@ -46,7 +46,7 @@ public class AiChatRoleDO extends BaseDO {
      */
     private String welcomeMessage;
     /**
-     * 角色设定(消息)
+     * 角色上下文
      */
     private String systemMessage;
 
@@ -65,9 +65,10 @@ public class AiChatRoleDO extends BaseDO {
     private Long modelId;
 
     /**
-     * 是否公开 true - 公开;false - 私有
+     * 是否公开
      *
-     * true - 公开;false - 私有
+     * 1. true - 公开;由管理员在【角色管理】所创建
+     * 2. false - 私有;由个人在【我的角色】所创建
      */
     private Boolean publicStatus;
 

+ 14 - 4
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/AiChatRoleMapper.java

@@ -1,17 +1,27 @@
 package cn.iocoder.yudao.module.ai.dal.mysql;
 
+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.role.AiChatRolePageReqVO;
 import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
 import org.apache.ibatis.annotations.Mapper;
 import org.springframework.stereotype.Repository;
 
 /**
- * role mapper
+ * AI 聊天角色 Mapper
  *
- * @fansili
- * @since v1.0
+ * @author fansili
  */
-@Repository
 @Mapper
 public interface AiChatRoleMapper extends BaseMapperX<AiChatRoleDO> {
+
+    default PageResult<AiChatRoleDO> selectPage(AiChatRolePageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<AiChatRoleDO>()
+                .likeIfPresent(AiChatRoleDO::getName, reqVO.getName())
+                .eqIfPresent(AiChatRoleDO::getCategory, reqVO.getCategory())
+                .eqIfPresent(AiChatRoleDO::getPublicStatus, reqVO.getPublicStatus())
+                .orderByDesc(AiChatRoleDO::getId));
+    }
+
 }

+ 0 - 76
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/AiChatRoleService.java

@@ -1,76 +0,0 @@
-package cn.iocoder.yudao.module.ai.service;
-
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.*;
-import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
-
-/**
- * chat 角色
- *
- * @fansili
- * @since v1.0
- */
-public interface AiChatRoleService {
-
-    /**
-     * 获取聊天角色列表
-     *
-     * @param req
-     * @return
-     */
-    PageResult<AiChatRoleListRespVO> list(AiChatRoleListReqVO req);
-
-    /**
-     * chat角色 - 添加
-     *
-     * @param req
-     * @return
-     */
-    void add(AiChatRoleAddReqVO req);
-
-    /**
-     * chat角色 - 修改
-     *
-     * @param req
-     */
-    void update(AiChatRoleUpdateReqVO req);
-
-
-    /**
-     * chat角色 - 修改可见性
-     *
-     * @param req
-     */
-    void updatePublicStatus(AiChatRoleUpdatePublicStatusReqVO req);
-
-    /**
-     * chat角色 - 删除
-     *
-     * @param chatRoleId
-     */
-    void delete(Long chatRoleId);
-
-    /**
-     * 获取角色
-     *
-     * @param roleId
-     * @return
-     */
-    AiChatRoleRespVO getChatRole(Long roleId);
-
-    /**
-     * 校验 - 角色是否存在
-     *
-     * @param id
-     * @return
-     */
-    AiChatRoleDO validateExists(Long id);
-
-    /**
-     * 校验 - 角色是否公开
-     *
-     * @param aiChatRoleDO
-     */
-    void validateIsPublic(AiChatRoleDO aiChatRoleDO);
-
-}

+ 5 - 7
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiChatConversationServiceImpl.java → yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatConversationServiceImpl.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.ai.service.model;
+package cn.iocoder.yudao.module.ai.service.impl;
 
 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
@@ -7,14 +7,15 @@ 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.role.AiChatRoleRespVO;
 import cn.iocoder.yudao.module.ai.convert.AiChatConversationConvert;
 import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatConversationDO;
 import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatModelDO;
+import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
 import cn.iocoder.yudao.module.ai.dal.mysql.AiChatConversationMapper;
 import cn.iocoder.yudao.module.ai.dal.mysql.AiChatModelMapper;
 import cn.iocoder.yudao.module.ai.service.AiChatConversationService;
-import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
+import cn.iocoder.yudao.module.ai.service.model.AiChatModelService;
+import cn.iocoder.yudao.module.ai.service.model.AiChatRoleService;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.jetbrains.annotations.NotNull;
@@ -45,10 +46,7 @@ public class AiChatConversationServiceImpl implements AiChatConversationService
         // 默认使用 sort 排序第一个模型
         AiChatModelDO aiChatModalDO = aiChatModalMapper.selectFirstModal();
         // 查询角色
-        AiChatRoleRespVO chatRoleRes = null;
-        if (req.getRoleId() != null) {
-            chatRoleRes = aiChatRoleService.getChatRole(req.getRoleId());
-        }
+        AiChatRoleDO chatRoleRes = req.getRoleId() != null ? aiChatRoleService.getChatRole(req.getRoleId()) : null;
         Long chatRoleId = chatRoleRes != null ? chatRoleRes.getId() : null;
         // 创建新的 Conversation
         AiChatConversationDO insertConversation = saveConversation(AiCommonConstants.CONVERSATION_DEFAULT_TITLE,

+ 0 - 129
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatRoleServiceImpl.java

@@ -1,129 +0,0 @@
-package cn.iocoder.yudao.module.ai.service.impl;
-
-import cn.hutool.core.util.StrUtil;
-import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
-import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
-import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
-import cn.iocoder.yudao.module.ai.ErrorCodeConstants;
-import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.*;
-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.model.AiChatModelService;
-import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
-import lombok.AllArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-
-/**
- * chat 角色
- *
- * @fansili
- * @since v1.0
- */
-@Service
-@AllArgsConstructor
-@Slf4j
-public class AiChatRoleServiceImpl implements AiChatRoleService {
-
-    private final AiChatRoleMapper aiChatRoleMapper;
-    private final AiChatModelService aiChatModalService;
-
-    @Override
-    public PageResult<AiChatRoleListRespVO> list(AiChatRoleListReqVO req) {
-        // 查询条件
-        LambdaQueryWrapperX<AiChatRoleDO> queryWrapperX = new LambdaQueryWrapperX<>();
-        // search 查询
-        if (!StrUtil.isBlank(req.getSearch())) {
-            queryWrapperX.eq(AiChatRoleDO::getName, req.getSearch());
-        }
-        // 默认排序id desc
-        queryWrapperX.orderByDesc(AiChatRoleDO::getId);
-        //
-        PageResult<AiChatRoleDO> aiChatRoleDOPageResult = aiChatRoleMapper.selectPage(req, queryWrapperX);
-        Long total = aiChatRoleDOPageResult.getTotal();
-        List<AiChatRoleDO> roleList = aiChatRoleDOPageResult.getList();
-        // 换货res
-        List<AiChatRoleListRespVO> chatRoleListResList = AiChatRoleConvert.INSTANCE.convertChatRoleListRes(roleList);
-        return new PageResult<>(chatRoleListResList, total);
-    }
-
-    @Override
-    public void add(AiChatRoleAddReqVO req) {
-        // 转换enum,并校验enum
-        AiChatRoleCategoryEnum.valueOfCategory(req.getCategory());
-        // 校验模型是否存在 TODO
-//        aiChatModalService.validateExists(req.getModelId());
-        // 转换do
-        AiChatRoleDO insertAiChatRoleDO = AiChatRoleConvert.INSTANCE.convertAiChatRoleDO(req);
-        insertAiChatRoleDO.setUserId(SecurityFrameworkUtils.getLoginUserId());
-        insertAiChatRoleDO.setStatus(CommonStatusEnum.ENABLE.getStatus());
-        // 保存
-        aiChatRoleMapper.insert(insertAiChatRoleDO);
-    }
-
-    @Override
-    public void update(AiChatRoleUpdateReqVO req) {
-        // 检查角色是否存在
-        validateExists(req.getId());
-        // 转换enum,并校验enum
-        AiChatRoleCategoryEnum.valueOfCategory(req.getCategory());
-        // 校验模型是否存在 TODO
-//        aiChatModalService.validateExists(req.getModelId());
-        // 转换do
-        AiChatRoleDO updateChatRole = AiChatRoleConvert.INSTANCE.convertAiChatRoleDO(req);
-        updateChatRole.setId(req.getId());
-        aiChatRoleMapper.updateById(updateChatRole);
-    }
-
-
-    @Override
-    public void updatePublicStatus(AiChatRoleUpdatePublicStatusReqVO req) {
-        // 检查角色是否存在
-        validateExists(req.getId());
-        // 更新
-        aiChatRoleMapper.updateById(
-                new AiChatRoleDO()
-                        .setId(req.getId())
-                        .setPublicStatus(req.getPublicStatus())
-        );
-    }
-
-    @Override
-    public void delete(Long chatRoleId) {
-        // 检查角色是否存在
-        validateExists(chatRoleId);
-        // 删除
-        aiChatRoleMapper.deleteById(chatRoleId);
-    }
-
-    @Override
-    public AiChatRoleRespVO getChatRole(Long roleId) {
-        // 检查角色是否存在
-        AiChatRoleDO aiChatRoleDO = validateExists(roleId);
-        return AiChatRoleConvert.INSTANCE.convertAiChatRoleRes(aiChatRoleDO);
-    }
-
-    public AiChatRoleDO validateExists(Long id) {
-        AiChatRoleDO aiChatRoleDO = aiChatRoleMapper.selectById(id);
-        if (aiChatRoleDO == null) {
-            throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_CHAT_ROLE_NOT_EXIST);
-        }
-        return aiChatRoleDO;
-    }
-
-    public void validateIsPublic(AiChatRoleDO aiChatRoleDO) {
-        if (aiChatRoleDO == null) {
-            return;
-        }
-        if (!aiChatRoleDO.getPublicStatus()) {
-            throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_CHAT_ROLE_NOT_PUBLIC);
-        }
-    }
-}
-

+ 5 - 23
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/impl/AiChatServiceImpl.java

@@ -23,12 +23,11 @@ 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.AiChatRoleService;
+import cn.iocoder.yudao.module.ai.service.model.AiChatRoleService;
 import cn.iocoder.yudao.module.ai.service.AiChatService;
 import cn.iocoder.yudao.module.ai.service.model.AiChatModelService;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import reactor.core.publisher.Flux;
@@ -53,12 +52,12 @@ import java.util.stream.Collectors;
 public class AiChatServiceImpl implements AiChatService {
 
     private final AiChatClientFactory aiChatClientFactory;
+
     private final AiChatMessageMapper aiChatMessageMapper;
     private final AiChatConversationMapper aiChatConversationMapper;
     private final AiChatConversationService chatConversationService;
     private final AiChatModelService aiChatModalService;
-    private final AiChatRoleService aiChatRoleService;
-    private final HttpMessageConverters messageConverters;
+    private final AiChatRoleService chatRoleService;
 
     @Transactional(rollbackFor = Exception.class)
     public AiChatMessageRespVO chat(AiChatMessageSendReqVO req) {
@@ -68,12 +67,7 @@ public class AiChatServiceImpl implements AiChatService {
         // 获取对话模型
         AiChatModelDO chatModel = aiChatModalService.validateChatModel(conversation.getModelId());
         // 获取角色信息
-        AiChatRoleDO aiChatRoleDO = null;
-        if (conversation.getRoleId() != null) {
-            aiChatRoleDO = aiChatRoleService.validateExists(conversation.getRoleId());
-        }
-        // 校验角色是否公开
-        aiChatRoleService.validateIsPublic(aiChatRoleDO);
+        AiChatRoleDO chatRoleDO = conversation.getRoleId() != null ? chatRoleService.validateChatRole(conversation.getRoleId()) : null;
         // 获取 client 类型
         AiPlatformEnum platformEnum = AiPlatformEnum.validatePlatform(chatModel.getPlatform());
         // 保存 chat message
@@ -142,12 +136,7 @@ public class AiChatServiceImpl implements AiChatService {
         // 获取对话模型
         AiChatModelDO chatModel = aiChatModalService.validateChatModel(conversation.getModelId());
         // 获取角色信息
-        AiChatRoleDO aiChatRoleDO = null;
-        if (conversation.getRoleId() != null) {
-            aiChatRoleDO = aiChatRoleService.validateExists(conversation.getRoleId());
-        }
-        // 校验角色是否公开
-        aiChatRoleService.validateIsPublic(aiChatRoleDO);
+        AiChatRoleDO chatRoleDO = conversation.getRoleId() != null ? chatRoleService.validateChatRole(conversation.getRoleId()) : null;
         // 创建 chat 需要的 Prompt
         Prompt prompt = new Prompt(aiChatMessageDO.getContent());
         // 提前创建一个 system message
@@ -204,13 +193,6 @@ public class AiChatServiceImpl implements AiChatService {
         AiChatConversationRespVO conversation = chatConversationService.getConversationOfValidate(req.getConversationId());
         // 获取对话模型
         AiChatModelDO chatModel = aiChatModalService.validateChatModel(conversation.getModelId());
-        // 获取角色信息
-        AiChatRoleDO aiChatRoleDO = null;
-        if (conversation.getRoleId() != null) {
-            aiChatRoleDO = aiChatRoleService.validateExists(conversation.getRoleId());
-        }
-        // 校验角色是否公开
-        aiChatRoleService.validateIsPublic(aiChatRoleDO);
         AiChatMessageDO userMessage = insertChatMessage(conversation.getId(), MessageType.USER, loginUserId, conversation.getRoleId(),
                 chatModel.getModel(), chatModel.getId(), req.getContent(),
                 null, conversation.getTemperature(), conversation.getMaxTokens(), conversation.getMaxContexts());

+ 61 - 0
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiChatRoleService.java

@@ -0,0 +1,61 @@
+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.role.AiChatRolePageReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.AiChatRoleSaveReqVO;
+import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
+import jakarta.validation.Valid;
+
+/**
+ * AI 聊天角色 Service 接口
+ *
+ * @author fansili
+ */
+public interface AiChatRoleService {
+
+    /**
+     * 创建聊天角色
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createChatRole(@Valid AiChatRoleSaveReqVO createReqVO);
+
+    /**
+     * 更新聊天角色
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateChatRole(@Valid AiChatRoleSaveReqVO updateReqVO);
+
+    /**
+     * 删除聊天角色
+     *
+     * @param id 编号
+     */
+    void deleteChatRole(Long id);
+
+    /**
+     * 获得聊天角色
+     *
+     * @param id 编号
+     * @return AI 聊天角色
+     */
+    AiChatRoleDO getChatRole(Long id);
+
+    /**
+     * 校验角色是否存在
+     *
+     * @param id 角色编号
+     */
+    AiChatRoleDO validateChatRole(Long id);
+
+    /**
+     * 获得AI 聊天角色分页
+     *
+     * @param pageReqVO 分页查询
+     * @return AI 聊天角色分页
+     */
+    PageResult<AiChatRoleDO> getChatRolePage(AiChatRolePageReqVO pageReqVO);
+
+}

+ 85 - 0
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiChatRoleServiceImpl.java

@@ -0,0 +1,85 @@
+package cn.iocoder.yudao.module.ai.service.model;
+
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
+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.role.AiChatRolePageReqVO;
+import cn.iocoder.yudao.module.ai.controller.admin.model.vo.role.AiChatRoleSaveReqVO;
+import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
+import cn.iocoder.yudao.module.ai.dal.mysql.AiChatRoleMapper;
+import jakarta.annotation.Resource;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.CHAT_ROLE_DISABLE;
+import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.CHAT_ROLE_NOT_EXISTS;
+
+/**
+ * AI 聊天角色 Service 实现类
+ *
+ * @author fansili
+ */
+@Service
+@AllArgsConstructor
+@Slf4j
+public class AiChatRoleServiceImpl implements AiChatRoleService {
+
+    @Resource
+    private AiChatRoleMapper chatRoleMapper;
+
+    @Override
+    public Long createChatRole(AiChatRoleSaveReqVO createReqVO) {
+        AiChatRoleDO chatRole = BeanUtils.toBean(createReqVO, AiChatRoleDO.class);
+        chatRoleMapper.insert(chatRole);
+        return chatRole.getId();
+    }
+
+    @Override
+    public void updateChatRole(AiChatRoleSaveReqVO updateReqVO) {
+        // 校验存在
+        validateChatRoleExists(updateReqVO.getId());
+        // 更新
+        AiChatRoleDO updateObj = BeanUtils.toBean(updateReqVO, AiChatRoleDO.class);
+        chatRoleMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteChatRole(Long id) {
+        // 校验存在
+        validateChatRoleExists(id);
+        // 删除
+        chatRoleMapper.deleteById(id);
+    }
+
+    private AiChatRoleDO validateChatRoleExists(Long id) {
+        AiChatRoleDO chatRole = chatRoleMapper.selectById(id);
+        if (chatRole == null) {
+            throw exception(CHAT_ROLE_NOT_EXISTS);
+        }
+        return chatRole;
+    }
+
+    @Override
+    public AiChatRoleDO getChatRole(Long id) {
+        return chatRoleMapper.selectById(id);
+    }
+
+    @Override
+    public AiChatRoleDO validateChatRole(Long id) {
+        AiChatRoleDO chatRole = validateChatRoleExists(id);
+        if (CommonStatusEnum.isDisable(chatRole.getStatus())) {
+            throw exception(CHAT_ROLE_DISABLE, chatRole.getName());
+        }
+        return chatRole;
+    }
+
+    @Override
+    public PageResult<AiChatRoleDO> getChatRolePage(AiChatRolePageReqVO pageReqVO) {
+        return chatRoleMapper.selectPage(pageReqVO);
+    }
+
+}
+