Commit 7344ec8aea5c6fc4dd30a0cc47cb1b773d3330b4
1 parent
31453e19
【新增】AI:聊天角色管理(100%)
Showing
6 changed files
with
199 additions
and
10 deletions
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/AiChatRoleController.java
| 1 | 1 | package cn.iocoder.yudao.module.ai.controller.admin.model; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.util.ObjUtil; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 6 | 7 | import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRolePageReqVO; |
| 7 | 8 | import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleRespVO; |
| 9 | +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleSaveMyReqVO; | |
| 8 | 10 | import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleSaveReqVO; |
| 9 | 11 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO; |
| 10 | 12 | import cn.iocoder.yudao.module.ai.service.model.AiChatRoleService; |
| ... | ... | @@ -17,7 +19,10 @@ import org.springframework.security.access.prepost.PreAuthorize; |
| 17 | 19 | import org.springframework.validation.annotation.Validated; |
| 18 | 20 | import org.springframework.web.bind.annotation.*; |
| 19 | 21 | |
| 22 | +import java.util.List; | |
| 23 | + | |
| 20 | 24 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 25 | +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | |
| 21 | 26 | |
| 22 | 27 | @Tag(name = "管理后台 - AI 聊天角色") |
| 23 | 28 | @RestController |
| ... | ... | @@ -28,13 +33,50 @@ public class AiChatRoleController { |
| 28 | 33 | @Resource |
| 29 | 34 | private AiChatRoleService chatRoleService; |
| 30 | 35 | |
| 31 | - // TODO 芋艿:我的分页 | |
| 36 | + @GetMapping("/my-page") | |
| 37 | + @Operation(summary = "获得【我的】聊天角色分页") | |
| 38 | + public CommonResult<PageResult<AiChatRoleRespVO>> getChatRoleMyPage(@Valid AiChatRolePageReqVO pageReqVO) { | |
| 39 | + PageResult<AiChatRoleDO> pageResult = chatRoleService.getChatRoleMyPage(pageReqVO, getLoginUserId()); | |
| 40 | + return success(BeanUtils.toBean(pageResult, AiChatRoleRespVO.class)); | |
| 41 | + } | |
| 42 | + | |
| 43 | + @GetMapping("/get-my") | |
| 44 | + @Operation(summary = "获得【我的】聊天角色") | |
| 45 | + @Parameter(name = "id", description = "编号", required = true, example = "1024") | |
| 46 | + public CommonResult<AiChatRoleRespVO> getChatRoleMy(@RequestParam("id") Long id) { | |
| 47 | + AiChatRoleDO chatRole = chatRoleService.getChatRole(id); | |
| 48 | + if (ObjUtil.notEqual(chatRole.getUserId(), getLoginUserId())) { | |
| 49 | + return success(null); | |
| 50 | + } | |
| 51 | + return success(BeanUtils.toBean(chatRole, AiChatRoleRespVO.class)); | |
| 52 | + } | |
| 53 | + | |
| 54 | + @PostMapping("/create-my") | |
| 55 | + @Operation(summary = "创建【我的】聊天角色") | |
| 56 | + public CommonResult<Long> createChatRoleMy(@Valid @RequestBody AiChatRoleSaveMyReqVO createReqVO) { | |
| 57 | + return success(chatRoleService.createChatRoleMy(createReqVO, getLoginUserId())); | |
| 58 | + } | |
| 32 | 59 | |
| 33 | - // TODO 芋艿:我的新增 | |
| 60 | + @PutMapping("/update-my") | |
| 61 | + @Operation(summary = "更新【我的】聊天角色") | |
| 62 | + public CommonResult<Boolean> updateChatRoleMy(@Valid @RequestBody AiChatRoleSaveMyReqVO updateReqVO) { | |
| 63 | + chatRoleService.updateChatRoleMy(updateReqVO, getLoginUserId()); | |
| 64 | + return success(true); | |
| 65 | + } | |
| 34 | 66 | |
| 35 | - // TODO 芋艿:我的修改 | |
| 67 | + @DeleteMapping("/delete-my") | |
| 68 | + @Operation(summary = "删除【我的】聊天角色") | |
| 69 | + @Parameter(name = "id", description = "编号", required = true) | |
| 70 | + public CommonResult<Boolean> deleteChatRoleMy(@RequestParam("id") Long id) { | |
| 71 | + chatRoleService.deleteChatRoleMy(id, getLoginUserId()); | |
| 72 | + return success(true); | |
| 73 | + } | |
| 36 | 74 | |
| 37 | - // TODO 芋艿:我的删除 | |
| 75 | + @GetMapping("/category-list") | |
| 76 | + @Operation(summary = "获得聊天角色的分类列表") | |
| 77 | + public CommonResult<List<String>> getChatRoleCategoryList() { | |
| 78 | + return success(chatRoleService.getChatRoleCategoryList()); | |
| 79 | + } | |
| 38 | 80 | |
| 39 | 81 | // ========== 角色管理 ========== |
| 40 | 82 | ... | ... |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/model/vo/chatRole/AiChatRoleSaveMyReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole; | |
| 2 | + | |
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | +import jakarta.validation.constraints.NotEmpty; | |
| 5 | +import lombok.Data; | |
| 6 | +import org.hibernate.validator.constraints.URL; | |
| 7 | + | |
| 8 | +@Schema(description = "管理后台 - AI 聊天角色新增/修改【我的】 Request VO") | |
| 9 | +@Data | |
| 10 | +public class AiChatRoleSaveMyReqVO { | |
| 11 | + | |
| 12 | + @Schema(description = "角色编号", example = "32746") | |
| 13 | + private Long id; | |
| 14 | + | |
| 15 | + @Schema(description = "角色名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") | |
| 16 | + @NotEmpty(message = "角色名称不能为空") | |
| 17 | + private String name; | |
| 18 | + | |
| 19 | + @Schema(description = "角色头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/1.png") | |
| 20 | + @NotEmpty(message = "角色头像不能为空") | |
| 21 | + @URL(message = "角色头像必须是 URL 格式") | |
| 22 | + private String avatar; | |
| 23 | + | |
| 24 | + @Schema(description = "角色描述", requiredMode = Schema.RequiredMode.REQUIRED, example = "你说的对") | |
| 25 | + @NotEmpty(message = "角色描述不能为空") | |
| 26 | + private String description; | |
| 27 | + | |
| 28 | + @Schema(description = "角色欢迎语", requiredMode = Schema.RequiredMode.REQUIRED, example = "Talk is cheap, i will show code") | |
| 29 | + @NotEmpty(message = "角色欢迎语不能为空") | |
| 30 | + private String welcomeMessage; | |
| 31 | + | |
| 32 | + @Schema(description = "角色上下文", requiredMode = Schema.RequiredMode.REQUIRED, example = "现在开始你扮演一位程序员,你是一名优秀的程序员,具有很强的逻辑思维能力,总能高效的解决问题") | |
| 33 | + @NotEmpty(message = "角色上下文不能为空") | |
| 34 | + private String systemMessage; | |
| 35 | + | |
| 36 | +} | |
| 0 | 37 | \ No newline at end of file | ... | ... |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/AiChatRoleMapper.java
| 1 | 1 | package cn.iocoder.yudao.module.ai.dal.mysql; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 5 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | 6 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| ... | ... | @@ -7,6 +8,8 @@ import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleP |
| 7 | 8 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO; |
| 8 | 9 | import org.apache.ibatis.annotations.Mapper; |
| 9 | 10 | |
| 11 | +import java.util.List; | |
| 12 | + | |
| 10 | 13 | /** |
| 11 | 14 | * AI 聊天角色 Mapper |
| 12 | 15 | * |
| ... | ... | @@ -23,4 +26,22 @@ public interface AiChatRoleMapper extends BaseMapperX<AiChatRoleDO> { |
| 23 | 26 | .orderByAsc(AiChatRoleDO::getSort)); |
| 24 | 27 | } |
| 25 | 28 | |
| 29 | + default PageResult<AiChatRoleDO> selectPageByMy(AiChatRolePageReqVO reqVO, Long userId) { | |
| 30 | + return selectPage(reqVO, new LambdaQueryWrapperX<AiChatRoleDO>() | |
| 31 | + .likeIfPresent(AiChatRoleDO::getName, reqVO.getName()) | |
| 32 | + .eqIfPresent(AiChatRoleDO::getCategory, reqVO.getCategory()) | |
| 33 | + // 情况一:公开 | |
| 34 | + .eq(Boolean.TRUE.equals(reqVO.getPublicStatus()), AiChatRoleDO::getPublicStatus, reqVO.getPublicStatus()) | |
| 35 | + // 情况二:私有 | |
| 36 | + .eq(Boolean.FALSE.equals(reqVO.getPublicStatus()), AiChatRoleDO::getUserId, userId) | |
| 37 | + .eq(Boolean.FALSE.equals(reqVO.getPublicStatus()), AiChatRoleDO::getStatus, CommonStatusEnum.ENABLE.getStatus()) | |
| 38 | + .orderByAsc(AiChatRoleDO::getSort)); | |
| 39 | + } | |
| 40 | + | |
| 41 | + default List<AiChatRoleDO> selectListGroupByCategory(Integer status) { | |
| 42 | + return selectList(new LambdaQueryWrapperX<AiChatRoleDO>() | |
| 43 | + .eq(AiChatRoleDO::getStatus, status) | |
| 44 | + .apply("GROUP BY category")); | |
| 45 | + } | |
| 46 | + | |
| 26 | 47 | } | ... | ... |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiChatRoleService.java
| ... | ... | @@ -2,10 +2,13 @@ package cn.iocoder.yudao.module.ai.service.model; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 4 | import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRolePageReqVO; |
| 5 | +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleSaveMyReqVO; | |
| 5 | 6 | import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleSaveReqVO; |
| 6 | 7 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO; |
| 7 | 8 | import jakarta.validation.Valid; |
| 8 | 9 | |
| 10 | +import java.util.List; | |
| 11 | + | |
| 9 | 12 | /** |
| 10 | 13 | * AI 聊天角色 Service 接口 |
| 11 | 14 | * |
| ... | ... | @@ -22,6 +25,15 @@ public interface AiChatRoleService { |
| 22 | 25 | Long createChatRole(@Valid AiChatRoleSaveReqVO createReqVO); |
| 23 | 26 | |
| 24 | 27 | /** |
| 28 | + * 创建【我的】聊天角色 | |
| 29 | + * | |
| 30 | + * @param createReqVO 创建信息 | |
| 31 | + * @param userId 用户编号 | |
| 32 | + * @return 编号 | |
| 33 | + */ | |
| 34 | + Long createChatRoleMy(AiChatRoleSaveMyReqVO createReqVO, Long userId); | |
| 35 | + | |
| 36 | + /** | |
| 25 | 37 | * 更新聊天角色 |
| 26 | 38 | * |
| 27 | 39 | * @param updateReqVO 更新信息 |
| ... | ... | @@ -29,6 +41,14 @@ public interface AiChatRoleService { |
| 29 | 41 | void updateChatRole(@Valid AiChatRoleSaveReqVO updateReqVO); |
| 30 | 42 | |
| 31 | 43 | /** |
| 44 | + * 创建【我的】聊天角色 | |
| 45 | + * | |
| 46 | + * @param updateReqVO 更新信息 | |
| 47 | + * @param userId 用户编号 | |
| 48 | + */ | |
| 49 | + void updateChatRoleMy(AiChatRoleSaveMyReqVO updateReqVO, Long userId); | |
| 50 | + | |
| 51 | + /** | |
| 32 | 52 | * 删除聊天角色 |
| 33 | 53 | * |
| 34 | 54 | * @param id 编号 |
| ... | ... | @@ -36,6 +56,14 @@ public interface AiChatRoleService { |
| 36 | 56 | void deleteChatRole(Long id); |
| 37 | 57 | |
| 38 | 58 | /** |
| 59 | + * 删除【我的】聊天角色 | |
| 60 | + * | |
| 61 | + * @param id 编号 | |
| 62 | + * @param userId 用户编号 | |
| 63 | + */ | |
| 64 | + void deleteChatRoleMy(Long id, Long userId); | |
| 65 | + | |
| 66 | + /** | |
| 39 | 67 | * 获得聊天角色 |
| 40 | 68 | * |
| 41 | 69 | * @param id 编号 |
| ... | ... | @@ -44,18 +72,34 @@ public interface AiChatRoleService { |
| 44 | 72 | AiChatRoleDO getChatRole(Long id); |
| 45 | 73 | |
| 46 | 74 | /** |
| 47 | - * 校验角色是否存在 | |
| 75 | + * 校验聊天角色是否合法 | |
| 48 | 76 | * |
| 49 | 77 | * @param id 角色编号 |
| 50 | 78 | */ |
| 51 | 79 | AiChatRoleDO validateChatRole(Long id); |
| 52 | 80 | |
| 53 | 81 | /** |
| 54 | - * 获得AI 聊天角色分页 | |
| 82 | + * 获得聊天角色分页 | |
| 55 | 83 | * |
| 56 | 84 | * @param pageReqVO 分页查询 |
| 57 | - * @return AI 聊天角色分页 | |
| 85 | + * @return 聊天角色分页 | |
| 58 | 86 | */ |
| 59 | 87 | PageResult<AiChatRoleDO> getChatRolePage(AiChatRolePageReqVO pageReqVO); |
| 60 | 88 | |
| 89 | + /** | |
| 90 | + * 获得【我的】聊天角色分页 | |
| 91 | + * | |
| 92 | + * @param pageReqVO 分页查询 | |
| 93 | + * @param userId 用户编号 | |
| 94 | + * @return 聊天角色分页 | |
| 95 | + */ | |
| 96 | + PageResult<AiChatRoleDO> getChatRoleMyPage(AiChatRolePageReqVO pageReqVO, Long userId); | |
| 97 | + | |
| 98 | + /** | |
| 99 | + * 获得聊天角色的分类列表 | |
| 100 | + * | |
| 101 | + * @return 分类列表 | |
| 102 | + */ | |
| 103 | + List<String> getChatRoleCategoryList(); | |
| 104 | + | |
| 61 | 105 | } |
| 62 | 106 | \ No newline at end of file | ... | ... |
yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/model/AiChatRoleServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.ai.service.model; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.util.ObjectUtil; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 4 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 6 | 7 | import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRolePageReqVO; |
| 8 | +import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleSaveMyReqVO; | |
| 7 | 9 | import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleSaveReqVO; |
| 8 | 10 | import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO; |
| 9 | 11 | import cn.iocoder.yudao.module.ai.dal.mysql.AiChatRoleMapper; |
| 10 | 12 | import jakarta.annotation.Resource; |
| 11 | -import lombok.AllArgsConstructor; | |
| 12 | 13 | import lombok.extern.slf4j.Slf4j; |
| 13 | 14 | import org.springframework.stereotype.Service; |
| 14 | 15 | |
| 16 | +import java.util.List; | |
| 17 | + | |
| 15 | 18 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 19 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | |
| 16 | 20 | import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.CHAT_ROLE_DISABLE; |
| 17 | 21 | import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.CHAT_ROLE_NOT_EXISTS; |
| 18 | 22 | |
| ... | ... | @@ -22,7 +26,6 @@ import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.CHAT_ROLE_NOT_EXISTS |
| 22 | 26 | * @author fansili |
| 23 | 27 | */ |
| 24 | 28 | @Service |
| 25 | -@AllArgsConstructor | |
| 26 | 29 | @Slf4j |
| 27 | 30 | public class AiChatRoleServiceImpl implements AiChatRoleService { |
| 28 | 31 | |
| ... | ... | @@ -37,6 +40,14 @@ public class AiChatRoleServiceImpl implements AiChatRoleService { |
| 37 | 40 | } |
| 38 | 41 | |
| 39 | 42 | @Override |
| 43 | + public Long createChatRoleMy(AiChatRoleSaveMyReqVO createReqVO, Long userId) { | |
| 44 | + AiChatRoleDO chatRole = BeanUtils.toBean(createReqVO, AiChatRoleDO.class).setUserId(userId) | |
| 45 | + .setStatus(CommonStatusEnum.ENABLE.getStatus()).setPublicStatus(false); | |
| 46 | + chatRoleMapper.insert(chatRole); | |
| 47 | + return chatRole.getId(); | |
| 48 | + } | |
| 49 | + | |
| 50 | + @Override | |
| 40 | 51 | public void updateChatRole(AiChatRoleSaveReqVO updateReqVO) { |
| 41 | 52 | // 校验存在 |
| 42 | 53 | validateChatRoleExists(updateReqVO.getId()); |
| ... | ... | @@ -46,6 +57,19 @@ public class AiChatRoleServiceImpl implements AiChatRoleService { |
| 46 | 57 | } |
| 47 | 58 | |
| 48 | 59 | @Override |
| 60 | + public void updateChatRoleMy(AiChatRoleSaveMyReqVO updateReqVO, Long userId) { | |
| 61 | + // 校验存在 | |
| 62 | + AiChatRoleDO chatRole = validateChatRoleExists(updateReqVO.getId()); | |
| 63 | + if (ObjectUtil.notEqual(chatRole.getUserId(), userId)) { | |
| 64 | + throw exception(CHAT_ROLE_NOT_EXISTS); | |
| 65 | + } | |
| 66 | + | |
| 67 | + // 更新 | |
| 68 | + AiChatRoleDO updateObj = BeanUtils.toBean(updateReqVO, AiChatRoleDO.class); | |
| 69 | + chatRoleMapper.updateById(updateObj); | |
| 70 | + } | |
| 71 | + | |
| 72 | + @Override | |
| 49 | 73 | public void deleteChatRole(Long id) { |
| 50 | 74 | // 校验存在 |
| 51 | 75 | validateChatRoleExists(id); |
| ... | ... | @@ -53,6 +77,17 @@ public class AiChatRoleServiceImpl implements AiChatRoleService { |
| 53 | 77 | chatRoleMapper.deleteById(id); |
| 54 | 78 | } |
| 55 | 79 | |
| 80 | + @Override | |
| 81 | + public void deleteChatRoleMy(Long id, Long userId) { | |
| 82 | + // 校验存在 | |
| 83 | + AiChatRoleDO chatRole = validateChatRoleExists(id); | |
| 84 | + if (ObjectUtil.notEqual(chatRole.getUserId(), userId)) { | |
| 85 | + throw exception(CHAT_ROLE_NOT_EXISTS); | |
| 86 | + } | |
| 87 | + // 删除 | |
| 88 | + chatRoleMapper.deleteById(id); | |
| 89 | + } | |
| 90 | + | |
| 56 | 91 | private AiChatRoleDO validateChatRoleExists(Long id) { |
| 57 | 92 | AiChatRoleDO chatRole = chatRoleMapper.selectById(id); |
| 58 | 93 | if (chatRole == null) { |
| ... | ... | @@ -80,5 +115,16 @@ public class AiChatRoleServiceImpl implements AiChatRoleService { |
| 80 | 115 | return chatRoleMapper.selectPage(pageReqVO); |
| 81 | 116 | } |
| 82 | 117 | |
| 118 | + @Override | |
| 119 | + public PageResult<AiChatRoleDO> getChatRoleMyPage(AiChatRolePageReqVO pageReqVO, Long userId) { | |
| 120 | + return chatRoleMapper.selectPageByMy(pageReqVO, userId); | |
| 121 | + } | |
| 122 | + | |
| 123 | + @Override | |
| 124 | + public List<String> getChatRoleCategoryList() { | |
| 125 | + List<AiChatRoleDO> list = chatRoleMapper.selectListGroupByCategory(CommonStatusEnum.ENABLE.getStatus()); | |
| 126 | + return convertList(list, AiChatRoleDO::getName); | |
| 127 | + } | |
| 128 | + | |
| 83 | 129 | } |
| 84 | 130 | ... | ... |
yudao-server/src/main/resources/application-local.yaml
| ... | ... | @@ -52,7 +52,7 @@ spring: |
| 52 | 52 | # url: jdbc:sqlserver://127.0.0.1:1433;DatabaseName=ruoyi-vue-pro;SelectMethod=cursor;encrypt=false;rewriteBatchedStatements=true;useUnicode=true;characterEncoding=utf-8 # SQLServer 连接的示例 |
| 53 | 53 | # url: jdbc:dm://127.0.0.1:5236?schema=RUOYI_VUE_PRO # DM 连接的示例 |
| 54 | 54 | username: root |
| 55 | - password: root | |
| 55 | + password: 123456 | |
| 56 | 56 | # username: sa # SQL Server 连接的示例 |
| 57 | 57 | # password: Yudao@2024 # SQL Server 连接的示例 |
| 58 | 58 | # username: SYSDBA # DM 连接的示例 | ... | ... |