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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.bonus.common.biz.enums.RepairTaskStatusEnum;
import com.bonus.common.biz.enums.TmTaskTypeEnum;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.basic.domain.BmFileInfo;
import com.bonus.material.basic.mapper.BmFileInfoMapper;
import com.bonus.material.repair.domain.*;
import com.bonus.material.repair.domain.vo.RepairDeviceListVo;
import com.bonus.material.repair.domain.vo.RepairDeviceVO;
import com.bonus.material.repair.mapper.RepairMapper;
import com.bonus.material.repair.service.RepairService;
import com.bonus.material.task.mapper.TmTaskMapper;
import com.bonus.system.api.domain.SysUser;
import com.bonus.system.api.model.LoginUser;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author syruan
 */
@Service("RepairService")
public class RepairServiceImpl implements RepairService {

    @Resource
    private RepairMapper repairMapper;

    @Resource
    private TmTaskMapper taskMapper;

    @Resource
    private BmFileInfoMapper bmFileInfoMapper;

    // 1:内部维修   2:外部返厂维修   3:报废
    private final int inRepairType = 1, outRepairType = 2, scrapRepairType = 3;

    // 维修管理方式--0：编码管理   1：数量管理
    private final int manageTypeByCode = 0, manageTypeByNumber = 1;

    @Override
    public List<RepairTask> getRepairTaskList(RepairTask bean) {
        return repairMapper.getRepairTaskList(bean);
    }

    @Override
    public List<RepairTask> exportRepairTaskList(RepairTask bean) {
        return repairMapper.exportRepairTaskList(bean);
    }

    @Override
    public List<RepairDeviceListVo> getRepairMaTypeList(RepairTaskDetails bean) {
        bean.setCompanyId(null);
        List<RepairDeviceListVo> repairMaTypeList = repairMapper.getRepairMaTypeList(bean);

        if (repairMaTypeList.isEmpty()) {
            return repairMaTypeList;
        }

        // 创建Map集合，用于快速分组，使用 ConcurrentHashMap 保证线程安全
        Map<Long, RepairDeviceListVo> resultMap = new ConcurrentHashMap<>();

        // 遍历处理，把相同的父级对象，拆分到子集合中
        repairMaTypeList.forEach(item -> {
            // 创建对象，并复制字段value
            RepairDeviceVO repairDeviceVO = new RepairDeviceVO();
            try {
                BeanUtil.copyProperties(item, repairDeviceVO);
            } catch (Exception e) {
                // 记录异常日志，并提供更详细的错误信息
                System.err.println("复制属性时发生错误: {}" + e.getMessage());
                throw new RuntimeException("复制属性时发生错误", e);
            }

            if (item.getTypeNameId() == null) {
                // 处理 typeNameId 为空的情况
                System.err.println("typeNameId 为空，跳过当前项: " + item);
                return;
            }

           // 使用 computeIfAbsent 方法，如果 key 不存在，则创建一个新对象，并添加到 resultMap 中
           resultMap.computeIfAbsent(item.getTypeNameId(), k -> item).getRepairDeviceList().add(repairDeviceVO);
        });
        return new ArrayList<>(resultMap.values());
    }

    /**
     * 提交维修记录
     * @param bean repairApplyRecord
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult submitRepairApply(@NotNull(message = "参数不能为空") RepairApplyRecord bean) {
        // 获取维修详情记录：待维修、已维修、报废的数量
        RepairTaskDetails details = repairMapper.getById(bean.getId());
        LoginUser loginUser = SecurityUtils.getLoginUser();
        bean.setCreateBy(String.valueOf(loginUser.getUserid()));

        // 获取维修配件列表
        List<RepairPartDetails> partList = bean.getPartList();
        BigDecimal sfCosts = new BigDecimal("0");

        // 收费配件
        String sfPart = "1";

        if (CollectionUtil.isNotEmpty(partList)) {
            bean.setRepairNum(partList.get(0).getRepairNum());
            bean.setRepairer(partList.get(0).getRepairer());
        }

        // 根据维修类型，更新维修数量、报废数量
        switch (bean.getRepairType()) {
            case inRepairType: {
                int repairNum = verifyRepairNum(bean, details);
                // 更新维修数量、并修改维修人员
                repairMapper.updateRepairedNum(bean.getId(), repairNum, loginUser.getUserid(), loginUser.getUserid());
                break;
            }
            case outRepairType: {
                int repairNum = verifyRepairNum(bean, details);
                // 更新维修数量、维修人员不变
                repairMapper.updateRepairedNumTwo(bean.getId(), repairNum, loginUser.getUserid());
                break;
            }
            case scrapRepairType: {
                int scrapNum = details.getScrapNum() + bean.getScrapNum();
                int num = scrapNum + details.getRepairedNum();
                if (num > details.getRepairNum()) {
                    throw new ServiceException("维修数量大于维修总量");
                }
                // 更新报废数量
                repairMapper.updateScrapNum(bean.getId(), scrapNum, loginUser.getUserid());
                break;
            }
            default:
                break;
        }

        // 判断配件列表是否为空
        if (CollectionUtil.isNotEmpty(partList)) {
            // 内部维修
            if (Objects.equals(inRepairType, bean.getRepairType())) {
                // 遍历配件列表，判断配件类型，收费还是不收费
                for (RepairPartDetails partDetails : partList) {
                    if (partDetails.getPartId() != null) {
                        // 有维修配件时,如果价格为空，设置为0
                        if (partDetails.getPartCost() == null) {
                            partDetails.setPartCost(new BigDecimal(0));
                        }
                        partDetails.setTaskId(bean.getTaskId());
                        partDetails.setMaId(bean.getMaId());
                        partDetails.setTypeId(bean.getTypeId());
                        partDetails.setCreateBy(String.valueOf(loginUser.getUserid()));
                        partDetails.setCompanyId(bean.getCompanyId());

                        // 根据 partId  找配件单价
                        BigDecimal partPrice = repairMapper.selectPartPrice(partDetails.getPartId());
                        // 设置配件费用
                        partDetails.setPartCost(partPrice);
                        // 添加【维修配件明细表】
                        repairMapper.addPart(partDetails);

                        bean.setPartPrice(partDetails.getPartCost());
                        bean.setPartId((long) partDetails.getPartId().intValue());
                        bean.setPartNum(partDetails.getPartNum());
                        bean.setRepairContent(partDetails.getRepairContent());
                        bean.setPartType(partDetails.getPartType());
                        // 添加【维修记录表】
                        repairMapper.addRecord(bean);
                    } else {
                        // 不选维修配件时, 只添加【维修记录表】
                        repairMapper.addRecord(bean);
                    }
                }
            }

            // 返厂维修
            if (outRepairType == bean.getRepairType()) {
                bean.setPartName(partList.get(0).getPartName());
                bean.setPartType(partList.get(0).getPartType());
                bean.setRepairContent(partList.get(0).getRepairContent());
                if (partList.get(0).getSupplierId() == null) {
                    throw new ServiceException("请选择返厂厂家");
                } else {
                    bean.setSupplierId(partList.get(0).getSupplierId());
                }
                if (partList.get(0).getPartPrice() == null) {
                    bean.setPartPrice(new BigDecimal(0));
                } else {
                    bean.setPartPrice(partList.get(0).getPartPrice());
                }
                bean.setPartNum(partList.get(0).getPartNum());
                // 新增【维修记录表】
                repairMapper.addRecord(bean);
            }

            // 配件费用计算
            sfCosts = countPartCosts(partList, sfCosts);

            // 判断是否是收费配件
            if (sfPart.equals(sfCosts.toString())) {
                // SQL: 新增【维修费用记录表】
                repairMapper.addRepairCost(bean, sfCosts, sfPart);
            }
        } else {
            // 新增【维修记录表--预报废】
            repairMapper.addRecord(bean);
        }
        return AjaxResult.success();
    }

    /**
     * 校验维修数量
     */
    private static int verifyRepairNum(RepairApplyRecord bean, RepairTaskDetails details) {
        int repairNum = OptionalInt.of(details.getRepairedNum()).orElse(0) + bean.getRepairNum();
        if (repairNum + OptionalInt.of(details.getScrapNum()).orElse(0) > details.getRepairNum()) {
            throw new ServiceException("维修数量大于维修总量");
        }
        return repairNum;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult fastRepairApply(List<RepairTaskDetails> list) {
        LoginUser loginUser = SecurityUtils.getLoginUser();

        // 判断待维修数量是否大于0
        for (RepairTaskDetails bean : list) {
            int repairedNum = bean.getRepairNum() - bean.getRepairedNum() - bean.getScrapNum();
            if (repairedNum <= 0) {
                throw new ServiceException("选中的数据中包含待维修数量为0的机具，请重新选择");
            }
        }

        // 执行SQL： 1.增加【维修记录表】、  2.修改【维修明细表】的维修数量
        for (RepairTaskDetails bean : list) {
            int repairedNum = bean.getRepairNum() - bean.getRepairedNum() - bean.getScrapNum();
            RepairApplyRecord repairRecord = new RepairApplyRecord();
            repairRecord.setTaskId(Long.valueOf(bean.getTaskId()));
            repairRecord.setMaId(Long.valueOf(bean.getMaId()));
            repairRecord.setTypeId(Long.valueOf(bean.getTypeId()));
            repairRecord.setRepairNum(repairedNum);
            // 快捷维修，设置为内部维修
            repairRecord.setRepairType(inRepairType);
            repairRecord.setCreateBy(String.valueOf(loginUser.getUserid()));
            repairRecord.setCompanyId(bean.getCompanyId());
            repairMapper.addRecord(repairRecord);
            int i = repairedNum + bean.getRepairedNum();
            repairMapper.updateRepairedNumTwo(bean.getId(), i, loginUser.getUserid());
        }

        // 执行完毕，无异常返回至前端
        return AjaxResult.success();
    }

    @Override
    public AjaxResult batchRepairApply(@NotNull List<RepairDeviceVO> repairDeviceVOList) {
        // 准备业务逻辑数据
        LoginUser loginUser = SecurityUtils.getLoginUser();
        // 配件集合
        List<RepairPartDetails> partList = new ArrayList<>();

        // 校验参数，过滤空数据
        repairDeviceVOList.removeIf(Objects::isNull);

        for (RepairDeviceVO bean : repairDeviceVOList) {
            if (bean.getManageType() == null) {
                throw new ServiceException("请选择物资管理方式");
            }
            if (Objects.equals(manageTypeByCode, bean.getManageType())) {
                // 物资管理方式--编码管理
                // 根据维修方式，更新维修数量、报废数量
                switch (bean.getRepairType()) {
                    case inRepairType: {
                        partList = bean.getCodeInRepairPartList();
                        // 更新维修数量、并修改维修人员
                        repairMapper.updateRepairedNum(bean.getId(), 1, loginUser.getUserid(), loginUser.getUserid());
                        break;
                    }
                    case outRepairType: {
                        partList = bean.getCodeOutRepairPartList();
                        // 更新维修数量、维修人员不变
                        repairMapper.updateRepairedNumTwo(bean.getId(), 1, loginUser.getUserid());
                        break;
                    }
                    case scrapRepairType: {
                        // 报废无需上传配件、直接初始化空集合
                        partList = bean.getCodeScrapRepairPartList();
                        // 更新报废数量
                        repairMapper.updateScrapNum(bean.getId(), 1, loginUser.getUserid());
                        break;
                    }
                    default:
                        System.err.println("请输入正确的维修类型:" + bean.getRepairType());
                        break;
                }
                // 统一处理配件集合数据
                copeNumberManageInList(bean, partList, loginUser, bean.getManageType());

            } else if (Objects.equals(manageTypeByNumber, bean.getManageType())) {
                // 物资管理方式--数量管理
                if (bean.getId() == null) {
                    throw new ServiceException("请完善参数，维修详情ID为空!");
                }

                // 处理配件--数量管理--内部维修
                if (CollectionUtil.isNotEmpty(bean.getNumberInRepairPartList())) {
                    // 获取维修详情表中的维修详情记录：待维修、已维修、已报废的数量
                    RepairTaskDetails details = repairMapper.getById(bean.getId());

                    if (Objects.isNull(details)) {
                        throw new ServiceException("此维修记录不存在，请检查后提交!");
                    }

                    partList = bean.getNumberInRepairPartList();
                    if (bean.getNumberInRepairPartList().get(0).getRepairNum() != null && bean.getNumberInRepairPartList().get(0).getRepairNum() != 0) {
                        // ---------------校验维修数量-----------------
                        // 统计已维修数量 + 本次维修数量
                        int repairNum = OptionalInt.of(details.getRepairedNum()).orElse(0) + bean.getNumberInRepairPartList().get(0).getRepairNum();
                        // 统计报废数量 + 维修合计数量
                        int num = repairNum + details.getScrapNum();
                        if (num > details.getRepairNum()) {
                            throw new ServiceException("维修数量大于维修总量");
                        }
                        // ---------------校验维修数量-----------------
                        // 更新维修数量、并修改维修人员
                        repairMapper.updateRepairedNum(bean.getId(), repairNum, loginUser.getUserid(), loginUser.getUserid());
                        // 处理配件集合数据
                        copeNumberManageInList(bean, partList, loginUser, bean.getManageType());
                    }
                }

                // 处理配件集合数据 -- 数量管理--外部返厂维修
                if (CollectionUtil.isNotEmpty(bean.getNumberOutRepairPartList())) {
                    // 获取维修详情表中的维修详情记录：待维修、已维修、已报废的数量
                    RepairTaskDetails details = repairMapper.getById(bean.getId());

                    if (Objects.isNull(details)) {
                        throw new ServiceException("此维修记录不存在，请检查后提交!");
                    }

                    BigDecimal sfCosts = new BigDecimal("0");
                    partList = bean.getNumberOutRepairPartList();

                    // 重新查询维修详情
                    details = repairMapper.getById(bean.getId());

                    // 判断外部维修配件数量是否为空
                    if (partList.get(0).getRepairNum() != null && partList.get(0).getRepairNum() != 0) {

                        // 统计已维修数量 + 本次维修数量
                        int repairNum = OptionalInt.of(details.getRepairedNum()).orElse(0) + partList.get(0).getRepairNum();
                        // 统计报废数量 + 维修合计数量
                        if ((repairNum + OptionalInt.of(details.getScrapNum()).orElse(0)) > details.getRepairNum()) {
                            throw new ServiceException("维修数量大于维修总量");
                        }

                        // 更新维修数量、维修人员不变
                        repairMapper.updateRepairedNumTwo(bean.getId(), repairNum, loginUser.getUserid());

                        if (partList.get(0).getSupplierId() == null) {
                            throw new ServiceException("请选择返厂厂家");
                        }

                        // 数量管理--外部返厂维修 -- 记录表插入数据
                        RepairApplyRecord repairApplyRecord = new RepairApplyRecord();
                        for (RepairPartDetails repairPartDetails : partList) {
                            repairApplyRecord.setId(bean.getId()).setTaskId(bean.getTaskId()).setMaId(bean.getMaId()).setTypeId(bean.getTypeId())
                                    .setRepairType(outRepairType).setRepairNum(repairPartDetails.getRepairNum()).setScrapNum(0)
                                    .setPartName(repairPartDetails.getPartName()).setPartType(repairPartDetails.getPartType())
                                    .setRepairContent(repairPartDetails.getRepairContent()).setSupplierId(repairPartDetails.getSupplierId())
                                    .setPartNum(repairPartDetails.getPartNum()).setRepairer(loginUser.getUsername())
                                    .setPartPrice(Optional.ofNullable(repairPartDetails.getPartPrice()).orElse(new BigDecimal(0)))
                                    .setCreateBy(loginUser.getUsername());

                            // 新增【维修记录表】
                            repairMapper.addRecord(repairApplyRecord);
                        }

                        sfCosts = countPartCosts(partList, sfCosts);
                        // TODO: 判断是否是收费配件，因数据存在多条，可能有些是免费配件 有些收费，所以这里用价格统一做处理，后续讨论
                        // SQL: 新增【维修费用记录表】
                        repairMapper.addRepairCost(repairApplyRecord, sfCosts, sfCosts.equals(new BigDecimal("0")) ? "0" : "1");
                    }
                }

                // 处理配件集合数据 -- 数量管理--报废维修
                if (CollectionUtil.isNotEmpty(bean.getNumberScrapRepairPartList())) {
                    // 判断报废数量是否为空
                    if (bean.getNumberScrapRepairPartList().get(0).getScrapNum() != null && bean.getNumberScrapRepairPartList().get(0).getScrapNum() > 0) {
                        // 获取维修详情表中的维修详情记录：待维修、已维修、已报废的数量
                        RepairTaskDetails details = repairMapper.getById(bean.getId());

                        if (Objects.isNull(details)) {
                            throw new ServiceException("此维修记录不存在，请检查后提交!");
                        }
                        // -------------校验维修数量开始----------------
                        // 统计历史已报废数量 + 本次报废数量 = 报废总数
                        int scrapNum = OptionalInt.of(details.getScrapNum()).orElse(0) + bean.getNumberScrapRepairPartList().get(0).getScrapNum();
                        // 统计 报废总数 + 历史已维修数量,
                        int num = scrapNum + details.getRepairedNum();
                        //  不能大与总的待维修数量
                        if (num > details.getRepairNum()) {
                            throw new ServiceException("报废数量大于维修总量! 本次报废数量:" + bean.getScrapNum() + ",已报废数量:" + details.getScrapNum() + ",维修总量:" + details.getRepairNum());
                        }
                        // -------------校验维修数量结束----------------

                        // 更新报废数量
                        repairMapper.updateScrapNum(bean.getId(), scrapNum, loginUser.getUserid());

                        if (CollectionUtil.isNotEmpty(bean.getNumberScrapRepairPartList().get(0).getFileList())) {
                            for (BmFileInfo fileInfo : bean.getNumberScrapRepairPartList().get(0).getFileList()) {
                                fileInfo.setTaskType(TmTaskTypeEnum.TM_TASK_REPAIR.getTaskTypeId())
                                        .setTaskId(bean.getTaskId()).setModelId(bean.getId())
                                        .setCreateBy(loginUser.getUsername());
                                bmFileInfoMapper.insertBmFileInfo(fileInfo);

                                // 报废类型无需配件，所以配件为空，添加【维修记录表】
                                // 维修记录表信息
                                RepairApplyRecord repairApplyRecord = new RepairApplyRecord();
                                repairApplyRecord.setTaskId(bean.getTaskId()).setMaId(bean.getMaId()).setTypeId(bean.getTypeId())
                                        .setRepairType(scrapRepairType).setStatus(0L).setIsSlt(0L).setPartNum(0)
                                        .setFileIds(fileInfo.getId() == null ? "" : String.valueOf(fileInfo.getId()))
                                        .setRepairNum(0).setScrapNum(bean.getNumberScrapRepairPartList().get(0).getScrapNum())
                                        .setScrapReason(bean.getNumberScrapRepairPartList().get(0).getScrapReason())
                                        .setScrapType(bean.getNumberScrapRepairPartList().get(0).getScrapType())
                                        .setRepairer(loginUser.getUsername()).setCreateBy(loginUser.getUsername());

                                // 因报废操作无需配件, 只添加【维修记录表】
                                repairMapper.addRecord(repairApplyRecord);
                            }
                        } else {
                            // 报废类型无需配件，所以配件为空，添加【维修记录表】
                            // 维修记录表信息
                            RepairApplyRecord repairApplyRecord = new RepairApplyRecord();
                            repairApplyRecord.setTaskId(bean.getTaskId()).setMaId(bean.getMaId()).setTypeId(bean.getTypeId())
                                    .setRepairType(scrapRepairType).setStatus(0L).setIsSlt(0L).setPartNum(0)
                                    .setRepairNum(0).setScrapNum(bean.getNumberScrapRepairPartList().get(0).getScrapNum())
                                    .setScrapReason(bean.getNumberScrapRepairPartList().get(0).getScrapReason())
                                    .setScrapType(bean.getNumberScrapRepairPartList().get(0).getScrapType())
                                    .setRepairer(loginUser.getUsername()).setCreateBy(loginUser.getUsername());

                            // 因报废操作无需配件, 只添加【维修记录表】
                            repairMapper.addRecord(repairApplyRecord);
                        }

                    }
                }
            } else {
                throw new ServiceException("请选择正确的维修类型");
            }
        }

        return AjaxResult.success("维修完成");
    }

    /**
     * 配件列表价格合计
     * @param partList 配件列表
     * @param sfCosts 配件价格合计
     * @return 配件合计后的价格
     */
    private static BigDecimal countPartCosts(List<RepairPartDetails> partList, BigDecimal sfCosts) {
        for (RepairPartDetails partDetails : partList) {
            if (partDetails.getPartPrice() != null) {
                BigDecimal partPrice = partDetails.getPartPrice();
                BigDecimal partNumber = new BigDecimal(partDetails.getPartNum());
                sfCosts = sfCosts.add(partPrice.multiply(partNumber));
            }
        }
        return sfCosts;
    }

    /**
     * 处理配件集合数据
     * @param bean 维修申请单
     * @param partList 配件列表
     * @param loginUser 当前登录用户
     * @param manageType 管理方式：0编码管理  1数量管理
     */
    private void copeNumberManageInList(RepairDeviceVO bean, List<RepairPartDetails> partList, LoginUser loginUser, Integer manageType) {
        if (CollectionUtil.isNotEmpty(partList)) {
            if (bean.getManageType() == null) {
                throw new ServiceException("请选择物资管理方式");
            }
            // 如果是数量管理，那么默认为内部维修
            if (bean.getRepairType() == null && manageType == manageTypeByNumber) {
                bean.setRepairType(inRepairType);
            }
            // 再检查还是null的话直接结束任务
            if (bean.getRepairType() == null) {
                return;
            }

            // 内部维修
            if (bean.getRepairType() == inRepairType) {
                RepairApplyRecord repairApplyRecord = new RepairApplyRecord();
                // 遍历配件列表，判断配件类型，收费还是不收费
                for (RepairPartDetails partDetails : partList) {
                    // 维修记录表信息
                    repairApplyRecord.setTaskId(bean.getTaskId()).setMaId(bean.getMaId()).setTypeId(bean.getTypeId()).setRepairType(inRepairType);
                    if (manageType == manageTypeByCode) {
                        repairApplyRecord.setRepairNum(scrapRepairType != bean.getRepairType() ? 1 : 0);
                        repairApplyRecord.setScrapNum(scrapRepairType == bean.getRepairType() ? 1 : 0);
                    }
                    if (manageType == manageTypeByNumber) {
                        repairApplyRecord.setRepairNum(partDetails.getRepairNum());
                    }
                    repairApplyRecord.setCreateBy(loginUser.getUsername());
                    repairApplyRecord.setStatus(0L);

                    if (partDetails.getPartId() != null && partDetails.getPartNum() != null) {
                        // 有维修配件时,如果价格为空，设置为0
                        if (partDetails.getPartCost() == null) {
                            partDetails.setPartCost(new BigDecimal(0));
                        }
                        partDetails.setTaskId(bean.getTaskId()).setMaId(bean.getMaId()).setTypeId(bean.getTypeId()).setCompanyId(null);
                        partDetails.setCreateBy(String.valueOf(loginUser.getUserid()));

                        // 根据 partId  找配件单价
                        BigDecimal partPrice = repairMapper.selectPartPrice(partDetails.getPartId());
                        // 设置配件单价费用
                        partDetails.setPartPrice(partPrice);
                        // 添加【维修配件明细表】
                        repairMapper.addPart(partDetails);

                        // 设置维修记录的配件费用
                        repairApplyRecord.setId(bean.getId()).setPartPrice(partPrice)
                                .setPartNum(partDetails.getPartNum())
                                .setRepairContent(partDetails.getRepairContent())
                                .setPartType(partDetails.getPartType())
                                .setPartId(partDetails.getPartId() == null ? 0L : partDetails.getPartId());
                        // 添加【维修记录表】
                        repairMapper.addRecord(repairApplyRecord);
                    } else {
                        // 不选维修配件时, 只添加【维修记录表】
                        repairMapper.addRecord(repairApplyRecord);
                    }
                }

                BigDecimal sfCosts = countPartCosts(partList, new BigDecimal(0));
                // TODO: 判断是否是收费配件，因数据存在多条，可能有些是免费配件 有些收费，所以这里用价格统一做处理，后续讨论
                // SQL: 新增【维修费用记录表】
                repairMapper.addRepairCost(repairApplyRecord, sfCosts, sfCosts.equals(new BigDecimal("0")) ? "0" : "1");
            }

            // 外部维修
            if (bean.getRepairType() == outRepairType) {
                // ---------------校验维修数量-----------------
                // 统计已维修数量 + 本次维修数量
                int repairNum = OptionalInt.of(bean.getRepairedNum()).orElse(0) + bean.getRepairNum();
                // 统计报废数量 + 维修合计数量  不能 大与> 总的待维修量
                if (repairNum + OptionalInt.of(bean.getScrapNum()).orElse(0) > bean.getRepairNum()) {
                    throw new ServiceException("维修数量大于维修总量");
                }

                // 更新维修数量、维修人员不变
                repairMapper.updateRepairedNumTwo(bean.getId(), repairNum, loginUser.getUserid());

                // 编码管理--外部返厂维修
                RepairApplyRecord repairApplyRecord = new RepairApplyRecord().setId(bean.getId()).setTaskId(bean.getTaskId()).setMaId(bean.getMaId())
                        .setTypeId(bean.getTypeId()).setRepairType(outRepairType)
                        .setPartName(partList.get(0).getPartName())
                        .setPartType(partList.get(0).getPartType())
                        .setRepairContent(partList.get(0).getRepairContent()).setPartNum(partList.get(0).getPartNum());

                if (partList.get(0).getSupplierId() == null) {
                    throw new ServiceException("请选择返厂厂家");
                }
                repairApplyRecord.setSupplierId(partList.get(0).getSupplierId());
                repairApplyRecord.setPartPrice(Optional.ofNullable(partList.get(0).getPartPrice()).orElse(new BigDecimal(0)));
                // 新增【维修记录表】
                repairMapper.addRecord(repairApplyRecord);

                // 配件费用计算
                BigDecimal sfCosts = countPartCosts(partList, new BigDecimal(0));

                // TODO: 判断是否是收费配件，因数据存在多条，可能有些是免费配件 有些收费，所以这里用价格统一做处理，后续讨论
                // SQL: 新增【维修费用记录表】
                repairMapper.addRepairCost(repairApplyRecord, sfCosts, sfCosts.equals(new BigDecimal("0")) ? "0" : "1");
            }

            // 如果是报废类型，进行上传附件相关处理
            if (scrapRepairType == bean.getRepairType()) {
                if (CollectionUtil.isNotEmpty(partList.get(0).getFileList())) {
                    for (BmFileInfo fileInfo : partList.get(0).getFileList()) {
                        fileInfo.setTaskType(TmTaskTypeEnum.TM_TASK_REPAIR.getTaskTypeId())
                                .setTaskId(bean.getTaskId()).setModelId(bean.getId())
                                .setCreateBy(loginUser.getUsername());
                        bmFileInfoMapper.insertBmFileInfo(fileInfo);

                        // 配件为空，添加【维修记录表】
                        RepairApplyRecord repairApplyRecord = new RepairApplyRecord();
                        repairApplyRecord.setTaskId(bean.getTaskId()).setMaId(bean.getMaId()).setTypeId(bean.getTypeId())
                                .setRepairType(bean.getRepairType()).setStatus(0L).setFileIds(String.valueOf(fileInfo.getId()))
                                .setRepairNum(bean.getRepairType() != scrapRepairType ? 1 : 0)
                                .setScrapNum(bean.getRepairType() == scrapRepairType ? 1 : 0)
                                .setCreateBy(loginUser.getUsername());

                        // 不选维修配件时, 只添加【维修记录表】
                        repairMapper.addRecord(repairApplyRecord);
                    }
                } else {
                    // 配件为空，添加【维修记录表】
                    RepairApplyRecord repairApplyRecord = new RepairApplyRecord();
                    repairApplyRecord.setTaskId(bean.getTaskId()).setMaId(bean.getMaId()).setTypeId(bean.getTypeId())
                            .setRepairType(bean.getRepairType()).setStatus(0L)
                            .setRepairNum(bean.getRepairType() != scrapRepairType ? 1 : 0)
                            .setScrapNum(bean.getRepairType() == scrapRepairType ? 1 : 0)
                            .setCreateBy(loginUser.getUsername());

                    // 不选维修配件时, 只添加【维修记录表】
                    repairMapper.addRecord(repairApplyRecord);
                }
            }

        } else {
            // 配件为空，添加【维修记录表】
            RepairApplyRecord repairApplyRecord = new RepairApplyRecord();
            repairApplyRecord.setTaskId(bean.getTaskId()).setMaId(bean.getMaId()).setTypeId(bean.getTypeId())
                    .setRepairType(bean.getRepairType()).setStatus(0L)
                    .setRepairNum(bean.getRepairType() != scrapRepairType ? 1 : 0)
                    .setScrapNum(bean.getRepairType() == scrapRepairType ? 1 : 0)
                    .setCreateBy(loginUser.getUsername());

            // 不选维修配件时, 只添加【维修记录表】
            repairMapper.addRecord(repairApplyRecord);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult endRepairTask(@NotNull List<RepairTask> taskList) {
        LoginUser loginUser = SecurityUtils.getLoginUser();

        // 1.查询选择任务是否还有未完成维修的数据
        for (RepairTask task : taskList) {
            if (repairMapper.getUnFinish(task) > 0) {
                return AjaxResult.error("选中的数据中包含维修未完成的，请完成维修再进行提交审核");
            }
        }

        // 2.更新tm_task任务状态
        repairMapper.updateTaskStatus(taskList, loginUser.getUserid(), RepairTaskStatusEnum.TASK_STATUS_COMPLETE.getStatus());

        // 3.业务逻辑处理
        for (RepairTask task : taskList) {
            task.setCreateBy(loginUser.getUserid());
            // 查询任务的协议id
            Long agreementId = repairMapper.getAgreementId(task);
            // 查询维修任务的详情表
            List<RepairTaskDetails> detailsList = repairMapper.getDetailsListByTaskId(task);
            // 新增tm_task表数据、修饰审核任务、状态是待审核
            task.setTaskType(TmTaskTypeEnum.TM_TASK_REPAIR_STORAGE.getTaskTypeId());
            task.setTaskStatus(RepairTaskStatusEnum.TASK_STATUS_TO_EXAM.getStatus());
            repairMapper.addTask(task);

            // 循环插入【修饰审核明细表】
            for (RepairTaskDetails details : detailsList) {
                details.setCreateBy(String.valueOf(loginUser.getUserid()));
                details.setTaskId(task.getTaskId());
                repairMapper.addAuditDetails(details);
            }
            // 新增协议任务表--关联修饰任务与协议
            task.setAgreementId(agreementId);
            repairMapper.createAgreementTask(task);
        }
        return AjaxResult.success();
    }

    @Override
    public AjaxResult rejectRepair(@NotNull List<Long> taskList) {
        try {
            taskList.forEach(taskId -> taskMapper.updateTaskStatus(String.valueOf(taskId), RepairTaskStatusEnum.TASK_STATUS_REJECT.getStatus()));
        } catch (DataAccessException e) {
            System.err.println(e.getMessage());
            return AjaxResult.error("数据库SQL修改执行失败" + e.getMessage());
        }
        return AjaxResult.success("执行完成");
    }

    /**
     * 维修明细--批量审核--更新明细status
     */
    @Override
    public int completeRepair(ArrayList<Long> ids) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        return repairMapper.completeRepair(ids, loginUser.getUserid());
    }

    @Override
    public List<SysUser> selectUserList() {
        return repairMapper.selectUserList();
    }

}
