package com.xly.entity; import cn.hutool.core.util.StrUtil; import com.xly.constant.ErrorCode; import com.xly.constant.ReturnTypeCode; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; import java.util.List; import java.util.Map; /** * TTS响应数据传输对象 * 增强版:支持流式处理 */ @Data @Builder @NoArgsConstructor @AllArgsConstructor public class AiResponseDTO implements Serializable { private static final long serialVersionUID = 1L; // ============ 原有字段 ============ /** * AI文字部分 */ private String aiText; /** * 系统拼接返回的文字部分 */ private String systemText; /** * 业务场景名称 */ private String sSceneName; /** * 业务方法名称 */ private String sMethodName; /** * 返回类型,默认MARKDOWN */ private String sReturnType = ReturnTypeCode.MAKEDOWN.getCode(); // ============ 新增字段:流式处理支持 ============ /** * 请求ID,用于追踪整个流式请求 */ private String requestId; /** * 响应码 */ private Integer code; /** * 响应消息 */ private String message; /** * 处理状态:PROCESSING, COMPLETED, FAILED */ private String status; /** * 当前处理的块编号(从0开始) */ private Integer chunkIndex; /** * 总块数 */ private Integer totalChunks; /** * 是否是最后一块 */ private Boolean isLastChunk; /** * 文本片段(用于流式传输) * 当aiText过大时,可以分段传输 */ private String textFragment; /** * 系统文本片段(用于流式传输) */ private String systemTextFragment; /** * 累积的完整AI文本(仅在最后一块时返回) */ private String fullAiText; /** * 累积的完整系统文本(仅在最后一块时返回) */ private String fullSystemText; /** * 处理进度(0-100) */ private Integer progress; /** * 时间戳 */ private Long timestamp; /** * 处理耗时(毫秒) */ private Long elapsedTime; /** * 扩展字段,用于存储额外的元数据 */ private Map metadata; /** * 错误信息(当status=FAILED时) */ private String errorMessage; /** * 错误码(当status=FAILED时) */ private String errorCode; /** * 数据库类型 X: 向量库 S:数据库 */ private String dbType; /** * 数据库类型 H: 缓存 D: 动态 */ private String dbCach; /*** * @Author 钱豹 * @Date 15:15 2026/4/14 * @Param * @return * @Description 操作未清类型 **/ private String sCopyTo; /*** * @Author 钱豹 * @Date 15:16 2026/4/14 * @Param * @return * @Description 未清记录ID **/ private String sCopyToSrcId; // ============ 便捷方法 ============ /** * 判断是否处理成功 */ public boolean isSuccess() { return code != null && code == 200; } /** * 判断是否处理中 */ public boolean isProcessing() { return "PROCESSING".equals(status); } /** * 判断是否已完成 */ public boolean isCompleted() { return "COMPLETED".equals(status); } /** * 判断是否失败 */ public boolean isFailed() { return "FAILED".equals(status); } /** * 获取完整的文本(AI文本 + 系统文本) */ public String getFullText() { StringBuilder sb = new StringBuilder(); if (StrUtil.isNotBlank(aiText)) { sb.append(aiText); } if (StrUtil.isNotBlank(systemText)) { sb.append(systemText); } return sb.toString(); } /** * 创建处理中的响应 */ public static AiResponseDTO processing(String requestId, String textFragment, Integer chunkIndex, Integer totalChunks) { return AiResponseDTO.builder() .requestId(requestId) .code(200) .message("Processing") .status("PROCESSING") .textFragment(textFragment) .chunkIndex(chunkIndex) .totalChunks(totalChunks) .timestamp(System.currentTimeMillis()) .progress(calculateProgress(chunkIndex, totalChunks)) .build(); } /** * 创建完成响应 */ public static AiResponseDTO completed(String requestId, String fullAiText, String fullSystemText, String sSceneName, String sMethodName, String sReturnType) { return AiResponseDTO.builder() .requestId(requestId) .code(200) .message("Completed") .status("COMPLETED") .fullAiText(fullAiText) .fullSystemText(fullSystemText) .aiText(fullAiText) .systemText(fullSystemText) .sSceneName(sSceneName) .sMethodName(sMethodName) .sReturnType(sReturnType) .progress(100) .timestamp(System.currentTimeMillis()) .isLastChunk(true) .build(); } /** * 创建失败响应 */ public static AiResponseDTO failed(String requestId, String errorMessage, String errorCode) { return AiResponseDTO.builder() .requestId(requestId) .code(500) .message("Failed") .status("FAILED") .errorMessage(errorMessage) .errorCode(errorCode) .timestamp(System.currentTimeMillis()) .build(); } /** * 计算进度 */ private static Integer calculateProgress(Integer chunkIndex, Integer totalChunks) { if (chunkIndex == null || totalChunks == null || totalChunks == 0) { return 0; } return (int) ((chunkIndex + 1) * 100.0 / totalChunks); } }