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

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.util.PhoneUtil;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.bonus.common.biz.constant.GlobalConstants;
import com.bonus.common.biz.constant.MaterialConstants;
import com.bonus.common.biz.domain.TypeTreeNode;
import com.bonus.common.biz.domain.lease.LeaseOutDetails;
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.core.web.domain.AjaxResult;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.material.back.domain.*;
import com.bonus.material.back.domain.vo.*;
import com.bonus.common.biz.domain.BmFileInfo;
import com.bonus.material.basic.domain.BmAgreementInfo;
import com.bonus.material.basic.domain.BmUnit;
import com.bonus.material.basic.mapper.BmAgreementInfoMapper;
import com.bonus.material.basic.mapper.BmFileInfoMapper;
import com.bonus.material.basic.mapper.BmUnitMapper;
import com.bonus.material.clz.domain.back.MaterialBackApplyDetails;
import com.bonus.material.clz.domain.back.MaterialBackApplyInfo;
import com.bonus.material.clz.mapper.MaterialBackInfoMapper;
import com.bonus.material.common.domain.dto.SelectDto;
import com.bonus.material.common.domain.vo.AgreementVo;
import com.bonus.material.common.mapper.SelectMapper;
import com.bonus.material.lease.mapper.LeaseApplyInfoMapper;
import com.bonus.material.ma.mapper.MachineMapper;
import com.bonus.material.purchase.config.RemoteConfig;
import com.bonus.material.settlement.domain.SltAgreementInfo;
import com.bonus.material.settlement.mapper.SltAgreementInfoMapper;
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.stereotype.Service;
import com.bonus.material.back.mapper.BackApplyInfoMapper;
import com.bonus.material.back.service.IBackApplyInfoService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;

/**
 * 退料任务Service业务层处理
 *
 * @author xsheng
 * @date 2024-10-16
 */
@Service
@Slf4j
public class BackApplyInfoServiceImpl implements IBackApplyInfoService {

    @Resource
    private BackApplyInfoMapper backApplyInfoMapper;

    @Resource
    private BmFileInfoMapper bmFileInfoMapper;

    @Resource
    private TmTaskMapper taskMapper;

    @Resource
    private TmTaskAgreementMapper taskAgreementMapper;

    @Resource
    private MachineMapper machineMapper;

    @Resource
    private RemoteConfig remoteConfig;

    @Resource
    private SltAgreementInfoMapper sltAgreementInfoMapper;

    @Resource
    private SelectMapper mapper;

    @Resource
    private LeaseApplyInfoMapper leaseApplyInfoMapper;

    @Resource
    private MaterialBackInfoMapper materialBackInfoMapper;

    @Resource
    private BmAgreementInfoMapper bmAgreementInfoMapper;

    @Resource
    private BmUnitMapper bmUnitMapper;

    /**
     * 查询退料任务 - 性能优化版
     *
     * @param id 退料任务主键
     * @return 退料任务
     */
    @Override
    public AjaxResult selectBackApplyInfoById(Long id, String keyWord) {
        BackApplyRequestVo backApplyRequestVo = new BackApplyRequestVo();
        //先根据外层id查询上层信息
        BackApplyInfo backApplyInfo = backApplyInfoMapper.selectBackApplyInfoById(id);
        Long userId = SecurityUtils.getLoginUser().getUserid();
        Set<String> userRoles = SecurityUtils.getLoginUser().getRoles();
        // 检查用户是否具有特殊角色
        boolean hasSpecialRole = hasSpecialRole(userRoles);
        if (!hasSpecialRole) {
            backApplyInfo.setUserId(userId == 0 ? null : userId);
        }
        // 首先根据用户名去ma_type_manage表查询是否存在绑定物资信息
        /*List<Long> typeIdList = backApplyInfoMapper.selectTypeIdList(userId);
        if (CollectionUtils.isEmpty(typeIdList)) {
            backApplyInfo.setUserId(userId == 0 ? null : userId);
        }*/

        // 设置审批人签名url,目前固定查询夏成刚签名信息
        BackApplyInfo info = backApplyInfoMapper.getDirectAuditUrl(backApplyInfo);
        if (info != null && StringUtils.isNotBlank(info.getDirectAuditSignUrl())) {
            backApplyInfo.setDirectAuditSignType(info.getDirectAuditSignType());
            if (!info.getDirectAuditSignUrl().startsWith("http")) {
                backApplyInfo.setDirectAuditSignUrl("data:image/png;base64," + info.getDirectAuditSignUrl());
            } else {
                backApplyInfo.setDirectAuditSignUrl(info.getDirectAuditSignUrl());
            }
        }

        // 设置退料人签名url
        if (StringUtils.isNotBlank(backApplyInfo.getBackSignUrl())) {
            if (!backApplyInfo.getBackSignUrl().startsWith("http")) {
                backApplyInfo.setBackSignUrl("data:image/png;base64," + backApplyInfo.getBackSignUrl());
            }
        }

        // 设置制单人签名url
        if (StringUtils.isNotBlank(backApplyInfo.getSignUrl())) {
            if (!backApplyInfo.getSignUrl().startsWith("http")) {
                backApplyInfo.setSignUrl("data:image/png;base64," + backApplyInfo.getBackSignUrl());
            }
        }

        backApplyRequestVo.setBackApplyInfo(backApplyInfo);
        
        //查询退料详情信息
        backApplyInfo.setKeyWord(keyWord);
        // 移出maCodeList集合中状态不为在用的数据
        List<MaCodeVo> newCodeList = new ArrayList<>();
        List<BackApplyDetails> backApplyDetailsList = backApplyInfoMapper.selectBackApplyDetailsListByTaskId(backApplyInfo);
        
        if (CollectionUtils.isNotEmpty(backApplyDetailsList)) {
            /*if (!CollectionUtils.isEmpty(typeIdList)) {
                backApplyDetailsList = backApplyDetailsList.stream()
                        .filter(item -> typeIdList.contains(item.getFirstId()))
                        .collect(Collectors.toList());
            }*/
            
            // 核心优化：减少数据库查询次数
            // 1. 一次性查询编码设备信息
            List<MaCodeVo> maCodeList = backApplyInfoMapper.selectByCode(id);
            
            // 2. 处理状态不为在用的设备编码
            if ("0".equals(backApplyInfo.getStatus()) && CollectionUtils.isNotEmpty(maCodeList)) {
                newCodeList = filterNonInUseEquipment(maCodeList);
                maCodeList = filterInUseEquipment(maCodeList);
            }
            
            // 3. 优化：只有在有编码设备时才查询类型树，减少不必要的复杂查询
            Map<Long, BigDecimal> typeNumMap = new HashMap<>();
            if (hasCodedEquipment(backApplyDetailsList)) {
                List<TypeTreeNode> listL4 = mapper.getUseTypeTreeL4(backApplyInfo);
                typeNumMap = buildTypeNumMappingSimple(listL4);
            }
            
            // 4. 一次性查询所有附件信息
            Map<Long, List<BmFileInfo>> allFileInfoMap = fetchAllFileInfosOptimized(id);
            
            // 5. 预构建映射表
            Map<Long, List<MaCodeVo>> typeCodeMap = buildTypeCodeMappingSimple(maCodeList);
            Map<Long, MaCodeVo> maIdCodeMap = buildMaIdCodeMappingSimple(maCodeList);
            
            // 6. 快速处理每个退料详情
            for (BackApplyDetails details : backApplyDetailsList) {
                processBackApplyDetailsSimple(details, typeNumMap, typeCodeMap, allFileInfoMap, newCodeList, maIdCodeMap);
            }
            
            backApplyRequestVo.setBackApplyDetailsList(backApplyDetailsList);
        }
        
        AjaxResult ajaxResult = AjaxResult.success();
        ajaxResult.put("data", backApplyRequestVo);
        
        if (CollectionUtils.isNotEmpty(newCodeList)) {
            String msg = buildNotificationMessage(newCodeList);
            ajaxResult.put("msg", msg);
        }
        return ajaxResult;
    }

    /**
     * 检查是否有编码设备
     */
    private boolean hasCodedEquipment(List<BackApplyDetails> backApplyDetailsList) {
        return backApplyDetailsList.stream().anyMatch(details -> "0".equals(details.getManageType()));
    }

    /**
     * 过滤非在用设备
     */
    private List<MaCodeVo> filterNonInUseEquipment(List<MaCodeVo> maCodeList) {
        return maCodeList.stream()
                .filter(maCodeVo -> StringUtils.isNotBlank(maCodeVo.getMaStatus()) && !"2".equals(maCodeVo.getMaStatus()))
                .collect(Collectors.toList());
    }

    /**
     * 过滤在用设备
     */
    private List<MaCodeVo> filterInUseEquipment(List<MaCodeVo> maCodeList) {
        return maCodeList.stream()
                .filter(maCodeVo -> "2".equals(maCodeVo.getMaStatus()))
                .collect(Collectors.toList());
    }

    /**
     * 简化版类型数量映射构建
     */
    private Map<Long, BigDecimal> buildTypeNumMappingSimple(List<TypeTreeNode> listL4) {
        if (CollectionUtils.isEmpty(listL4)) {
            return new HashMap<>();
        }
        Map<Long, BigDecimal> typeNumMap = new HashMap<>();
        for (TypeTreeNode node : listL4) {
            typeNumMap.put(node.getTypeId(), node.getNum());
        }
        return typeNumMap;
    }

    /**
     * 简化版类型编码映射构建
     */
    private Map<Long, List<MaCodeVo>> buildTypeCodeMappingSimple(List<MaCodeVo> maCodeList) {
        Map<Long, List<MaCodeVo>> typeCodeMap = new HashMap<>();
        for (MaCodeVo vo : maCodeList) {
            if (StringUtils.isNotBlank(vo.getTypeId())) {
                Long typeId = Long.parseLong(vo.getTypeId());
                typeCodeMap.computeIfAbsent(typeId, k -> new ArrayList<>()).add(vo);
            }
        }
        return typeCodeMap;
    }

    /**
     * 简化版机具ID映射构建
     */
    private Map<Long, MaCodeVo> buildMaIdCodeMappingSimple(List<MaCodeVo> maCodeList) {
        Map<Long, MaCodeVo> maIdCodeMap = new HashMap<>();
        for (MaCodeVo vo : maCodeList) {
            maIdCodeMap.put(vo.getMaId(), vo);
        }
        return maIdCodeMap;
    }

    /**
     * 优化版附件查询 - 一次性查询
     */
    private Map<Long, List<BmFileInfo>> fetchAllFileInfosOptimized(Long taskId) {
        // 一次性查询该任务的所有附件
        BmFileInfo queryParam = new BmFileInfo();
        queryParam.setTaskId(taskId);
        queryParam.setTaskType(3);
        List<BmFileInfo> allFileInfos = bmFileInfoMapper.selectBmFileInfoList(queryParam);
        
        // 按modelId分组
        Map<Long, List<BmFileInfo>> fileInfoMap = new HashMap<>();
        for (BmFileInfo fileInfo : allFileInfos) {
            fileInfoMap.computeIfAbsent(fileInfo.getModelId(), k -> new ArrayList<>()).add(fileInfo);
        }
        return fileInfoMap;
    }

    /**
     * 简化版退料详情处理
     */
    private void processBackApplyDetailsSimple(BackApplyDetails details, 
                                             Map<Long, BigDecimal> typeNumMap,
                                             Map<Long, List<MaCodeVo>> typeCodeMap,
                                             Map<Long, List<BmFileInfo>> allFileInfoMap,
                                             List<MaCodeVo> newCodeList,
                                             Map<Long, MaCodeVo> maIdCodeMap) {
        
        // 1. 设置在用数量
        BigDecimal num = typeNumMap.get(details.getTypeId());
        if (num != null) {
            details.setNum(num);
        }
        
        // 2. 设置附件信息
        List<BmFileInfo> detailFileInfos = allFileInfoMap.get(details.getId());
        if (CollectionUtils.isNotEmpty(detailFileInfos)) {
            details.setBmFileInfos(detailFileInfos);
        }
        
        // 3. 处理编码设备
        if ("0".equals(details.getManageType())) {
            processCodedEquipmentSimple(details, typeCodeMap, allFileInfoMap);
        }
        
        // 4. 处理非在用状态的设备
        processNonInUseEquipmentSimple(details, newCodeList, maIdCodeMap);
    }

    /**
     * 简化版编码设备处理
     */
    private void processCodedEquipmentSimple(BackApplyDetails details, 
                                           Map<Long, List<MaCodeVo>> typeCodeMap,
                                           Map<Long, List<BmFileInfo>> allFileInfoMap) {
        List<MaCodeVo> codeList = typeCodeMap.get(details.getTypeId());
        if (CollectionUtils.isEmpty(codeList)) {
            return;
        }
        
        // 计算总数
        BigDecimal totalGoodNum = BigDecimal.ZERO;
        BigDecimal totalBadNum = BigDecimal.ZERO;
        List<MaCodeDto> maCodeDtos = new ArrayList<>();
        
        for (MaCodeVo maCodeVo : codeList) {
            if (StringUtils.isBlank(maCodeVo.getMaCode())) {
                continue;
            }
            
            // 累加数量
            if (maCodeVo.getGoodNum() != null) {
                totalGoodNum = totalGoodNum.add(maCodeVo.getGoodNum());
            }
            if (maCodeVo.getBadNum() != null) {
                totalBadNum = totalBadNum.add(maCodeVo.getBadNum());
            }
            
            // 创建编码DTO
            MaCodeDto maCodeDto = createMaCodeDto(maCodeVo);
            List<BmFileInfo> fileInfos = allFileInfoMap.get(maCodeVo.getMaId());
            if (CollectionUtils.isNotEmpty(fileInfos)) {
                maCodeDto.setBmFileInfos(fileInfos);
            }
            maCodeDtos.add(maCodeDto);
        }
        
        details.setGoodNum(totalGoodNum);
        details.setBadNum(totalBadNum);
        details.setMaCodeList(maCodeDtos);
    }

    /**
     * 简化版非在用设备处理
     */
    private void processNonInUseEquipmentSimple(BackApplyDetails details, 
                                              List<MaCodeVo> newCodeList, 
                                              Map<Long, MaCodeVo> maIdCodeMap) {
        if (CollectionUtils.isEmpty(newCodeList)) {
            return;
        }
        
        for (MaCodeVo maCodeVo : newCodeList) {
            if (!maCodeVo.getTypeId().equals(details.getTypeId().toString())) {
                continue;
            }
            
            details.setPreNum(details.getPreNum().subtract(BigDecimal.valueOf(1)));
            
            MaCodeVo info = maIdCodeMap.get(maCodeVo.getMaId());
            if (info != null) {
                if (info.getGoodNum() != null && info.getGoodNum().compareTo(BigDecimal.ZERO) > 0) {
                    details.setGoodNum(details.getGoodNum().subtract(info.getGoodNum()));
                } else if (info.getBadNum() != null && info.getBadNum().compareTo(BigDecimal.ZERO) > 0) {
                    details.setBadNum(details.getBadNum().subtract(info.getBadNum()));
                }
            }
        }
    }

    /**
     * 创建MaCodeDto对象
     */
    private MaCodeDto createMaCodeDto(MaCodeVo maCodeVo) {
        MaCodeDto maCodeDto = new MaCodeDto();
        maCodeDto.setMaCode(maCodeVo.getMaCode());
        maCodeDto.setMaId(maCodeVo.getMaId());
        
        if (maCodeVo.getGoodNum() != null && maCodeVo.getGoodNum().compareTo(BigDecimal.ZERO) > 0) {
            maCodeDto.setApDetection("完好");
        } else if (maCodeVo.getBadNum() != null && maCodeVo.getBadNum().compareTo(BigDecimal.ZERO) > 0) {
            maCodeDto.setApDetection("损坏");
        }
        
        maCodeDto.setTypeName(maCodeVo.getTypeName());
        maCodeDto.setMaterialName(maCodeVo.getMaterialName());
        maCodeDto.setTypeId(maCodeVo.getTypeId());
        maCodeDto.setMaStatus(maCodeVo.getMaStatus());
        maCodeDto.setMaterialType(maCodeVo.getMaterialType());
        maCodeDto.setGoodNum(maCodeVo.getGoodNum());
        maCodeDto.setBadNum(maCodeVo.getBadNum());
        
        return maCodeDto;
    }

    /**
     * 优化消息构建
     */
    private String buildNotificationMessage(List<MaCodeVo> newCodeList) {
        StringBuilder msgBuilder = new StringBuilder("您所选择的编码设备编号");
        
        String codes = newCodeList.stream()
                .map(MaCodeVo::getMaCode)
                .collect(Collectors.joining(", "));
        
        msgBuilder.append(codes).append("已被他人完成退料，请注意查看！");
        
        return msgBuilder.toString().replaceAll("\n", "");
    }

    /**
     * 查询编码设备信息
     */
    private List<MaCodeVo> fetchMaCodeList(Long id) {
        return backApplyInfoMapper.selectByCode(id);
    }

    /**
     * 查询编码设备附件信息
     * @param taskId
     * @param modelId
     * @return
     */
    private List<BmFileInfo> fetchBmFileInfos(Long taskId, Long modelId) {
        BmFileInfo fileInfo = new BmFileInfo();
        fileInfo.setTaskId(taskId);
        fileInfo.setTaskType(3);
        fileInfo.setModelId(modelId);
        return bmFileInfoMapper.selectBmFileInfoList(fileInfo);
    }

    /**
     * 查询退料任务列表
     *
     * @param backApplyInfo 退料任务
     * @return 退料任务
     */
    @Override
    public List<BackApplyInfo> selectBackApplyInfoList(BackApplyInfo backApplyInfo) {
        List<BackApplyInfo> list = backApplyInfoMapper.selectBackApplyInfoList(backApplyInfo);
        // 如果列表为空，直接返回空列表
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        // 将list集合中typeName为空的数据过滤出来
        List<BackApplyInfo> infos = list.stream().filter(item -> StringUtils.isBlank(item.getTypeName()))
                .collect(Collectors.toList());
        Long userId = SecurityUtils.getLoginUser().getUserid();
        // 首先根据用户名去ma_type_manage表查询是否存在绑定物资信息
        //List<Long> typeIdList = backApplyInfoMapper.selectTypeIdList(userId);
        Set<String> userRoles = SecurityUtils.getLoginUser().getRoles();
        // 检查用户是否具有特殊角色
        boolean hasSpecialRole = hasSpecialRole(userRoles);
        if (!hasSpecialRole) {
            backApplyInfo.setUserId(userId == 0 ? null : userId);
        }
        list = backApplyInfoMapper.selectBackApplyInfoList(backApplyInfo);
        for (BackApplyInfo applyInfo : list) {
            if (StringUtils.isNotBlank(applyInfo.getBackSignUrl())) {
                if (!applyInfo.getBackSignUrl().startsWith("http")) {
                    applyInfo.setBackSignUrl("data:image/png;base64," + applyInfo.getBackSignUrl());
                }
            }
        }
        if (CollectionUtils.isNotEmpty(infos)) {
            for (BackApplyInfo info : infos) {
                // 假设Info类中有get单号Code()方法获取单号
                String infoCode = info.getCode();

                // 检查list中是否已存在相同单号的元素
                boolean exists = list.stream()
                        .anyMatch(item -> infoCode.equals(item.getCode()));

                // 如果不存在则添加
                if (!exists) {
                    list.add(info);
                }
            }

        }
        if (CollectionUtils.isNotEmpty( list)) {
            list = list.stream()
                    .sorted(Comparator.comparing(BackApplyInfo::getCreateTime,
                            Comparator.nullsFirst(Comparator.naturalOrder())).reversed())
                    .collect(Collectors.toList());
        }
        // 提取关键字
        String keyWord = backApplyInfo.getKeyWord();
        // 如果关键字不为空，进行过滤
        if (!StringUtils.isBlank(keyWord)) {
            list = list.stream()
                    .filter(item -> containsKeyword(item, keyWord))
                    .collect(Collectors.toList());
        }
        // 如果需要导出
        if (backApplyInfo.getIsExport()) {
            for (BackApplyInfo applyInfo : list) {
                applyInfo.setPrintStatus("0".equals(applyInfo.getPrintStatus()) ? "未打印" : "已打印");
                switch (applyInfo.getStatus()) {
                    case "0":
                        applyInfo.setStatus("退料未完成");
                        break;
                    case "1":
                        applyInfo.setStatus("维修驳回");
                        break;
                    case "2":
                        applyInfo.setStatus("退料已完成");
                        break;
                    default:
                        break;
                }
            }
        }
        return list;
    }

    /**
     * 检查用户是否具有特殊角色
     * @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(BackApplyInfo item, String keyWord) {
        return (item.getTypeName() != null && item.getTypeName().contains(keyWord)) ||
                (item.getCode() != null && item.getCode().contains(keyWord)) ||
                (item.getBackPerson() != null && item.getBackPerson().contains(keyWord)) ||
                (item.getUnitName() != null && item.getUnitName().contains(keyWord)) ||
                (item.getProName() != null && item.getProName().contains(keyWord)) ||
                (item.getPhone() != null && item.getPhone().contains(keyWord));
    }

    /**
     * 更新电子签名
     *
     * @param backApplyInfo 电子签名信息
     */
    @Override
    public int updateSignById(BackApplyInfo backApplyInfo) {
        return backApplyInfoMapper.updateSignById(backApplyInfo);
    }

    /**
     * 新增退料任务
     *
     * @param dto 退料任务
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult insertBackApplyInfo(BackApplyRequestVo dto) {
        if (dto == null || dto.getBackApplyInfo() == null || CollectionUtils.isEmpty(dto.getBackApplyDetailsList())) {
            return AjaxResult.error("参数为空，请重新选择后上传!");
        }
        //对传入的手机号进行校验
        if (StringUtils.isNotBlank(dto.getBackApplyInfo().getPhone()) && !PhoneUtil.isMobile(dto.getBackApplyInfo().getPhone())) {
            return AjaxResult.error("手机号格式不正确，请重新填写!");
        }
        //对提交的退料详情数目进行校验
        for (BackApplyDetails backApplyDetails : dto.getBackApplyDetailsList()) {
            if (backApplyDetails.getNum() != null && backApplyDetails.getPreNum() != null) {
                if (backApplyDetails.getNum().compareTo( backApplyDetails.getPreNum())<0) {
                    return AjaxResult.error(backApplyDetails.getTypeName() + "退料数量不能大于预退数量，请重新填写!");
                }
            }
            if (backApplyDetails.getGoodNum() != null && backApplyDetails.getBadNum() != null && backApplyDetails.getPreNum() != null) {
                if (backApplyDetails.getGoodNum().add(backApplyDetails.getBadNum()).compareTo( backApplyDetails.getPreNum())>0) {
                    return AjaxResult.error(backApplyDetails.getTypeName() + "完好数量和不合格数量之和不能大于预退数量，请重新填写!");
                }
            }
            if (backApplyDetails.getGoodNum() != null && backApplyDetails.getBadNum() != null && CollectionUtils.isNotEmpty(backApplyDetails.getMaCodeList())) {
                if (backApplyDetails.getGoodNum().add(backApplyDetails.getBadNum()).compareTo( BigDecimal.valueOf(backApplyDetails.getMaCodeList().size()))>0) {
                    return AjaxResult.error(backApplyDetails.getTypeName() + "完好数量和不合格数量之和不能大于预退数量，请重新填写!");
                }
            }
        }
        int result = 0;
        try {
             int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId());
             String code = genderTaskCode(thisMonthMaxOrder);
             TmTask tmTask = new TmTask(null, TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId(),
                    BackTaskStatusEnum.BACK_TASK_NO_FINISHED.getStatus(),
                    null,thisMonthMaxOrder + 1, code);
             tmTask.setCreateTime(DateUtils.getNowDate());
             tmTask.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
             BackApplyInfo backApplyInfo = dto.getBackApplyInfo();
             backApplyInfo.setCode(code);
             backApplyInfo.setCreateBy(SecurityUtils.getLoginUser().getUserid().toString());
             backApplyInfo.setCreateTime(DateUtils.getNowDate());
             // 保存退料信息到 tm_task 表中
             result += taskMapper.insertTmTask(tmTask);
             if (result > 0) {
                TmTaskAgreement tmTaskAgreement = new TmTaskAgreement(tmTask.getTaskId(), dto.getBackApplyInfo().getAgreementId());
                tmTaskAgreement.setCreateTime(DateUtils.getNowDate());
                tmTaskAgreement.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                taskAgreementMapper.insertTmTaskAgreement(tmTaskAgreement);
                backApplyInfo.setTaskId(tmTask.getTaskId());

                 /** 设置审批人为默认的李勇 --防止代码冲突 **/
                 Long peopleId = backApplyInfoMapper.getDirectAuditBy();
                 backApplyInfo.setDirectAuditBy(peopleId);
                 /** 设置审批人为默认的李勇 --防止代码冲突 **/

                result += backApplyInfoMapper.insertBackApplyInfo(backApplyInfo);
             }
             // 保存退料详情
             result = saveBackApplyDetails(dto, backApplyInfo, result);
        } catch (Exception e) {
            log.error("保存退料信息时发生异常: ", e);
        }
        return result > 0 ? AjaxResult.success() : AjaxResult.error("保存失败，请重试!");
    }

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

    /**
     * 保存退料详情
     * @param dto
     * @param backApplyInfo
     * @param result
     * @return
     */
    private int saveBackApplyDetails(BackApplyRequestVo dto, BackApplyInfo backApplyInfo, int result) {
        List<TypeTreeNode> listL4 = new ArrayList<>();
        // 针对app二维码扫描时，需要根据单位id和工程id获取协议id，然后根据协议id获取退料在用数量
        if (backApplyInfo.getUnitId() != null && backApplyInfo.getProId() != null) {
            SelectDto selectDto = new SelectDto();
            selectDto.setUnitId(backApplyInfo.getUnitId().intValue());
            selectDto.setProjectId(backApplyInfo.getProId().toString());
            List<AgreementVo> list = mapper.getAgreementInfoById(selectDto);
            if (CollectionUtils.isNotEmpty(list)) {
                backApplyInfo.setAgreementId(Long.valueOf(list.get(0).getAgreementId()));
                listL4 = mapper.getUseTypeTreeL4(backApplyInfo);
            }
        }
        for (BackApplyDetails details : dto.getBackApplyDetailsList()) {
            if (details.getNum() == null && CollectionUtils.isNotEmpty(listL4)) {
                for (TypeTreeNode typeTreeNode : listL4) {
                    // 如果找到匹配的 typeId，则更新数量
                    if (typeTreeNode.getTypeId() == details.getTypeId()) {
                        details.setNum(typeTreeNode.getNum());
                        break;
                    }
                }
            }
            details.setCode(backApplyInfo.getCode());
            details.setParentId(backApplyInfo.getId());
            details.setAuditNum(details.getPreNum());
            details.setStatus(String.valueOf(BackTaskStatusEnum.BACK_TASK_NO_FINISHED.getStatus()));
            details.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
            details.setCreateTime(DateUtils.getNowDate());
            // 保存退料详情
            result += backApplyInfoMapper.insertBackApplyDetails(details);
            // 处理附件
            result = saveBmFileInfo(details, backApplyInfo.getId(), result);
            // 判断是否为编码设备并处理附件
            result = saveMaCodeBmFileInfo(details, backApplyInfo.getId(), result);
        }
        return result;
    }

    /**
     * 保存附件
     * @param details
     * @param taskId
     * @param result
     * @return
     */
    private int saveBmFileInfo(BackApplyDetails details, Long taskId, int result) {
        if (CollectionUtils.isNotEmpty(details.getBmFileInfos())) {
            for (BmFileInfo bmFileInfo : details.getBmFileInfos()) {
                bmFileInfo.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                bmFileInfo.setCreateTime(DateUtils.getNowDate());
                bmFileInfo.setTaskId(taskId);
                bmFileInfo.setTaskType(3);
                bmFileInfo.setModelId(details.getId());
                result += bmFileInfoMapper.insertBmFileInfo(bmFileInfo);
            }
        }
        return result;
    }

    /**
     * 保存编码设备附件
     * @param details
     * @param id
     * @param result
     * @return
     */
    private int saveMaCodeBmFileInfo(BackApplyDetails details, Long id, int result) {
        // 设置公共字段
        setCommonFields(details, id);
        if (CollectionUtils.isNotEmpty(details.getMaCodeList())) {
            for (MaCodeDto maCodeDto : details.getMaCodeList()) {
                // 设置每个 MaCodeDto 的独立属性
                details.setMaId(maCodeDto.getMaId());
                details.setPreNum(BigDecimal.valueOf(1));
                details.setApDetection(maCodeDto.getApDetection());
                if ("1".equals(maCodeDto.getApDetection())) {
                    details.setGoodNum(BigDecimal.valueOf(1));
                } else {
                    details.setGoodNum(BigDecimal.valueOf(0));
                }
                if ("0".equals(maCodeDto.getApDetection())) {
                    details.setBadNum(BigDecimal.valueOf(1));
                } else {
                    details.setBadNum(BigDecimal.valueOf(0));
                }
                // 插入 CheckDetails
                result += backApplyInfoMapper.insertCheckDetails(details);
                if (CollectionUtils.isNotEmpty(maCodeDto.getBmFileInfos())) {
                    for (BmFileInfo bmFileInfo : maCodeDto.getBmFileInfos()) {
                        bmFileInfo.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                        bmFileInfo.setCreateTime(DateUtils.getNowDate());
                        bmFileInfo.setTaskId(details.getId());
                        bmFileInfo.setTaskType(3);
                        bmFileInfo.setModelId(maCodeDto.getMaId());
                        result += bmFileInfoMapper.insertBmFileInfo(bmFileInfo);
                    }
                }
            }
        } else {
            // 如果 MaCodeList 为空，只插入 CheckDetails
            result += backApplyInfoMapper.insertCheckDetails(details);
        }
        return result;
    }

    /**
     * 设置公共字段
     * @param details
     * @param id
     */
    private void setCommonFields(BackApplyDetails details, Long id) {
        details.setParentId(id);
        details.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        details.setCreateTime(DateUtils.getNowDate());
        details.setStatus("0");
        // 默认为 0，表示未完成
        details.setIsFinished(0);
        // 默认返回状态 1
        details.setBackStatus("1");
    }

    /**
     * 修改退料任务
     *
     * @param dto 退料任务
     * @return 结果
     */
    @Override
    public AjaxResult updateBackApplyInfo(BackApplyRequestVo dto) {
        if (dto == null || dto.getBackApplyInfo() == null || dto.getBackApplyInfo().getId() == null || CollectionUtils.isEmpty(dto.getBackApplyDetailsList())) {
            return AjaxResult.error("参数为空，请重新选择后上传!");
        }
        //对提交的退料详情数量进行校验
        for (BackApplyDetails backApplyDetails : dto.getBackApplyDetailsList()) {
            if (backApplyDetails.getNum() != null && backApplyDetails.getPreNum() != null) {
                if (backApplyDetails.getNum().compareTo(backApplyDetails.getPreNum())<0 ) {
                    return AjaxResult.error(backApplyDetails.getTypeName() + "退料数量不能大于预退数量，请重新填写!");
                }
            }
        }
        try {
            //针对修改，先删除，后添加
            //对传入的手机号进行校验
            if (StringUtils.isNotBlank(dto.getBackApplyInfo().getPhone()) && !PhoneUtil.isMobile(dto.getBackApplyInfo().getPhone())) {
                return AjaxResult.error("手机号格式不正确，请重新填写!");
            }
            // 查询信息
            Long id = dto.getBackApplyInfo().getId();
            BackApplyInfo backApplyInfo = backApplyInfoMapper.selectBackApplyInfoById(id);
            List<BackApplyDetails> backApplyDetailsList = backApplyInfoMapper.selectBackApplyDetailsListByTaskId(dto.getBackApplyInfo());
            List<MaCodeVo> maCodeList = backApplyInfoMapper.selectByCode(id);
            int result = 0;
            // 删除相关任务信息
            result += backApplyInfoMapper.deleteBackApplyDetails(id);
            result += backApplyInfoMapper.deleteCheckDetails(id);
            // 删除退料详情附件
            result += deleteFileInfoForDetails(backApplyDetailsList, id);
            // 删除编码设备附件
            result += deleteFileInfoForMaCodes(maCodeList, id);
            if (result > 0) {
                //执行新增操作
                BackApplyInfo info = dto.getBackApplyInfo();
                info.setUpdateTime(DateUtils.getNowDate());
                info.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                info.setCode(backApplyInfo.getCode());
                result += backApplyInfoMapper.updateBackApplyInfo(info);
                // 保存退料详情
                result = saveBackApplyDetails(dto, info, result);
                return AjaxResult.success(result);
            }
        } catch (Exception e) {
            throw new ServiceException("修改失败，请联系管理员");
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 删除退料任务信息
     *
     * @param id 退料任务主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult deleteBackApplyInfoById(Long id) {
        try {
            // 查询信息
            BackApplyInfo backApplyInfo = backApplyInfoMapper.selectBackApplyInfoById(id);
            List<BackApplyDetails> backApplyDetailsList = backApplyInfoMapper.selectBackApplyDetailsListByTaskId(backApplyInfo);
            List<MaCodeVo> maCodeList = backApplyInfoMapper.selectByCode(id);
            // 删除相关任务信息
            int result = deleteTaskInfo(backApplyInfo);
            // 删除退料详情附件
            result += deleteFileInfoForDetails(backApplyDetailsList, id);
            // 删除编码设备附件
            result += deleteFileInfoForMaCodes(maCodeList, id);
            if (result > 0) {
                return AjaxResult.success(result);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 删除任务信息
     * @param backApplyInfo
     * @return
     */
    private int deleteTaskInfo(BackApplyInfo backApplyInfo) {
        // 删除任务、任务协议及相关信息
        int result = 0;
        result += taskMapper.deleteTmTaskByTaskId(backApplyInfo.getTaskId());
        result += taskAgreementMapper.deleteTmTaskAgreementByTaskId(backApplyInfo.getTaskId());
        result += backApplyInfoMapper.deleteBackApply(backApplyInfo.getId());
        result += backApplyInfoMapper.deleteBackApplyDetails(backApplyInfo.getId());
        result += backApplyInfoMapper.deleteCheckDetails(backApplyInfo.getId());
        return result;
    }

    /**
     * 删除退料详情相关附件
     * @param backApplyDetailsList
     * @param taskId
     * @return
     */
    private int deleteFileInfoForDetails(List<BackApplyDetails> backApplyDetailsList, Long taskId) {
        // 删除退料详情相关附件
        int result = 0;
        if (CollectionUtils.isNotEmpty(backApplyDetailsList)) {
            for (BackApplyDetails details : backApplyDetailsList) {
                BmFileInfo bmFileInfo = new BmFileInfo();
                bmFileInfo.setModelId(details.getId());
                bmFileInfo.setTaskId(taskId);
                bmFileInfo.setTaskType(3);
                List<BmFileInfo> bmFileInfos = bmFileInfoMapper.selectBmFileInfoList(bmFileInfo);
                if (CollectionUtils.isNotEmpty(bmFileInfos)) {
                    result += bmFileInfoMapper.deleteBmFileInfoByBizInfo(bmFileInfo);
                }
            }
        }
        return result;
    }

    /**
     * 删除编码设备相关附件
     * @param maCodeList
     * @param taskId
     * @return
     */
    private int deleteFileInfoForMaCodes(List<MaCodeVo> maCodeList, Long taskId) {
        // 删除编码设备相关附件
        int result = 0;
        if (CollectionUtils.isNotEmpty(maCodeList)) {
            for (MaCodeVo maCodeVo : maCodeList) {
                BmFileInfo bmFileInfo = new BmFileInfo();
                bmFileInfo.setModelId(maCodeVo.getMaId());
                bmFileInfo.setTaskId(taskId);
                bmFileInfo.setTaskType(3);
                List<BmFileInfo> bmFileInfos = bmFileInfoMapper.selectBmFileInfoList(bmFileInfo);
                if (CollectionUtils.isNotEmpty(bmFileInfos)) {
                    result += bmFileInfoMapper.deleteBmFileInfoByBizInfo(bmFileInfo);
                }
            }
        }
        return result;
    }

    /**
     * 根据机具编码和类型查询机具是否存在
     * @param dto
     * @return
     */
    @Override
    public AjaxResult getMachineById(BackApplyInfo dto) {
        if (dto == null) {
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "参数不能为空");
        }
        if (dto.getUnitId() == null) {
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "单位ID为空");
        }
        if (dto.getProId() == null) {
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "工程ID为空");
        }
        if (StringUtils.isBlank(dto.getTypeId())) {
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "机具类型ID为空");
        }
        return AjaxResult.success(backApplyInfoMapper.getMachineById(dto));
    }

    /**
     * 提交退料申请
     * @param backApplyInfo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult submitBackApply(@NotNull(message = "参数不能为空") BackApplyInfo backApplyInfo) {
        if (backApplyInfo.getUnitId() == null || backApplyInfo.getProId() == null) {
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "参数不能为空");
        }
        List<BackApplyInfo> codeList = new ArrayList<>();
        // 根据传入的id查询退料申请信息
        List<BackApplyInfo> applyInfoList = backApplyInfoMapper.selectBackDetails(backApplyInfo);
        // 将applyInfoList中状态不为在用的数据收集到新集合中
        if (CollectionUtils.isNotEmpty(applyInfoList)) {
            for (BackApplyInfo applyInfo : applyInfoList) {
                if (StringUtils.isNotBlank(applyInfo.getMaStatus())) {
                    if (!"2".equals(applyInfo.getMaStatus())) {
                        codeList.add(applyInfo);
                    }
                }
            }
        }
        if (CollectionUtils.isNotEmpty(codeList)) {
            StringBuilder msgBuilder = new StringBuilder("您所选择的编码设备编号");
            for (int i = 0; i < codeList.size(); i++) {
                String maCode = codeList.get(i).getMaCode();
                msgBuilder.append(maCode);
                if (i < codeList.size() - 1) {
                    msgBuilder.append(", ");
                }
            }
            msgBuilder.append("已被他人完成退料，请编辑后重新提交！");
            String msg = msgBuilder.toString();
            msg = msg.replaceAll("\n", "");
            return AjaxResult.error(msg);
        }
        int result = 0;
        //先查询退料详情信息
        List<BackApplyDetails> applyDetails = backApplyInfoMapper.selectBackApplyDetailsListByTaskId(backApplyInfo);
        // 根据id查询协议id
        Long agreementId = backApplyInfoMapper.selectAgreementId(backApplyInfo);
        // 先查第四层类型
        backApplyInfo.setAgreementId(agreementId);
        List<TypeTreeNode> listL4 = mapper.getUseTypeTreeL4(backApplyInfo);
        if (CollectionUtils.isNotEmpty(applyDetails)) {
            for (BackApplyDetails applyDetail : applyDetails) {
                if (CollectionUtils.isNotEmpty(listL4)) {
                    for (TypeTreeNode typeTreeNode : listL4) {
                        if(applyDetail.getTypeId()!=null){
                            if (applyDetail.getTypeId().equals(typeTreeNode.getTypeId())) {
                                if (applyDetail.getPreNum().compareTo(typeTreeNode.getNum()) > 0) {
                                    return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "退料数量不能大于在用数量");
                                }
                            }
                        }

                    }
                }
            }
        } else {
            return AjaxResult.error("退料物资为空，无法进行提交");
        }
        // 设置更新信息,
        backApplyInfo.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        backApplyInfo.setUpdateTime(DateUtils.getNowDate());
        backApplyInfo.setTaskStatus(BackTaskStatusEnum.BACK_TASK_IN_FINISHED.getStatus());
        // 更新任务表及退料申请表状态
        result += updateTaskAndBackInfo(backApplyInfo);
        if (result > 0 && CollectionUtils.isNotEmpty(applyInfoList)) {
            for (BackApplyInfo applyInfo : applyInfoList) {
                result += machineMapper.updateStatus(applyInfo.getMaId(), MaMachineStatusEnum.BACK_REPAIR.getStatus());
            }
            // 获取applyInfoList的typeId并生成集合
            List<String> typeIdList = applyInfoList.stream()
                    .map(BackApplyInfo::getTypeId).distinct()
                    .collect(Collectors.toList());
            // 插入任务表
            Long newTaskId = insertTt(SecurityUtils.getLoginUser().getSysUser().getNickName(), backApplyInfo.getRemark(), backApplyInfo.getTaskId());
            // 插入协议任务表
            result += insertTta(newTaskId, applyInfoList);
            for (String typeId : typeIdList) {
                // 查询待维修的机具设备
                backApplyInfo.setTypeId(typeId);
                List<BackApplyInfo> wxList = backApplyInfoMapper.getWxList(backApplyInfo);
                if (CollectionUtils.isNotEmpty(wxList)) {
                    // 插入维修记录表
                    result += insertRad(newTaskId, wxList);
                    // 更新结算表
                    List<BackApplyInfo> allList = backApplyInfoMapper.selectBackDetails(backApplyInfo);
                    if (CollectionUtils.isNotEmpty(allList)) {
                        int res = updateSlt4Bean(backApplyInfo, allList);
                        // 检查机具是否领料
                        if (res == 0) {
                            throw new RuntimeException("该机具未被领料使用");
                        }
                    }
                    // 完成退料部分，更新 back_check_details
                    finishBackCheckDetails(backApplyInfo);
                }
            }
            // 如果所有操作都成功
            if (result > 0) {
                return AjaxResult.success();
            }
        }
        // 操作失败，返回错误
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 结算处理
     * @param record
     * @param allList
     * @return
     */
    private int updateSlt4BeanXm(BackApplyInfo record, List<BackApplyInfo> allList) {
        for (BackApplyInfo bean : allList) {
            List<SltAgreementInfo> infoList = backApplyInfoMapper.getStlInfo(bean);
            if (infoList.size() > 0) {
                BigDecimal backNum = bean.getBackNum();
                for (SltAgreementInfo info : infoList) {
                    BigDecimal num = info.getBackNum();
                    if (backNum.compareTo(num) == 0) {
                        backApplyInfoMapper.updateStlInfo(info, record);
                        break;
                    } else if (backNum.compareTo(num) > 0) {
                        backNum = backNum.subtract(num);
                        backApplyInfoMapper.updateStlInfo(info, record);
                    } else {
                        BigDecimal many = num.subtract(backNum);
                        backApplyInfoMapper.updateStlInfoTwo(info, record, backNum);
                        backApplyInfoMapper.insStlInfoTwo(info, many);
                        break;
                    }
                }
            } else {
                return 0;
            }
        }
        return 1;
    }

    /**
     * 生成材料站退料任务单号
     * @param thisMonthMaxOrder
     * @return
     */
    private String genderClzTaskCode(int thisMonthMaxOrder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date nowDate = DateUtils.getNowDate();
        String format = dateFormat.format(nowDate);
        String result = format.replace("-", "");
        return MaterialConstants.BACK_MATERIAL_TASK_TYPE_LABEL + result + String.format("-%03d", thisMonthMaxOrder + 1);
    }

    /**
     * 同步材料站结算
     * @param record
     * @param allList
     * @return
     */
    private int updateSlt4BeanClz(MaterialBackApplyInfo record, List<BackApplyInfo> allList) {
        for (BackApplyInfo bean : allList) {
            MaterialBackApplyInfo materialBackApplyInfo = new MaterialBackApplyInfo();
            materialBackApplyInfo.setAgreementId(bean.getAgreementId());
            materialBackApplyInfo.setTypeId(bean.getTypeId());
            materialBackApplyInfo.setMaId(bean.getMaId() != null ? bean.getMaId() : null);
            List<SltAgreementInfo> infoList = materialBackInfoMapper.getStlInfo(materialBackApplyInfo);
            if (infoList.size() > 0) {
                BigDecimal backNum = bean.getBackNum();
                for (SltAgreementInfo info : infoList) {
                    BigDecimal num = info.getBackNum();
                    if (backNum.compareTo(num) == 0) {
                        materialBackInfoMapper.updateStlInfo(info, record);
                        break;
                    } else if (backNum.compareTo(num) > 0) {
                        backNum = backNum.subtract(num);
                        materialBackInfoMapper.updateStlInfo(info, record);
                    } else {
                        BigDecimal many = num.subtract(backNum);
                        materialBackInfoMapper.updateStlInfoTwo(info, record, backNum);
                        materialBackInfoMapper.insStlInfoTwo(info, many);
                        break;
                    }
                }
            } else {
                return 0;
            }
        }
        return 1;
    }

    /**
     * 编辑打印状态
     * @param id
     * @return
     */
    @Override
    public AjaxResult editPrintStatus(Long id) {
        BackApplyInfo info = new BackApplyInfo().setId(id).setPrintStatus("1");
        int result = backApplyInfoMapper.updateBackApplyInfo(info);
        return result > 0 ? AjaxResult.success() : AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 新增退料申请app
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult insertApp(BackAppRequestVo dto) {
        int result = 0;
        if (dto != null && dto.getBackApplyInfo() != null && dto.getBackApplyInfo().getId() == null) {
            //只新增主任务单
            //对传入的手机号进行校验
            if (StringUtils.isNotBlank(dto.getBackApplyInfo().getPhone()) && !PhoneUtil.isMobile(dto.getBackApplyInfo().getPhone())) {
                return AjaxResult.error("手机号格式不正确，请重新填写!");
            }
            int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId());
            String code = genderTaskCode(thisMonthMaxOrder);
            // 根据单号查询此任务是否存在
            TmTask newTask = taskMapper.selectTaskByCode(code);
            if (newTask != null) {
                return AjaxResult.error("此任务单号已存在，请勿重复提交!");
            }
            TmTask tmTask = new TmTask(null, TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId(),
                    BackTaskStatusEnum.BACK_TASK_NO_FINISHED.getStatus(),
                    null, thisMonthMaxOrder + 1, code);
            tmTask.setCreateTime(DateUtils.getNowDate());
            tmTask.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
            BackApplyInfo backApplyInfo = dto.getBackApplyInfo();
            backApplyInfo.setCode(code);
            backApplyInfo.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
            backApplyInfo.setCreateTime(DateUtils.getNowDate());
            result = getResultTask(dto, result, tmTask, backApplyInfo);
            if (result > 0) {
                BackApplyInfo info = new BackApplyInfo();
                info.setId(backApplyInfo.getId());
                info.setTaskId(tmTask.getTaskId());
                return AjaxResult.success(info);
            }
        } else if (dto != null && dto.getBackApplyInfo() != null && dto.getBackApplyInfo().getId() != null
                && ((dto.getBackApplyDetails() != null) || CollectionUtils.isNotEmpty(dto.getBackApplyDetailsList()))) {
            if (dto.getBackApplyDetails() != null) {
                //编码退料入库
                dto.getBackApplyInfo().setTypeId(String.valueOf(dto.getBackApplyDetails().getTypeId()));
                result = getResultMaCode(dto, result);
            }
            if (CollectionUtils.isNotEmpty(dto.getBackApplyDetailsList())) {
                //数量退料入库
                for (BackApplyDetails details : dto.getBackApplyDetailsList()) {
                    result = getResultNum(dto, result, details);
                }
            }
            if (result > 0) {
                return AjaxResult.success();
            }
        } else if (dto != null && dto.getBackApplyInfo() != null && dto.getBackApplyDetails() != null) {
            //对传入的手机号进行校验
            if (StringUtils.isNotBlank(dto.getBackApplyInfo().getPhone()) && !PhoneUtil.isMobile(dto.getBackApplyInfo().getPhone())) {
                return AjaxResult.error("手机号格式不正确，请重新填写!");
            }
            int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId());
            String code = genderTaskCode(thisMonthMaxOrder);
            // 根据单号查询此任务是否存在
            TmTask newTask = taskMapper.selectTaskByCode(code);
            if (newTask != null) {
                return AjaxResult.error("此任务单号已存在，请勿重复提交!");
            }
            TmTask tmTask = new TmTask(null, TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId(),
                    BackTaskStatusEnum.BACK_TASK_NO_FINISHED.getStatus(),
                    null, thisMonthMaxOrder + 1, code);
            tmTask.setCreateTime(DateUtils.getNowDate());
            tmTask.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
            BackApplyInfo backApplyInfo = dto.getBackApplyInfo();
            backApplyInfo.setCode(code);
            backApplyInfo.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
            backApplyInfo.setCreateTime(DateUtils.getNowDate());
            // 保存退料信息到 tm_task 表中
            result = getResultTask(dto, result, tmTask, backApplyInfo);
            extractedMaCode(dto, result, code, backApplyInfo);
            if (result > 0) {
                return AjaxResult.success();
            }
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * app直接编码保存方法抽取
     * @param dto
     * @param result
     * @param code
     * @param backApplyInfo
     */
    private void extractedMaCode(BackAppRequestVo dto, int result, String code, BackApplyInfo backApplyInfo) {
        //根据协议以及类型id查询领料数量
        Integer num = backApplyInfoMapper.getNum(backApplyInfo);
        //编码退料入库
        Long id = backApplyInfo.getId();
        BackApplyDetails details = dto.getBackApplyDetails();
        details.setCode(code);
        details.setParentId(id);
        details.setNum(BigDecimal.valueOf(num));
        details.setAuditNum(details.getPreNum());
        details.setStatus(String.valueOf(BackTaskStatusEnum.BACK_TASK_NO_FINISHED.getStatus()));
        details.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        details.setCreateTime(DateUtils.getNowDate());
        // 保存退料详情
        result += backApplyInfoMapper.insertBackApplyDetails(details);
        // 设置公共字段
        setCommonFields(details, id);
        details.setPreNum(BigDecimal.valueOf(1));
        // 插入 CheckDetails
        result += backApplyInfoMapper.insertCheckDetails(details);
        //更新ma_machine表状态为11（退料暂存）
        //result += machineMapper.updateStatus(details.getMaId(), MaMachineStatusEnum.RETURNED_MATERIAL.getStatus());
        if (CollectionUtils.isNotEmpty(details.getBmFileInfos())) {
            for (BmFileInfo bmFileInfo : details.getBmFileInfos()) {
                bmFileInfo.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                bmFileInfo.setCreateTime(DateUtils.getNowDate());
                bmFileInfo.setTaskId(details.getId());
                bmFileInfo.setTaskType(3);
                bmFileInfo.setModelId(details.getMaId());
                result += bmFileInfoMapper.insertBmFileInfo(bmFileInfo);
            }
        }
    }

    /**
     * 保存退料信息到任务及任务协议表
     * @param dto
     * @param result
     * @param tmTask
     * @param backApplyInfo
     * @return
     */
    private int getResultTask(BackAppRequestVo dto, int result, TmTask tmTask, BackApplyInfo backApplyInfo) {
        // 保存退料信息到 tm_task 表中
        result += taskMapper.insertTmTask(tmTask);
        if (result > 0) {
            TmTaskAgreement tmTaskAgreement = new TmTaskAgreement(tmTask.getTaskId(), dto.getBackApplyInfo().getAgreementId());
            tmTaskAgreement.setCreateTime(DateUtils.getNowDate());
            tmTaskAgreement.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
            taskAgreementMapper.insertTmTaskAgreement(tmTaskAgreement);
            backApplyInfo.setTaskId(tmTask.getTaskId());
            result += backApplyInfoMapper.insertBackApplyInfo(backApplyInfo);
        }
        return result;
    }

    /**
     * 数量退料入库
     * @param dto
     * @param result
     * @param details
     * @return
     */
    private int getResultNum(BackAppRequestVo dto, int result, BackApplyDetails details) {
        details.setCode(dto.getBackApplyInfo().getCode());
        details.setParentId(dto.getBackApplyInfo().getId());
        details.setAuditNum(details.getPreNum());
        details.setStatus(String.valueOf(BackTaskStatusEnum.BACK_TASK_NO_FINISHED.getStatus()));
        details.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        details.setCreateTime(DateUtils.getNowDate());
        // 保存退料详情
        //现根据id查询back_apply_details表，看数据是否存在，存在则对数量进行更新，不存在则插入
        BackApplyDetails backApplyDetails = backApplyInfoMapper.selectBackApplyDetailsById(details);
        if (backApplyDetails != null) {
            details.setId(backApplyDetails.getId());
            result += backApplyInfoMapper.updateDetails(details);
        } else {
            result += backApplyInfoMapper.insertBackApplyDetails(details);
        }
        // 设置公共字段
        setCommonFields(details, dto.getBackApplyInfo().getId());
        // 插入 CheckDetails
        //根据id查询back_check_details表，看数据是否存在，存在则对数量进行更新，不存在则插入
        BackApplyDetails checkDetails = backApplyInfoMapper.selectCheckDetails(details);
        if (checkDetails != null) {
            details.setId(checkDetails.getId());
            result += backApplyInfoMapper.updateCheck(details);
        } else {
            result += backApplyInfoMapper.insertCheckDetails(details);
        }
        // 处理附件
        result = saveBmFileInfo(details, dto.getBackApplyInfo().getId(), result);
        return result;
    }

    /**
     * 编码退料入库
     * @param dto
     * @param result
     * @return
     */
    private int getResultMaCode(BackAppRequestVo dto, int result) {
        //根据协议以及类型id查询领料数量
        Integer num = backApplyInfoMapper.getNum(dto.getBackApplyInfo());
        //编码退料入库
        BackApplyDetails details = dto.getBackApplyDetails();
        details.setCode(dto.getBackApplyInfo().getCode());
        details.setParentId(dto.getBackApplyInfo().getId());
        details.setPreNum(BigDecimal.valueOf(dto.getBackApplyDetails().getMaVos().size()));
        details.setAuditNum(details.getPreNum());
        details.setNum(BigDecimal.valueOf(num));
        details.setGoodNum(details.getGoodNum());
        details.setBadNum(details.getBadNum());
        details.setStatus(String.valueOf(BackTaskStatusEnum.BACK_TASK_NO_FINISHED.getStatus()));
        details.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        details.setCreateTime(DateUtils.getNowDate());
        // 保存退料详情
        //现根据id查询back_apply_details表，看数据是否存在，存在则对数量进行更新，不存在则插入
        BackApplyDetails backApplyDetails = backApplyInfoMapper.selectBackApplyDetailsById(details);
        if (backApplyDetails != null) {
            details.setId(backApplyDetails.getId());
            result += backApplyInfoMapper.updateDetails(details);
        } else {
            result += backApplyInfoMapper.insertBackApplyDetails(details);
        }
        // 设置公共字段
        setCommonFields(details, dto.getBackApplyInfo().getId());
        //根据id查询back_check_details表，看数据是否存在，存在则对数量进行更新，不存在则插入
        for(MaCodeDto maCodeDto : details.getMaVos()){
            details.setPreNum(BigDecimal.ONE);
            details.setMaId(maCodeDto.getMaId());

            BackApplyDetails checkDetails = backApplyInfoMapper.selectCheckDetails(details);
            if (checkDetails != null) {

            }else{
                // 如果details.getGoodNum()大于0
                if (details.getGoodNum().compareTo(BigDecimal.ZERO) > 0) {
                    details.setGoodNum(BigDecimal.ONE);
                    details.setBadNum(BigDecimal.ZERO);
                } else {
                    details.setGoodNum(BigDecimal.ZERO);
                    details.setBadNum(BigDecimal.ONE);
                }
                result += backApplyInfoMapper.insertCheckDetails(details);
                if (CollectionUtils.isNotEmpty(details.getBmFileInfos())) {
                    for (BmFileInfo bmFileInfo : details.getBmFileInfos()) {
                        bmFileInfo.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                        bmFileInfo.setCreateTime(DateUtils.getNowDate());
                        bmFileInfo.setTaskId(details.getId());
                        bmFileInfo.setTaskType(3);
                        bmFileInfo.setModelId(maCodeDto.getMaId());
                        result += bmFileInfoMapper.insertBmFileInfo(bmFileInfo);
                    }
                }
            }


        }
        return result;
    }

    /**
     * app内层删除退料任务
     * @param backApplyInfo
     * @return
     */
    @Override
    public AjaxResult delete(BackApplyInfo backApplyInfo) {
        // 单个编码删除
        if (backApplyInfo.getMaId() != null) {
            // 先查询相关编码信息
            List<MaCodeVo> maCodeVoList = backApplyInfoMapper.selectByCode(backApplyInfo.getParentId());
            // 更新 back_apply_details 表信息
            BackApplyDetails backApplyDetails = new BackApplyDetails();
            backApplyDetails.setParentId(backApplyInfo.getParentId());
            backApplyDetails.setTypeId(Long.valueOf(backApplyInfo.getTypeId()));
            backApplyDetails.setPreNum(BigDecimal.valueOf(1));
            int result = backApplyInfoMapper.update(backApplyDetails);
            // 删除 back_check_details 表信息
            result += deleteBackCheckDetails(backApplyInfo);
            //修改机具状态
            result += machineMapper.updateStatus(backApplyInfo.getMaId(), MaMachineStatusEnum.IN_USE.getStatus());
            // 删除相关文件信息
            if (CollectionUtils.isNotEmpty(maCodeVoList)) {
                result += deleteBmFileInfoForCodes(maCodeVoList, backApplyInfo.getId());
            }
            // 查询back_check_details中是否还有数据，如果没有，删除back_apply_details
            List<BackApplyDetails> list = backApplyInfoMapper.selectBackApplyDetailsList(backApplyDetails);
            if (CollectionUtils.isEmpty(list)) {
                result += backApplyInfoMapper.deleteBackApplyDetailsById(backApplyDetails);
            }
            if (result > 0) {
                return AjaxResult.success();
            }
        }
        // 查询相关编码信息
        List<MaCodeVo> maCodeVoList = backApplyInfoMapper.selectByCode(backApplyInfo.getParentId());
        // 清除明细表以及相关的文件信息
        int result = deleteApplyDetails(backApplyInfo);
        result += deleteBackCheckDetails(backApplyInfo);
        // 删除文件信息
        result += deleteBmFileInfoByParentId(backApplyInfo.getParentId(), backApplyInfo.getId());

        // 删除与 MaCodeVo 相关的文件信息
        if (CollectionUtils.isNotEmpty(maCodeVoList)) {
            result += deleteBmFileInfoForCodes(maCodeVoList, backApplyInfo.getId());
        }
        if (result > 0) {
            return AjaxResult.success();
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 删除 back_check_details 表信息
     * @param backApplyInfo
     * @return
     */
    private int deleteBackCheckDetails(BackApplyInfo backApplyInfo) {
        return backApplyInfoMapper.deleteDetails(backApplyInfo);
    }

    /**
     * 删除 back_apply_details 表信息
     * @param backApplyInfo
     * @return
     */
    private int deleteApplyDetails(BackApplyInfo backApplyInfo) {
       return backApplyInfoMapper.deleteApplyDetails(backApplyInfo);
    }

    /**
     * 删除与指定 parentId 和 modelId 相关的文件信息
     * @param parentId
     * @param modelId
     * @return
     */
    private int deleteBmFileInfoByParentId(Long parentId, Long modelId) {
        BmFileInfo fileInfo = new BmFileInfo();
        fileInfo.setTaskId(parentId);
        fileInfo.setModelId(modelId);
        return bmFileInfoMapper.deleteBmFileInfoByBizInfo(fileInfo);
    }

    /**
     * 删除与 maCodeVo 中的 maId 相关的文件信息
     * @param maCodeVoList
     * @param taskId
     * @return
     */
    private int deleteBmFileInfoForCodes(List<MaCodeVo> maCodeVoList, Long taskId) {
        int result = 0;
        for (MaCodeVo maCodeVo : maCodeVoList) {
            BmFileInfo bmFileInfo = new BmFileInfo();
            bmFileInfo.setTaskId(taskId);
            bmFileInfo.setModelId(maCodeVo.getMaId());
            result += bmFileInfoMapper.deleteBmFileInfoByBizInfo(bmFileInfo);
        }
        return result;
    }

    /**
     * app编码检索
     * @param dto
     * @return
     */
    @Override
    public AjaxResult getMachine(BackApplyInfo dto) {
        // 首先根据id、maCode或者qrCode进行查询，看此条数据是否已经存在该退料单中
        if (dto.getId() != null && (StringUtils.isNotBlank(dto.getMaCode()) || StringUtils.isNotBlank(dto.getQrCode()))) {
            List<MaCodeVo> maCodeVoList = backApplyInfoMapper.getMachineByIdAndCode(dto);
            if (CollectionUtils.isNotEmpty(maCodeVoList)) {
                return AjaxResult.error("该编码已存在该退料单中，请重新选择");
            }
        }
        //判断输入或者编码识别或者二维码识别是否为领料工程和单位对应
        List<MaCodeVo> list = new ArrayList<>();
        dto.setUserId(SecurityUtils.getLoginUser().getUserid());
        if (dto.getMaCode() != null) {
            // 判断是否有这个设备编码
            List<MaCodeVo> listOneMaCode = backApplyInfoMapper.getMachineByOneMaCode(dto);
            if(CollectionUtils.isEmpty(listOneMaCode)){
                return AjaxResult.error("该设备编码不存在，请重新选择");
            }
            // 判断是否是在用状态
            List<MaCodeVo> listTwoMaCode = backApplyInfoMapper.getMachineByTwoMaCode(dto);
            if(CollectionUtils.isEmpty(listTwoMaCode)){
                return AjaxResult.error("该设备编码非在用状态，请重新选择");
            }
            // 判断是否是当前协议下的设备
            List<MaCodeVo> listThreeMaCode = backApplyInfoMapper.getMachineByThreeMaCode(dto);
            if(CollectionUtils.isEmpty(listThreeMaCode)){
                return AjaxResult.error("该设备编码非当前协议下的设备，请重新选择");
            }
            // 判断是否是当前人负责的设备
            list = backApplyInfoMapper.getMachine(dto);
            if (CollectionUtils.isEmpty(list)) {
                return AjaxResult.error("该设备编码非您负责的设备，请重新选择");
            }
        } else if (dto.getQrCode() != null) {
            // 判断是否有这个二维码
            List<MaCodeVo> listOne = backApplyInfoMapper.getMachineByOne(dto);
            if(CollectionUtils.isEmpty(listOne)){
                return AjaxResult.error("该二维码不存在，请重新选择");
            }
            // 判断是否是在用状态
            List<MaCodeVo> listTwo = backApplyInfoMapper.getMachineByTwo(dto);
            if(CollectionUtils.isEmpty(listTwo)){
                return AjaxResult.error("该二维码非在用状态，请重新选择");
            }
            // 判断是否是当前协议下的设备
            List<MaCodeVo> listThree = backApplyInfoMapper.getMachineByThree(dto);
            if(CollectionUtils.isEmpty(listThree)){
                return AjaxResult.error("该二维码非当前协议下的设备，请重新选择");
            }
            // 判断是否是当前人负责的设备
            list = backApplyInfoMapper.getMachineByQrCode(dto);
            if (CollectionUtils.isEmpty(list)) {
                return AjaxResult.error("该编码非您负责的设备，请重新选择");
            }
        }
        if (CollectionUtils.isNotEmpty(list)) {
            for (MaCodeVo maCodeVo : list) {
                Map<String, String> maMachineMap = remoteConfig.getDictValue("ma_machine_status");
                String name = maMachineMap.get(maCodeVo.getMaStatus());
                maCodeVo.setMaStatusName(StringUtils.isBlank(name) ? "" : name);
            }
            return AjaxResult.success(list);
        }
        return AjaxResult.error(HttpCodeEnum.SYSTEM_ERROR.getCode(), "检索为空或该设备非该单位和工程所领");
    }

    /**
     * app查询单个类型设备编码
     * @param backApplyInfo
     * @return
     */
    @Override
    public AjaxResult getMaCodeList(BackApplyInfo backApplyInfo) {
        // 查询相关编码信息
        List<MaCodeVo> maCodeVoList = backApplyInfoMapper.selectByTypeId(backApplyInfo);
        List<MaCodeDto> maCodeDtos = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(maCodeVoList)) {
            for (MaCodeVo maCodeVo : maCodeVoList) {
                MaCodeDto maCodeDto = new MaCodeDto();
                maCodeDto.setMaCode(maCodeVo.getMaCode());
                maCodeDto.setMaId(maCodeVo.getMaId());
                maCodeDto.setApDetection(maCodeVo.getApDetection());
                maCodeDto.setTypeName(maCodeVo.getTypeName());
                maCodeDto.setMaterialName(maCodeVo.getMaterialName());
                maCodeDto.setTypeId(maCodeVo.getTypeId());
                maCodeDto.setMaStatus(maCodeVo.getMaStatus());
                maCodeDto.setMaterialType(maCodeVo.getMaterialType());
                maCodeDto.setCreateBy(maCodeVo.getCreateBy());
                maCodeDto.setCreateTime(maCodeVo.getCreateTime());
                // 查询并设置编码附件
                List<BmFileInfo> bmFileInfoList = fetchBmFileInfos(backApplyInfo.getId(), maCodeVo.getMaId());
                if (CollectionUtils.isNotEmpty(bmFileInfoList)) {
                    maCodeDto.setBmFileInfos(bmFileInfoList);
                }
                maCodeDtos.add(maCodeDto);
            }
        }
        return AjaxResult.success(maCodeDtos);
    }

    /**
     * app编码查看保存
     * @param maCode
     * @return
     */
    @Override
    public AjaxResult updateMaCode(MaCode maCode) {
        int result = 0;
        if (CollectionUtils.isNotEmpty(maCode.getMaCodeDtoList())) {
            // 遍历 maCodeDtoList
            for (MaCodeDto maCodeDto : maCode.getMaCodeDtoList()) {
                // 参数校验
                if (maCodeDto.getId() == null ||maCodeDto.getParentId() == null || maCodeDto.getMaId() == null) {
                    return AjaxResult.error("参数错误");
                }
                // 更新 back_check_details 表
                maCodeDto.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                maCodeDto.setUpdateTime(DateUtils.getNowDate());
                result += backApplyInfoMapper.updateMaCode(maCodeDto);
                // 获取 bmFileInfos
                List<BmFileInfo> bmFileInfos = maCodeDto.getBmFileInfos();
                if (CollectionUtils.isNotEmpty(bmFileInfos)) {
                    // 准备删除的文件 ID 列表
                    BmFileInfo fileInfo = new BmFileInfo();
                    fileInfo.setTaskId(maCodeDto.getId());
                    fileInfo.setModelId(maCodeDto.getMaId());
                    // 获取现有的附件信息
                    List<BmFileInfo> bmFileInfoList = bmFileInfoMapper.selectBmFileInfoList(fileInfo);
                    // 如果已有附件记录，则删除
                    if (CollectionUtils.isNotEmpty(bmFileInfoList)) {
                        Long[] ids = bmFileInfoList.stream()
                                .map(BmFileInfo::getId)
                                .toArray(Long[]::new);
                        result += bmFileInfoMapper.deleteBmFileInfoByIds(ids);
                    }
                    // 批量插入新的附件
                    for (BmFileInfo bmFileInfo : bmFileInfos) {
                        bmFileInfo.setTaskId(maCodeDto.getId());
                        bmFileInfo.setModelId(maCodeDto.getMaId());
                        result += bmFileInfoMapper.insertBmFileInfo(bmFileInfo);
                    }
                }
            }
            // 如果成功执行了至少一项操作，返回成功
            if (result > 0) {
                return AjaxResult.success("保存成功", result);
            }
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    /**
     * 查询工程是否结算
     * @param backApplyInfo
     * @return
     */
    @Override
    public AjaxResult selectIsSltById(BackApplyInfo backApplyInfo) {
        SltAgreementInfo info = new SltAgreementInfo();
        info.setAgreementId(backApplyInfo.getAgreementId());
        List<SltAgreementInfo> list = sltAgreementInfoMapper.selectSltAgreementInfoList(info);
        if (CollectionUtils.isNotEmpty(list)) {
            // 查看list中的isSlt字段是否包含1，如果包含，说明此工程已结算，无法再建立退料任务
            for (SltAgreementInfo sltAgreementInfo : list) {
                if ("1".equals(sltAgreementInfo.getIsSlt())) {
                    return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "工程已结算，无法再建立退料任务");
                }
            }
        }
        return AjaxResult.success();
    }

    /**
     * 根据id查询退料详情
     * @param backApplyDetails
     * @return
     */
    @Override
    public List<BackApplyDetails> getDetailsById(BackApplyDetails backApplyDetails) {
        return backApplyInfoMapper.getDetailsById(backApplyDetails);
    }

    /**
     * app退料退回
     * @param backApplyDetails
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult backOutBack(BackApplyDetails backApplyDetails) {
        int result = 0;
        TmTask tmTask = taskMapper.selectTmTaskByTaskId(backApplyDetails.getTaskId());
        if (tmTask != null && tmTask.getTaskStatus().equals(BackTaskStatusEnum.BACK_TASK_IN_FINISHED.getStatus())) {
            return AjaxResult.error("该任务已完成，不能进行退回操作");
        }
        BackApplyDetails info = backApplyInfoMapper.selectBackApplyDetailsById(backApplyDetails);
        // 针对于数量退回的设备，进行file文件的删除
        if (backApplyDetails.getMaId() == null) {
            BmFileInfo bmFileInfo = new BmFileInfo();
            bmFileInfo.setTaskId(backApplyDetails.getTaskId());
            bmFileInfo.setModelId(info.getId());
            bmFileInfo.setTaskType(3);
            result += bmFileInfoMapper.deleteBmFileInfoByBizInfo(bmFileInfo);
            if (result > 0) {
                // 删除back_apply_details的数据
                result += backApplyInfoMapper.deleteBackApplyDetailsById(backApplyDetails);
                // 删除back_check_details的数据
                BackApplyInfo backApplyInfo = new BackApplyInfo();
                backApplyInfo.setParentId(backApplyDetails.getParentId());
                backApplyInfo.setTypeId(backApplyDetails.getTypeId().toString());
                result += backApplyInfoMapper.deleteDetails(backApplyInfo);
            }
            if (result > 0) {
                return AjaxResult.success("退料退回成功");
            }
        } else if (backApplyDetails.getMaId() != null) {
            BmFileInfo bmFileInfo = new BmFileInfo();
            bmFileInfo.setTaskId(info.getId());
            bmFileInfo.setModelId(backApplyDetails.getMaId());
            bmFileInfo.setTaskType(3);
            result += bmFileInfoMapper.deleteBmFileInfoByBizInfo(bmFileInfo);
            if (result > 0) {
                // 先根据id查询back_apply_details的数据
                if (info.getPreNum().compareTo(backApplyDetails.getPreNum()) == 0) {
                    // 删除back_apply_details的数据
                    result += backApplyInfoMapper.deleteBackApplyDetailsById(backApplyDetails);
                } else {
                    // 更新back_apply_details的数据
                    result += backApplyInfoMapper.update(backApplyDetails);
                }
                // 删除back_check_details的数据
                BackApplyInfo backApplyInfo = new BackApplyInfo();
                backApplyInfo.setParentId(backApplyDetails.getParentId());
                backApplyInfo.setTypeId(backApplyDetails.getTypeId().toString());
                result += backApplyInfoMapper.deleteDetails(backApplyInfo);
                // 更新ma_machine表的状态
                LeaseOutDetails leaseOutDetails = new LeaseOutDetails();
                leaseOutDetails.setTypeId(backApplyDetails.getTypeId());
                result += machineMapper.updateMaMachineStatus(leaseOutDetails, MaMachineStatusEnum.IN_USE.getStatus());
            }
            if (result > 0) {
                return AjaxResult.success("退料退回成功");
            }
        }
        return AjaxResult.error("退料退回失败");
    }

    /**
     * 查询修试查询-退料查询列表
     * @param dto
     * @return
     */
    @Override
    public List<BackApplyVo> selectBackApplyList(BackApplyVo dto) {
        List<BackApplyVo> list = backApplyInfoMapper.selectBackApplyList(dto);
        if (CollectionUtils.isNotEmpty(list)) {
            for (BackApplyVo backApplyVo : list) {
                // 根据id查询维修单号
                BackApplyInfo backApplyInfo = backApplyInfoMapper.selectRepairCode(backApplyVo);
                if (backApplyInfo != null && backApplyInfo.getCode() != null) {
                    backApplyVo.setRepairCode(backApplyInfo.getCode());
                }
            }
            // 如果关键字不为空，根据关键字查询
            if (!StringUtils.isBlank(dto.getKeyWord())) {
                list = list.stream()
                        .filter(item -> containsBackKeyword(item, dto.getKeyWord()))
                        .collect(Collectors.toList());
            }
        }
        return list;
    }

    /**
     * 查询修试查询-退料查询二级列表
     * @param dto
     * @return
     */
    @Override
    public BackApplyInfoVo selectSecondList(BackApplyInfoVo dto) {
        // 根据id以及typeId以及maId查询相关信息
        BackApplyInfoVo info = backApplyInfoMapper.selectIdList(dto);
        // 查询退料相关信息
        BackApplyInfoVo vo = backApplyInfoMapper.selectDetails(dto);
        BmFileInfo bmFileInfo = new BmFileInfo();
        if (dto != null && dto.getTypeId() != null) {
            bmFileInfo.setTaskId(dto.getId());
            bmFileInfo.setTaskType(3);
            bmFileInfo.setModelId(info.getBackId());
            List<BmFileInfo> bmFileInfoList = bmFileInfoMapper.selectBmFileInfoList(bmFileInfo);
            if (!CollectionUtils.isEmpty(bmFileInfoList)) {
                vo.setFileInfoList(bmFileInfoList);
            }
        } else if (dto != null && dto.getMaId() != null) {
            bmFileInfo.setTaskId(info.getBackId());
            bmFileInfo.setTaskType(3);
            bmFileInfo.setModelId(dto.getMaId());
            List<BmFileInfo> bmFileInfoList = bmFileInfoMapper.selectBmFileInfoList(bmFileInfo);
            if (!CollectionUtils.isEmpty(bmFileInfoList)) {
                vo.setFileInfoList(bmFileInfoList);
            }
        }
        return vo;
    }

    /**
     * 根据单位和工程id查询领料机具
     * @param dto
     * @return
     */
    @Override
    public AjaxResult selectMachineById(BackApplyInfo dto) {
        List<MaCodeVo> list = backApplyInfoMapper.getMachineById(dto);
        if (CollectionUtils.isNotEmpty(list)) {
            // 根据id查询该单据可能存在的设备编码
            List<MaCodeVo> maCodeVos = backApplyInfoMapper.selectByCode(dto.getId());
            if (CollectionUtils.isNotEmpty(maCodeVos)) {
                // 获取maCodeVos中的编码
                List<String> maCodes = maCodeVos.stream().map(MaCodeVo::getMaCode).collect(Collectors.toList());
                // 将maCodes中存在于list集合中的编码，把数据从list集合中去除
                list = list.stream().
                        filter(info -> !maCodes.contains(info.getMaCode())).
                        collect(Collectors.toList());
            }
        }
        return AjaxResult.success(list);
    }

    @Override
    public List<MaCodeVo> selectMachineByIdList(BackApplyInfo dto) {
        List<MaCodeVo> list = backApplyInfoMapper.getMachineById(dto);
        if (CollectionUtils.isNotEmpty(list)) {
            // 根据id查询该单据可能存在的设备编码
            List<MaCodeVo> maCodeVos = backApplyInfoMapper.selectByCode(dto.getId());
            if (CollectionUtils.isNotEmpty(maCodeVos)) {
                // 获取maCodeVos中的编码
                List<String> maCodes = maCodeVos.stream().map(MaCodeVo::getMaCode).collect(Collectors.toList());
                // 将maCodes中存在于list集合中的编码，把数据从list集合中去除
                list = list.stream().
                        filter(info -> !maCodes.contains(info.getMaCode())).
                        collect(Collectors.toList());
            }
        }
        return list;
    }

    /**
     * APP删除退料任务
     * @param id
     * @return
     */
    @Override
    public AjaxResult deleteByApp(Long id) {
        try {
            // 查询信息
            BackApplyInfo backApplyInfo = backApplyInfoMapper.selectBackApplyInfoById(id);
            List<BackApplyDetails> backApplyDetailsList = backApplyInfoMapper.selectBackApplyDetailsListByTaskId(backApplyInfo);
            if (CollectionUtils.isNotEmpty(backApplyDetailsList)) {
                return AjaxResult.error("该单据中存在相关退料数据，不允许删除");
            }
            // 删除相关任务信息
            int result = deleteTaskInfo(backApplyInfo);
            if (result > 0) {
                return AjaxResult.success(result);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    @Override
    public AjaxResult getMachineByCode(BackApplyInfo dto) {
        dto.setUserId(SecurityUtils.getLoginUser().getUserid());
        return backApplyInfoMapper.getMachineByCode(dto);
    }

    @Override
    public AjaxResult addHandlingOrder(HandlingOrder bean) {
        try {
            Long userId = SecurityUtils.getLoginUser().getUserid();
            bean.setCreateBy(userId.toString());
            int re = backApplyInfoMapper.addHandlingOrder(bean);
            if (re>0){
                return AjaxResult.success("添加成功");
            } else {
                return AjaxResult.error("添加失败");
            }
        } catch (Exception e) {
            log.error("添加装卸单失败", e);
            return AjaxResult.error("添加装卸单失败");
        }
    }

    @Override
    public List<HandlingOrder> getHandlingOrderList(HandlingOrder bean) {
        List<HandlingOrder> list = backApplyInfoMapper.getHandlingOrderList(bean);
        if (list.size()>0){
            for (HandlingOrder handlingOrder : list){
                if (StringUtils.isNotBlank(handlingOrder.getSignUrl())) {
                    if (!handlingOrder.getSignUrl().startsWith("http")) {
                        handlingOrder.setSignUrl("data:image/png;base64," + handlingOrder.getSignUrl());
                    }
                }
            }
        }
        return list;
    }

    @Override
    public AjaxResult uploadSort(HandlingOrder bean) {
        try {
            //查询排号是否存在
            bean.setReserveDate(DateUtils.getDate());
            int re = backApplyInfoMapper.selectSort(bean);
            if (re > 0) {
                return AjaxResult.error("今日该号已存在");
            }
            Long userId = SecurityUtils.getLoginUser().getUserid();
            bean.setUpdateBy(userId.toString());
            int res = backApplyInfoMapper.uploadSort(bean);
            if (res > 0) {
                return AjaxResult.success("排号成功");
            } else {
                return AjaxResult.error("排号失败");
            }
        } catch (Exception e) {
            log.error("排号失败", e);
            return AjaxResult.error("排号失败");
        }
    }

    /**
     * 查询未签字退料任务列表
     * @param backApplyInfo
     * @return
     */
    @Override
    public List<BackApplyInfo> getNoSignList(BackApplyInfo backApplyInfo) {
        backApplyInfo.setIsSign(1);
        Long userId = SecurityUtils.getLoginUser().getUserid();
        // 首先根据用户名去ma_type_manage表查询是否存在绑定物资信息
        /*List<Long> typeIdList = backApplyInfoMapper.selectTypeIdList(userId);
        if (CollectionUtils.isEmpty(typeIdList)) {
            backApplyInfo.setUserId(userId == 0 ? null : userId);
        }*/
        Set<String> userRoles = SecurityUtils.getLoginUser().getRoles();
        // 检查用户是否具有特殊角色
        boolean hasSpecialRole = hasSpecialRole(userRoles);
        if (!hasSpecialRole) {
            backApplyInfo.setUserId(userId == 0 ? null : userId);
        }
        List<BackApplyInfo> list = backApplyInfoMapper.selectBackApplyInfoList(backApplyInfo);
        // 提取关键字
        String keyWord = backApplyInfo.getKeyWord();
        // 如果关键字不为空，进行过滤
        if (!StringUtils.isBlank(keyWord)) {
            list = list.stream()
                    .filter(item -> containsKeyword(item, keyWord))
                    .collect(Collectors.toList());
        }
        return list;
    }

    /**
     * 查询材料员待确认的任务
     * @param backApplyInfo
     * @return
     */
    @Override
    public List<BackApplyInfo> getCompleteBackTaskList(BackApplyInfo backApplyInfo) {
        // 查询已签名数据
        backApplyInfo.setIsSign(2);
        List<BackApplyInfo> list = backApplyInfoMapper.selectBackApplyInfoList(backApplyInfo);
        //材料站权限过滤
        String username = SecurityUtils.getLoginUser().getUsername();
        if(!CollectionUtils.isEmpty(list)) {
            list =  list.stream()
                    .filter(info -> {
                        // 调用 mapper 方法检查是否有符合条件的数据
                        int count = leaseApplyInfoMapper.checkPermission(info.getExternalId(), username);
                        return count > 0;
                    })
                    .collect(Collectors.toList());
        }
        // 提取关键字
        String keyWord = backApplyInfo.getKeyWord();
        // 如果关键字不为空，进行过滤
        if (!StringUtils.isBlank(keyWord)) {
            list = list.stream()
                    .filter(item -> containsKeyword(item, keyWord))
                    .collect(Collectors.toList());
        }
        return list;
    }

    /**
     * 材料员确认接口
     * @param backApplyInfo
     * @return
     */
    @Override
    public int confirmMaterial(BackApplyInfo backApplyInfo) {
        return backApplyInfoMapper.updateBackApplyInfo(backApplyInfo);
    }

    @Override
    public AjaxResult getSort(HandlingOrder bean) {
        HandlingOrder beans = new HandlingOrder();
        String timeTypes = "";
        try {
//            //判断现在是上午还是下午，上午为A，下午为B
//            Calendar calendar = Calendar.getInstance();
//            int hour = calendar.get(Calendar.HOUR_OF_DAY);
//            String timeType = (hour < 12) ? "A" : "B";
//            timeTypes = timeType;
//            bean.setTimeType(timeType);
//            bean.setReserveDate(DateUtils.getDate());
//            //查询当前的排号
//            HandlingOrder bean1 = backApplyInfoMapper.getSort(bean);
//            if (bean1 != null && bean1.getSort() != null) {
//                Integer sort = bean1.getSort() + 1;
//                beans.setSort(sort);
//                beans.setTimeType(timeType);
//            } else {
//                beans.setTimeType(timeType);
//                beans.setSort(1);
//            }
            return AjaxResult.success(beans);
        } catch (Exception e) {
            log.error("获取排号失败", e);
            beans.setTimeType(timeTypes);
            return AjaxResult.success(beans);
        }
    }

    /**
     * 班组退料提交
     * @param backApplyInfo
     * @return
     */
    @Override
    public AjaxResult submitBzBackApply(BackApplyInfo backApplyInfo) {
        if (backApplyInfo.getUnitId() == null || backApplyInfo.getProId() == null) {
            return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), "参数不能为空");
        }
        // 原本的领料班组单位ID
        Long teamUnitId = backApplyInfo.getUnitId();

        // 如果单位类型为班组，则查询该班在机具签署✍️的协议ID，查询班组挂靠的项目部协议信息
        LeaseOutDetails leaseOutDetail = leaseApplyInfoMapper.selectProjectUnitAgreementIdByTeamAndProject(
                Math.toIntExact(backApplyInfo.getUnitId()),
                Math.toIntExact(backApplyInfo.getProId())
        );
        if (leaseOutDetail == null) {
            throw new ServiceException("项目部协议信息查询为空");
        }

        // 把后续流程设置为项目部的协议进行处理
        backApplyInfo.setAgreementId(leaseOutDetail.getProjectUnitAgreementId());
        backApplyInfo.setUnitId(leaseOutDetail.getProjectUnitAgreementId());
        SelectDto dto = new SelectDto();
        dto.setProId(backApplyInfo.getProId()).setUnitId(Math.toIntExact(backApplyInfo.getUnitId()));
        List<AgreementVo> list = mapper.getAgreementInfoByIdBack(dto);

        List<BackApplyInfo> codeList = new ArrayList<>();
        // 根据传入的id查询退料申请信息
        List<BackApplyInfo> applyInfoList = backApplyInfoMapper.selectBackDetails(backApplyInfo);
        // 将applyInfoList中状态不为在用的数据收集到新集合中
        if (CollectionUtils.isNotEmpty(applyInfoList)) {
            for (BackApplyInfo applyInfo : applyInfoList) {
                // 根据maId查询设备是否处于在用状态(需要同时查询机具和材料站)
                if (applyInfo.getMaId() != null) {
                    //List<SltAgreementInfo> infoList = backApplyInfoMapper.getUserList(applyInfo);
                    List<SltAgreementInfo> clzList = backApplyInfoMapper.getClzUserList(applyInfo);
                    if (CollectionUtils.isEmpty(clzList)) {
                        codeList.add(applyInfo);
                    }
                }
            }
        }
        if (CollectionUtils.isNotEmpty(codeList)) {
            StringBuilder msgBuilder = new StringBuilder("您所选择的编码设备编号");
            for (int i = 0; i < codeList.size(); i++) {
                String maCode = codeList.get(i).getMaCode();
                msgBuilder.append(maCode);
                if (i < codeList.size() - 1) {
                    msgBuilder.append(", ");
                }
            }
            msgBuilder.append("已被他人完成退料，请编辑后重新提交！");
            String msg = msgBuilder.toString();
            msg = msg.replaceAll("\n", "");
            return AjaxResult.error(msg);
        }
        int result = 0;
        //先查询退料详情信息
        List<BackApplyDetails> applyDetails = backApplyInfoMapper.selectBackApplyDetailsListByTaskId(backApplyInfo);
        if (CollectionUtils.isEmpty(applyDetails)) {
            return AjaxResult.error("退料物资为空，无法进行提交");
        }
        // 设置更新信息,
        backApplyInfo.setUpdateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        backApplyInfo.setUpdateTime(DateUtils.getNowDate());
        backApplyInfo.setTaskStatus(BackTaskStatusEnum.BACK_TASK_IN_FINISHED.getStatus());
        // 更新任务表及退料申请表状态
        result += updateTaskAndBackInfo(backApplyInfo);
        if (result > 0 && CollectionUtils.isNotEmpty(applyInfoList)) {
            for (BackApplyInfo applyInfo : applyInfoList) {
                result += machineMapper.updateStatus(applyInfo.getMaId(), MaMachineStatusEnum.BACK_REPAIR.getStatus());
                // 查询该设备是否存在于材料站中 不判断，直接修改设备状态
                //List<SltAgreementInfo> clzList = backApplyInfoMapper.getClzUserList(applyInfo);
            }
            // 获取applyInfoList的typeId并生成集合
            List<String> typeIdList = applyInfoList.stream()
                    .map(BackApplyInfo::getTypeId).distinct()
                    .collect(Collectors.toList());
            // 插入任务表
            Long newTaskId = insertTt(SecurityUtils.getLoginUser().getSysUser().getNickName(), backApplyInfo.getRemark(), backApplyInfo.getTaskId());
            // 插入协议任务表,使用的是项目部协议ID
            result += insertTeamTta(newTaskId, leaseOutDetail.getProjectUnitAgreementId());

            // -----------------给材料站新建退料任务，处理数据开始✅ ----------------
            MaterialBackApplyInfo materialBackApplyInfo =  new MaterialBackApplyInfo();
            BmAgreementInfo bmAgreementInfo = new BmAgreementInfo();
            bmAgreementInfo.setUnitId(teamUnitId);
            bmAgreementInfo.setProjectId(backApplyInfo.getProId());
            BmAgreementInfo info = bmAgreementInfoMapper.queryByTeamIdAndProjectIdCl(bmAgreementInfo);
            BackApplyInfo backApplyInfo4 = new BackApplyInfo();

            int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_MATERIAL_BACK.getTaskTypeId());
            String code = genderClzTaskCode(thisMonthMaxOrder);
            TmTask tmTask = new TmTask(null, TmTaskTypeEnum.TM_TASK_MATERIAL_BACK.getTaskTypeId(),
                    BackTaskStatusEnum.BACK_TASK_IN_FINISHED.getStatus(), null, thisMonthMaxOrder + 1, code);
            tmTask.setCreateTime(DateUtils.getNowDate());
            String createBy = SecurityUtils.getLoginUser().getSysUser().getNickName();
            tmTask.setCreateBy(createBy);
            materialBackApplyInfo.setCode(code);
            materialBackApplyInfo.setCreateBy(createBy);
            materialBackApplyInfo.setCreateTime(DateUtils.getNowDate());
            // 保存退料信息到 tm_task 表中
            result += taskMapper.insertTmTask(tmTask);
            if (result > 0) {
                TmTaskAgreement tmTaskAgreement = new TmTaskAgreement(tmTask.getTaskId(), info.getAgreementId());
                tmTaskAgreement.setCreateTime(DateUtils.getNowDate());
                tmTaskAgreement.setCreateBy(createBy);
                taskAgreementMapper.insertTmTaskAgreement(tmTaskAgreement);
                materialBackApplyInfo.setTaskId(tmTask.getTaskId());
                materialBackApplyInfo.setBackStyle("2");
                materialBackApplyInfo.setStatus("2");
                BackApplyInfo backApplyInfo1 = backApplyInfoMapper.selectBackApplyInfoById(backApplyInfo.getId());
                if (backApplyInfo1 != null) {
                    materialBackApplyInfo.setBackPerson(StringUtils.isNotBlank(backApplyInfo1.getBackPerson()) ? backApplyInfo1.getBackPerson() : "");
                    materialBackApplyInfo.setPhone(StringUtils.isNotBlank(backApplyInfo1.getPhone()) ? backApplyInfo1.getPhone() : "");
                }
                result += materialBackInfoMapper.insertBackApplyInfo(materialBackApplyInfo);
                if (CollectionUtils.isNotEmpty(applyDetails)) {
                    for (BackApplyDetails applyInfo : applyDetails) {
                        MaterialBackApplyDetails details = new MaterialBackApplyDetails();
                        details.setCode(code);
                        details.setParentId(materialBackApplyInfo.getId());
                        details.setPreNum(applyInfo.getPreNum());
                        details.setAuditNum(applyInfo.getPreNum());
                        details.setStatus(String.valueOf(BackTaskStatusEnum.BACK_TASK_NO_FINISHED.getStatus()));
                        details.setCreateBy(createBy);
                        details.setCreateTime(DateUtils.getNowDate());
                        details.setTypeId(applyInfo.getTypeId());
                        // 保存退料详情
                        result += materialBackInfoMapper.insertBackApplyDetails(details);
                    }
                }
            }
            // -----------------给材料站新建退料任务，处理数据结束✅ ----------------


            // 材料站对分公司建立退料任务
            int backMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId());
            String backCode = genderTaskCode(backMonthMaxOrder);
            TmTask newTask = new TmTask(null, TmTaskTypeEnum.TM_TASK_BACK.getTaskTypeId(),
                    BackTaskStatusEnum.BACK_TASK_IN_FINISHED.getStatus(),
                    null, backMonthMaxOrder + 1, backCode);
            newTask.setCreateTime(DateUtils.getNowDate());
            newTask.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
            backApplyInfo4.setCode(backCode);
            backApplyInfo4.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
            backApplyInfo4.setCreateTime(DateUtils.getNowDate());
            // 保存退料信息到 tm_task 表中
            result += taskMapper.insertTmTask(newTask);
            if (result > 0) {
                // 根据单位和工程id查询项目部关联协议id
                BackApplyInfo backApplyInfo3 = backApplyInfoMapper.selectInfo(backApplyInfo);
                if (backApplyInfo3 != null) {
                    // 给项目部处理的时候要使用挂靠的项目部协议ID
                    TmTaskAgreement tmTaskAgreement = new TmTaskAgreement(newTask.getTaskId(), leaseOutDetail.getAgreementId());
                    tmTaskAgreement.setCreateTime(DateUtils.getNowDate());
                    tmTaskAgreement.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                    taskAgreementMapper.insertTmTaskAgreement(tmTaskAgreement);
                }
                backApplyInfo4.setTaskId(newTask.getTaskId());
                BackApplyInfo backApplyInfo2 = backApplyInfoMapper.selectBackApplyInfoById(backApplyInfo.getId());
                if (backApplyInfo2 != null) {
                    backApplyInfo4.setBackPerson(StringUtils.isNotBlank(backApplyInfo2.getBackPerson()) ? backApplyInfo2.getBackPerson() : "");
                    backApplyInfo4.setPhone(StringUtils.isNotBlank(backApplyInfo2.getPhone()) ? backApplyInfo2.getPhone() : "");
                    backApplyInfo4.setBackStyle("2");
                }
                result += backApplyInfoMapper.insertBackApplyInfo(backApplyInfo4);
            }
            // 保存退料详情
            if (CollectionUtils.isNotEmpty(applyDetails)) {
                for (BackApplyDetails applyDetail : applyDetails) {
                    // 保存退料详情
                    applyDetail.setAuditNum(applyDetail.getPreNum());
                    result += backApplyInfoMapper.insertBackApplyDetails(applyDetail);
                }
            }
            for (String typeId : typeIdList) {
                // 查询待维修的机具设备
                backApplyInfo.setTypeId(typeId);
                List<BackApplyInfo> wxList = backApplyInfoMapper.getWxList(backApplyInfo);
                if (CollectionUtils.isNotEmpty(wxList)) {
                    // 插入维修记录表
                    result += insertRad(newTaskId, wxList);
                    // 更新结算表
                    List<BackApplyInfo> allList = backApplyInfoMapper.selectBackDetails(backApplyInfo);
                    if (CollectionUtils.isNotEmpty(allList)) {
                        // 更新结算协议✍️表
                        int res = updateBzSlt4Bean(backApplyInfo, allList);
                        // 检查机具是否领料
                        if (res == 0) { throw new RuntimeException("该机具未被领料使用");}

                        List<BackApplyInfo> clzList = new ArrayList<>();
                        List<BackApplyInfo> xmList = new ArrayList<>();
                        for (BackApplyInfo applyInfo : allList) {
                            applyInfo.setAgreementId(info.getAgreementId());
                            MaterialBackApplyDetails details = new MaterialBackApplyDetails();
                            details.setParentId(materialBackApplyInfo.getId());
                            details.setTypeId(Long.parseLong(typeId));
                            details.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                            details.setCreateTime(DateUtils.getNowDate());
                            details.setPreNum(applyInfo.getBackNum());
                            details.setStatus("0");
                            details.setMaId(applyInfo.getMaId() != null ? applyInfo.getMaId() : null);
                            details.setIsFinished(1);
                            result += materialBackInfoMapper.insertCheckDetails(details);

                            // 查询材料站同步数据
                            clzList = backApplyInfoMapper.selectClzList(details);
                            BackApplyDetails backApplyDetails = new BackApplyDetails();
                            backApplyDetails.setParentId(backApplyInfo4.getId());
                            backApplyDetails.setTypeId(Long.parseLong(typeId));
                            backApplyDetails.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                            backApplyDetails.setCreateTime(DateUtils.getNowDate());
                            backApplyDetails.setPreNum(applyInfo.getBackNum());
                            backApplyDetails.setMaId(applyInfo.getMaId() != null ? applyInfo.getMaId() : null);
                            backApplyDetails.setStatus("0");
                            backApplyDetails.setIsFinished(1);
                            result += backApplyInfoMapper.insertCheckDetails(backApplyDetails);
                            // 查询项目部同步数据
                            //xmList = backApplyInfoMapper.selectXmList(backApplyDetails);
                        }
                        res = updateSlt4BeanClz(materialBackApplyInfo, clzList);
                        if (res == 0) { throw new RuntimeException("同步材料站结算出错");}
                            /*res = updateSlt4BeanXm(backApplyInfo4, xmList);
                            if (res == 0) {
                                throw new RuntimeException("同步项目部结算出错");
                            }*/
                    }
                    // 完成退料部分，更新 back_check_details
                    finishBackCheckDetails(backApplyInfo);
                }
            }
            // 如果所有操作都成功
            if (result > 0) {
                return AjaxResult.success();
            }
        }
        // 操作失败，返回错误
        return AjaxResult.error(HttpCodeEnum.FAIL.getCode(), HttpCodeEnum.FAIL.getMsg());
    }

    @Override
    public AjaxResult delHandlingOrder(HandlingOrder bean) {
        try {
            int res = backApplyInfoMapper.delHandlingOrder(bean);
            if (res > 0){
                return AjaxResult.success("删除成功");
            } else {
                return AjaxResult.error("删除失败");
            }

        } catch (Exception e) {
            log.error("系统错误, " + e.getMessage());
            return AjaxResult.error("删除失败");
        }
    }

    @Override
    public List<BackApplyInfo> selectNotSyncProject() {
        return backApplyInfoMapper.selectNotSyncProject();
    }

    @Override
    public int syncProject(BackApplyInfo backApplyInfo) {
        return backApplyInfoMapper.syncProject(backApplyInfo);
    }

    @Override
    public int syncProjectDetails(BackApplyInfo backApplyInfo) {
        BackApplyInfo backApplyInfo2 = new BackApplyInfo();
        backApplyInfo2.setId(backApplyInfo.getId());
        backApplyInfo2.setTypeName("领料单");
        backApplyInfoMapper.syncProjectDetails(backApplyInfo2);
        backApplyInfo2.setTypeName("退料单");
        backApplyInfoMapper.syncProjectDetails(backApplyInfo2);
        backApplyInfo2.setTypeName("业务联系单");
        backApplyInfoMapper.syncProjectDetails(backApplyInfo2);
        return 1;
    }

    /**
     * 处理班组退料结算协议
     * @param record
     * @param allList
     * @return
     */
    private int updateBzSlt4Bean(BackApplyInfo record, List<BackApplyInfo> allList) {
        for (BackApplyInfo bean : allList) {
            List<SltAgreementInfo> infoList = backApplyInfoMapper.getStlInfo(bean);
            if (CollectionUtils.isEmpty(infoList)) {
                // 退料单位的协议ID如果查不到，就通过别的协议查（例如班组的协议查不到，可能是项目部去领用的）
                if (!Objects.equals(record.getAgreementId(), bean.getAgreementId())) {
                    infoList = backApplyInfoMapper.getStlInfo(bean.setAgreementId(record.getAgreementId()));
                    if (CollectionUtils.isEmpty(infoList)) return 0;
                } else {
                    return 0;
                }
            }
            BigDecimal backNum = bean.getBackNum();
            // 遍历每个typeId
            for (SltAgreementInfo info : infoList) {
                // 获取前端要退数量
                BigDecimal num = info.getBackNum();
                if (backNum.compareTo(num) == 0) {
                    backApplyInfoMapper.updateStlInfo(info, record);
                    break;
                } else if (backNum.compareTo(num) > 0) {
                    backNum = backNum.subtract(num);
                    backApplyInfoMapper.updateStlInfo(info, record);
                } else {
                    BigDecimal many = num.subtract(backNum);
                    backApplyInfoMapper.updateStlInfoTwo(info, record, backNum);
                    backApplyInfoMapper.insStlInfoTwo(info, many);
                    break;
                }
            }

            // 查询是否存在班组数据
            List<SltAgreementInfo> tbList = backApplyInfoMapper.getTbList(bean);
            // 非班组退料才同步班组分公司数据
            BigDecimal tbBackNum = bean.getBackNum();
            if (CollectionUtils.isNotEmpty(tbList)) {
                for (SltAgreementInfo info : tbList) {
                    // 获取前端要退数量
                    BigDecimal num = info.getBackNum();
                    if (tbBackNum.compareTo(num) == 0) {
                        backApplyInfoMapper.updateStlInfo(info, record);
                        break;
                    } else if (tbBackNum.compareTo(num) > 0) {
                        tbBackNum = tbBackNum.subtract(num);
                        backApplyInfoMapper.updateStlInfo(info, record);
                    } else {
                        BigDecimal many = num.subtract(tbBackNum);
                        backApplyInfoMapper.updateStlInfoTwo(info, record, tbBackNum);
                        backApplyInfoMapper.insStlInfoTwo(info, many);
                        break;
                    }
                }
            }
        }
        return 1;
    }

    @Override
    public List<ExitPermit> getExitPermitList(ExitPermit bean) {
        try {
            return backApplyInfoMapper.getExitPermitList(bean);
        } catch (Exception e) {
            log.error("获取退料任务列表失败", e);
            return new ArrayList<>();
        }
    }

    @Override
    public AjaxResult addExitPermit(ExitPermit bean) {
        try {
            Long userId = SecurityUtils.getLoginUser().getUserid();
            bean.setCreateBy(userId.toString());
            int re = backApplyInfoMapper.addExitPermit(bean);
            if (re > 0) {
                return AjaxResult.success("添加成功");
            } else {
                return AjaxResult.error("添加失败");
            }
        } catch (Exception e) {
            log.error("添加出门证失败", e);
            return AjaxResult.error("添加出门证失败");
        }
    }


    /**
     * 关键字搜索
     *
     * @param item
     * @param keyWord
     * @return
     */
    private boolean containsBackKeyword(BackApplyVo item, String keyWord) {
        return (item.getTypeName() != null && item.getTypeName().contains(keyWord)) ||
                (item.getTypeModelName() != null && item.getTypeModelName().contains(keyWord)) ||
                (item.getBackPerson() != null && item.getBackPerson().contains(keyWord)) ||
                (item.getBackUnitName() != null && item.getBackUnitName().contains(keyWord)) ||
                (item.getBackProName() != null && item.getBackProName().contains(keyWord)) ||
                (item.getAgreementCode() != null && item.getAgreementCode().contains(keyWord)) ||
                (item.getBackCode() != null && item.getBackCode().contains(keyWord)) ||
                (item.getRepairCode() != null && item.getRepairCode().contains(keyWord)) ||
                (item.getMaCode() != null && item.getMaCode().contains(keyWord));
    }


    /**
     * 更新任务表及退料申请表状态
     * @param backApplyInfo
     * @return
     */
    private int updateTaskAndBackInfo(BackApplyInfo backApplyInfo) {
        int result = backApplyInfoMapper.updateTaskStatus(backApplyInfo);
        result += backApplyInfoMapper.updateBack(backApplyInfo);
        result += backApplyInfoMapper.updateBackDetails(backApplyInfo);
        return result;
    }

    /**
     * 更新结算表
     * @param record
     * @param allList
     * @return
     */
    private int updateSlt4Bean(BackApplyInfo record, List<BackApplyInfo> allList) {
        for (BackApplyInfo bean : allList) {
            List<SltAgreementInfo> infoList = backApplyInfoMapper.getStlInfo(bean);
            if (infoList.size() > 0) {
                BigDecimal backNum = bean.getBackNum();
                for (SltAgreementInfo info : infoList) {
                    BigDecimal num = info.getBackNum();
                    if (backNum.compareTo(num) == 0) {
                        backApplyInfoMapper.updateStlInfo(info, record);
                        break;
                    } else if (backNum.compareTo(num) > 0) {
                        backNum = backNum.subtract(num);
                        backApplyInfoMapper.updateStlInfo(info, record);
                    } else {
                        BigDecimal many = num.subtract(backNum);
                        backApplyInfoMapper.updateStlInfoTwo(info, record, backNum);
                        backApplyInfoMapper.insStlInfoTwo(info, many);
                        break;
                    }
                }
            } else {
                return 0;
            }
        }
        return 1;
    }

    /**
     * 完成退料申请
     * @param backApplyInfo
     */
    private void finishBackCheckDetails(BackApplyInfo backApplyInfo) {
        backApplyInfoMapper.updateCheckDetails(backApplyInfo);
    }

    /**
     * 插入维修记录表
     * @param taskId
     * @param wxList
     * @return
     */
    private int insertRad(Long taskId, List<BackApplyInfo> wxList) {
        int result = 0;
        if (wxList != null) {
            for (BackApplyInfo wx : wxList) {
                wx.setTaskId(taskId);
                wx.setStatus("0");
                wx.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
                result = backApplyInfoMapper.insertRad(wx);
            }
        }
        return result;
    }

    /**
     * 插入协议任务表
     * @param taskId
     * @param list
     * @return
     */
    private int insertTta(Long taskId, List<BackApplyInfo> list) {
        int res;
        String agreementId = String.valueOf(list.get(0).getAgreementId());
        TmTaskAgreement tmTaskAgreement = new TmTaskAgreement(taskId, Long.parseLong(agreementId));
        tmTaskAgreement.setCreateTime(DateUtils.getNowDate());
        tmTaskAgreement.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        res = taskAgreementMapper.insertTmTaskAgreement(tmTaskAgreement);
        return res;
    }

    /**
     * 插入协议任务表 -- 班组专用
     */
    private int insertTeamTta(Long taskId, Long agreementId) {
        int res;
        TmTaskAgreement tmTaskAgreement = new TmTaskAgreement(taskId, agreementId);
        tmTaskAgreement.setCreateTime(DateUtils.getNowDate());
        tmTaskAgreement.setCreateBy(SecurityUtils.getLoginUser().getSysUser().getNickName());
        res = taskAgreementMapper.insertTmTaskAgreement(tmTaskAgreement);
        return res;
    }

    /**
     * 插入任务表
     * @param createBy
     * @return
     */
    private Long insertTt(String createBy, String remark, Long preTaskId) {
        Long newTask = null;
        int thisMonthMaxOrder = taskMapper.getMonthMaxOrderByDate(DateUtils.getCurrentYear(), DateUtils.getCurrentMonth(), TmTaskTypeEnum.TM_TASK_REPAIR.getTaskTypeId());
        // 生成维修单号
        String code = genderWxTaskCode(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.setRemark(remark);
        tmTask.setPreTaskId(preTaskId);
        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 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_TASK_TYPE_LABEL + result + String.format("-%03d", thisMonthMaxOrder + 1);
    }

}
