package com.bonus.material.repair.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.bonus.common.biz.constant.GlobalConstants;
import com.bonus.common.biz.constant.MaterialConstants;
import com.bonus.common.biz.domain.repair.RepairInputDetails;
import com.bonus.common.biz.domain.vo.KeyValueVO;
import com.bonus.common.biz.enums.*;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.utils.DateUtils;
import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.back.mapper.BackApplyInfoMapper;
import com.bonus.material.repair.domain.*;
import com.bonus.material.repair.domain.vo.RepairAuditDetailsVO;
import com.bonus.material.repair.domain.vo.RepairHomeInfo;
import com.bonus.material.repair.domain.vo.ScrapApplyDetailsVO;
import com.bonus.material.repair.domain.vo.ScrapAudit;
import com.bonus.material.repair.mapper.RepairApplyDetailsMapper;
import com.bonus.material.repair.mapper.RepairAuditDetailsMapper;
import com.bonus.material.repair.mapper.RepairInputDetailsMapper;
import com.bonus.material.repair.mapper.RepairMapper;
import com.bonus.material.repair.service.IRepairAuditDetailsService;
import com.bonus.material.scrap.domain.ScrapApplyDetails;
import com.bonus.material.scrap.mapper.ScrapApplyDetailsMapper;
import com.bonus.material.task.domain.TmTask;
import com.bonus.material.task.domain.TmTaskAgreement;
import com.bonus.material.task.mapper.TmTaskAgreementMapper;
import com.bonus.material.task.mapper.TmTaskMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.bonus.common.biz.constant.MaterialConstants.SCRAP_TASK_TYPE_LABEL;

/**
 * 修试审核详细Service业务层处理
 *
 * @author syruan
 * @date 2024-10-16
 */
@Service
@Slf4j
public class RepairAuditDetailsServiceImpl implements IRepairAuditDetailsService {

    @Resource
    private RepairAuditDetailsMapper repairAuditDetailsMapper;

    @Resource
    private TmTaskMapper taskMapper;

    @Resource
    private TmTaskAgreementMapper agreementMapper;

    @Resource
    private ScrapApplyDetailsMapper scrapApplyDetailsMapper;

    @Resource
    private RepairApplyDetailsMapper repairApplyDetailsMapper;

    @Resource
    private RepairInputDetailsMapper repairInputDetailsMapper;

    @Resource
    private TmTaskAgreementMapper taskAgreementMapper;

    @Resource
    private RepairMapper repairMapper;

    @Resource
    private BackApplyInfoMapper backApplyInfoMapper;

    @Override
    public List<RepairPart> getPartRecord(RepairAuditDetails repairAuditDetails) {
        RepairAuditDetails bean = repairAuditDetailsMapper.getRepairId(repairAuditDetails);
        return repairAuditDetailsMapper.getPartRecord(bean);
    }

    @Override
    public List<RepairRecord> getRepairRecord(RepairAuditDetails repairAuditDetails) {
        RepairAuditDetails bean = repairAuditDetailsMapper.getRepairId(repairAuditDetails);
        return repairAuditDetailsMapper.getRepairRecord(bean);
    }

    /**
     * @param repairAuditDetails 查询参数
     */
    @Override
    public List<RepairAuditDetails> getRepairAuditList(RepairAuditDetails repairAuditDetails) {
        Long userId = SecurityUtils.getLoginUser().getUserid();
        // 首先根据用户名去ma_type_manage表查询是否存在绑定物资信息
        /*List<Long> typeIdList = backApplyInfoMapper.selectTypeIdList(userId);
        if (CollectionUtils.isEmpty(typeIdList)) {
            repairAuditDetails.setUserId(userId == 0 ? null : userId);
        }*/
        Set<String> userRoles = SecurityUtils.getLoginUser().getRoles();
        // 检查用户是否具有特殊角色
        boolean hasSpecialRole = hasSpecialRole(userRoles);
        if (!hasSpecialRole) {
            repairAuditDetails.setUserId(userId == 0 ? null : userId);
        }
        return repairAuditDetailsMapper.selectRepairAuditDetailsList(repairAuditDetails);
    }

    @Override
    public void queryTimeCope(@NotNull RepairAuditDetails repairAuditDetails) {
        Map<String, Object> params = repairAuditDetails.getParams();
        if (null != params && !params.isEmpty()) {
            formatTimeParam(params, "beginTime", " 00:00:00");
            formatTimeParam(params, "endTime", " 23:59:59");
            repairAuditDetails.setParams(params);
        }
    }

    @Override
    public List<RepairAuditDetailsVO> exportRepairQuestList(RepairAuditDetails bean) {
        return repairAuditDetailsMapper.exportRepairQuestList(bean);
    }

    /**
     * 查询试验审核列表
     *
     * @param repairAuditDetails 查询参数
     */
    @Override
    public List<ScrapApplyDetailsVO> selectRepairQuestList(RepairAuditDetails repairAuditDetails) {
        try {
            Long userId = SecurityUtils.getLoginUser().getUserid();
            /*// 首先根据用户名去ma_type_manage表查询是否存在绑定物资信息
            List<Long> typeIdList = backApplyInfoMapper.selectTypeIdList(userId);
            if (CollectionUtils.isEmpty(typeIdList)) {
                repairAuditDetails.setUserId(userId == 0 ? null : userId);
            }*/
            Set<String> userRoles = SecurityUtils.getLoginUser().getRoles();
            // 检查用户是否具有特殊角色
            boolean hasSpecialRole = hasSpecialRole(userRoles);
            if (!hasSpecialRole) {
                repairAuditDetails.setUserId(userId == 0 ? null : userId);
            }
            // 获取所有需要查询的 taskId、过滤空的
            List<ScrapApplyDetailsVO> repairQuestList = repairAuditDetailsMapper.selectRepairQuestList(repairAuditDetails);
            // 通过流过滤掉空对象 并转换为 List集合
            List<Long> taskIds = repairQuestList.stream()
                    .filter(Objects::nonNull)
                    .map(ScrapApplyDetailsVO::getTaskId)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());

            // 批量查询 typeName
            List<KeyValueVO> keyValueList = repairAuditDetailsMapper.selectTypeNamesByTaskIds(taskIds);
            // 设置 itemType
            if (CollectionUtil.isNotEmpty(keyValueList)) {
                Map<String, String> keyValueMap = keyValueList.stream()
                        .filter(vo -> vo.getMapKey() != null && vo.getMapValue() != null) // 过滤键或值为 null 的元素
                        .collect(Collectors.toMap(KeyValueVO::getMapKey, KeyValueVO::getMapValue));
                for (ScrapApplyDetailsVO scrapApplyDetailsVO : repairQuestList) {
                    Long taskId = scrapApplyDetailsVO.getTaskId();
                    if (taskId != null) {
                        String typeName = keyValueMap.get(String.valueOf(taskId));
                        if (typeName != null) {
                            scrapApplyDetailsVO.setItemType(typeName);
                        }
                    }
                }
            }
            if (CollectionUtil.isNotEmpty(repairQuestList)) {
                String keyWord = repairAuditDetails.getKeyWord();
                // 如果关键字不为空，进行过滤
                if (!StringUtils.isBlank(keyWord)) {
                    repairQuestList = repairQuestList.stream()
                            .filter(item -> containsKeyword(item, keyWord))
                            .collect(Collectors.toList());
                }
            }
            return repairQuestList;
        } catch (Exception e) {
            // 异常处理
            System.err.println("Error occurred while selecting repair quest list: " + e.getMessage());
            throw new ServiceException("Failed to get repair quest list" + e.getMessage());
        }
    }

    /**
     * 检查用户是否具有特殊角色
     * @param userRoles
     * @return
     */
    private boolean hasSpecialRole(Set<String> userRoles) {
        if (userRoles == null) {
            return false;
        }
        List<String> allowedRoles = GlobalConstants.allowedRoles;
        return allowedRoles.stream().anyMatch(userRoles::contains);
    }

    /**
     * 关键字搜索
     * @param item
     * @param keyWord
     * @return
     */
    private boolean containsKeyword(ScrapApplyDetailsVO item, String keyWord) {
        return (item.getItemType() != null && item.getItemType().contains(keyWord)) ||
                (item.getRepairTaskCode() != null && item.getRepairTaskCode().contains(keyWord)) ||
                (item.getScrapNum() != null && item.getScrapNum().contains(keyWord)) ||
                (item.getRepairNum() != null && item.getRepairNum().contains(keyWord)) ||
                (item.getUnitName() != null && item.getUnitName().contains(keyWord)) ||
                (item.getProjectName() != null && item.getProjectName().contains(keyWord)) ||
                (item.getCreateBy() != null && item.getCreateBy().contains(keyWord));
    }

    /**
     * 修饰审核任务审核
     *
     * @param scrapAudit 审核信息
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int auditRepair(@NotNull ScrapAudit scrapAudit) throws Exception {
        String checkResult = scrapAudit.getCheckResult();
        List<RepairAuditDetails> auditDetailList = scrapAudit.getAuditDetailList();
        List<Long> taskIdList = scrapAudit.getTaskIdList();
        BigDecimal b = BigDecimal.valueOf(0);
        char status;
        for (Long taskId : taskIdList) {
            TmTask tmTask = taskMapper.selectTmTaskByTaskId(taskId);
            if (Objects.equals(tmTask.getTaskStatus(), RepairTaskStatusEnum.TASK_STATUS_REVIEW.getStatus())) {
                throw new Exception("任务已审核已通过");
            }

            List<RepairAuditDetails> auditAllList = repairAuditDetailsMapper.selectRepairAuditDetailsByTaskId(taskId);
            List<RepairAuditDetails> notAuditList = repairAuditDetailsMapper.selectNotAuditByTaskId(taskId);
            // 查询协议表
            TmTaskAgreement tmTaskAgreement = agreementMapper.selectTmTaskAgreementByTaskId(taskId);
            String taskCode;
            int taskStatus;
            int taskType;
            int companyId = 0;
            if ("通过".equals(checkResult)) {
                status = 1;
                List<RepairAuditDetails> repairInputList = new ArrayList<>();
                List<RepairAuditDetails> scrapNumList = new ArrayList<>();
                if (CollectionUtil.isNotEmpty(auditDetailList)) {
                    for (RepairAuditDetails bean : auditDetailList) {
                        if (bean.getRepairedNum().compareTo(b) > 0) {
                            repairInputList.add(bean);
                        }
                        if (bean.getScrapNum().compareTo(b) > 0) {
                            scrapNumList.add(bean);
                        }
                    }
                } else {
                    repairInputList = repairAuditDetailsMapper.selectRepairInputByTaskId(taskId);
                    //获取维修报废列表
                    scrapNumList = repairAuditDetailsMapper.selectScrapNumByTaskId(taskId);
                }

                if (CollectionUtil.isNotEmpty(repairInputList)) {
                    if (repairInputList.get(0).getCompanyId() != null) {
                        companyId = repairInputList.get(0).getCompanyId();
                    }

                    taskCode = purchaseCodeRule("R", 5);
                    taskStatus = 53;
                    taskType = 50;
                    long inputTaskId = genTask(taskCode, taskType, taskStatus, tmTaskAgreement, companyId);
                    for (RepairAuditDetails inputDetails : repairInputList) {
                        Long typeId = inputDetails.getTypeId();
                        Long maId = inputDetails.getMaId();
                        BigDecimal repairNum = inputDetails.getRepairedNum();
                        // 创建修饰后入库任务
                        if (0 < repairNum.compareTo(b)) {
                            // 添加修试后入库任务
                            RepairInputDetails repairInputDetails = new RepairInputDetails();
                            repairInputDetails.setTaskId(inputTaskId);
                            repairInputDetails.setAuditId(inputDetails.getId());
                            repairInputDetails.setRepairId(inputDetails.getRepairId());
                            repairInputDetails.setRepairNum(inputDetails.getRepairedNum());
                            repairInputDetails.setTypeId(inputDetails.getTypeId());
                            repairInputDetails.setMaId(inputDetails.getMaId());
                            repairInputDetails.setStatus("0");
                            repairInputDetails.setCreateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
                            repairInputDetails.setCreateTime(new Date());
                            repairInputDetails.setCompanyId((long) companyId);
                            repairInputDetailsMapper.insertRepairInputDetails(repairInputDetails);
                        }
                        repairAuditDetailsMapper.updateRepairCost(inputDetails,status);
                        // 根据repairId找到taskId和 typeId 、maid
                        List<String> repairApplyRecordId = repairAuditDetailsMapper.getRepairApplyRecordId(inputDetails.getRepairId());
                        // 再去repair_apply_record 中查，并给一个标识表示审核完成
                        for (String id : repairApplyRecordId) {
                            repairAuditDetailsMapper.updateRecodeStatus(id);
                        }
                    }
                }
                if (CollectionUtil.isNotEmpty(scrapNumList)) {
                    if (null != scrapNumList.get(0).getCompanyId()) {
                        companyId = scrapNumList.get(0).getCompanyId();
                    }
                    taskCode = purchaseCodeRule(SCRAP_TASK_TYPE_LABEL, TmTaskTypeEnum.TM_TASK_SCRAP.getTaskTypeId());
                    //创建报废任务
                    long scrapTaskId = genTask(taskCode, TmTaskTypeEnum.TM_TASK_SCRAP.getTaskTypeId(), RepairTaskStatusEnum.SCRAP_UNDER_REVIEW.getStatus(), tmTaskAgreement, companyId);
                    for (RepairAuditDetails scrapDetails : scrapNumList) {
                        RepairAuditDetails byRepairId = scrapApplyDetailsMapper.getByRepairId(String.valueOf(scrapDetails.getRepairId()));
                        List<RepairRecord> repairRecord = scrapApplyDetailsMapper.getGyoupRepairRecord(byRepairId);
                        Long typeId = scrapDetails.getTypeId();
                        Long maId = scrapDetails.getMaId();
                        // 创建报废任务
                        BigDecimal scrapNum = scrapDetails.getScrapNum();
                        if (0 < scrapNum.compareTo(b)) {
                            for (RepairRecord bean : repairRecord){
                                ScrapApplyDetails scrapApplyDetails = new ScrapApplyDetails();
                                scrapApplyDetails.setTaskId(scrapTaskId);
                                scrapApplyDetails.setTypeId(typeId);
                                scrapApplyDetails.setMaId(maId);
                                scrapApplyDetails.setScrapNum(bean.getScrapNum());
                                scrapApplyDetails.setScrapType(bean.getScrapType());
                                scrapApplyDetails.setScrapSource("2");
                                scrapApplyDetails.setStatus("0");
                                scrapApplyDetails.setParentId(scrapDetails.getId());
                                scrapApplyDetails.setCreateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
                                scrapApplyDetails.setCreateTime(new Date());
                                scrapApplyDetails.setCompanyId((long) companyId);
                                scrapApplyDetailsMapper.insertScrapApplyDetails(scrapApplyDetails);
                            }
                        }
                    }

                }
                // 修饰审核通过时改修任务为已通过审核
                if (null != auditDetailList) {
                    if (auditDetailList.size() == notAuditList.size()) {
                        tmTask.setTaskStatus(47);
                    }
                } else if (null != auditAllList) {
                    if (auditAllList.size() == notAuditList.size()) {
                        tmTask.setTaskStatus(47);
                    }
                }
                tmTask.setUpdateTime(new Date());
                tmTask.setUpdateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
                taskMapper.updateTmTask(tmTask);
            } else {
                status = 2;
                List<RepairAuditDetails> repairDetailList = new ArrayList<>();
                if (CollectionUtil.isNotEmpty(auditDetailList)) {
                    repairDetailList.addAll(auditDetailList);
                } else {
                    repairDetailList.addAll(auditAllList);
                }
                if (CollectionUtil.isNotEmpty(repairDetailList)) {
                    if (null != repairDetailList.get(0).getCompanyId()) {
                        companyId = repairDetailList.get(0).getCompanyId();
                    }
                    taskCode = purchaseCodeRule(MaterialConstants.REPAIR_TASK_TYPE_LABEL, 4);
                    taskStatus = 43;
                    taskType = 4;
                    long inputTaskId = genTask(taskCode, taskType, taskStatus, tmTaskAgreement, companyId);
                    for (RepairAuditDetails inputDetails : repairDetailList) {
                        Long backId = repairAuditDetailsMapper.getBackId(inputDetails.getRepairId());
                        /* 添加驳回后维修详细表数据*/
                        RepairTaskDetails repairTaskDetails = new RepairTaskDetails();
                        repairTaskDetails.setTaskId(inputTaskId);
                        repairTaskDetails.setMaId(String.valueOf(inputDetails.getMaId()));
                        repairTaskDetails.setTypeId(String.valueOf(inputDetails.getTypeId()));
                        BigDecimal repairNum = inputDetails.getRepairNum();
                        repairTaskDetails.setRepairNum(repairNum);
                        repairTaskDetails.setStatus("0");
                        repairTaskDetails.setCreateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
                        repairTaskDetails.setCompanyId((long) companyId);
                        repairTaskDetails.setBackId(backId);
                        repairAuditDetailsMapper.insertRepairDetails(repairTaskDetails);
                        repairAuditDetailsMapper.updateRepairCost(inputDetails,status);
                    }
                }
                // 修饰审核任务不通过时
                TmTask tmTaskNotExam = new TmTask();
                tmTaskNotExam.setTaskId(taskId);
                tmTaskNotExam.setRemark(scrapAudit.getRemark());
                if (repairDetailList.size() == notAuditList.size()) {
                    tmTaskNotExam.setTaskStatus(RepairTaskStatusEnum.TASK_STATUS_NO_REVIEW.getStatus());
                }
                tmTaskNotExam.setUpdateTime(new Date());
                tmTaskNotExam.setUpdateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
                taskMapper.updateTmTask(tmTaskNotExam);
            }
            if (CollectionUtil.isNotEmpty(scrapAudit.getAuditDetailList())) {
                if (CollectionUtil.isNotEmpty(auditDetailList)) {
                    for (RepairAuditDetails bean : auditDetailList) {
                        bean.setAuditBy(SecurityUtils.getLoginUser().getUserid());
                        bean.setStatus(String.valueOf(status));
                        bean.setUpdateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
                        bean.setAuditRemark(scrapAudit.getRemark());
                        repairAuditDetailsMapper.updateStatus(bean);
                    }
                }
            } else {
                if (null != auditAllList) {
                    for (RepairAuditDetails bean : auditAllList) {
                        bean.setAuditBy(SecurityUtils.getLoginUser().getUserid());
                        bean.setStatus(String.valueOf(status));
                        bean.setUpdateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
                        bean.setAuditRemark(scrapAudit.getRemark());
                        repairAuditDetailsMapper.updateStatus(bean);
                    }
                }
            }
        }
        return 1;
    }

    /**采购单号编码生成规则*/
    private @NotNull String purchaseCodeRule(String code, Integer taskType) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        Date nowDate = DateUtils.getNowDate();
        String format = dateFormat.format(nowDate);
        String taskNum = taskMapper.selectTaskNumByMonths(nowDate, taskType);
        if (StringUtils.isNotEmpty(taskNum)){
            // 将字符串转换为整数并加一
            int num = Integer.parseInt(taskNum) + 1;
            // 将结果转换回字符串格式
            taskNum = String.format("%03d", num);
        }else {
            taskNum = "001";
        }
        return code + format + "-" + taskNum;
    }

    /**
     * 生成任务并返回任务id
     */
    private long genTask(String taskCode, int taskType, int taskStatus, @NotNull TmTaskAgreement tmTaskAgreement, int companyId) {
        TmTask task = new TmTask();
        task.setCode(taskCode);
        task.setTaskStatus(taskStatus);
        task.setTaskType(taskType);
        task.setCompanyId((long) companyId);
        task.setCreateTime(new Date());
        task.setCreateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
        taskMapper.insertTmTask(task);
        // 添加协议信息表
        TmTaskAgreement taskAgreement = new TmTaskAgreement();
        long taskId = task.getTaskId();
        taskAgreement.setTaskId(taskId);
        if (tmTaskAgreement.getAgreementId() == null) {
            throw new ServiceException("缺少协议数据");
        } else {
            taskAgreement.setAgreementId(tmTaskAgreement.getAgreementId());
        }
        taskAgreement.setCreateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
        agreementMapper.insertTmTaskAgreement(taskAgreement);
        return taskId;
    }


    /**
     * 查询修试审核详细
     *
     * @param id 修试审核详细主键
     * @return 修试审核详细
     */
    @Override
    public RepairAuditDetails selectRepairAuditDetailsById(Long id) {
        return repairAuditDetailsMapper.selectRepairAuditDetailsById(id);
    }

    /**
     * 公共方法来处理时间格式化
     */
    @Override
    public void formatTimeParam(@NotNull Map<String, Object> params, String key, String suffix) {
        String time = (String) params.get(key);
        if (time != null && !time.isEmpty()) {
            params.put(key, time.trim() + suffix);
        } else {
            params.remove(key);
        }
    }

    /**
     * 查询修试审核详细列表
     *
     * @param repairAuditDetails 修试审核详细
     * @return 修试审核详细
     */
    @Override
    public List<RepairAuditDetails> selectRepairAuditDetailsList(RepairAuditDetails repairAuditDetails) {
        return repairAuditDetailsMapper.selectRepairAuditDetailsList(repairAuditDetails);
    }

    /**
     * 新增修试审核详细
     *
     * @param repairAuditDetails 修试审核详细
     * @return 结果
     */
    @Override
    public int insertRepairAuditDetails(@NotNull RepairAuditDetails repairAuditDetails) {
        repairAuditDetails.setCreateTime(DateUtils.getNowDate());
        try {
            return repairAuditDetailsMapper.insertRepairAuditDetails(repairAuditDetails);
        } catch (Exception e) {
            throw new ServiceException("错误信息描述");
        }
    }

    /**
     * 修改修试审核详细
     *
     * @param repairAuditDetails 修试审核详细
     * @return 结果
     */
    @Override
    public int updateRepairAuditDetails(@NotNull RepairAuditDetails repairAuditDetails) {
        repairAuditDetails.setUpdateTime(DateUtils.getNowDate());
        try {
            return repairAuditDetailsMapper.updateRepairAuditDetails(repairAuditDetails);
        } catch (Exception e) {
            throw new ServiceException("错误信息描述");
        }
    }

    /**
     * (外层)批量修改修试审核详细
     *
     * @param repairAuditDetails (外层)修试审核详细集合
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int outerAudit(@NotNull List<RepairAuditDetails> repairAuditDetails) {
        final List<Long> taskIds = repairAuditDetails.stream()
                .filter(Objects::nonNull)
                .map(RepairAuditDetails::getTaskId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        if (taskIds.isEmpty()) {
            return 0;
        }
        final List<RepairAuditDetails> repairAuditDetailsByQuery = repairAuditDetailsMapper.selectRepairAuditDetailsByTaskIds(taskIds);
        if (CollectionUtils.isEmpty(repairAuditDetailsByQuery)) {
            return 0;
        }

        // 1:通过 2:驳回 0:未处理
        final String status = repairAuditDetails.get(0).getStatus();
        try {
            if ("1".equals(status)) {
                for (final RepairAuditDetails repairAuditDetail : repairAuditDetails) {
//                    // 删除repair_input_details 维修入库明细？
//                    repairInputDetailsMapper.deleteRepairInputDetailsByTaskId(repairAuditDetail.getTaskId());
                    // 查询协议ID
                    Long agreementId = taskAgreementMapper.selectAgreementIdByTaskId(repairAuditDetail.getTaskId());
                    // 查询维修审核明细
                    final List<RepairAuditDetails> repairAuditDetailList = repairAuditDetailsMapper.selectRepairAuditDetailsByTaskIds(Collections.singletonList(repairAuditDetail.getTaskId()));
                    // 批量插入维修入库明细
                    List<ScrapApplyDetails> scrapApplyDetails = new ArrayList<>();
                    batchInsertRepairInputDetails(scrapApplyDetails, repairAuditDetailList, agreementId);
                    // 更新任务状态
                    taskMapper.updateTaskStatus(String.valueOf(repairAuditDetail.getTaskId()), RepairTaskStatusEnum.TASK_STATUS_REVIEW.getStatus());
                }
            } else if ("2".equals(status)) {
                for (RepairAuditDetails auditDetails : repairAuditDetails) {
                    RepairTask task = new RepairTask();
                    task.setTaskId(auditDetails.getTaskId());
                    Long agreementId = repairMapper.getAgreementId(task);
                    // 插入任务表
                    Long newTaskId = insertWxTt(SecurityUtils.getLoginUser().getSysUser().getNickName());
                    // 插入协议任务表
                    insertTta(newTaskId, agreementId);
                    // 处理 -- 修饰审核任务状态
                    taskMapper.updateTaskStatus(String.valueOf(auditDetails.getTaskId()), RepairTaskStatusEnum.TASK_STATUS_NO_REVIEW.getStatus());
                    // 处理 -- 原维修任务单的状态（提交修饰审核前拆分的任务）
                    TmTask preTmTaskInfo = taskMapper.selectTmTaskByTaskId(auditDetails.getTaskId());
                    List<RepairTaskDetails> detailsList = repairApplyDetailsMapper.getRepairDetailsWhichNotSent(preTmTaskInfo.getPreTaskId());
                    Long backId = null;
                    String level = null;
                    if (!CollectionUtils.isEmpty(detailsList)) {
                        backId = detailsList.get(0).getBackId();
                        // 根据backId查询最大级level
                        RepairTaskDetails details = repairApplyDetailsMapper.getMaxLevel(backId);
                        if (details != null) {
                            level = details.getLevel();
                        }
                    }
                    // 根据taskId查询维修审核明细
                    final List<RepairAuditDetails> repairAuditDetailsByTaskId = repairAuditDetailsMapper.selectRepairAuditDetailsByTaskId(auditDetails.getTaskId());
                    if (!CollectionUtils.isEmpty(repairAuditDetailsByTaskId)) {
                        for (RepairAuditDetails repairAuditDetail : repairAuditDetailsByTaskId) {
                            RepairTaskDetails repairTaskDetails = new RepairTaskDetails();
                            repairTaskDetails.setNewTaskId(newTaskId);
                            repairTaskDetails.setMaId(repairAuditDetail.getMaId() == null ? null : repairAuditDetail.getMaId().toString());
                            repairTaskDetails.setTypeId(repairAuditDetail.getTypeId().toString());
                            repairTaskDetails.setRepairNum(repairAuditDetail.getRepairNum());
                            repairTaskDetails.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                            repairTaskDetails.setBackId(backId);
                            repairTaskDetails.setStatus("0");
                            repairTaskDetails.setIsDs(1);
                            if(StringUtils.isNotBlank( level)) {
                                repairTaskDetails.setLevel(String.valueOf(Integer.parseInt(level) + 1));
                            }
                            repairMapper.insertRepaired(repairTaskDetails);
                        }
                    }
                }
            }

            try {
                final List<Long> ids = repairAuditDetailsByQuery.stream()
                        .filter(Objects::nonNull)
                        .map(RepairAuditDetails::getId)
                        .filter(Objects::nonNull)
                        .collect(Collectors.toList());
                Long auditBy = SecurityUtils.getLoginUser().getUserid();
                return repairAuditDetailsMapper.updateRepairAuditDetailsBatch(ids, String.valueOf(status), auditBy);
            } catch (final Exception e) {
                throw new ServiceException("错误信息描述");
            }
        } catch (ServiceException e) {
            log.error("修改维修审核状态失败", e);
            throw new ServiceException("修饰审核失败，请联系管理员");
        }
    }

    /**
     * 新增维修任务
     * @param createBy
     * @return
     */
    private Long insertWxTt(String createBy) {
        Long newTask = null;
        int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_REPAIR.getTaskTypeId());
        // 生成维修单号
        String code = genderNewWxTaskCode(thisMonthMaxOrder);
        TmTask tmTask = new TmTask(null, TmTaskTypeEnum.TM_TASK_REPAIR.getTaskTypeId(), RepairTaskStatusEnum.TASK_STATUS_PROCESSING.getStatus(),
                null,thisMonthMaxOrder + 1, code);
        tmTask.setCreateTime(DateUtils.getNowDate());
        tmTask.setCreateBy(createBy);
        // 插入任务
        int taskId = taskMapper.insertTmTask(tmTask);
        // 如果插入成功且返回的 taskId 大于 0
        if (taskId > 0 && tmTask.getTaskId() > 0) {
            newTask = tmTask.getTaskId();
        }
        return newTask;
    }

    /**
     * 生成维修单号
     * @param thisMonthMaxOrder
     * @return
     */
    private String genderNewWxTaskCode(int thisMonthMaxOrder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date nowDate = DateUtils.getNowDate();
        String format = dateFormat.format(nowDate);
        String result = format.replace("-", "");
        return MaterialConstants.REPAIR_TASK_TYPE_LABEL + result + String.format("-%03d", thisMonthMaxOrder + 1);
    }

    /**
     * 批量修改修试审核详细
     *
     * @param repairAuditDetails 修试审核详细
     * @return 结果
     */
    @Override
    public int updateRepairAuditDetailsBatch(@NotNull List<RepairAuditDetails> repairAuditDetails) {
        List<Long> ids = repairAuditDetails.stream()
                .filter(Objects::nonNull)
                .map(RepairAuditDetails::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        if (ids.isEmpty()) {
            return 0;
        }
        final RepairAuditDetails auditDetails1 = repairAuditDetails.get(0);
        final String status = auditDetails1.getStatus(); // 1通过 2驳回
        // 根据repairId查询前任务id
        RepairAuditDetails dto = repairApplyDetailsMapper.selectById(auditDetails1.getRepairId());
        // 查询报废详情
        final List<ScrapApplyDetails> scrapApplyDetails = scrapApplyDetailsMapper.selectScrapByTaskId(dto);
        if ("1".equals(status)) {
            //根据任务id查询协议id
            final Long agreementId = taskAgreementMapper.selectAgreementIdByTaskId(auditDetails1.getTaskId());
            batchInsertRepairInputDetails(scrapApplyDetails,repairAuditDetails, agreementId);
        } else if ("2".equals(status)) {
            RepairTask task = new RepairTask();
            task.setTaskId(dto.getTaskId());
            Long agreementId = repairMapper.getAgreementId(task);
            // 插入任务表
            Long newTaskId = insertWxTt(SecurityUtils.getLoginUser().getSysUser().getNickName());
            // 插入协议任务表
            insertTta(newTaskId, agreementId);
            // 处理 -- 修饰审核任务状态
            //taskMapper.updateTaskStatus(String.valueOf(dto.getTaskId()), RepairTaskStatusEnum.TASK_STATUS_NO_REVIEW.getStatus());
            List<RepairTaskDetails> detailsList = repairApplyDetailsMapper.getRepairDetailsWhichNotSent(dto.getTaskId());
            Long backId = null;
            String level = null;
            if (!CollectionUtils.isEmpty(detailsList)) {
                backId = detailsList.get(0).getBackId();
                // 根据backId查询最大级level
                RepairTaskDetails details = repairApplyDetailsMapper.getMaxLevel(backId);
                if (details != null) {
                    level = details.getLevel();
                }
            }
            for (RepairAuditDetails repairAuditDetail : repairAuditDetails) {
                RepairTaskDetails repairTaskDetails = new RepairTaskDetails();
                repairTaskDetails.setNewTaskId(newTaskId);
                repairTaskDetails.setMaId(repairAuditDetail.getMaId() == null ? null : repairAuditDetail.getMaId().toString());
                repairTaskDetails.setTypeId(repairAuditDetail.getTypeId().toString());
                repairTaskDetails.setRepairNum(repairAuditDetail.getRepairNum());
                repairTaskDetails.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                repairTaskDetails.setBackId(backId);
                repairTaskDetails.setIsDs(1);
                repairAuditDetail.setStatus("0");
                if(StringUtils.isNotBlank( level)) {
                    repairTaskDetails.setLevel(String.valueOf(Integer.parseInt(level) + 1));
                }
                repairMapper.insertRepaired(repairTaskDetails);
            }
        }

        try {
            Long userId = SecurityUtils.getLoginUser().getUserid();
            int result = repairAuditDetailsMapper.updateRepairAuditDetailsBatch(ids, status, userId);
            // 根据任务id查询内层详情任务状态，更新外层任务状态
            List<RepairAuditDetails> repairAuditDetailsByTaskId = repairAuditDetailsMapper.getAuditStatus(auditDetails1.getTaskId());
            if (!CollectionUtils.isEmpty(repairAuditDetailsByTaskId)) {
                // 获取集合中的全部status集合
                List<Integer> statusList = repairAuditDetailsByTaskId.stream()
                        .map(scrapApplyDetail -> Integer.parseInt(scrapApplyDetail.getStatus()))
                        .collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(statusList)) {
                    boolean notContainsNoFinished =!statusList.contains(RepairTaskStatusEnum.TASK_STATUS_PROCESSING.getStatus());
                    boolean allReject = true;
                    for (Integer newStatus : statusList) {
                        if (!newStatus.equals(RepairTaskStatusEnum.TASK_STATUS_REJECT.getStatus())) {
                            allReject = false;
                            break;
                        }
                    }
                    if (notContainsNoFinished && !allReject) {
                        taskMapper.updateTaskStatus(auditDetails1.getTaskId().toString(), RepairTaskStatusEnum.TASK_STATUS_REVIEW.getStatus());
                    } else if (notContainsNoFinished && allReject) {
                        taskMapper.updateTaskStatus(auditDetails1.getTaskId().toString(), RepairTaskStatusEnum.TASK_STATUS_NO_REVIEW.getStatus());
                    }
                }
            }
            return result;
        } catch (final Exception e) {
            throw new ServiceException("错误信息描述");
        }
    }

    /**
     * 批量插入维修明细
     * @param scrapApplyDetailList 报废明细
     * @param repairAuditDetailsByQuery 维修明细by查询
     * @param agreementId 协议ID
     */
    private void batchInsertRepairInputDetails(List<ScrapApplyDetails> scrapApplyDetailList, List<RepairAuditDetails> repairAuditDetailsByQuery, Long agreementId) {
        boolean inputFlag = false;
        boolean scrapFlag = false;
        for (RepairAuditDetails repairAuditDetails : repairAuditDetailsByQuery) {
            if (repairAuditDetails.getRepairedNum().compareTo(BigDecimal.ZERO) > 0) {
                inputFlag = true;  // 标记需要插入修饰任务
            }
            if (repairAuditDetails.getScrapNum().compareTo(BigDecimal.ZERO) > 0) {
                scrapFlag = true;  // 标记需要插入报废任务
            }
            // 如果两个标志都已满足，提前跳出循环
            if (inputFlag && scrapFlag) {
                break;
            }
        }
        //插入修饰审核入库任务表
        Long newTaskId = null;
        if (inputFlag) {
            // 插入任务表
            newTaskId = insertTt();
            // 插入任务协议关联表
            insertTta(newTaskId, agreementId);
        }
        //插入报废任务表
        Long newScrapTaskId = null;
        if (scrapFlag) {
            newScrapTaskId = insertScrapTt();
            insertScrapTta(newScrapTaskId, agreementId);
        }
        final List<RepairInputDetails> inputList = new ArrayList<>();

        List<RepairAuditDetails> dtoArray = new ArrayList<>();
        List<ScrapApplyDetails> listAll = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(repairAuditDetailsByQuery)) {
            dtoArray = repairApplyDetailsMapper.selectRepairCodeByIds(repairAuditDetailsByQuery.stream().map(RepairAuditDetails::getRepairId).collect(Collectors.toList()));
            repairApplyDetailsMapper.updateRepairApplyDetailsAfterAuditBatch(repairAuditDetailsByQuery);
            listAll = scrapApplyDetailsMapper.selectScrapByTaskIdList(repairAuditDetailsByQuery);
        }

        for (final RepairAuditDetails details : repairAuditDetailsByQuery) {
            RepairAuditDetails dto;
            if (CollectionUtil.isEmpty(dtoArray)) {
                dto = repairApplyDetailsMapper.selectById(details.getRepairId());
                // 根据taskId修改repair_apply_record的status状态为已审核1
                repairApplyDetailsMapper.updateRepairApplyDetailsAfterAudit(dto);
            } else {
                dto = dtoArray.stream().filter(dto1 -> dto1.getRepairId().equals(details.getRepairId())).findFirst().orElse(null);
            }

            List<ScrapApplyDetails> list;
            if (CollectionUtil.isNotEmpty(listAll)) {
                list = listAll.stream().filter(item -> {
                    if (dto != null) {
                        return item.getTaskId().equals(dto.getTaskId());
                    }
                    return false;
                }).collect(Collectors.toList());
            } else {
                list = scrapApplyDetailsMapper.selectScrapByTaskId(dto);
            }

            if (details.getRepairedNum().compareTo(BigDecimal.ZERO) > 0) {
                //修改机具状态为修试后待入库
                if (null != details.getMaId()) {
                    details.setStatus(MaMachineStatusEnum.REPAIR_TO_STORE.getStatus().toString());
                    repairAuditDetailsMapper.updateMachine(details);
                }
                final RepairInputDetails inputVo = new RepairInputDetails();
                BeanUtils.copyProperties(details, inputVo);
                inputVo.setRepairNum(details.getRepairedNum());
                inputVo.setAuditId(details.getId());
                inputVo.setStatus("0");
                inputVo.setTaskId(newTaskId);
                inputVo.setCreateBy(String.valueOf(SecurityUtils.getLoginUser().getUserid()));
                inputList.add(inputVo);
            }
            if (details.getScrapNum().compareTo(BigDecimal.ZERO) > 0) {
                //修改机具状态为报废待审核
                if (null != details.getMaId()) {
                    details.setStatus(MaMachineStatusEnum.SCRAP_TO_AUDIT.getStatus().toString());
                    repairAuditDetailsMapper.updateMachine(details);
                }
                if (!CollectionUtils.isEmpty(list)) {
                    for (ScrapApplyDetails info : list) {
                        if (info.getScrapNum().compareTo(BigDecimal.ZERO) == 0) {
                            continue;
                        }
                        ScrapApplyDetails scrapApplyDetails = new ScrapApplyDetails();
                        scrapApplyDetails.setTaskId(newScrapTaskId);
                        scrapApplyDetails.setTypeId(details.getTypeId());
                        scrapApplyDetails.setMaId(details.getMaId() == null ? null : details.getMaId());
                        scrapApplyDetails.setScrapNum(info.getScrapNum());
                        scrapApplyDetails.setScrapSource("2");
                        scrapApplyDetails.setStatus("0");
                        scrapApplyDetails.setParentId(details.getId());
                        scrapApplyDetails.setCreateTime(new Date());
                        scrapApplyDetails.setScrapReason(info.getScrapReason() == null ? "" : info.getScrapReason());
                        scrapApplyDetails.setScrapType(info.getScrapType() == null ? null : info.getScrapType());
                        scrapApplyDetails.setCreateBy(info.getCreateBy() == null ? SecurityUtils.getLoginUser().getSysUser().getNickName() : info.getCreateBy());
                        scrapApplyDetailsMapper.insertScrapApplyDetails(scrapApplyDetails);
                    }
                }
            }
        }
        // 插入维修入库明细
        if (!CollectionUtils.isEmpty(inputList)) {
            repairInputDetailsMapper.batchInsertRepairInputDetails(inputList);
        }
    }

    /**
     * 插入报废任务表
     * @param newScrapTaskId
     * @param agreementId
     */
    private void insertScrapTta(Long newScrapTaskId, Long agreementId) {
        final TmTaskAgreement tmTaskAgreement = new TmTaskAgreement(newScrapTaskId, agreementId);
        tmTaskAgreement.setCreateTime(DateUtils.getNowDate());
        tmTaskAgreement.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        taskAgreementMapper.insertTmTaskAgreement(tmTaskAgreement);
    }

    /**
     * 插入报废任务表
     * @return
     */
    private Long insertScrapTt() {
        Long newTask = null;
        int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_SCRAP.getTaskTypeId());
        // 生成报废单号
        String code = genderBfTaskCode(thisMonthMaxOrder);
        // 根据单号查询该任务是否存在
        TmTask task = taskMapper.selectTaskByCode(code);
        if (task != null) {
            throw new RuntimeException("该审核任务正在进行中，请勿重复提交!");
        }
        TmTask tmTask = new TmTask(null, TmTaskTypeEnum.TM_TASK_SCRAP.getTaskTypeId(), ScrapTaskStatusEnum.SCRAP_TASK_NO_FINISHED.getStatus(),
                null,thisMonthMaxOrder + 1, code);
        tmTask.setCreateTime(DateUtils.getNowDate());
        tmTask.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        // 插入任务
        int taskId = taskMapper.insertTmTask(tmTask);
        // 如果插入成功且返回的 taskId 大于 0
        if (taskId > 0 && tmTask.getTaskId() > 0) {
            newTask = tmTask.getTaskId();
        }
        return newTask;
    }

    /**
     * 生成报废单号
     * @param thisMonthMaxOrder
     * @return
     */
    private String genderBfTaskCode(int thisMonthMaxOrder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date nowDate = DateUtils.getNowDate();
        String format = dateFormat.format(nowDate);
        String result = format.replace("-", "");
        return MaterialConstants.SCRAP_TASK_TYPE_LABEL + result + String.format("-%03d", thisMonthMaxOrder + 1);
    }

    /**
     * 插入任务关联表
     * @param newTaskId
     * @param agreementId
     */
    private void insertTta(Long newTaskId, Long agreementId) {
        final TmTaskAgreement tmTaskAgreement = new TmTaskAgreement(newTaskId, agreementId);
        tmTaskAgreement.setCreateTime(DateUtils.getNowDate());
        tmTaskAgreement.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        taskAgreementMapper.insertTmTaskAgreement(tmTaskAgreement);
    }

    /**
     * 插入任务表
     * @return
     */
    private Long insertTt() {
        Long newTask = null;
        int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_REPAIR_INPUT.getTaskTypeId());
        // 生成修饰入库单号
        String code = genderWxTaskCode(thisMonthMaxOrder);
        TmTask tmTask = new TmTask(null, TmTaskTypeEnum.TM_TASK_REPAIR_INPUT.getTaskTypeId(), RepairInputStatusEnum.INPUT_TASK_NO_FINISHED.getStatus(),
                null,thisMonthMaxOrder + 1, code);
        tmTask.setCreateTime(DateUtils.getNowDate());
        tmTask.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        // 根据code查询此任务单号是否存在
        TmTask task = taskMapper.selectTaskByCode(code);
        if (task != null) {
            throw new RuntimeException("该审核任务正在进行中，请勿重复提交!");
        }
        // 插入任务
        int taskId = taskMapper.insertTmTask(tmTask);
        // 如果插入成功且返回的 taskId 大于 0
        if (taskId > 0 && tmTask.getTaskId() > 0) {
            newTask = tmTask.getTaskId();
        }
        return newTask;
    }

    /**
     * 生成修饰入库单号
     * @param thisMonthMaxOrder
     * @return
     */
    private String genderWxTaskCode(int thisMonthMaxOrder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date nowDate = DateUtils.getNowDate();
        String format = dateFormat.format(nowDate);
        String result = format.replace("-", "");
        return MaterialConstants.REPAIR_INPUT_TASK_TYPE_LABEL + result + String.format("-%03d", thisMonthMaxOrder + 1);
    }

    /**
     * 批量删除修试审核详细
     *
     * @param ids 需要删除的修试审核详细主键
     * @return 结果
     */
    @Override
    public int deleteRepairAuditDetailsByIds(Long[] ids) {
        return repairAuditDetailsMapper.deleteRepairAuditDetailsByIds(ids);
    }

    /**
     * 删除修试审核详细信息
     *
     * @param id 修试审核详细主键
     * @return 结果
     */
    @Override
    public int deleteRepairAuditDetailsById(Long id) {
        return repairAuditDetailsMapper.deleteRepairAuditDetailsById(id);
    }

    /**
     * 查询修试审核任务详情
     * @param repairAuditDetails
     * @return
     */
    @Override
    public List<RepairAuditDetails> getDetailsList(RepairAuditDetails repairAuditDetails) {
        return repairAuditDetailsMapper.getDetailsList(repairAuditDetails);
    }

    /**
     * 查询修饰一览表
     * @param dto
     * @return
     */
    @Override
    public List<RepairHomeInfo> getRepairHomeList(RepairHomeInfo dto) {
        BigDecimal totalBackNum = BigDecimal.ZERO.setScale(3, RoundingMode.HALF_UP);
        BigDecimal totalRepairedNum = BigDecimal.ZERO.setScale(3, RoundingMode.HALF_UP);
        BigDecimal totalRepairingNum = BigDecimal.ZERO.setScale(3, RoundingMode.HALF_UP);
        BigDecimal totalScrapNum = BigDecimal.ZERO.setScale(3, RoundingMode.HALF_UP);
        BigDecimal totalTestNum = BigDecimal.ZERO.setScale(3, RoundingMode.HALF_UP);
        BigDecimal totalChangePartNum = BigDecimal.ZERO.setScale(3, RoundingMode.HALF_UP);
        BigDecimal totalAmountPartPrice = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
        BigDecimal totalNoAmountPartPrice = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
        // 查询总接收数量
        List<RepairHomeInfo> repairHomeList = repairAuditDetailsMapper.getRepairHomeList(dto);
        if (!CollectionUtils.isEmpty(repairHomeList)) {
            String keyWord = dto.getKeyWord();
            // 如果关键字不为空，进行过滤
            if (!StringUtils.isBlank(keyWord)) {
                repairHomeList = repairHomeList.stream()
                        .filter(item -> containsRepairKeyword(item, keyWord))
                        .collect(Collectors.toList());
            }
            for (RepairHomeInfo repairHomeInfo : repairHomeList) {
                // 根据taskId和typeId查询详情数据
                List<RepairHomeInfo> detailsList = repairAuditDetailsMapper.selectDetails(repairHomeInfo);
                if (!CollectionUtils.isEmpty(detailsList)) {
                    BigDecimal repairedNum = BigDecimal.ZERO.setScale(3, RoundingMode.HALF_UP);
                    BigDecimal repairingNum = BigDecimal.ZERO.setScale(3, RoundingMode.HALF_UP);
                    BigDecimal scrapNum = BigDecimal.ZERO.setScale(3, RoundingMode.HALF_UP);
                    BigDecimal testNum = BigDecimal.ZERO.setScale(3, RoundingMode.HALF_UP);
                    BigDecimal changePartNum = BigDecimal.ZERO.setScale(3, RoundingMode.HALF_UP);
                    BigDecimal amountPartPrice = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
                    BigDecimal noAmountPartPrice = BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
                    for (RepairHomeInfo homeInfo : detailsList) {
                        repairedNum = repairedNum.add(homeInfo.getRepairedNum());
                        //repairingNum = repairingNum.add(homeInfo.getRepairingNum());
                        scrapNum = scrapNum.add(homeInfo.getScrapNum());
                        testNum = testNum.add(homeInfo.getTestNum());
                        changePartNum = changePartNum.add(homeInfo.getChangePartNum());
                        noAmountPartPrice = noAmountPartPrice.add(homeInfo.getNoAmountPartPrice());
                        amountPartPrice = amountPartPrice.add(homeInfo.getAmountPartPrice());
                        totalChangePartNum = totalChangePartNum.add(homeInfo.getChangePartNum());
                        totalAmountPartPrice = totalAmountPartPrice.add(homeInfo.getAmountPartPrice());
                        totalNoAmountPartPrice = totalNoAmountPartPrice.add(homeInfo.getNoAmountPartPrice());
                        totalRepairedNum = totalRepairedNum.add(homeInfo.getRepairedNum());
                        totalScrapNum = totalScrapNum.add(homeInfo.getScrapNum());
                        totalTestNum = totalTestNum.add(homeInfo.getTestNum());
                    }
                    repairHomeInfo.setRepairedNum(repairedNum);
                    repairHomeInfo.setScrapNum(scrapNum);
                    repairHomeInfo.setRepairingNum(repairHomeInfo.getBackNum().subtract(repairedNum));
                    repairHomeInfo.setTestNum(testNum);
                    repairHomeInfo.setChangePartNum(changePartNum);
                    repairHomeInfo.setAmountPartPrice(amountPartPrice);
                    repairHomeInfo.setNoAmountPartPrice(noAmountPartPrice);
                    totalRepairingNum = totalRepairingNum.add(repairHomeInfo.getRepairingNum());
                }
                totalBackNum = totalBackNum.add(repairHomeInfo.getBackNum());
            }
            if (dto.getIsExport() == 0) {
                RepairHomeInfo info = new RepairHomeInfo();
                info.setBackNum(totalBackNum);
                info.setRepairedNum(totalRepairedNum);
                info.setRepairingNum(totalRepairingNum);
                info.setScrapNum(totalScrapNum);
                info.setTestNum(totalTestNum);
                info.setChangePartNum(null);
                info.setAmountPartPrice(null);
                info.setNoAmountPartPrice(null);
                info.setUnitName("合计");
                repairHomeList.add(0, info);
            }
        }
        return repairHomeList;
    }

    /**
     * 判断是否包含关键字
     * @param item
     * @param keyWord
     * @return
     */
    private boolean containsRepairKeyword(RepairHomeInfo item, String keyWord) {
        return (item.getTypeName() != null && item.getTypeName().contains(keyWord)) ||
                (item.getTypeModelName() != null && item.getTypeModelName().contains(keyWord)) ||
                (item.getRepairCode() != null && item.getRepairCode().contains(keyWord));
    }

    /**
     * 查询修饰一览表总计
     * @param dto
     * @return
     */
    @Override
    public List<RepairHomeInfo> getRepairHomeTotalList(RepairHomeInfo dto) {
        List<RepairHomeInfo> infos = new ArrayList<>();
        // 本月固定时间段查询
        List<RepairHomeInfo> repairHomeList = getRepairHomeList(dto);
        // 根据前端传入的startTime和endTime进行上月同比时间查询
        if (!StringUtils.isEmpty(dto.getStartTime()) && !StringUtils.isEmpty(dto.getEndTime())) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            LocalDate startDate = LocalDate.parse(dto.getStartTime(), formatter);
            LocalDate endDate = LocalDate.parse(dto.getEndTime(), formatter);
            // 获取上月同期开始时间
            LocalDate lastMonthStart = startDate.minusMonths(1);
            // 获取上月同期结束时间
            LocalDate lastMonthEnd = endDate.minusMonths(1);
            dto.setStartTime(lastMonthStart.format(formatter));
            dto.setEndTime(lastMonthEnd.format(formatter));
            List<RepairHomeInfo> lastMonthList = getRepairHomeList(dto);
            if (!CollectionUtils.isEmpty(lastMonthList) && !CollectionUtils.isEmpty(repairHomeList)) {
                    RepairHomeInfo thisMonthInfo = repairHomeList.get(0);
                    RepairHomeInfo lastMonthInfo = lastMonthList.get(0);
                    // 计算各项指标的同比
                    calculateAndAddInfo(infos, thisMonthInfo::getBackNum, lastMonthInfo::getBackNum, RepairHomeInfo::setBackNum);
                    calculateAndAddInfo(infos, thisMonthInfo::getRepairedNum, lastMonthInfo::getRepairedNum, RepairHomeInfo::setRepairedNum);
                    calculateAndAddInfo(infos, thisMonthInfo::getRepairingNum, lastMonthInfo::getRepairingNum, RepairHomeInfo::setRepairingNum);
                    calculateAndAddInfo(infos, thisMonthInfo::getScrapNum, lastMonthInfo::getScrapNum, RepairHomeInfo::setScrapNum);
                    calculateAndAddInfo(infos, thisMonthInfo::getTestNum, lastMonthInfo::getTestNum, RepairHomeInfo::setTestNum);
            } else if (CollectionUtils.isEmpty(lastMonthList) && !CollectionUtils.isEmpty(repairHomeList)) {
                RepairHomeInfo thisMonthInfo = repairHomeList.get(0);
                RepairHomeInfo info = new RepairHomeInfo();
                info.setBackNum(thisMonthInfo.getBackNum());
                info.setIncrease(BigDecimal.valueOf(100));
                info.setIsIncrease(true);
                infos.add(info);
                info = new RepairHomeInfo();
                info.setRepairedNum(thisMonthInfo.getRepairedNum());
                info.setIncrease(BigDecimal.valueOf(100));
                info.setIsIncrease(true);
                infos.add(info);
                info = new RepairHomeInfo();
                info.setRepairingNum(thisMonthInfo.getRepairingNum());
                info.setIncrease(BigDecimal.valueOf(100));
                info.setIsIncrease(true);
                infos.add(info);
                info = new RepairHomeInfo();
                info.setScrapNum(thisMonthInfo.getScrapNum());
                info.setIncrease(BigDecimal.valueOf(100));
                info.setIsIncrease(true);
                infos.add(info);
                info = new RepairHomeInfo();
                info.setTestNum(thisMonthInfo.getTestNum());
                info.setIncrease(BigDecimal.valueOf(100));
                info.setIsIncrease(true);
                infos.add(info);
            } else if (!CollectionUtils.isEmpty(lastMonthList) && CollectionUtils.isEmpty(repairHomeList)) {
                RepairHomeInfo info = new RepairHomeInfo();
                info.setBackNum(BigDecimal.ZERO);
                info.setIncrease(BigDecimal.valueOf(100));
                info.setIsIncrease(false);
                infos.add(info);
                info = new RepairHomeInfo();
                info.setRepairedNum(BigDecimal.ZERO);
                info.setIncrease(BigDecimal.valueOf(100));
                info.setIsIncrease(false);
                infos.add(info);
                info = new RepairHomeInfo();
                info.setRepairingNum(BigDecimal.ZERO);
                info.setIncrease(BigDecimal.valueOf(100));
                info.setIsIncrease(false);
                infos.add(info);
                info = new RepairHomeInfo();
                info.setScrapNum(BigDecimal.ZERO);
                info.setIncrease(BigDecimal.valueOf(100));
                info.setIsIncrease(false);
                infos.add(info);
                info = new RepairHomeInfo();
                info.setTestNum(BigDecimal.ZERO);
                info.setIncrease(BigDecimal.valueOf(100));
                info.setIsIncrease(false);
                infos.add(info);
            } else {
                RepairHomeInfo info = new RepairHomeInfo();
                info.setBackNum(BigDecimal.ZERO);
                info.setIncrease(BigDecimal.ZERO);
                info.setIsIncrease(true);
                infos.add(info);
                info = new RepairHomeInfo();
                info.setRepairedNum(BigDecimal.ZERO);
                info.setIncrease(BigDecimal.ZERO);
                info.setIsIncrease(true);
                infos.add(info);
                info = new RepairHomeInfo();
                info.setRepairingNum(BigDecimal.ZERO);
                info.setIncrease(BigDecimal.ZERO);
                info.setIsIncrease(true);
                infos.add(info);
                info = new RepairHomeInfo();
                info.setScrapNum(BigDecimal.ZERO);
                info.setIncrease(BigDecimal.ZERO);
                info.setIsIncrease(true);
                infos.add(info);
                info = new RepairHomeInfo();
                info.setTestNum(BigDecimal.ZERO);
                info.setIncrease(BigDecimal.ZERO);
                info.setIsIncrease(true);
                infos.add(info);
            }
        }
        return infos;
    }

    /**
     * 计算指标的同比
     * @param infos
     * @param thisMonthSupplier
     * @param lastMonthSupplier
     * @param setter
     */
    private void calculateAndAddInfo(List<RepairHomeInfo> infos,
                                     java.util.function.Supplier<BigDecimal> thisMonthSupplier,
                                     java.util.function.Supplier<BigDecimal> lastMonthSupplier,
                                     java.util.function.BiConsumer<RepairHomeInfo, BigDecimal> setter) {
        BigDecimal thisMonthValue = thisMonthSupplier.get();
        BigDecimal lastMonthValue = lastMonthSupplier.get();

        BigDecimal increase = calculateIncrease(thisMonthValue, lastMonthValue);

        RepairHomeInfo vo = new RepairHomeInfo();
        setter.accept(vo, thisMonthValue);
        vo.setIncrease(increase);
        vo.setIsIncrease(increase.compareTo(BigDecimal.ZERO) > 0);
        infos.add(vo);
    }

    /**
     * 计算指标的同比
     * @param thisMonthValue
     * @param lastMonthValue
     * @return
     */
    private BigDecimal calculateIncrease(BigDecimal thisMonthValue, BigDecimal lastMonthValue) {
        if (lastMonthValue.compareTo(BigDecimal.ZERO) != 0) {
            return thisMonthValue.subtract(lastMonthValue).divide(lastMonthValue, 2, RoundingMode.HALF_UP);
        }
        return BigDecimal.ZERO;
    }

}
