package com.hdkj.lt.mq.service.abnormal.impl;

import cn.hutool.core.lang.generator.SnowflakeGenerator;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hdkj.lt.base.constants.RedisKeyConstants;
import com.hdkj.lt.base.constants.RocketMQConstants;
import com.hdkj.lt.base.enums.EventTypeEnum;
import com.hdkj.lt.base.exception.ExceptionCast;
import com.hdkj.lt.core.bizms.modle.po.operationAbnormality.*;
import com.hdkj.lt.core.log.exception.ExceptionErrorLogCast;
import com.hdkj.lt.core.log.model.param.ErrorLogParam;
import com.hdkj.lt.core.mq.client.RocketMQTemplate;
import com.hdkj.lt.core.mq.config.RocketMQProperties;
import com.hdkj.lt.core.mq.model.RocketMQMessageEntity;
import com.hdkj.lt.core.plugins.thread.MultiThreadExecuteService;
import com.hdkj.lt.feign.IRefreshCacheApiClient;
import com.hdkj.lt.modle.dto.abnormal.*;
import com.hdkj.lt.modle.vo.svg.LineFileInfoVO;
import com.hdkj.lt.mq.mapper.abnormal.*;
import com.hdkj.lt.mq.service.abnormal.*;
import com.hdkj.lt.mq.service.base.ISvgFileInfoService;
import com.hdkj.hussar.ApiResponse;
import cn.hutool.core.util.IdUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.hdkj.lt.base.constants.CommonConstant.*;

/**
 * @author userlrk
 * @description 针对表【fhzg_grid_operation_abnormality(运行异常转供异常信息表)】的数据库操作Service实现
 * @createDate 2025-07-05 11:26:21
 */
@Slf4j
@Service
public class FhzgGridOperationAbnormalityServiceImpl extends ServiceImpl<FhzgGridOperationAbnormalityMapper, FhzgGridOperationAbnormality>
        implements FhzgGridOperationAbnormalityService {

    @Autowired
    private FhzgOperationAbnormalityAwaitTransferPathDetailMapper detailMapper;
    @Autowired
    private FhzgOperationAbnormalityAwaitTransferPathDetailService detailService;
    @Autowired
    RocketMQProperties rocketMQProperties;
    @Autowired
    RocketMQTemplate rocketMQTemplate;
    @Autowired
    private FhzgGridOperationAbnormalityMapper abnormalityMapper;
    @Autowired
    private FhzgOperationAbnormalityLineLoadfactorLossService lineLoadFactorLossService;
    @Autowired
    private FhzgOperationAbnormalityLineLoadfactorLossMapper lineLoadFactorLossMapper;
    @Autowired
    private FhzgOperationAbnormalityVoltageViolationService voltageViolationService;
    @Autowired
    private FhzgOperationAbnormalityVoltageViolationMapper voltageViolationMapper;
    @Autowired
    private FhzgOperationAbnormalitySwitchingSequenceService switchingSequenceService;
    @Autowired
    private FhzgOperationAbnormalitySwitchingSequenceMapper switchingSequenceMapper;
    @Autowired
    private FhzgOperationAbnormalityTransferAreaResultService resultService;
    @Autowired
    private ISvgFileInfoService svgFileInfoService;
    @Autowired
    private IRefreshCacheApiClient refreshCacheApiClient;
    @Autowired
    private MultiThreadExecuteService multiThreadExecuteService;

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private static final RoundingMode ROUNDING_MODE = RoundingMode.HALF_UP;

    /**
     * 解析计算推演平台运行调优数据
     *
     * @param obNormalId
     */
    @Override
    public void dealOperationAbnormalData(Long obNormalId) {
        LambdaQueryWrapper<FhzgOperationAbnormalityTransferAreaResult> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FhzgOperationAbnormalityTransferAreaResult::getOaId, obNormalId);
        FhzgOperationAbnormalityTransferAreaResult areaResult = resultService.getOne(wrapper);
        if (areaResult == null) {
            return;
        }
        FhzgGridOperationAbnormality abnormality = this.getById(obNormalId);
        String analysisJson = areaResult.getTransferAreaJson();
        //处理入参json
        Optional.ofNullable(areaResult.getTransferAreaJson())
                .map(e -> JSON.parseObject(e, ApiResponse.class))
                .filter(e -> ObjectUtils.isNotEmpty(e.getData()))
                .map(e -> JSON.parseObject(JSON.toJSONString(e.getData()), ApiAbnormalDataDTO.class))
                .ifPresent(data -> {
                    AbnormalOperationDTO abnormalOperationDTO = data.getResult();
                    //处理异常信息
                    dealWithSwitchSeq(abnormalOperationDTO.getSwitchSeq().getListSwitchOp(), obNormalId);
                    //处理开关顺序
                    dealWithSwitchSwitchingSequence(abnormalOperationDTO.getSwitchSeq().getListSwitchOp(), obNormalId);
                    //处理结果分析（线路损耗）
                    dealWithSFeederResult(abnormalOperationDTO.getFeederResult(), obNormalId);
                    //处理结果分析（配电电压越限信息）
                    dealWithVoltage(abnormalOperationDTO.getVolResult(), obNormalId);
                    if (abnormality != null) {
                        Long id = IdUtil.getSnowflakeNextId();
                        //新增svg文件绑定
                        svgFileInfoService.getSvgGenerationFile(abnormality.getLineId(), abnormality.getId(), FIVE);
                        abnormalityMapper.saveScheme(obNormalId, id);
                        //方案svg文件绑定
                        LineFileInfoVO svgGenerationFile = svgFileInfoService.getSvgGenerationFile(abnormality.getLineId(), id, SIX);
                        if (svgGenerationFile == null) {
                            ErrorLogParam errorLogParam = new ErrorLogParam()
                                    .setErrorTime(LocalDateTime.now())
                                    .setEventType(EventTypeEnum.TOPO_FILE.getCode())
                                    .setEventId(abnormality.getId().toString())
                                    .setErrorCategory("运行调优成图调用失败")
                                    .setErrorLevel("Warning")
                                    .setSourceSystem("2")
                                    .setOperationStep("运行调优成图")
                                    .setRelatedId(obNormalId.toString())
                                    .setStage("8")
                                    .setRelatedCategory("fhzg_grid_operation_abnormality")
                                    .setDetails("运行调优id：" + abnormality.getId() + "方案id：" + id + " 成图服务报错，请求参数: lineId:" + abnormality.getLineId() + ", objId" + id + ", type:" + TWO);
                            ExceptionErrorLogCast.cast(errorLogParam);
                        }
                        // 生成动画反演数据
                        CompletableFuture.runAsync(() -> refreshCacheApiClient.generateCartoonData(abnormality.getId(), "3"), multiThreadExecuteService.getExecutor());
                    }
                });
    }

    /**
     * 解析计算推演平台返回运行异常JSON
     */
    @Override
    public void dealOperationAbnormalDataForTest(AbnormalOperationDTO abnormalOperationDTO) {
        //测试数据
        Long obNormalId = Long.valueOf(abnormalOperationDTO.getVolResult().getSummary());
        String analysisJson = "";
        //处理入参json
//        AbnormalOperationDTO abnormalOperationDTO = JSON
//                .parseObject(JSON.toJSONString(analysisJson), AbnormalOperationDTO.class);
        //处理异常信息
        FhzgGridOperationAbnormality abnormality = this.getById(obNormalId);
        dealWithSwitchSeq(abnormalOperationDTO.getSwitchSeq().getListSwitchOp(), obNormalId);
        //处理开关顺序
        dealWithSwitchSwitchingSequence(abnormalOperationDTO.getSwitchSeq().getListSwitchOp(), obNormalId);
        //处理结果分析（线路损耗）
        dealWithSFeederResult(abnormalOperationDTO.getFeederResult(), obNormalId);
        //处理结果分析（配电电压越限信息）
        dealWithVoltage(abnormalOperationDTO.getVolResult(), obNormalId);
        if (abnormality != null) {
            //新增svg文件绑定
            svgFileInfoService.getSvgGenerationFile(abnormality.getLineId(), abnormality.getId(), FIVE);
        }
    }

    /**
     * 接收运行方式优化通知消息,保存至异常信息表
     *
     * @param dataDTO
     */
    @Override
    public void AcceptOperationAbnormalMessage(AbnormalMessageDataDTO dataDTO) {
        LambdaQueryWrapper<FhzgGridOperationAbnormality> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FhzgGridOperationAbnormality::getEventId, dataDTO.getId());
        List<FhzgGridOperationAbnormality> areaResult = abnormalityMapper.selectList(wrapper);
        if (areaResult != null && !areaResult.isEmpty()) {
            List<Long> ids = areaResult.stream().map(FhzgGridOperationAbnormality::getId).collect(Collectors.toList());
            this.removeByIds(ids);
        }
        dataDTO.getFeeders().forEach(ab -> {
            Long id = IdUtil.getSnowflakeNextId();
            FhzgGridOperationAbnormality operationAbnormality = FhzgGridOperationAbnormality.builder()
                    .id(id)
                    .psrType(ab.getPsrType())
                    .eventId(dataDTO.getId())
                    .reason(dataDTO.getReason())
                    .lineId(ab.getPsrId())
                    .alarmStartTime(ab.getLoadAlarmStartTime())
                    .alarmEndTime(ab.getLoadAlarmEndTime())
                    .ratedCurrent(ab.getRateCurrent())
                    .maxLoadFactor(ab.getMaxLoad())
                    .maxLoadFactorTime(ab.getMaxLoadTime())
                    .alarmSustainedTime(calculateTime(ab.getLoadAlarmStartTime(), ab.getLoadAlarmEndTime()))
                    .loadCondition(String.valueOf(ab.getLoadAlarmType()))
                    .optimizationTime(dataDTO.getDateTime())
                    .loadAlarmType(dataDTO.getLoadAlarmType())
                    .maxVol(ab.getMaxVol())
                    .minVol(ab.getMinVol())
                    .build();
            this.save(operationAbnormality);
            try {
                //TOPIC_ID_TO_ANALYSIS_RESULT_TICKET
                if (rocketMQProperties.getEnabled()) {
                    RocketMQMessageEntity messageEntity = RocketMQMessageEntity.builder()
                            .topicId(RocketMQConstants.TOPIC_ID_TO_ANALYSIS_RESULT_TICKET)
                            .cacheKey(RedisKeyConstants.ASYNC_POWER_CUT_RESULT_TOPIC_TICKET)
                            .tag("3") // 1-计划停电，2-故障停电 3-运行调优
                            .body(id).build();
                    rocketMQTemplate.sendAsyncMessage(messageEntity);
                }
            } catch (Exception e) {
                ExceptionCast.cast("运行调优发送mq失败");

            }
        });


    }


    /**
     * 解析结果信息(线路损耗)
     *
     * @param feederResult
     */
    public void dealWithSFeederResult(FeederResultDTO feederResult, Long oaId) {
        //删除旧数据防止重复
        LambdaQueryWrapper<FhzgOperationAbnormalityLineLoadfactorLoss> lambdaQueryWrapper =
                new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FhzgOperationAbnormalityLineLoadfactorLoss::getOaId, oaId);
        if (!lineLoadFactorLossMapper.selectList(lambdaQueryWrapper).isEmpty()) {
            lineLoadFactorLossMapper.delete(lambdaQueryWrapper);
        }
        FhzgGridOperationAbnormality abnormality = this.getById(oaId);
        List<FhzgOperationAbnormalityLineLoadfactorLoss> lineLoadFactorLosses = new ArrayList<>();
        //保存线路损耗信息
        feederResult.getListFeeder().forEach(f -> {
            if (abnormality != null && f.getPsrID() != null) {
                if (Objects.equals(f.getPsrID(), abnormality.getLineId())) {
                    abnormality.setLineName(f.getName());
                    this.updateById(abnormality);
                }
            }
            //计算转供前后功率
            BigDecimal beforeFactor = null;
            BigDecimal afterFactor = null;
            BigDecimal changeFactor = null;
            BigDecimal lossChange = null;
            if (f.getBeforeI() != null) {
                beforeFactor = f.getBeforeI().divide(f.getRateCurrent(), 4, ROUNDING_MODE)
                        .multiply(BigDecimal.valueOf(100));
            }
            if (f.getAfterI() != null) {
                afterFactor = f.getAfterI().divide(f.getRateCurrent(), 4, ROUNDING_MODE)
                        .multiply(BigDecimal.valueOf(100));
                changeFactor = afterFactor.subtract(beforeFactor);
            }
            if (f.getLineLossAfter() != null && f.getLineLossBefore() != null) {
                lossChange = f.getLineLossAfter().subtract(f.getLineLossBefore());
            }
            FhzgOperationAbnormalityLineLoadfactorLoss
                    lineLoadFactorLoss = FhzgOperationAbnormalityLineLoadfactorLoss
                    .builder()
                    .id(IdUtil.getSnowflakeNextId())
                    .lineLossBefore(f.getLineLossBefore())
                    .lineLossAfter(f.getLineLossAfter())
                    .rateCurrent(f.getRateCurrent())
                    .beforeCurrent(f.getBeforeI())
                    .afterCurrent(f.getAfterI())
                    .beforeFactor(beforeFactor)
                    .afterFactor(afterFactor)
                    .changeFactor(changeFactor)
                    .name(f.getName())
                    .psrId(f.getPsrID())
                    .psrType(f.getPsrType())
                    .lineLossChange(lossChange)
                    .oaId(oaId)
                    .build();
            lineLoadFactorLosses.add(lineLoadFactorLoss);
        });
        lineLoadFactorLossService.saveBatch(lineLoadFactorLosses);
    }

    /**
     * 解析运行异常转供路径细明信息
     *
     * @param seqDTOList
     * @param oaId
     */
    public void dealWithSwitchSeq(List<ListSwitchOpDTO> seqDTOList, Long oaId) {
        //删除旧数据防止重复
        LambdaQueryWrapper<FhzgOperationAbnormalityAwaitTransferPathDetail> lambdaQueryWrapper =
                new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FhzgOperationAbnormalityAwaitTransferPathDetail::getOaId, oaId);
        if (!detailMapper.selectList(lambdaQueryWrapper).isEmpty()) {
            detailMapper.delete(lambdaQueryWrapper);
        }
        List<FhzgOperationAbnormalityAwaitTransferPathDetail> pathDetails = new ArrayList<>();
        List<FhzgOperationAbnormalityAwaitTransferPathDetail> pathDetails2 = new ArrayList<>();
        seqDTOList.forEach(e -> {
            if (e.getFeederOut() == null || e.getFeederIn() == null) {
                return;
            }
            //1被带供  2带供
            BigDecimal iAfterFactor1 = null;
            BigDecimal iBeforeFactor1 = null;
            BigDecimal iAfterFactor2 = null;
            BigDecimal iBeforeFactor2 = null;
            BigDecimal loadChange1 = null;
            BigDecimal loadChange2 = null;
            BigDecimal currentChange1 = null;
            BigDecimal currentChange2 = null;
            //计算带供后功率变化值(判空校验)
            if (e.getFeederOut().getAfterI() != null) {
                iAfterFactor1 = e.getFeederOut().getAfterI().divide(e.getFeederOut().getRateCurrent(), 4, ROUNDING_MODE)
                        .multiply(BigDecimal.valueOf(100));
                currentChange1 = e.getFeederOut().getAfterI().subtract(e.getFeederOut().getBeforeI());
            }
            if (e.getFeederOut().getBeforeI() != null) {
                iBeforeFactor1 = e.getFeederOut().getBeforeI().divide(e.getFeederOut().getRateCurrent(), 4, ROUNDING_MODE)
                        .multiply(BigDecimal.valueOf(100));
            }
            if (e.getFeederIn().getAfterI() != null) {
                iAfterFactor2 = e.getFeederIn().getAfterI().divide(e.getFeederIn().getRateCurrent(), 4, ROUNDING_MODE)
                        .multiply(BigDecimal.valueOf(100));
                currentChange2 = e.getFeederIn().getAfterI().subtract(e.getFeederIn().getBeforeI());
            }
            if (e.getFeederIn().getBeforeI() != null) {
                iBeforeFactor2 = e.getFeederIn().getBeforeI().divide(e.getFeederIn().getRateCurrent(), 4, ROUNDING_MODE)
                        .multiply(BigDecimal.valueOf(100));
            }
            if (iAfterFactor1 != null && iBeforeFactor1 != null) {
                loadChange1 = iAfterFactor1.subtract(iBeforeFactor1);
            }
            if (iBeforeFactor2 != null && iAfterFactor2 != null) {
                loadChange2 = iAfterFactor2.subtract(iBeforeFactor2);
            }

            String groupId = IdUtil.getSnowflakeNextIdStr();
            //保存被带供信息
            FhzgOperationAbnormalityAwaitTransferPathDetail
                    detailType1 = FhzgOperationAbnormalityAwaitTransferPathDetail
                    .builder()
                    .oaId(oaId)
                    .id(IdUtil.getSnowflakeNextId())
                    .ratedCurrent(e.getFeederOut().getRateCurrent())
                    .transferType("1")
                    .afterLoadFactor(iAfterFactor1)
                    .beforeLoadFactor(iBeforeFactor1)
                    .loadChange(loadChange1)
                    .beforeCurrent(e.getFeederOut().getBeforeI())
                    .afterCurrent(e.getFeederOut().getAfterI())
                    //被带供不保存合环开关
                    //.closeSwitchId(e.getCloseBreakerOp().getBreaker_id())
                    //.closeSwitchName(e.getCloseBreakerOp().getName())
                    .lineId(e.getFeederOut().getPsrID())
                    .lineName(e.getFeederOut().getName())
                    .groupLineId(groupId)
                    .currentChange(currentChange1)
                    .build();
            pathDetails.add(detailType1);
            //保存带供信息
            FhzgOperationAbnormalityAwaitTransferPathDetail detailType2 = FhzgOperationAbnormalityAwaitTransferPathDetail
                    .builder()
                    .oaId(oaId)
                    .id(IdUtil.getSnowflakeNextId())
                    .ratedCurrent(e.getFeederIn().getRateCurrent())
                    .transferType("2")
                    .afterLoadFactor(iAfterFactor2)
                    .beforeLoadFactor(iBeforeFactor2)
                    .loadChange(loadChange2)
                    .beforeCurrent(e.getFeederIn().getBeforeI())
                    .afterCurrent(e.getFeederIn().getAfterI())
                    .closeSwitchId(e.getCloseBreakerOp().getBreaker_id())
                    .closeSwitchName(e.getCloseBreakerOp().getName())
                    .lineId(e.getFeederIn().getPsrID())
                    .lineName(e.getFeederIn().getName())
                    .groupLineId(groupId)
                    .currentChange(currentChange2)
                    .build();
            pathDetails2.add(detailType2);
        });
        //被带供线路去重
        List<FhzgOperationAbnormalityAwaitTransferPathDetail> result =
                new ArrayList<>(pathDetails.stream().collect(Collectors
                                .toMap(FhzgOperationAbnormalityAwaitTransferPathDetail::getLineId,
                                        Function.identity(), (oldValue, newValue) -> newValue))
                        .values());
        result.addAll(pathDetails2);
        detailService.saveBatch(result);
    }

    /**
     * 解析开关动作顺序信息
     */
    public void dealWithSwitchSwitchingSequence(List<ListSwitchOpDTO> seqDTOList, Long oaId) {
        //删除旧数据防止重复
        LambdaQueryWrapper<FhzgOperationAbnormalitySwitchingSequence> lambdaQueryWrapper =
                new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FhzgOperationAbnormalitySwitchingSequence::getOaId, oaId);
        if (!switchingSequenceMapper.selectList(lambdaQueryWrapper).isEmpty()) {
            switchingSequenceMapper.delete(lambdaQueryWrapper);
        }
        //动作顺序计数
        int[] count = {0};
        List<FhzgOperationAbnormalitySwitchingSequence> sequences = new ArrayList<>();
        seqDTOList.forEach(se -> {
            FhzgOperationAbnormalitySwitchingSequence switchingSequenceFirst = FhzgOperationAbnormalitySwitchingSequence
                    .builder()
                    .id(IdUtil.getSnowflakeNextId())
                    .oaId(oaId)
                    .switchId(se.getCloseBreakerOp().getBreaker_id())
                    .switchName(se.getCloseBreakerOp().getName())
                    .switchingSeq(count[0])
                    .isAutoSwitch(se.getCloseBreakerOp().getAutoType())
                    .operationType(se.getCloseBreakerOp().getOperation_type())
                    .operationTime(convertTimeFormat(se.getCloseBreakerOp().getTimestamp()))
                    .build();
            sequences.add(switchingSequenceFirst);
            count[0]++;
            FhzgOperationAbnormalitySwitchingSequence switchingSequenceSecond = FhzgOperationAbnormalitySwitchingSequence
                    .builder()
                    .id(IdUtil.getSnowflakeNextId())
                    .oaId(oaId)
                    .switchId(se.getOpenBreakerOp().getBreaker_id())
                    .switchName(se.getOpenBreakerOp().getName())
                    .switchingSeq(count[0])
                    .isAutoSwitch(se.getOpenBreakerOp().getAutoType())
                    .operationType(se.getOpenBreakerOp().getOperation_type())
                    .operationTime(convertTimeFormat(se.getOpenBreakerOp().getTimestamp()))
                    .build();
            sequences.add(switchingSequenceSecond);
            count[0]++;
        });
        switchingSequenceService.saveBatch(sequences);
    }

    /**
     * 解析配电压越限信息
     */
    public void dealWithVoltage(VolResultDTO volResultDTO, Long oaId) {
        //删除旧数据防止重复
        LambdaQueryWrapper<FhzgOperationAbnormalityVoltageViolation> lambdaQueryWrapper =
                new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(FhzgOperationAbnormalityVoltageViolation::getOaId, oaId);
        if (!voltageViolationMapper.selectList(lambdaQueryWrapper).isEmpty()) {
            voltageViolationMapper.delete(lambdaQueryWrapper);
        }
        //保存电压越限信息
        List<FhzgOperationAbnormalityVoltageViolation> voltageViolations = new ArrayList<>();
        if (volResultDTO == null) {
            return;
        }
        volResultDTO.getDetails().forEach(d -> {
            //计算电压越位幅度
            BigDecimal extend = null;
            if (d.getAfter_U() != null) {
                if (d.getAfter_U().compareTo(new BigDecimal("10.7")) > 0) {
                    extend = d.getAfter_U().subtract(new BigDecimal("10.7"))
                            .divide(BigDecimal.valueOf(10),5, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
                } else if ((d.getAfter_U().compareTo(new BigDecimal("9.3")) < 0)) {
                    extend = new BigDecimal("9.3").subtract(d.getAfter_U())
                            .divide(BigDecimal.valueOf(10), 5,RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
                }
                if (extend != null) {
                    extend = extend.abs();
                }
            }
            FhzgOperationAbnormalityVoltageViolation voltageViolation = FhzgOperationAbnormalityVoltageViolation
                    .builder().afterVoltage(d.getAfter_U())
                    .beforeVoltage(d.getBefore_U())
                    .afterVoltage_lv(d.getAfter_Ulv())
                    .beforeVoltage_lv(d.getBefore_Ulv())
                    .custType(d.getLoadType())
                    .psrName(d.getName())
                    .psrType(d.getPsrType())
                    .psrId(d.getPsrID())
                    .extentOvervoltage(extend)
                    .oaId(oaId)
                    .build();
            voltageViolations.add(voltageViolation);
        });
        voltageViolationService.saveBatch(voltageViolations);
    }

    /**
     * 计算时间从差值
     *
     * @param start
     * @param end
     * @return
     */
    public static BigDecimal calculateTime(Date start, Date end) {
        long l = Math.abs(end.getTime() - start.getTime());
        BigDecimal millisToHours = BigDecimal.valueOf(1000 * 3600);
        return BigDecimal.valueOf(l).divide(millisToHours, 6, ROUNDING_MODE);
    }

    /**
     * 时间格式转换
     *
     * @param original
     * @return
     */
    private LocalDateTime convertTimeFormat(String original) {
//        Instant instant = Instant.parse(original);
//        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//        String dateTime = dateTimeFormatter.format(instant);
//        return LocalDateTime.parse(String.format(dateTime), formatter);
        DateTimeFormatter dateTimeFormat = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime dateTime = LocalDateTime.parse(original, dateTimeFormat);
        return dateTime;
    }
}




