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

This commit is contained in:
YunaiV 2024-05-13 22:55:01 +08:00
parent 31453e19d4
commit 7344ec8aea
6 changed files with 199 additions and 10 deletions

View File

@ -1,10 +1,12 @@
package cn.iocoder.yudao.module.ai.controller.admin.model;
import cn.hutool.core.util.ObjUtil;
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.chatRole.AiChatRolePageReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleRespVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleSaveMyReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleSaveReqVO;
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
import cn.iocoder.yudao.module.ai.service.model.AiChatRoleService;
@ -17,7 +19,10 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "管理后台 - AI 聊天角色")
@RestController
@ -28,13 +33,50 @@ public class AiChatRoleController {
@Resource
private AiChatRoleService chatRoleService;
// TODO 芋艿我的分页
@GetMapping("/my-page")
@Operation(summary = "获得【我的】聊天角色分页")
public CommonResult<PageResult<AiChatRoleRespVO>> getChatRoleMyPage(@Valid AiChatRolePageReqVO pageReqVO) {
PageResult<AiChatRoleDO> pageResult = chatRoleService.getChatRoleMyPage(pageReqVO, getLoginUserId());
return success(BeanUtils.toBean(pageResult, AiChatRoleRespVO.class));
}
// TODO 芋艿我的新增
@GetMapping("/get-my")
@Operation(summary = "获得【我的】聊天角色")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
public CommonResult<AiChatRoleRespVO> getChatRoleMy(@RequestParam("id") Long id) {
AiChatRoleDO chatRole = chatRoleService.getChatRole(id);
if (ObjUtil.notEqual(chatRole.getUserId(), getLoginUserId())) {
return success(null);
}
return success(BeanUtils.toBean(chatRole, AiChatRoleRespVO.class));
}
// TODO 芋艿我的修改
@PostMapping("/create-my")
@Operation(summary = "创建【我的】聊天角色")
public CommonResult<Long> createChatRoleMy(@Valid @RequestBody AiChatRoleSaveMyReqVO createReqVO) {
return success(chatRoleService.createChatRoleMy(createReqVO, getLoginUserId()));
}
// TODO 芋艿我的删除
@PutMapping("/update-my")
@Operation(summary = "更新【我的】聊天角色")
public CommonResult<Boolean> updateChatRoleMy(@Valid @RequestBody AiChatRoleSaveMyReqVO updateReqVO) {
chatRoleService.updateChatRoleMy(updateReqVO, getLoginUserId());
return success(true);
}
@DeleteMapping("/delete-my")
@Operation(summary = "删除【我的】聊天角色")
@Parameter(name = "id", description = "编号", required = true)
public CommonResult<Boolean> deleteChatRoleMy(@RequestParam("id") Long id) {
chatRoleService.deleteChatRoleMy(id, getLoginUserId());
return success(true);
}
@GetMapping("/category-list")
@Operation(summary = "获得聊天角色的分类列表")
public CommonResult<List<String>> getChatRoleCategoryList() {
return success(chatRoleService.getChatRoleCategoryList());
}
// ========== 角色管理 ==========

View File

@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import org.hibernate.validator.constraints.URL;
@Schema(description = "管理后台 - AI 聊天角色新增/修改【我的】 Request VO")
@Data
public class AiChatRoleSaveMyReqVO {
@Schema(description = "角色编号", example = "32746")
private Long id;
@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 = "角色头像不能为空")
@URL(message = "角色头像必须是 URL 格式")
private String avatar;
@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;
}

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.ai.dal.mysql;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
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;
@ -7,6 +8,8 @@ import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleP
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* AI 聊天角色 Mapper
*
@ -23,4 +26,22 @@ public interface AiChatRoleMapper extends BaseMapperX<AiChatRoleDO> {
.orderByAsc(AiChatRoleDO::getSort));
}
default PageResult<AiChatRoleDO> selectPageByMy(AiChatRolePageReqVO reqVO, Long userId) {
return selectPage(reqVO, new LambdaQueryWrapperX<AiChatRoleDO>()
.likeIfPresent(AiChatRoleDO::getName, reqVO.getName())
.eqIfPresent(AiChatRoleDO::getCategory, reqVO.getCategory())
// 情况一公开
.eq(Boolean.TRUE.equals(reqVO.getPublicStatus()), AiChatRoleDO::getPublicStatus, reqVO.getPublicStatus())
// 情况二私有
.eq(Boolean.FALSE.equals(reqVO.getPublicStatus()), AiChatRoleDO::getUserId, userId)
.eq(Boolean.FALSE.equals(reqVO.getPublicStatus()), AiChatRoleDO::getStatus, CommonStatusEnum.ENABLE.getStatus())
.orderByAsc(AiChatRoleDO::getSort));
}
default List<AiChatRoleDO> selectListGroupByCategory(Integer status) {
return selectList(new LambdaQueryWrapperX<AiChatRoleDO>()
.eq(AiChatRoleDO::getStatus, status)
.apply("GROUP BY category"));
}
}

View File

@ -2,10 +2,13 @@ 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.chatRole.AiChatRolePageReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleSaveMyReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleSaveReqVO;
import cn.iocoder.yudao.module.ai.dal.dataobject.model.AiChatRoleDO;
import jakarta.validation.Valid;
import java.util.List;
/**
* AI 聊天角色 Service 接口
*
@ -21,6 +24,15 @@ public interface AiChatRoleService {
*/
Long createChatRole(@Valid AiChatRoleSaveReqVO createReqVO);
/**
* 创建我的聊天角色
*
* @param createReqVO 创建信息
* @param userId 用户编号
* @return 编号
*/
Long createChatRoleMy(AiChatRoleSaveMyReqVO createReqVO, Long userId);
/**
* 更新聊天角色
*
@ -28,6 +40,14 @@ public interface AiChatRoleService {
*/
void updateChatRole(@Valid AiChatRoleSaveReqVO updateReqVO);
/**
* 创建我的聊天角色
*
* @param updateReqVO 更新信息
* @param userId 用户编号
*/
void updateChatRoleMy(AiChatRoleSaveMyReqVO updateReqVO, Long userId);
/**
* 删除聊天角色
*
@ -35,6 +55,14 @@ public interface AiChatRoleService {
*/
void deleteChatRole(Long id);
/**
* 删除我的聊天角色
*
* @param id 编号
* @param userId 用户编号
*/
void deleteChatRoleMy(Long id, Long userId);
/**
* 获得聊天角色
*
@ -44,18 +72,34 @@ public interface AiChatRoleService {
AiChatRoleDO getChatRole(Long id);
/**
* 校验角色是否存在
* 校验聊天角色是否合法
*
* @param id 角色编号
*/
AiChatRoleDO validateChatRole(Long id);
/**
* 获得AI 聊天角色分页
* 获得聊天角色分页
*
* @param pageReqVO 分页查询
* @return AI 聊天角色分页
* @return 聊天角色分页
*/
PageResult<AiChatRoleDO> getChatRolePage(AiChatRolePageReqVO pageReqVO);
/**
* 获得我的聊天角色分页
*
* @param pageReqVO 分页查询
* @param userId 用户编号
* @return 聊天角色分页
*/
PageResult<AiChatRoleDO> getChatRoleMyPage(AiChatRolePageReqVO pageReqVO, Long userId);
/**
* 获得聊天角色的分类列表
*
* @return 分类列表
*/
List<String> getChatRoleCategoryList();
}

View File

@ -1,18 +1,22 @@
package cn.iocoder.yudao.module.ai.service.model;
import cn.hutool.core.util.ObjectUtil;
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.chatRole.AiChatRolePageReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.AiChatRoleSaveMyReqVO;
import cn.iocoder.yudao.module.ai.controller.admin.model.vo.chatRole.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 java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.CHAT_ROLE_DISABLE;
import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.CHAT_ROLE_NOT_EXISTS;
@ -22,7 +26,6 @@ import static cn.iocoder.yudao.module.ai.ErrorCodeConstants.CHAT_ROLE_NOT_EXISTS
* @author fansili
*/
@Service
@AllArgsConstructor
@Slf4j
public class AiChatRoleServiceImpl implements AiChatRoleService {
@ -36,6 +39,14 @@ public class AiChatRoleServiceImpl implements AiChatRoleService {
return chatRole.getId();
}
@Override
public Long createChatRoleMy(AiChatRoleSaveMyReqVO createReqVO, Long userId) {
AiChatRoleDO chatRole = BeanUtils.toBean(createReqVO, AiChatRoleDO.class).setUserId(userId)
.setStatus(CommonStatusEnum.ENABLE.getStatus()).setPublicStatus(false);
chatRoleMapper.insert(chatRole);
return chatRole.getId();
}
@Override
public void updateChatRole(AiChatRoleSaveReqVO updateReqVO) {
// 校验存在
@ -45,6 +56,19 @@ public class AiChatRoleServiceImpl implements AiChatRoleService {
chatRoleMapper.updateById(updateObj);
}
@Override
public void updateChatRoleMy(AiChatRoleSaveMyReqVO updateReqVO, Long userId) {
// 校验存在
AiChatRoleDO chatRole = validateChatRoleExists(updateReqVO.getId());
if (ObjectUtil.notEqual(chatRole.getUserId(), userId)) {
throw exception(CHAT_ROLE_NOT_EXISTS);
}
// 更新
AiChatRoleDO updateObj = BeanUtils.toBean(updateReqVO, AiChatRoleDO.class);
chatRoleMapper.updateById(updateObj);
}
@Override
public void deleteChatRole(Long id) {
// 校验存在
@ -53,6 +77,17 @@ public class AiChatRoleServiceImpl implements AiChatRoleService {
chatRoleMapper.deleteById(id);
}
@Override
public void deleteChatRoleMy(Long id, Long userId) {
// 校验存在
AiChatRoleDO chatRole = validateChatRoleExists(id);
if (ObjectUtil.notEqual(chatRole.getUserId(), userId)) {
throw exception(CHAT_ROLE_NOT_EXISTS);
}
// 删除
chatRoleMapper.deleteById(id);
}
private AiChatRoleDO validateChatRoleExists(Long id) {
AiChatRoleDO chatRole = chatRoleMapper.selectById(id);
if (chatRole == null) {
@ -80,5 +115,16 @@ public class AiChatRoleServiceImpl implements AiChatRoleService {
return chatRoleMapper.selectPage(pageReqVO);
}
@Override
public PageResult<AiChatRoleDO> getChatRoleMyPage(AiChatRolePageReqVO pageReqVO, Long userId) {
return chatRoleMapper.selectPageByMy(pageReqVO, userId);
}
@Override
public List<String> getChatRoleCategoryList() {
List<AiChatRoleDO> list = chatRoleMapper.selectListGroupByCategory(CommonStatusEnum.ENABLE.getStatus());
return convertList(list, AiChatRoleDO::getName);
}
}

View File

@ -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: root
password: 123456
# username: sa # SQL Server 连接的示例
# password: Yudao@2024 # SQL Server 连接的示例
# username: SYSDBA # DM 连接的示例