package com.ai.da.common.RabbitMQ;

import com.ai.da.common.config.exception.BusinessException;
import com.ai.da.common.constant.CommonConstant;
import com.ai.da.common.utils.RedisUtil;
import com.ai.da.model.dto.GenerateThroughImageTextDTO;
import com.ai.da.model.vo.GenerateResultVO;
import com.ai.da.model.vo.PoseTransformationVO;
import com.ai.da.service.*;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.rabbitmq.client.Channel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.StringEscapeUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;


@Slf4j
@Component
@RequiredArgsConstructor
public class GenerateConsumer {

    private final GenerateService generateService;

    private final UserLikeGroupService userLikeGroupService;

    private final DesignService designService;

    private final CloudTaskService cloudTaskService;

    private final RabbitMQProperties rabbitMQProperties;

    private final RedisUtil redisUtil;

    private final MessageCenterService messageCenterService;

    @Value("${redis.key.orderForGenerate}")
    private String consumptionOrderKey;

    @Value("${redis.key.generateCancelSet}")
    private String cancelSetKey;

    @Value("${redis.key.generateExceptionMap}")
    private String exceptionMapKey;

    @Value("${redis.key.generateResult}")
    private String generateResultKey;
    @Value("${redis.key.toProductImageResultKey}")
    private String toProductImageResultKey;
    @Value("${redis.key.relightResultKey}")
    private String relightResultKey;

    public void generate(Message msg, Channel channel, String consumerName) {
        log.info("============start listening==========");
        long start = System.currentTimeMillis();
        Map<String, String> resp = jsonBytesToMap(msg, channel);
        String uniqueId = resp.get("tasks_id");
//        String uniqueId = generateThroughImageTextDTO.getUniqueId();
        log.info("From " + consumerName + " : " + uniqueId);

        try {
            // 2、判断当前消息是否在取消列表中
            Boolean isMember = redisUtil.isElementExistsInSet(cancelSetKey, uniqueId);
            if (isMember) {
                try {
                    // 2.1 手动确认该消息
                    channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
                } catch (IOException ex) {
                    log.error("手动确认，不返回队列重新消费");
                }
            } else {
                GenerateThroughImageTextDTO generateThroughImageTextDTO = JSONObject.parseObject(msg.getBody(), GenerateThroughImageTextDTO.class);
                generateService.generateThroughImageText(generateThroughImageTextDTO);
                // 将消息从redis排队队列中删除,需保证被消费的消息存储到db之后再从redis删除
                redisUtil.removeFromZSet(consumptionOrderKey, uniqueId);

            }
        } catch (Exception e) {
            log.error(e.getMessage());
            // channel.basicNack() 为不确认deliveryTag对应的消息，第二个参数是否应用于多消息，第三个参数是否requeue
            try {
                // 第二个参数，是否批量确认消息，当传false时，只确认当前 deliveryTag对应的消息;当传true时，会确认当前及之前所有未确认的消息。
                channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
                // 将消息从redis排队队列中删除,需保证被消费的消息存储到db之后再从redis删除
                redisUtil.removeFromZSet(consumptionOrderKey, uniqueId);
                String key = generateResultKey + ":" + uniqueId;
                GenerateResultVO generateResultVO = new GenerateResultVO(uniqueId, null, null, "Fail");
                redisUtil.addToString(key, new Gson().toJson(generateResultVO), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
            } catch (IOException exception) {
                log.error("手动确认，取消返回队列，不再重新消费");
            }
            // 将入参和错误信息存入数据库
            String exceptionMessage = JSONObject.toJSONString(resp) +
                    " Exception message ： " + e.getMessage();
            HashMap<String, String> exceptionInfo = new HashMap<>();
            exceptionInfo.put(String.valueOf(uniqueId), exceptionMessage);
            // 存redis
            redisUtil.addToMap(exceptionMapKey, exceptionInfo);
        }
        long end = System.currentTimeMillis();

        log.info(" task_id： " + uniqueId + "----------" + consumerName + " 执行时长：" + (end - start) + "毫秒");
        log.info("=============end listening===========");
    }

    public void processGenerateResult(Message msg, Channel channel) {
        log.info("============ProcessGenerateResult listening==========");
        long start = System.currentTimeMillis();

        Map<String, String> generateResult = jsonBytesToMap(msg, channel);
        log.info("generate response : {}", generateResult);

        try {
            log.info("tasks_id : {} start ", generateResult.get("tasks_id"));
            if (generateResult.get("status").equals("SUCCESS")) {
                String url = generateResult.get("image_url");
                String taskId = generateResult.get("tasks_id");
                String category = generateResult.get("category");
                generateService.processGenerateResult(taskId, url, category);
            } else {
                // 修改redis中的数据状态为exception
                String key = generateResultKey + ":" + generateResult.get("tasks_id");
                redisUtil.addToString(key, new Gson().toJson(new GenerateResultVO(generateResult.get("tasks_id"), null, null, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
                // 将异常信息存到exception中
                HashMap<String, String> exceptionInfo = new HashMap<>();
                exceptionInfo.put(generateResult.get("tasks_id"), generateResult.get("data"));
                // 存redis
                redisUtil.addToMap(exceptionMapKey, exceptionInfo);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            try {
                channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
                // 将消息从redis排队队列中删除,需保证被消费的消息存储到db之后再从redis删除
                redisUtil.removeFromZSet(consumptionOrderKey, generateResult.get("tasks_id"));
            } catch (IOException exception) {
                log.error("手动确认，取消返回队列，不再重新消费");
            }
            // 将入参和错误信息存入数据库
            String exceptionMessage = JSONObject.toJSONString(generateResult) +
                    " Exception message ： " + e.getMessage();
            HashMap<String, String> exceptionInfo = new HashMap<>();
            exceptionInfo.put(String.valueOf(generateResult.get("tasks_id")), exceptionMessage);
            // 存redis
            redisUtil.addToMap(exceptionMapKey, exceptionInfo);
        }

        long end = System.currentTimeMillis();
        log.info("tasks_id : {}, end , message : {}, 执行时长： {} 毫秒", generateResult.get("tasks_id"), generateResult.get("message"), (end - start));
        log.info("============ProcessGenerateResult End listening==========");

    }

    public void processToProductImageResult(Message msg, Channel channel) {
        log.info("============processToProductImageResult listening==========");
        long start = System.currentTimeMillis();

        Map<String, String> generateResult = jsonBytesToMap(msg, channel);
        log.info("toProductImage response : {}", generateResult);

        try {
            log.info("tasks_id : {} start ", generateResult.get("tasks_id"));
            if (generateResult.get("status").equals("SUCCESS")) {
                String url = generateResult.get("image_url");
                String taskId = generateResult.get("tasks_id");
                String category = generateResult.get("category");
                generateService.processToProductImageResult(taskId, url, category);
            } else if (generateResult.get("status").equals("NO_FACE")) {
                String taskId = generateResult.get("tasks_id");
                userLikeGroupService.toProduct(taskId);
            } else {
                // 修改redis中的数据状态为exception
                String key = toProductImageResultKey + ":" + generateResult.get("tasks_id");
                generateService.updateToProductTaskStatus(generateResult.get("tasks_id"), "Fail");
                redisUtil.addToString(key, new Gson().toJson(new GenerateResultVO(generateResult.get("tasks_id"), null, null, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
                // 将异常信息存到exception中
                HashMap<String, String> exceptionInfo = new HashMap<>();
                exceptionInfo.put(generateResult.get("tasks_id"), generateResult.get("data"));
                // 存redis
                redisUtil.addToMap(exceptionMapKey, exceptionInfo);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            try {
                channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
                // 将消息从redis排队队列中删除,需保证被消费的消息存储到db之后再从redis删除
                redisUtil.removeFromZSet(consumptionOrderKey, generateResult.get("tasks_id"));
            } catch (IOException exception) {
                log.error("手动确认，取消返回队列，不再重新消费");
            }
            // 将入参和错误信息存入数据库
            String exceptionMessage = JSONObject.toJSONString(generateResult) +
                    " Exception message ： " + e.getMessage();
            HashMap<String, String> exceptionInfo = new HashMap<>();
            exceptionInfo.put(String.valueOf(generateResult.get("tasks_id")), exceptionMessage);
            // 存redis
            redisUtil.addToMap(exceptionMapKey, exceptionInfo);
        }

        long end = System.currentTimeMillis();
        log.info("tasks_id : {}, end , message : {}, 执行时长： {} 毫秒", generateResult.get("tasks_id"), generateResult.get("message"), (end - start));
        log.info("============ProcessToProductImageResult End listening==========");
    }

    private void processRelightResult(Message msg, Channel channel) {
        log.info("============processRelightResult listening==========");
        long start = System.currentTimeMillis();

        Map<String, String> generateResult = jsonBytesToMap(msg, channel);
        log.info("toProductImage response : {}", generateResult);

        try {
            log.info("tasks_id : {} start ", generateResult.get("tasks_id"));
            if (generateResult.get("status").equals("SUCCESS")) {
                String url = generateResult.get("image_url");
                String taskId = generateResult.get("tasks_id");
                String category = generateResult.get("category");
                generateService.processRelightResult(taskId, url, category);
            } else if (generateResult.get("status").equals("NO_FACE")) {
                String taskId = generateResult.get("tasks_id");
                userLikeGroupService.relight(taskId);
            } else {
                // 修改redis中的数据状态为exception
                String key = relightResultKey + ":" + generateResult.get("tasks_id");
                generateService.updateToProductTaskStatus(generateResult.get("tasks_id"), "Fail");
                redisUtil.addToString(key, new Gson().toJson(new GenerateResultVO(generateResult.get("tasks_id"), null, null, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
                // 将异常信息存到exception中
                HashMap<String, String> exceptionInfo = new HashMap<>();
                exceptionInfo.put(generateResult.get("tasks_id"), generateResult.get("data"));
                // 存redis
                redisUtil.addToMap(exceptionMapKey, exceptionInfo);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            try {
                channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
                // 将消息从redis排队队列中删除,需保证被消费的消息存储到db之后再从redis删除
                redisUtil.removeFromZSet(consumptionOrderKey, generateResult.get("tasks_id"));
            } catch (IOException exception) {
                log.error("手动确认，取消返回队列，不再重新消费");
            }
            // 将入参和错误信息存入数据库
            String exceptionMessage = JSONObject.toJSONString(generateResult) +
                    " Exception message ： " + e.getMessage();
            HashMap<String, String> exceptionInfo = new HashMap<>();
            exceptionInfo.put(String.valueOf(generateResult.get("tasks_id")), exceptionMessage);
            // 存redis
            redisUtil.addToMap(exceptionMapKey, exceptionInfo);
        }

        long end = System.currentTimeMillis();
        log.info("tasks_id : {}, end , message : {}, 执行时长： {} 毫秒", generateResult.get("tasks_id"), generateResult.get("message"), (end - start));
        log.info("============ProcessRelightResult End listening==========");
    }

    public void processPoseTransformResult(Message msg, Channel channel) {
        log.info("============ProcessPoseTransformResult listening==========");
        long start = System.currentTimeMillis();

        Map<String, String> generateResult = jsonBytesToMap(msg, channel);
        log.info("PoseTransformation response : {}", generateResult);

        try {
            log.info("tasks_id : {} start ", generateResult.get("tasks_id"));
            if (generateResult.get("status").equals("SUCCESS")) {
                String gifUrl = generateResult.get("gif_url");
                String taskId = generateResult.get("tasks_id");
                String videoUrl = generateResult.get("video_url");
                String imageUrl = generateResult.get("image_url");
                generateService.processPoseTransformResult(taskId, gifUrl, videoUrl, imageUrl);
            } else {
                // 修改redis中的数据状态为exception
                String key = generateResultKey + ":" + generateResult.get("tasks_id");
                generateService.updatePoseTransferStatus(generateResult.get("tasks_id"), "Fail", null);
                redisUtil.addToString(key, new Gson().toJson(new PoseTransformationVO(null, generateResult.get("tasks_id"),null, null, null, (byte)0, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
                // 将异常信息存到exception中
                HashMap<String, String> exceptionInfo = new HashMap<>();
                exceptionInfo.put(generateResult.get("tasks_id"), generateResult.get("message"));
                // 存redis
                redisUtil.addToMap(exceptionMapKey, exceptionInfo);
                // 记录失败状态并向用户发送提示消息
                generateService.processPTFailSituation(generateResult.get("tasks_id"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            try {
                channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
                // 将消息从redis排队队列中删除,需保证被消费的消息存储到db之后再从redis删除
                redisUtil.removeFromZSet(consumptionOrderKey, generateResult.get("tasks_id"));
            } catch (IOException exception) {
                log.error("手动确认，取消返回队列，不再重新消费");
            }
            // 将入参和错误信息存入数据库
            String exceptionMessage = JSONObject.toJSONString(generateResult) +
                    " Exception message ： " + e.getMessage();
            HashMap<String, String> exceptionInfo = new HashMap<>();
            exceptionInfo.put(String.valueOf(generateResult.get("tasks_id")), exceptionMessage);
            // 存redis
            redisUtil.addToMap(exceptionMapKey, exceptionInfo);
            // 记录失败状态并向用户发送提示消息
            generateService.processPTFailSituation(generateResult.get("tasks_id"));
        }

        long end = System.currentTimeMillis();
        log.info("tasks_id : {}, end , message : {}, 执行时长： {} 毫秒", generateResult.get("tasks_id"), generateResult.get("message"), (end - start));
        log.info("============ProcessPoseTransformResult End listening==========");

    }

    public static Map<String, String> jsonBytesToMap(Message msg, Channel channel) {
        try {
            // 1. byte[] -> String
            String jsonString = new String(msg.getBody(), StandardCharsets.UTF_8).trim();
            // 2. 处理可能的双重转义
            if (jsonString.startsWith("\"") && jsonString.endsWith("\"")) {
                jsonString = jsonString.substring(1, jsonString.length() - 1);
                // 使用 Apache Commons Text， 将 JSON 字符串中的转义字符还原为原始字符
                jsonString = StringEscapeUtils.unescapeJson(jsonString);
            }
            // 3. 验证 JSON 格式
            if (!isValidJson(jsonString)) {
                throw new IllegalArgumentException("Invalid JSON format");
            }
            // 4. 解析为 Map
            ObjectMapper mapper = new ObjectMapper();
            return mapper.readValue(jsonString, new TypeReference<Map<String, String>>() {});
        } catch (Exception e) {
            log.error("消息解析失败: {}", e.getMessage(), e);
            try {
                // 仅对不可恢复错误（如非 JSON 数据）进行 ACK
                if (e instanceof JsonParseException || e instanceof IllegalArgumentException) {
                    channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
                    log.warn("因消息格式错误，已确认并丢弃消息。原始消息为：{}", msg);
                }
            } catch (IOException ex) {
                log.error("消息确认失败: {}", ex.getMessage(), ex);
            }
            throw new RuntimeException("Failed to parse JSON to Map", e);
        }
    }

    // 辅助方法：验证字符串是否为合法 JSON
    private static boolean isValidJson(String json) {
        try {
            new ObjectMapper().readTree(json);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    private void processDesignBatchResult(Message msg, Channel channel) {
        log.info("============processDesignBatchResult listening==========");
        long start = System.currentTimeMillis();

        Map<String, Object> generateResult = JSONObject.parseObject(msg.getBody(), Map.class);
        log.info("designBatch response : {}", generateResult);
        designService.processDesignBatch(generateResult);
    }

    private void processToProductImageBatchResult(Message msg, Channel channel) {
        log.info("============processToProductImageResultBatch listening==========");
        long start = System.currentTimeMillis();

        JSONObject generateResult = JSONObject.parseObject(msg.getBody(), JSONObject.class);
        log.info("toProductImageBatch response : {}", generateResult);

        try {
            log.info("task_id : {} start ", generateResult.get("task_id"));
            if (!StringUtils.isEmpty(generateResult.getString("progress"))) {
                String progress = generateResult.getString("progress");
                String url = null;
                if (!progress.startsWith("0") && !progress.equals("OK")) {
                    JSONObject result = generateResult.getJSONObject("result");
                    if (Objects.nonNull(result)) {
                        url = result.getString("product_img");
                        String taskId = generateResult.getString("task_id");
                        userLikeGroupService.toProductBatch(taskId, url, progress);
                    }
                } else if (progress.startsWith("0/")) {
                    String batchTaskId = generateResult.getString("task_id");
                    if (!StringUtils.isEmpty(batchTaskId)) {
                        cloudTaskService.startTask(batchTaskId);
                    }
                } else if (progress.equals("OK")) {
                    String batchTaskId = generateResult.getString("task_id");
                    if (!StringUtils.isEmpty(batchTaskId)) {
                        cloudTaskService.completeTask(batchTaskId);
                    }
                }
            } else {
                // 修改redis中的数据状态为exception
                String key = toProductImageResultKey + ":" + generateResult.get("task_id");
                generateService.updateToProductTaskStatus(generateResult.getString("task_id"), "Fail");
                redisUtil.addToString(key, new Gson().toJson(new GenerateResultVO(generateResult.getString("tasks_id"), null, null, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
                // 将异常信息存到exception中
                HashMap<String, String> exceptionInfo = new HashMap<>();
                exceptionInfo.put(generateResult.getString("task_id"), generateResult.getString("data"));
                // 存redis
                redisUtil.addToMap(exceptionMapKey, exceptionInfo);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            try {
                channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
                // 将消息从redis排队队列中删除,需保证被消费的消息存储到db之后再从redis删除
                redisUtil.removeFromZSet(consumptionOrderKey, generateResult.getString("task_id"));
            } catch (IOException exception) {
                log.error("手动确认，取消返回队列，不再重新消费");
            }
            // 将入参和错误信息存入数据库
            String exceptionMessage = JSONObject.toJSONString(generateResult) +
                    " Exception message ： " + e.getMessage();
            HashMap<String, String> exceptionInfo = new HashMap<>();
            exceptionInfo.put(String.valueOf(generateResult.get("task_id")), exceptionMessage);
            // 存redis
            redisUtil.addToMap(exceptionMapKey, exceptionInfo);
        }

        long end = System.currentTimeMillis();
        log.info("task_id : {}, end , message : {}, 执行时长： {} 毫秒", generateResult.get("task_id"), generateResult.get("message"), (end - start));
        log.info("============ProcessToProductImageBatchResult End listening==========");
    }

    private void processRelightBatchResult(Message msg, Channel channel) {
        log.info("============processRelightResult listening==========");
        long start = System.currentTimeMillis();

        JSONObject generateResult = JSONObject.parseObject(msg.getBody(), JSONObject.class);
        log.info("relightBatch response : {}", generateResult);

        try {
            log.info("task_id : {} start ", generateResult.get("task_id"));
            if (!StringUtils.isEmpty(generateResult.getString("progress"))) {
                String progress = generateResult.getString("progress");
                String url = null;
                if (!progress.startsWith("0") && !progress.equals("OK")) {
                    JSONObject result = generateResult.getJSONObject("result");
                    if (Objects.nonNull(result)) {
                        url = result.getString("relight_img");
                        String taskId = generateResult.getString("task_id");
                        userLikeGroupService.relightBatch(taskId, url, progress);
                    }
                } else if (progress.startsWith("0/")) {
                    String batchTaskId = generateResult.getString("task_id");
                    if (!StringUtils.isEmpty(batchTaskId)) {
                        cloudTaskService.startTask(batchTaskId);
                    }
                } else if (progress.equals("OK")) {
                    String batchTaskId = generateResult.getString("task_id");
                    if (!StringUtils.isEmpty(batchTaskId)) {
                        cloudTaskService.completeTask(batchTaskId);
                    }
                }
            } else {
                // 修改redis中的数据状态为exception
                String key = relightResultKey + ":" + generateResult.get("task_id");
                generateService.updateToProductTaskStatus(generateResult.getString("task_id"), "Fail");
                redisUtil.addToString(key, new Gson().toJson(new GenerateResultVO(generateResult.getString("tasks_id"), null, null, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
                // 将异常信息存到exception中
                HashMap<String, String> exceptionInfo = new HashMap<>();
                exceptionInfo.put(generateResult.getString("task_id"), generateResult.getString("data"));
                // 存redis
                redisUtil.addToMap(exceptionMapKey, exceptionInfo);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            try {
                channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
                // 将消息从redis排队队列中删除,需保证被消费的消息存储到db之后再从redis删除
                redisUtil.removeFromZSet(consumptionOrderKey, generateResult.getString("task_id"));
            } catch (IOException exception) {
                log.error("手动确认，取消返回队列，不再重新消费");
            }
            // 将入参和错误信息存入数据库
            String exceptionMessage = JSONObject.toJSONString(generateResult) +
                    " Exception message ： " + e.getMessage();
            HashMap<String, String> exceptionInfo = new HashMap<>();
            exceptionInfo.put(String.valueOf(generateResult.get("task_id")), exceptionMessage);
            // 存redis
            redisUtil.addToMap(exceptionMapKey, exceptionInfo);
        }

        long end = System.currentTimeMillis();
        log.info("task_id : {}, end , message : {}, 执行时长： {} 毫秒", generateResult.get("task_id"), generateResult.get("message"), (end - start));
        log.info("============ProcessRelightBatchResult End listening==========");
    }

    private void processPoseTransformBatchResult(Message msg, Channel channel) {
        log.info("============ProcessPoseTransformBatchResult listening==========");
        long start = System.currentTimeMillis();

        JSONObject generateResult = JSONObject.parseObject(msg.getBody(), JSONObject.class);
        log.info("PoseTransformationBatch response : {}", generateResult);

        try {
            log.info("task_id : {} start ", generateResult.get("task_id"));
            if (!StringUtils.isEmpty(generateResult.getString("progress"))) {
                String progress = generateResult.getString("progress");
                String taskId = generateResult.getString("task_id");
                generateService.processPoseTransformResultBatch(progress, taskId);

                JSONArray result = generateResult.getJSONArray("result");
                if (!StringUtils.isEmpty(result)) {
                    JSONObject jsonObject = result.getJSONObject(0);
                    String gifUrl = jsonObject.getString("gif_url");
                    String videoUrl = jsonObject.getString("video_url");
                    String imageUrl = jsonObject.getString("first_image_url");
                    generateService.processPoseTransformResultBatch(taskId, gifUrl, videoUrl, imageUrl, progress);
                }
            } else {
                // 修改redis中的数据状态为exception
                String key = generateResultKey + ":" + generateResult.getString("task_id");
                generateService.updatePoseTransferStatus(generateResult.getString("task_id"), "Fail", null);
                redisUtil.addToString(key, new Gson().toJson(new PoseTransformationVO(null, generateResult.getString("task_id"),null, null, null, (byte)0, "Fail")), CommonConstant.GENERATE_RESULT_EXPIRE_TIME);
                // 将异常信息存到exception中
                HashMap<String, String> exceptionInfo = new HashMap<>();
                exceptionInfo.put(generateResult.getString("task_id"), generateResult.getString("message"));
                // 存redis
                redisUtil.addToMap(exceptionMapKey, exceptionInfo);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            try {
                channel.basicAck(msg.getMessageProperties().getDeliveryTag(), false);
                // 将消息从redis排队队列中删除,需保证被消费的消息存储到db之后再从redis删除
                redisUtil.removeFromZSet(consumptionOrderKey, generateResult.getString("task_id"));
            } catch (IOException exception) {
                log.error("手动确认，取消返回队列，不再重新消费");
            }
            // 将入参和错误信息存入数据库
            String exceptionMessage = JSONObject.toJSONString(generateResult) +
                    " Exception message ： " + e.getMessage();
            HashMap<String, String> exceptionInfo = new HashMap<>();
            exceptionInfo.put(generateResult.getString("task_id"), exceptionMessage);
            // 存redis
            redisUtil.addToMap(exceptionMapKey, exceptionInfo);
        }

        long end = System.currentTimeMillis();
        log.info("tasks_id : {}, end , message : {}, 执行时长： {} 毫秒", generateResult.get("tasks_id"), generateResult.get("message"), (end - start));
        log.info("============ProcessPoseTransformResult End listening==========");
    }

    @RabbitListener(queues = "#{rabbitMQProperties.queues.generate}")
    @RabbitHandler
    public void generateConsumer1(Message msg, Channel channel) {
        generate(msg, channel, "consumer 1");
    }

    @RabbitListener(queues = "#{rabbitMQProperties.queues.generate}")
    @RabbitHandler
    public void generateConsumer2(Message msg, Channel channel) {
        generate(msg, channel, "consumer 2");
    }

    @RabbitListener(queues = "#{rabbitMQProperties.queues.generate}")
    @RabbitHandler
    public void generateConsumer3(Message msg, Channel channel) {
        generate(msg, channel, "consumer 3");
    }

    @RabbitListener(queues = "#{rabbitMQProperties.queues.generate}")
    @RabbitHandler
    public void generateConsumer4(Message msg, Channel channel) {
        generate(msg, channel, "consumer 4");
    }

    @RabbitListener(queues = "#{rabbitMQProperties.queues.generate}")
    @RabbitHandler
    public void generateConsumer5(Message msg, Channel channel) {
        generate(msg, channel, "consumer 5");
    }

    @RabbitListener(queues = "#{rabbitMQProperties.queues.generate}")
    @RabbitHandler
    public void generateConsumer6(Message msg, Channel channel) {
        generate(msg, channel, "consumer 6");
    }

    @RabbitListener(queues = "#{rabbitMQProperties.queues.generate}")
    @RabbitHandler
    public void generateConsumer7(Message msg, Channel channel) {
        generate(msg, channel, "consumer 7");
    }

    @RabbitListener(queues = "#{rabbitMQProperties.queues.generate}")
    @RabbitHandler
    public void generateConsumer8(Message msg, Channel channel) {
        generate(msg, channel, "consumer 8");
    }

    @RabbitListener(queues = "#{rabbitMQProperties.queues.generate}")
    @RabbitHandler
    public void generateConsumer9(Message msg, Channel channel) {
        generate(msg, channel, "consumer 9");
    }

    @RabbitListener(queues = "#{rabbitMQProperties.queues.generateResult}")
    @RabbitHandler
    public void getGenerateResult(Message msg, Channel channel) {
        processGenerateResult(msg, channel);
    }

    @RabbitListener(queues = "#{rabbitMQProperties.queues.toProductImageResult}")
    @RabbitHandler
    public void getToProductImageResult(Message msg, Channel channel) {
        processToProductImageResult(msg, channel);
    }

    @RabbitListener(queues = "#{rabbitMQProperties.queues.relightResult}")
    @RabbitHandler
    public void getRelightResult(Message msg, Channel channel) {
        processRelightResult(msg, channel);
    }

    @RabbitListener(queues = "#{rabbitMQProperties.queues.poseTransform}")
    @RabbitHandler
    public void getPoseTransformationResult(Message msg, Channel channel) {
        processPoseTransformResult(msg, channel);
    }
    @RabbitListener(queues = "#{rabbitMQProperties.queues.designBatch}")
    @RabbitHandler
    public void getDesignBatchResult(Message msg, Channel channel) {
        processDesignBatchResult(msg, channel);
    }
    @RabbitListener(queues = "#{rabbitMQProperties.queues.toProductImageBatch}")
    @RabbitHandler
    public void getToProductImageBatchResult(Message msg, Channel channel) {
        processToProductImageBatchResult(msg, channel);
    }

    @RabbitListener(queues = "#{rabbitMQProperties.queues.relightBatch}")
    @RabbitHandler
    public void getRelightBatchResult(Message msg, Channel channel) {
        processRelightBatchResult(msg, channel);
    }

    @RabbitListener(queues = "#{rabbitMQProperties.queues.poseTransformBatch}")
    @RabbitHandler
    public void getPoseTransformBatchResult(Message msg, Channel channel) {
        processPoseTransformBatchResult(msg, channel);
    }
}
