AiResponseDTO.java 6.32 KB
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<String, Object> 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);
    }
}