mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 10:37:41 +08:00 
			
		
		
		
	【代码评审】AI:调整 message 接口
This commit is contained in:
		| @ -1,50 +0,0 @@ | |||||||
| package cn.iocoder.yudao.module.ai.controller; |  | ||||||
|  |  | ||||||
| import cn.iocoder.yudao.framework.common.pojo.CommonResult; |  | ||||||
| import cn.iocoder.yudao.module.ai.service.AiChatService; |  | ||||||
| import cn.iocoder.yudao.module.ai.vo.AiChatReq; |  | ||||||
| import io.swagger.v3.oas.annotations.Operation; |  | ||||||
| import io.swagger.v3.oas.annotations.tags.Tag; |  | ||||||
| import lombok.AllArgsConstructor; |  | ||||||
| import lombok.extern.slf4j.Slf4j; |  | ||||||
| import org.springframework.beans.factory.annotation.Autowired; |  | ||||||
| import org.springframework.http.MediaType; |  | ||||||
| import org.springframework.validation.annotation.Validated; |  | ||||||
| import org.springframework.web.bind.annotation.GetMapping; |  | ||||||
| import org.springframework.web.bind.annotation.ModelAttribute; |  | ||||||
| import org.springframework.web.bind.annotation.RequestMapping; |  | ||||||
| import org.springframework.web.bind.annotation.RestController; |  | ||||||
| import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * ia 模块 |  | ||||||
|  * |  | ||||||
|  * @author fansili |  | ||||||
|  * @time 2024/4/13 17:44 |  | ||||||
|  * @since 1.0 |  | ||||||
|  */ |  | ||||||
| @Tag(name = "A1-AI聊天") |  | ||||||
| @RestController |  | ||||||
| @RequestMapping("/ai") |  | ||||||
| @Slf4j |  | ||||||
| @AllArgsConstructor |  | ||||||
| public class AiChatController { |  | ||||||
|  |  | ||||||
|     @Autowired |  | ||||||
|     private final AiChatService chatService; |  | ||||||
|  |  | ||||||
|     @Operation(summary = "聊天-chat", description = "这个一般等待时间比较久,需要全部完成才会返回!") |  | ||||||
|     @GetMapping("/chat") |  | ||||||
|     public CommonResult<String> chat(@Validated @ModelAttribute AiChatReq req) { |  | ||||||
|         return CommonResult.success(chatService.chat(req)); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // TODO @芋艿:调用这个方法异常,Unable to handle the Spring Security Exception because the response is already committed. |  | ||||||
|     @Operation(summary = "聊天-stream", description = "这里跟通义千问一样采用的是 Server-Sent Events (SSE) 通讯模式") |  | ||||||
|     @GetMapping(value = "/chatStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) |  | ||||||
|     public SseEmitter chatStream(@Validated @ModelAttribute AiChatReq req) { |  | ||||||
|         Utf8SseEmitter sseEmitter = new Utf8SseEmitter(); |  | ||||||
|         chatService.chatStream(req, sseEmitter); |  | ||||||
|         return sseEmitter; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,44 +0,0 @@ | |||||||
| package cn.iocoder.yudao.module.ai.controller; |  | ||||||
|  |  | ||||||
| import cn.iocoder.yudao.framework.common.pojo.CommonResult; |  | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; |  | ||||||
| import cn.iocoder.yudao.module.ai.service.AiChatMessageService; |  | ||||||
| import cn.iocoder.yudao.module.ai.vo.AiChatMessageListRes; |  | ||||||
| import cn.iocoder.yudao.module.ai.vo.AiChatMessageReq; |  | ||||||
| import io.swagger.v3.oas.annotations.Operation; |  | ||||||
| import io.swagger.v3.oas.annotations.tags.Tag; |  | ||||||
| import lombok.AllArgsConstructor; |  | ||||||
| import lombok.extern.slf4j.Slf4j; |  | ||||||
| import org.springframework.validation.annotation.Validated; |  | ||||||
| import org.springframework.web.bind.annotation.*; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * chat message |  | ||||||
|  * |  | ||||||
|  * @author fansili |  | ||||||
|  * @time 2024/4/24 17:22 |  | ||||||
|  * @since 1.0 |  | ||||||
|  */ |  | ||||||
| @Tag(name = "A3-聊天-对话") |  | ||||||
| @RestController |  | ||||||
| @RequestMapping("/ai/chat/message") |  | ||||||
| @Slf4j |  | ||||||
| @AllArgsConstructor |  | ||||||
| public class AiChatMessageController { |  | ||||||
|  |  | ||||||
|     private final AiChatMessageService chatMessageService; |  | ||||||
|  |  | ||||||
|     @Operation(summary = "聊天记录", description = "查询个人的聊天记录") |  | ||||||
|     @GetMapping("/list") |  | ||||||
|     public PageResult<AiChatMessageListRes> list(@Validated @ModelAttribute AiChatMessageReq req) { |  | ||||||
|         return chatMessageService.list(req); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Operation(summary = "聊天记录 - 删除", description = "删除记录") |  | ||||||
|     @DeleteMapping("/{chatConversationId}/{id}") |  | ||||||
|     public CommonResult delete(@PathVariable("chatConversationId") Long chatConversationId, |  | ||||||
|                                @PathVariable("id") Long id) { |  | ||||||
|         chatMessageService.delete(chatConversationId, id); |  | ||||||
|         return CommonResult.success(null); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -0,0 +1,62 @@ | |||||||
|  | package cn.iocoder.yudao.module.ai.controller.admin.chat; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||||||
|  | import cn.iocoder.yudao.module.ai.controller.Utf8SseEmitter; | ||||||
|  | import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageRespVO; | ||||||
|  | import cn.iocoder.yudao.module.ai.service.AiChatService; | ||||||
|  | import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO; | ||||||
|  | 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.extern.slf4j.Slf4j; | ||||||
|  | import org.springframework.http.MediaType; | ||||||
|  | import org.springframework.validation.annotation.Validated; | ||||||
|  | import org.springframework.web.bind.annotation.*; | ||||||
|  | import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||||||
|  |  | ||||||
|  | // TODO @芋艿:权限标识; | ||||||
|  | @Tag(name = "管理后台 - 聊天消息") | ||||||
|  | @RestController | ||||||
|  | @RequestMapping("/ai/chat/message") | ||||||
|  | @Slf4j | ||||||
|  | public class AiChatMessageController { | ||||||
|  |     @Resource | ||||||
|  |     private AiChatService chatService; | ||||||
|  |  | ||||||
|  |     @Operation(summary = "发送消息(段式)", description = "一次性返回,响应较慢") | ||||||
|  |     @PostMapping("/send") | ||||||
|  |     public CommonResult<AiChatMessageRespVO> sendMessage(@Validated @ModelAttribute AiChatMessageSendReqVO sendReqVO) { | ||||||
|  |         // TODO @fan:使用 static import;这样就 success 就行了; | ||||||
|  |         return success(null); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // TODO @芋艿:调用这个方法异常,Unable to handle the Spring Security Exception because the response is already committed.;可以再试试 | ||||||
|  |     // TODO @fan:要不要使用 Flux 来返回;可以使用 Flux<AiChatMessageRespVO> | ||||||
|  |     @Operation(summary = "发送消息(流式)", description = "流式返回,响应较快") | ||||||
|  |     @PostMapping(value = "/send-stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE) | ||||||
|  |     public SseEmitter sendMessageStream(@Validated @ModelAttribute AiChatMessageSendReqVO sendReqVO) { | ||||||
|  |         Utf8SseEmitter sseEmitter = new Utf8SseEmitter(); | ||||||
|  |         chatService.chatStream(sendReqVO, sseEmitter); | ||||||
|  |         return sseEmitter; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Operation(summary = "获得指定会话的消息列表") | ||||||
|  |     @GetMapping("/list-by-conversation-id") | ||||||
|  |     @Parameter(name = "conversationId", required = true, description = "会话编号", example = "1024") | ||||||
|  |     public CommonResult<List<AiChatMessageRespVO>> getMessageListByConversationId(@RequestParam("conversationId") Long conversationId) { | ||||||
|  |         return success(null); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Operation(summary = "删除消息") | ||||||
|  |     @DeleteMapping("/delete") | ||||||
|  |     @Parameter(name = "id", required = true, description = "消息编号", example = "1024") | ||||||
|  |     public CommonResult<Boolean> delete(@RequestParam("id") Long id) { | ||||||
|  |         return success(null); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -0,0 +1,37 @@ | |||||||
|  | package cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message; | ||||||
|  |  | ||||||
|  | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  | import lombok.Data; | ||||||
|  |  | ||||||
|  | @Schema(description = "管理后台 - AI 聊天消息 Response VO") | ||||||
|  | @Data | ||||||
|  | public class AiChatMessageRespVO { | ||||||
|  |  | ||||||
|  |     @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | ||||||
|  |     private Long id; | ||||||
|  |  | ||||||
|  |     @Schema(description = "会话编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048") | ||||||
|  |     private Long conversationId; | ||||||
|  |  | ||||||
|  |     @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "role") | ||||||
|  |     private String type; // 参见 MessageType 枚举类 | ||||||
|  |  | ||||||
|  |     @Schema(description = "用户编号", example = "4096") | ||||||
|  |     private Long userId; // 仅当 user 发送时非空 | ||||||
|  |  | ||||||
|  |     @Schema(description = "角色编号", example = "888") | ||||||
|  |     private Long roleId; // 仅当 assistant 回复时非空 | ||||||
|  |  | ||||||
|  |     @Schema(description = "模型标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "gpt-3.5-turbo") | ||||||
|  |     private String model; // 参见 AiOpenAiModelEnum 枚举类 | ||||||
|  |  | ||||||
|  |     @Schema(description = "模型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123") | ||||||
|  |     private Long modelId; | ||||||
|  |  | ||||||
|  |     @Schema(description = "聊天内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "你好,你好啊") | ||||||
|  |     private String content; | ||||||
|  |  | ||||||
|  |     @Schema(description = "消耗 Token 数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "80") | ||||||
|  |     private Integer tokens; | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -0,0 +1,22 @@ | |||||||
|  | package cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message; | ||||||
|  |  | ||||||
|  | import io.swagger.v3.oas.annotations.media.Schema; | ||||||
|  | import jakarta.validation.constraints.NotEmpty; | ||||||
|  | import jakarta.validation.constraints.NotNull; | ||||||
|  | import jakarta.validation.constraints.Size; | ||||||
|  | import lombok.Data; | ||||||
|  | import lombok.experimental.Accessors; | ||||||
|  |  | ||||||
|  | @Schema(description = "管理后台 - AI 聊天消息发送 Request VO") | ||||||
|  | @Data | ||||||
|  | public class AiChatMessageSendReqVO { | ||||||
|  |  | ||||||
|  |     @Schema(description = "聊天对话编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | ||||||
|  |     @NotNull(message = "聊天对话编号不能为空") | ||||||
|  |     private Long conversationId; | ||||||
|  |  | ||||||
|  |     @Schema(description = "聊天内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "帮我写个 Java 算法") | ||||||
|  |     @NotEmpty(message = "聊天内容不能为空") | ||||||
|  |     private String content; | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -1 +0,0 @@ | |||||||
| package cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message; |  | ||||||
| @ -1,7 +1,7 @@ | |||||||
| package cn.iocoder.yudao.module.ai.convert; | package cn.iocoder.yudao.module.ai.convert; | ||||||
|  |  | ||||||
| import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO; | import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO; | ||||||
| import cn.iocoder.yudao.module.ai.vo.AiChatMessageListRes; | import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageRespVO; | ||||||
| import org.mapstruct.Mapper; | import org.mapstruct.Mapper; | ||||||
| import org.mapstruct.factory.Mappers; | import org.mapstruct.factory.Mappers; | ||||||
|  |  | ||||||
| @ -25,5 +25,5 @@ public interface AiChatMessageConvert { | |||||||
|      * @param list |      * @param list | ||||||
|      * @return |      * @return | ||||||
|      */ |      */ | ||||||
|     List<AiChatMessageListRes> convert(List<AiChatMessageDO> list); |     List<AiChatMessageRespVO> convert(List<AiChatMessageDO> list); | ||||||
| } | } | ||||||
|  | |||||||
| @ -81,7 +81,7 @@ public class AiChatMessageDO extends BaseDO { | |||||||
|     /** |     /** | ||||||
|      * 消耗 Token 数量 |      * 消耗 Token 数量 | ||||||
|      */ |      */ | ||||||
|     private Integer usedTokens; |     private Integer tokens; | ||||||
|  |  | ||||||
|     // TODO 芋艿:是否作为上下文语料?use_context,待定 |     // TODO 芋艿:是否作为上下文语料?use_context,待定 | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,7 +0,0 @@ | |||||||
| package cn.iocoder.yudao.module.ai.dal; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * @author fansili |  | ||||||
|  * @time 2024/4/25 15:36 |  | ||||||
|  * @since 1.0 |  | ||||||
|  */ |  | ||||||
| @ -1,8 +1,7 @@ | |||||||
| package cn.iocoder.yudao.module.ai.service; | package cn.iocoder.yudao.module.ai.service; | ||||||
|  |  | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
| import cn.iocoder.yudao.module.ai.vo.AiChatMessageListRes; | import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageRespVO; | ||||||
| import cn.iocoder.yudao.module.ai.vo.AiChatMessageReq; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * chat message |  * chat message | ||||||
| @ -19,7 +18,7 @@ public interface AiChatMessageService { | |||||||
|      * @param req |      * @param req | ||||||
|      * @return |      * @return | ||||||
|      */ |      */ | ||||||
|     PageResult<AiChatMessageListRes> list(AiChatMessageReq req); |     PageResult<AiChatMessageRespVO> list(AiChatMessageReq req); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * message - 删除 |      * message - 删除 | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| package cn.iocoder.yudao.module.ai.service; | package cn.iocoder.yudao.module.ai.service; | ||||||
|  |  | ||||||
| import cn.iocoder.yudao.module.ai.controller.Utf8SseEmitter; | import cn.iocoder.yudao.module.ai.controller.Utf8SseEmitter; | ||||||
| import cn.iocoder.yudao.module.ai.vo.AiChatReq; | import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 聊天 chat |  * 聊天 chat | ||||||
| @ -18,7 +18,7 @@ public interface AiChatService { | |||||||
|      * @param req |      * @param req | ||||||
|      * @return |      * @return | ||||||
|      */ |      */ | ||||||
|     String chat(AiChatReq req); |     String chat(AiChatMessageSendReqVO req); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * chat stream |      * chat stream | ||||||
| @ -27,5 +27,5 @@ public interface AiChatService { | |||||||
|      * @param sseEmitter |      * @param sseEmitter | ||||||
|      * @return |      * @return | ||||||
|      */ |      */ | ||||||
|     void chatStream(AiChatReq req, Utf8SseEmitter sseEmitter); |     void chatStream(AiChatMessageSendReqVO req, Utf8SseEmitter sseEmitter); | ||||||
| } | } | ||||||
|  | |||||||
| @ -11,8 +11,7 @@ import cn.iocoder.yudao.module.ai.dal.dataobject.chat.AiChatMessageDO; | |||||||
| import cn.iocoder.yudao.module.ai.mapper.AiChatConversationMapper; | import cn.iocoder.yudao.module.ai.mapper.AiChatConversationMapper; | ||||||
| import cn.iocoder.yudao.module.ai.mapper.AiChatMessageMapper; | import cn.iocoder.yudao.module.ai.mapper.AiChatMessageMapper; | ||||||
| import cn.iocoder.yudao.module.ai.service.AiChatMessageService; | import cn.iocoder.yudao.module.ai.service.AiChatMessageService; | ||||||
| import cn.iocoder.yudao.module.ai.vo.AiChatMessageListRes; | import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageRespVO; | ||||||
| import cn.iocoder.yudao.module.ai.vo.AiChatMessageReq; |  | ||||||
| import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||||
| @ -35,7 +34,7 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { | |||||||
|     private final AiChatConversationMapper aiChatConversationMapper; |     private final AiChatConversationMapper aiChatConversationMapper; | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public PageResult<AiChatMessageListRes> list(AiChatMessageReq req) { |     public PageResult<AiChatMessageRespVO> list(AiChatMessageReq req) { | ||||||
|         // 查询 |         // 查询 | ||||||
|         LambdaQueryWrapperX<AiChatMessageDO> queryWrapperX = new LambdaQueryWrapperX<>(); |         LambdaQueryWrapperX<AiChatMessageDO> queryWrapperX = new LambdaQueryWrapperX<>(); | ||||||
|         queryWrapperX.eq(AiChatMessageDO::getConversationId, req.getChatConversationId()); |         queryWrapperX.eq(AiChatMessageDO::getConversationId, req.getChatConversationId()); | ||||||
| @ -43,7 +42,7 @@ public class AiChatMessageServiceImpl implements AiChatMessageService { | |||||||
|         queryWrapperX.orderByDesc(AiChatMessageDO::getId); |         queryWrapperX.orderByDesc(AiChatMessageDO::getId); | ||||||
|         PageResult<AiChatMessageDO> pageResult = aiChatMessageMapper.selectPage(req, queryWrapperX); |         PageResult<AiChatMessageDO> pageResult = aiChatMessageMapper.selectPage(req, queryWrapperX); | ||||||
|         // 转换 res |         // 转换 res | ||||||
|         List<AiChatMessageListRes> messageListResList = AiChatMessageConvert.INSTANCE.convert(pageResult.getList()); |         List<AiChatMessageRespVO> messageListResList = AiChatMessageConvert.INSTANCE.convert(pageResult.getList()); | ||||||
|         return new PageResult(messageListResList, pageResult.getTotal()); |         return new PageResult(messageListResList, pageResult.getTotal()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ import cn.iocoder.yudao.module.ai.mapper.AiChatRoleMapper; | |||||||
| import cn.iocoder.yudao.module.ai.service.AiChatConversationService; | import cn.iocoder.yudao.module.ai.service.AiChatConversationService; | ||||||
| import cn.iocoder.yudao.module.ai.service.AiChatService; | import cn.iocoder.yudao.module.ai.service.AiChatService; | ||||||
| import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationRespVO; | import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.conversation.AiChatConversationRespVO; | ||||||
| import cn.iocoder.yudao.module.ai.vo.AiChatReq; | import cn.iocoder.yudao.module.ai.controller.admin.chat.vo.message.AiChatMessageSendReqVO; | ||||||
| import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||||
| import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||||
| import org.springframework.http.MediaType; | import org.springframework.http.MediaType; | ||||||
| @ -53,7 +53,7 @@ public class AiChatServiceImpl implements AiChatService { | |||||||
|      * @return |      * @return | ||||||
|      */ |      */ | ||||||
|     @Transactional(rollbackFor = Exception.class) |     @Transactional(rollbackFor = Exception.class) | ||||||
|     public String chat(AiChatReq req) { |     public String chat(AiChatMessageSendReqVO req) { | ||||||
|         Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); |         Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); | ||||||
|         // 获取 client 类型 |         // 获取 client 类型 | ||||||
|         AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(req.getModal()); |         AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(req.getModal()); | ||||||
| @ -83,7 +83,7 @@ public class AiChatServiceImpl implements AiChatService { | |||||||
|         return content; |         return content; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void saveChatMessage(AiChatReq req, AiChatConversationRespVO conversationRes, Long loginUserId) { |     private void saveChatMessage(AiChatMessageSendReqVO req, AiChatConversationRespVO conversationRes, Long loginUserId) { | ||||||
|         Long chatConversationId = conversationRes.getId(); |         Long chatConversationId = conversationRes.getId(); | ||||||
|         // 增加 chat message 记录 |         // 增加 chat message 记录 | ||||||
|         aiChatMessageMapper.insert( |         aiChatMessageMapper.insert( | ||||||
| @ -101,7 +101,7 @@ public class AiChatServiceImpl implements AiChatService { | |||||||
|         aiChatConversationMapper.updateIncrChatCount(req.getConversationId()); |         aiChatConversationMapper.updateIncrChatCount(req.getConversationId()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void saveSystemChatMessage(AiChatReq req, AiChatConversationRespVO conversationRes, Long loginUserId, String systemPrompts) { |     public void saveSystemChatMessage(AiChatMessageSendReqVO req, AiChatConversationRespVO conversationRes, Long loginUserId, String systemPrompts) { | ||||||
|         Long chatConversationId = conversationRes.getId(); |         Long chatConversationId = conversationRes.getId(); | ||||||
|         // 增加 chat message 记录 |         // 增加 chat message 记录 | ||||||
|         aiChatMessageMapper.insert( |         aiChatMessageMapper.insert( | ||||||
| @ -128,7 +128,7 @@ public class AiChatServiceImpl implements AiChatService { | |||||||
|      * @return |      * @return | ||||||
|      */ |      */ | ||||||
|     @Override |     @Override | ||||||
|     public void chatStream(AiChatReq req, Utf8SseEmitter sseEmitter) { |     public void chatStream(AiChatMessageSendReqVO req, Utf8SseEmitter sseEmitter) { | ||||||
|         Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); |         Long loginUserId = SecurityFrameworkUtils.getLoginUserId(); | ||||||
|         // 获取 client 类型 |         // 获取 client 类型 | ||||||
|         AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(req.getModal()); |         AiPlatformEnum platformEnum = AiPlatformEnum.valueOfPlatform(req.getModal()); | ||||||
|  | |||||||
| @ -1,28 +0,0 @@ | |||||||
| package cn.iocoder.yudao.module.ai.vo; |  | ||||||
|  |  | ||||||
| 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 message list req |  | ||||||
|  * |  | ||||||
|  * @author fansili |  | ||||||
|  * @time 2024/4/14 16:12 |  | ||||||
|  * @since 1.0 |  | ||||||
|  */ |  | ||||||
| @Data |  | ||||||
| @Accessors(chain = true) |  | ||||||
| public class AiChatMessageDeleteReq extends PageParam { |  | ||||||
|  |  | ||||||
|     @Schema(description = "id") |  | ||||||
|     @NotNull |  | ||||||
|     private Long id; |  | ||||||
|  |  | ||||||
|     @Schema(description = "聊天ID,关联到特定的会话或对话") |  | ||||||
|     @NotNull |  | ||||||
|     private Long chatConversationId; |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @ -1,42 +0,0 @@ | |||||||
| package cn.iocoder.yudao.module.ai.vo; |  | ||||||
|  |  | ||||||
| import io.swagger.v3.oas.annotations.media.Schema; |  | ||||||
| import lombok.Data; |  | ||||||
| import lombok.experimental.Accessors; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * 看板 message list req |  | ||||||
|  * |  | ||||||
|  * @author fansili |  | ||||||
|  * @time 2024/4/24 17:28 |  | ||||||
|  * @since 1.0 |  | ||||||
|  */ |  | ||||||
| @Data |  | ||||||
| @Accessors(chain = true) |  | ||||||
| public class AiChatMessageListRes { |  | ||||||
|  |  | ||||||
|     @Schema(description = "编号") |  | ||||||
|     private Long id; |  | ||||||
|  |  | ||||||
|     @Schema(description = "聊天ID,关联到特定的会话或对话") |  | ||||||
|     private Long chatConversationId; |  | ||||||
|  |  | ||||||
|     @Schema(description = "角色ID,用于标识发送消息的用户或系统的身份") |  | ||||||
|     private Long userId; |  | ||||||
|  |  | ||||||
|     @Schema(description = "消息具体内容,存储用户的发言或者系统响应的文字信息") |  | ||||||
|     private String message; |  | ||||||
|  |  | ||||||
|     @Schema(description = "消息类型,枚举值可能包括'system'(系统消息)、'user'(用户消息)和'assistant'(助手消息)") |  | ||||||
|     private String messageType; |  | ||||||
|  |  | ||||||
|     @Schema(description = "在生成消息时采用的Top-K采样大小") |  | ||||||
|     private Double topK; |  | ||||||
|  |  | ||||||
|     @Schema(description = "Top-P核采样方法的概率阈值") |  | ||||||
|     private Double topP; |  | ||||||
|  |  | ||||||
|     @Schema(description = "温度参数,用于调整生成回复的随机性和多样性程度,") |  | ||||||
|     private Double temperature; |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @ -1,24 +0,0 @@ | |||||||
| package cn.iocoder.yudao.module.ai.vo; |  | ||||||
|  |  | ||||||
| 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 message list req |  | ||||||
|  * |  | ||||||
|  * @author fansili |  | ||||||
|  * @time 2024/4/14 16:12 |  | ||||||
|  * @since 1.0 |  | ||||||
|  */ |  | ||||||
| @Data |  | ||||||
| @Accessors(chain = true) |  | ||||||
| public class AiChatMessageReq extends PageParam { |  | ||||||
|  |  | ||||||
|     @Schema(description = "聊天ID,关联到特定的会话或对话") |  | ||||||
|     @NotNull |  | ||||||
|     private Long chatConversationId; |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @ -1,48 +0,0 @@ | |||||||
| package cn.iocoder.yudao.module.ai.vo; |  | ||||||
|  |  | ||||||
| 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; |  | ||||||
|  |  | ||||||
| /** |  | ||||||
|  * chat req |  | ||||||
|  * |  | ||||||
|  * @author fansili |  | ||||||
|  * @time 2024/4/14 16:12 |  | ||||||
|  * @since 1.0 |  | ||||||
|  */ |  | ||||||
| @Data |  | ||||||
| @Accessors(chain = true) |  | ||||||
| public class AiChatReq { |  | ||||||
|  |  | ||||||
|     @Schema(description = "ai模型(查看 AiClientNameEnum)") |  | ||||||
|     @NotNull(message = "模型不能为空!") |  | ||||||
|     @Size(max = 30, message = "模型字符最大 30个字符!") |  | ||||||
|     private String modal; |  | ||||||
|  |  | ||||||
|     @Schema(description = "对话Id") |  | ||||||
|     @NotNull(message = "对话id不能为空") |  | ||||||
|     private Long conversationId; |  | ||||||
|  |  | ||||||
|     @Schema(description = "chat角色模板") |  | ||||||
|     private Long chatRoleId; |  | ||||||
|  |  | ||||||
|     @NotNull(message = "提示词不能为空!") |  | ||||||
|     @Size(max = 5000, message = "提示词最大5000个字符!") |  | ||||||
|     @Schema(description = "填入固定值,1 issues, 2 pr") |  | ||||||
|     private String prompt; |  | ||||||
|  |  | ||||||
|     @Schema(description = "用于控制随机性和多样性的温度参数") |  | ||||||
|     private Double temperature; |  | ||||||
|  |  | ||||||
|     @Schema(description = "生成时,核采样方法的概率阈值。例如,取值为0.8时,仅保留累计概率之和大于等于0.8的概率分布中的token,\n" + |  | ||||||
|             "     * 作为随机采样的候选集。取值范围为(0,1.0),取值越大,生成的随机性越高;取值越低,生成的随机性越低。\n" + |  | ||||||
|             "     * 默认值为0.8。注意,取值不要大于等于1\n") |  | ||||||
|     private Double topP; |  | ||||||
|  |  | ||||||
|     @Schema(description = "在生成消息时采用的Top-K采样大小,表示模型生成回复时考虑的候选项集合的大小") |  | ||||||
|     private Double topK; |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @ -1,21 +0,0 @@ | |||||||
| package cn.iocoder.yudao.module.ai.vo; |  | ||||||
|  |  | ||||||
| import cn.iocoder.yudao.module.ai.enums.AiOpenAiModelEnum; |  | ||||||
| import io.swagger.v3.oas.annotations.media.Schema; |  | ||||||
| import jakarta.validation.constraints.NotNull; |  | ||||||
| import lombok.Data; |  | ||||||
|  |  | ||||||
| // TODO done @fansili 1)swagger 注释不太对;2)有了 swagger 注释,就不用类注释了 |  | ||||||
| @Data |  | ||||||
| @Schema(description = "用户 App - 上传文件 Request VO") |  | ||||||
| public class AiChatReqVO { |  | ||||||
|  |  | ||||||
|     @Schema(description = "提示词", requiredMode = Schema.RequiredMode.REQUIRED) |  | ||||||
|     @NotNull(message = "提示词不能为空!") |  | ||||||
|     private String prompt; |  | ||||||
|  |  | ||||||
|     @Schema(description = "AI模型", requiredMode = Schema.RequiredMode.REQUIRED) |  | ||||||
|     @NotNull(message = "AI模型不能为空") |  | ||||||
|     private AiOpenAiModelEnum aiModel; |  | ||||||
|  |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user
	 zhijiantianya@gmail.com
					zhijiantianya@gmail.com