【调整】根据api设计调整部分字段,和业务逻辑

This commit is contained in:
cherishsince 2024-05-06 18:21:17 +08:00
parent 2b7e7763bf
commit c0470dcabb
19 changed files with 266 additions and 33 deletions

View File

@ -33,5 +33,6 @@ public interface ErrorCodeConstants {
ErrorCode AI_MODAL_CONFIG_PARAMS_INCORRECT = new ErrorCode(1_022_000_081, "AI 模型 config 参数不正确! {} ");
ErrorCode AI_MODAL_NOT_SUPPORTED_MODAL = new ErrorCode(1_022_000_082, "AI 模型不支持的 modal! {} ");
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 模型禁用不能使用!");
}

View File

@ -32,13 +32,13 @@ public class AiChatConversationController {
private final AiChatConversationService chatConversationService;
@Operation(summary = "创建 - 对话普通对话")
@PostMapping("/createConversation")
@PutMapping("/createConversation")
public CommonResult<AiChatConversationRes> createConversation(@RequestBody @Validated AiChatConversationCreateUserReq req) {
return CommonResult.success(chatConversationService.createConversation(req));
}
@Operation(summary = "创建 - 对话角色对话")
@PostMapping("/createRoleConversation")
@PutMapping("/createRoleConversation")
public CommonResult<AiChatConversationRes> createRoleConversation(@RequestBody @Validated AiChatConversationCreateRoleReq req) {
return CommonResult.success(chatConversationService.createRoleConversation(req));
}
@ -55,6 +55,14 @@ public class AiChatConversationController {
return CommonResult.success(chatConversationService.listConversation(req));
}
@Operation(summary = "更新 - 更新模型")
@PostMapping("/{id}/modal")
public CommonResult<Void> updateModal(@PathVariable("id") Long id,
@RequestParam("modalId") Long modalId) {
chatConversationService.updateModal(id, modalId);
return CommonResult.success(null);
}
@Operation(summary = "删除")
@DeleteMapping("/{id}")
public CommonResult<Void> delete(@PathVariable("id") Long id) {

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.ai.convert;
import cn.iocoder.yudao.module.ai.dal.dataobject.AiChatModalDO;
import cn.iocoder.yudao.module.ai.vo.AiChatModalAddReq;
import cn.iocoder.yudao.module.ai.vo.AiChatModalListRes;
import cn.iocoder.yudao.module.ai.vo.AiChatModalRes;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
@ -40,4 +41,14 @@ public interface AiChatModalConvert {
@Mapping(target = "config", ignore = true)
})
AiChatModalDO convertAiChatModalDO(AiChatModalAddReq req);
/**
* 转换 - AiChatModalRes
*
* @param aiChatModalDO
* @return
*/
AiChatModalRes convertAiChatModalRes(AiChatModalDO aiChatModalDO);
}

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.ai.convert;
import cn.iocoder.yudao.module.ai.dal.dataobject.AiChatRoleDO;
import cn.iocoder.yudao.module.ai.vo.AiChatRoleAddReq;
import cn.iocoder.yudao.module.ai.vo.AiChatRoleRes;
import cn.iocoder.yudao.module.ai.vo.AiChatRoleUpdateReq;
import cn.iocoder.yudao.module.ai.vo.AiChatRoleListRes;
import org.mapstruct.Mapper;
@ -44,4 +45,12 @@ public interface AiChatRoleConvert {
* @return
*/
AiChatRoleDO convertAiChatRoleDO(AiChatRoleUpdateReq req);
/**
* 转换 - AiChatRoleRes
*
* @param aiChatRoleDO
* @return
*/
AiChatRoleRes convertAiChatRoleRes(AiChatRoleDO aiChatRoleDO);
}

View File

@ -25,12 +25,18 @@ public class AiChatConversationDO extends BaseDO {
private Long userId;
@Schema(description = "chat角色Id")
private Long chatRoleId;
private Long roleId;
@Schema(description = "chat角色名称")
private String chatRoleName;
private String roleName;
@Schema(description = "标题(有程序自动生成)")
@Schema(description = "模型id")
private Long modalId;
@Schema(description = "使用的模型")
private String modal;
@Schema(description = "标题")
private String title;
@Schema(description = "对话类型(roleChat、userChat)")

View File

@ -1,6 +1,10 @@
package cn.iocoder.yudao.module.ai.mapper;
import cn.hutool.core.collection.CollUtil;
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.dal.dataobject.AiChatModalDO;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
@ -15,4 +19,22 @@ import org.springframework.stereotype.Repository;
@Repository
@Mapper
public interface AiChatModalMapper extends BaseMapperX<AiChatModalDO> {
/**
* 查询 - 第一个modal
*
* @return
*/
default AiChatModalDO selectFirstModal() {
PageResult<AiChatModalDO> pageResult = selectPage(new PageParam().setPageNo(1).setPageSize(1),
new LambdaQueryWrapperX<AiChatModalDO>()
.orderByAsc(AiChatModalDO::getSort)
);
if (CollUtil.isEmpty(pageResult.getList())) {
return null;
}
return pageResult.getList().get(0);
}
}

View File

@ -48,6 +48,15 @@ public interface AiChatConversationService {
*/
List<AiChatConversationRes> listConversation(AiChatConversationListReq req);
/**
* 更新 - 更新模型
*
* @param id
* @param modalId
* @return
*/
void updateModal(Long id, Long modalId);
/**
* 删除 - 根据id
*

View File

@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.ai.vo.AiChatModalAddReq;
import cn.iocoder.yudao.module.ai.vo.AiChatModalListReq;
import cn.iocoder.yudao.module.ai.vo.AiChatModalListRes;
import cn.iocoder.yudao.module.ai.vo.AiChatModalRes;
/**
* ai modal
@ -44,4 +45,11 @@ public interface AiChatModalService {
*/
void delete(Long id);
/**
* 获取 - 获取 modal
*
* @param modalId
* @return
*/
AiChatModalRes getChatModal(Long modalId);
}

View File

@ -51,4 +51,11 @@ public interface AiChatRoleService {
*/
void delete(Long chatRoleId);
/**
* 获取角色
*
* @param roleId
* @return
*/
AiChatRoleRes getChatRole(Long roleId);
}

View File

@ -5,15 +5,16 @@ import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.ai.ErrorCodeConstants;
import cn.iocoder.yudao.module.ai.convert.AiChatConversationConvert;
import cn.iocoder.yudao.module.ai.dal.dataobject.AiChatConversationDO;
import cn.iocoder.yudao.module.ai.dal.dataobject.AiChatRoleDO;
import cn.iocoder.yudao.module.ai.dal.dataobject.AiChatModalDO;
import cn.iocoder.yudao.module.ai.enums.AiChatConversationTypeEnum;
import cn.iocoder.yudao.module.ai.enums.AiChatModalDisableEnum;
import cn.iocoder.yudao.module.ai.mapper.AiChatConversationMapper;
import cn.iocoder.yudao.module.ai.mapper.AiChatModalMapper;
import cn.iocoder.yudao.module.ai.mapper.AiChatRoleMapper;
import cn.iocoder.yudao.module.ai.service.AiChatConversationService;
import cn.iocoder.yudao.module.ai.vo.AiChatConversationCreateRoleReq;
import cn.iocoder.yudao.module.ai.vo.AiChatConversationCreateUserReq;
import cn.iocoder.yudao.module.ai.vo.AiChatConversationListReq;
import cn.iocoder.yudao.module.ai.vo.AiChatConversationRes;
import cn.iocoder.yudao.module.ai.service.AiChatModalService;
import cn.iocoder.yudao.module.ai.service.AiChatRoleService;
import cn.iocoder.yudao.module.ai.vo.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
@ -33,7 +34,10 @@ import java.util.List;
public class AiChatConversationServiceImpl implements AiChatConversationService {
private final AiChatRoleMapper aiChatRoleMapper;
private final AiChatModalMapper aiChatModalMapper;
private final AiChatConversationMapper aiChatConversationMapper;
private final AiChatModalService aiChatModalService;
private final AiChatRoleService aiChatRoleService;
@Override
public AiChatConversationRes createConversation(AiChatConversationCreateUserReq req) {
@ -45,9 +49,12 @@ public class AiChatConversationServiceImpl implements AiChatConversationService
if (latestConversation != null && latestConversation.getChatCount() <= 0) {
return AiChatConversationConvert.INSTANCE.covnertChatConversationRes(latestConversation);
}
// 获取第一个模型
AiChatModalDO aiChatModalDO = aiChatModalMapper.selectFirstModal();
// 创建新的 Conversation
AiChatConversationDO insertConversation = saveConversation(req.getTitle(), loginUserId,
null, null, AiChatConversationTypeEnum.USER_CHAT);
null, null, AiChatConversationTypeEnum.USER_CHAT,
aiChatModalDO.getId(), aiChatModalDO.getModal());
// 转换 res
return AiChatConversationConvert.INSTANCE.covnertChatConversationRes(insertConversation);
}
@ -57,43 +64,56 @@ public class AiChatConversationServiceImpl implements AiChatConversationService
// 获取用户id
Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
// 查询最新的对话
AiChatConversationDO latestConversation = aiChatConversationMapper.selectLatestConversation(loginUserId);
// 如果有对话没有被使用过那就返回这个
if (latestConversation != null && latestConversation.getChatCount() <= 0) {
return AiChatConversationConvert.INSTANCE.covnertChatConversationRes(latestConversation);
}
AiChatRoleDO aiChatRoleDO = aiChatRoleMapper.selectById(req.getChatRoleId());
// AiChatConversationDO latestConversation = aiChatConversationMapper.selectLatestConversation(loginUserId);
// // 如果有对话没有被使用过那就返回这个
// if (latestConversation != null && latestConversation.getChatCount() <= 0) {
// return AiChatConversationConvert.INSTANCE.covnertChatConversationRes(latestConversation);
// }
// 查询角色
AiChatRoleRes chatRoleRes = aiChatRoleService.getChatRole(req.getRoleId());
// 获取第一个模型
AiChatModalDO aiChatModalDO = aiChatModalMapper.selectFirstModal();
// 创建新的 Conversation
AiChatConversationDO insertConversation = saveConversation(req.getTitle(), loginUserId,
req.getChatRoleId(), aiChatRoleDO.getName(), AiChatConversationTypeEnum.ROLE_CHAT);
req.getRoleId(), chatRoleRes.getName(), AiChatConversationTypeEnum.ROLE_CHAT,
aiChatModalDO.getId(), aiChatModalDO.getModal());
// 转换 res
return AiChatConversationConvert.INSTANCE.covnertChatConversationRes(insertConversation);
}
private @NotNull AiChatConversationDO saveConversation(String title,
Long userId,
Long chatRoleId,
String chatRoleName,
AiChatConversationTypeEnum typeEnum) {
Long roleId,
String roleName,
AiChatConversationTypeEnum typeEnum,
Long modalId,
String modal) {
AiChatConversationDO insertConversation = new AiChatConversationDO();
insertConversation.setId(null);
insertConversation.setUserId(userId);
insertConversation.setChatRoleId(chatRoleId);
insertConversation.setChatRoleName(chatRoleName);
insertConversation.setRoleId(roleId);
insertConversation.setRoleName(roleName);
insertConversation.setTitle(title);
insertConversation.setChatCount(0);
insertConversation.setType(typeEnum.getType());
insertConversation.setModalId(modalId);
insertConversation.setModal(modal);
aiChatConversationMapper.insert(insertConversation);
return insertConversation;
}
@Override
public AiChatConversationRes getConversation(Long id) {
AiChatConversationDO aiChatConversationDO = validateExists(id);
return AiChatConversationConvert.INSTANCE.covnertChatConversationRes(aiChatConversationDO);
}
private @NotNull AiChatConversationDO validateExists(Long id) {
AiChatConversationDO aiChatConversationDO = aiChatConversationMapper.selectById(id);
if (aiChatConversationDO == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_CHAT_CONTINUE_NOT_EXIST);
}
return AiChatConversationConvert.INSTANCE.covnertChatConversationRes(aiChatConversationDO);
return aiChatConversationDO;
}
@Override
@ -106,6 +126,24 @@ public class AiChatConversationServiceImpl implements AiChatConversationService
return AiChatConversationConvert.INSTANCE.covnertChatConversationResList(top100Conversation);
}
@Override
public void updateModal(Long id, Long modalId) {
// 校验对话是否存在
validateExists(id);
// 获取模型
AiChatModalRes chatModal = aiChatModalService.getChatModal(modalId);
// 判断模型是否禁用
if (AiChatModalDisableEnum.YES.getValue().equals(chatModal.getDisable())) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_DISABLE_NOT_USED);
}
// 更新对话
aiChatConversationMapper.updateById(new AiChatConversationDO()
.setId(id)
.setModalId(chatModal.getId())
.setModal(chatModal.getModal())
);
}
@Override
public void delete(Long id) {
aiChatConversationMapper.deleteById(id);

View File

@ -22,6 +22,7 @@ import cn.iocoder.yudao.module.ai.service.AiChatModalService;
import cn.iocoder.yudao.module.ai.vo.AiChatModalAddReq;
import cn.iocoder.yudao.module.ai.vo.AiChatModalListReq;
import cn.iocoder.yudao.module.ai.vo.AiChatModalListRes;
import cn.iocoder.yudao.module.ai.vo.AiChatModalRes;
import jakarta.validation.ConstraintViolation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -108,11 +109,19 @@ public class AiChatModalServiceImpl implements AiChatModalService {
aiChatModalMapper.deleteById(id);
}
private void validateChatModalExists(Long id) {
@Override
public AiChatModalRes getChatModal(Long modalId) {
// 检查 modal 是否存在
AiChatModalDO aiChatModalDO = validateChatModalExists(modalId);
return AiChatModalConvert.INSTANCE.convertAiChatModalRes(aiChatModalDO);
}
private AiChatModalDO validateChatModalExists(Long id) {
AiChatModalDO aiChatModalDO = aiChatModalMapper.selectById(id);
if (aiChatModalDO == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.AI_MODAL_NOT_EXIST);
}
return aiChatModalDO;
}
private void validateModal(String platform, String modal) {

View File

@ -99,6 +99,13 @@ public class AiChatRoleServiceImpl implements AiChatRoleService {
aiChatRoleMapper.deleteById(chatRoleId);
}
@Override
public AiChatRoleRes getChatRole(Long roleId) {
// 检查角色是否存在
AiChatRoleDO aiChatRoleDO = validateChatRoleExists(roleId);
return AiChatRoleConvert.INSTANCE.convertAiChatRoleRes(aiChatRoleDO);
}
private AiChatRoleDO validateChatRoleExists(Long id) {
AiChatRoleDO aiChatRoleDO = aiChatRoleMapper.selectById(id);
if (aiChatRoleDO == null) {

View File

@ -18,7 +18,7 @@ public class AiChatConversationCreateRoleReq {
@Schema(description = "chat角色Id")
@NotNull(message = "聊天角色id不能为空!")
private Long chatRoleId;
private Long roleId;
@Schema(description = "标题(有程序自动生成)")
@NotNull(message = "标题不能为空!")

View File

@ -19,4 +19,5 @@ public class AiChatConversationCreateUserReq {
@Schema(description = "对话标题")
@NotNull(message = "标题不能为空!")
private String title;
}

View File

@ -22,10 +22,16 @@ public class AiChatConversationRes {
private Long userId;
@Schema(description = "chat角色Id")
private Long chatRoleId;
private Long roleId;
@Schema(description = "chat角色名称")
private String chatRoleName;
private String roleName;
@Schema(description = "模型id")
private Long modalId;
@Schema(description = "使用的模型")
private String modal;
@Schema(description = "标题(有程序自动生成)")
private String title;
@ -35,4 +41,5 @@ public class AiChatConversationRes {
@Schema(description = "聊天次数(有程序自动生成)")
private Integer chatCount;
}

View File

@ -0,0 +1,41 @@
package cn.iocoder.yudao.module.ai.vo;
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 AiChatModalRes {
@Schema(description = "id")
private Long id;
@Schema(description = "模型平台 参考 AiPlatformEnum")
private String platform;
@Schema(description = "模型类型 参考 YiYanChatModel、XingHuoChatModel")
private String modal;
@Schema(description = "模型名字")
private String name;
@Schema(description = "模型照片")
private String image;
@Schema(description = "禁用 0、正常 1、禁用")
private Integer disable;
@Schema(description = "排序 asc 排序")
private Integer sort;
@Schema(description = "modal 配置")
private String config;
}

View File

@ -0,0 +1,37 @@
package cn.iocoder.yudao.module.ai.vo;
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 AiChatRoleRes {
@Schema(description = "id")
private Long id;
@Schema(description = "用户id")
private Long userId;
@Schema(description = "角色名字")
private String name;
@Schema(description = "角色介绍,详细描述角色的功能或用途")
private String introduce;
@Schema(description = "分类,角色所属的类别,如娱乐、创作等")
private String classify;
@Schema(description = "状态 open、close")
private String enable;
@Schema(description = "角色的使用次数统计")
private Integer useCount;
}

View File

@ -2,15 +2,27 @@
### 登录 详细使用 https://www.jetbrains.com/help/idea/testing-restful-web-services.html、https://www.cnblogs.com/crazymakercircle/p/14317222.html
### 对话 - 创建对话
POST {{baseUrl}}/ai/chat/conversation/create
PUT {{baseUrl}}/ai/chat/conversation/createConversation
Content-Type: application/json
Authorization: {{token}}
{
"chatType": "userChat"
"title": "新增对话"
}
### 对话 - 创建对话
PUT {{baseUrl}}/ai/chat/conversation/createRoleConversation
Content-Type: application/json
Authorization: {{token}}
{
"roleId": 7,
"title": "新增对话"
}
### 对话 - id获取
GET {{baseUrl}}/ai/chat/conversation/1781604279872581644
Authorization: {{token}}

View File

@ -19,14 +19,14 @@ Authorization: {{token}}
### chat update
POST {{baseUrl}}/ai/chat/role/6
POST {{baseUrl}}/ai/chat/role/7
Content-Type: application/json
Authorization: {{token}}
{
"modelId": 1,
"name": "小红书写作v1---hh😄",
"introduce": "采用gpt3.5模型,拥有小红书优质作者写作经验。",
"name": "小红书写作v1---hh😄",
"introduce": "采用gpt3.5模型,拥有小红书优质作者写作经验。0----",
"classify": "writing",
"enable": "close"
}