package com.rongwei.bscommon.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rongwei.bscommon.sys.dao.*;
import com.rongwei.bscommon.sys.service.*;
import com.rongwei.bscommon.sys.utils.ApsUtils;
import com.rongwei.bsentity.domain.*;
import com.rongwei.bsentity.vo.CommonUpdateProductionStatusReq;
import com.rongwei.bsentity.vo.PreviousProcessVo;
import com.rongwei.bsentity.vo.ProcessIdRelationVo;
import com.rongwei.commonservice.service.SysMindMappingService;
import com.rongwei.rwadmincommon.system.domain.SysOrganizationDo;
import com.rongwei.rwadmincommon.system.service.SysOrganizationService;
import com.rongwei.rwadmincommon.system.vo.SysOrganizationVo;
import com.rongwei.rwadmincommon.system.vo.SysUserVo;
import com.rongwei.rwcommon.base.BaseDo;
import com.rongwei.rwcommon.base.R;
import com.rongwei.rwcommon.utils.SecurityUtil;
import com.rongwei.rwcommon.utils.StringUtils;
import com.rongwei.rwcommonentity.commonservers.domain.SysMindMappingDo;
import com.rongwei.safecommon.utils.CXCommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.rongwei.safecommon.utils.SaveConstans.LockmarkType.LOCKMARK_N;
import static com.rongwei.safecommon.utils.SaveConstans.LockmarkType.LOCKMARK_Y;
import static com.rongwei.safecommon.utils.SaveConstans.MINUS_ONE;

/**
 * <p>
 * 生产订单_坯料计划_工序作业 服务实现类
 * </p>
 *
 * @author fpy
 * @since 2024-03-01
 */
@Slf4j
@Service
public class ApsProcessOperationServiceImpl extends ServiceImpl<ApsProcessOperationDao, ApsProcessOperationDo> implements ApsProcessOperationService {
    @Autowired
    private ApsProcessOperationDao apsProcessOperationDao;

    @Autowired
    private ApsBlankOrderDao apsBlankOrderDao;

    @Autowired
    private ApsCraftRouteService apsCraftRouteService;

    @Autowired
    ApsCraftRouteStepService apsCraftRouteStepService;

    @Autowired
    ApsCraftRouteOutMaterRequestService apsCraftRouteOutMaterRequestService;

    @Autowired
    ApsCraftRouteStepEquService apsCraftRouteStepEquService;

    @Autowired
    ApsProcessOperationService apsProcessOperationService;

    @Autowired
    ApsProcessOperationOutMaterService apsProcessOperationOutMaterService;

    @Autowired
    ApsProcessOperationEquService apsProcessOperationEquService;

    @Autowired
    SysMindMappingService sysMindMappingService;

    @Autowired
    private ApsProcessOperationProcessEquService apsProcessOperationProcessEquService;
    @Autowired
    private ApsProductionOrderService apsProductionOrderService;
    @Autowired
    private ApsBlankOrderService apsBlankOrderService;
    @Autowired
    private AspCheckItemsService aspCheckItemsService;
    @Autowired
    private SysOrganizationService sysOrganizationService;

    @Autowired
    private ApsProcessOperationBackupDao apsProcessOperationBackupDao;
    @Autowired
    private ApsProcessOperationProcessEquDao apsProcessOperationProcessEquDao;
    @Autowired
    private ApsProcessOperationProcessEquBackupDao apsProcessOperationProcessEquBackupDao;
    @Autowired
    private ApsScheduleConfigService apsScheduleConfigService;
    @Resource
    private ApsProductionOrderDao apsProductionOrderDao;


    private final static Map<String, String> UNIT_MAP = new HashMap<String, String>() {{
        put("kg", "公斤");
        put("ton", "吨");
    }};

    DecimalFormat df = new DecimalFormat("0.####");


    /**
     * 更新工序的待加工批次号信息
     *
     * @param ids
     * @param batchNumn
     */
    public void updateBachmaterialprocessByIds(List<String> ids, String batchNumn, int unqualifiedQuantity) {
        apsProcessOperationDao.updateBachmaterialprocessByIds(ids, batchNumn, unqualifiedQuantity);
    }

    /**
     * 更新当前工序的输出已检验卷数，不合格卷数，合格卷数
     *
     * @param id
     * @param currentCheckNum
     * @param qualifiedQuantity
     * @param unqualifiedQuantity
     */
    public void updateAboutCheckBatchNum(String id, Integer currentCheckNum, Integer qualifiedQuantity, Integer unqualifiedQuantity) {
        apsProcessOperationDao.updateAboutCheckBatchNum(id, currentCheckNum, qualifiedQuantity, unqualifiedQuantity);
    }

    /**
     * 根据工序ID 获取当前工序之后的所有工序信息 包含当前工序
     */
    public List<ProcessIdRelationVo> getAllNextProcessOperationById(List<String> ids) {
        return apsProcessOperationDao.getAllNextProcessOperationById(ids);
    }

    /*
    数量单位字典
     */


    /*
    选择工艺路线后续操作
     */
    @Override
    @Transactional
    public R resetCraftRoute(Map<String, Object> params) {
        try {
            JSONObject blanckdata = new JSONObject(params.get("BLANKDATA"));
            String craftrouteid = params.get("CRAFTROUTEID").toString();

            // 获取排程参数设置
            List<ApsScheduleConfigDo> apsConfigs = apsScheduleConfigService.list();
            BigDecimal aluminumdensity = apsConfigs.get(0).getAluminumdensity();

            //先清空之前的相关数据
            Map<String, Object> blanckMap = new HashMap<>();
            blanckMap.put("BLANKID", blanckdata.getStr("ID"));
            clearCraftRoute(blanckMap);

            //工艺路线对应的步骤信息
            Map<String, Object> map = new HashMap<>();
            map.put("CRAFTROUTEID", craftrouteid);
            List<ApsCraftRouteStepDo> apsCraftRouteStepDoList = apsCraftRouteStepService.listByMap(map).stream().collect(Collectors.toList());
            Collections.sort(apsCraftRouteStepDoList, Comparator.comparingInt(ApsCraftRouteStepDo::getLevel));
            Collections.sort(apsCraftRouteStepDoList, Comparator.comparing(ApsCraftRouteStepDo::getCreatedate));

            //工艺路线对应的输出
            List<ApsCraftRouteOutMaterRequestDo> apsCraftRouteOutMaterRequestDoList = apsCraftRouteOutMaterRequestService.listByMap(map).stream().collect(Collectors.toList());

            //工艺路线对应的可选设备
            Map<String, Object> equmap = new HashMap<>();
            equmap.put("DELETED", "0");
            List<ApsCraftRouteStepEquDo> apsCraftRouteStepEquDoList = apsCraftRouteStepEquService.listByMap(equmap).stream().collect(Collectors.toList());

            //工艺路线对应的思维导图
            List<SysMindMappingDo> sysMindMappingDos = new ArrayList<>();
            Map<String, Object> mindMap = new HashMap<>();
            mindMap.put("BSID", craftrouteid);
            List<SysMindMappingDo> sysMindMappingDoList = sysMindMappingService.listByMap(mindMap).stream().collect(Collectors.toList());
            Collections.sort(sysMindMappingDoList, Comparator.comparing(SysMindMappingDo::getTreecode, Comparator.nullsFirst(Comparator.naturalOrder())));
            if (sysMindMappingDoList.size() == 0) {
                return R.error("工艺路线图不存在");
            }
            SysMindMappingDo sysMindMappingDo = BeanUtil.toBean(sysMindMappingDoList.get(0), SysMindMappingDo.class);
            String mindStrId = SecurityUtil.getUUID();
            sysMindMappingDo.setId(mindStrId);
            sysMindMappingDo.setBsid(blanckdata.getStr("ID"));
            sysMindMappingDo.setBstable("aps_process_operation");
            sysMindMappingDos.add(sysMindMappingDo);

            List<String> overRouteStepIds = new ArrayList<>();
            List<PreviousProcessVo> newProcessIds = new ArrayList<>();//前道工序信息
            List<ApsProcessOperationDo> apsProcessOperationDoList = new ArrayList<>();
            List<ApsProcessOperationOutMaterDo> apsProcessOperationOutMaterDoList = new ArrayList<>();
            List<ApsProcessOperationEquDo> apsProcessOperationEquDoList = new ArrayList<>();
            for (ApsCraftRouteStepDo apsCraftRouteStepDo : apsCraftRouteStepDoList) {
                if (overRouteStepIds.contains(apsCraftRouteStepDo.getId())) {
                    continue;
                } else {
                    String processId;
                    ApsProcessOperationDo apsProcessOperationDo;
                    PreviousProcessVo previousProcessVo;
                    if (StringUtils.isNotBlank(apsCraftRouteStepDo.getPreviousstepid())) {
                        //后面工序
                        List<ApsCraftRouteStepDo> apsCraftRouteStepDoList1 = apsCraftRouteStepDoList.stream().filter(acrs -> apsCraftRouteStepDo.getPreviousstepid().equals(acrs.getPreviousstepid())).collect(Collectors.toList());
                        Collections.sort(apsCraftRouteStepDoList1, Comparator.comparing(ApsCraftRouteStepDo::getCreatedate));
                        for (ApsCraftRouteStepDo apsCraftRouteStepDo1 : apsCraftRouteStepDoList1) {
                            previousProcessVo = new PreviousProcessVo();
                            processId = SecurityUtil.getUUID();
                            apsProcessOperationDo = BeanUtil.toBean(apsCraftRouteStepDo1, ApsProcessOperationDo.class);
                            apsProcessOperationDo.setId(processId);

                            //前道工序输出
                            List<PreviousProcessVo> processVo = newProcessIds.stream().filter(pro -> pro.getPreviousstepid().equals(apsCraftRouteStepDo1.getPreviousstepid())).collect(Collectors.toList());
                            ApsProcessOperationOutMaterDo outMaterDo = processVo.get(0).getApsProcessOperationOutMaterDo();

                            //更新前道工序的后道工序
                            ApsProcessOperationDo aDo = apsProcessOperationDoList.stream().filter(qtr -> processVo.get(0).getProcessId().equals(qtr.getId())).findAny().orElse(null);
                            if (StringUtils.isBlank(aDo.getNextprocessid())) {
                                aDo.setNextprocessid(processId);
                                aDo.setNextprocess(apsProcessOperationDo.getProcessname());
                            } else {
                                aDo.setNextprocessid(aDo.getNextprocessid() + "," + processId);
                                aDo.setNextprocess(aDo.getNextprocess() + "," + apsProcessOperationDo.getProcessname());
                            }

                            apsProcessOperationDo.setPreviousprocessid(processVo.get(0).getProcessId());
                            apsProcessOperationDo.setPreviousprocess(processVo.get(0).getProcessName());
                            apsProcessOperationDo.setPlaninputid(outMaterDo.getId());
                            String meterInput = getInMeterInfo(outMaterDo.getProducttype(), outMaterDo.getMetal(), outMaterDo.getMetalstate(), outMaterDo.getThickness(), outMaterDo.getProwidth(), outMaterDo.getProlength());
                            apsProcessOperationDo.setPlaninput(meterInput + outMaterDo.getSinglerollweight() + UNIT_MAP.getOrDefault(outMaterDo.getNumunit(), ""));
                            apsProcessOperationDo.setProducttypeid(outMaterDo.getProducttypeid());
                            apsProcessOperationDo.setProducttype(outMaterDo.getProducttype());
                            apsProcessOperationDo.setMetal(outMaterDo.getMetal());
                            apsProcessOperationDo.setMetalstate(outMaterDo.getMetalstate());
                            apsProcessOperationDo.setThickness(outMaterDo.getThickness());
                            apsProcessOperationDo.setProwidth(outMaterDo.getProwidth());
                            apsProcessOperationDo.setProlength(outMaterDo.getProlength());
                            apsProcessOperationDo.setSinglerollweight(outMaterDo.getSinglerollweight());
                            Integer planInRall = outMaterDo.getPlanrollnum() - outMaterDo.getPlanstockrollnum() - outMaterDo.getPlanprodrollnum();
                            apsProcessOperationDo.setPlaninrall(planInRall);
                            //输入物料ID对应前道工序作业输出物料只有一个后道工序作业），则不可编辑，自动计算=计划输入卷数
                            if (apsCraftRouteStepDoList1.size() == 1) {
                                apsProcessOperationDo.setPlanprocessrall(processVo.get(0).getPlanprocessrall());
                                if (!apsProcessOperationDo.getProcessway().equals("合并加工")) {
                                    BigDecimal loadingmin = apsProcessOperationDo.getLoadingmin() == null ? BigDecimal.valueOf(0) : apsProcessOperationDo.getLoadingmin();
                                    BigDecimal cuttingmin = apsProcessOperationDo.getCuttingmin() == null ? BigDecimal.valueOf(0) : apsProcessOperationDo.getCuttingmin();
                                    if (apsProcessOperationDo.getTimeway().equals("10")) {
                                        //如果计时方式=按设备运转速度计时，计划作业时长=计划加工卷数*(上料时长+下料时长+(输入单卷重/（输入物料宽度/1000*输入物料厚度/1000*设备运转速度/1000*铝的密度）))
                                        BigDecimal prowidth = apsProcessOperationDo.getProwidth() == null ? BigDecimal.valueOf(1) : apsProcessOperationDo.getProwidth();
                                        BigDecimal thickness = apsProcessOperationDo.getThickness() == null ? BigDecimal.valueOf(1) : apsProcessOperationDo.getThickness();
                                        BigDecimal workspeed = apsProcessOperationDo.getWorkspeed() == null ? BigDecimal.valueOf(1) : apsProcessOperationDo.getWorkspeed();
                                        BigDecimal onceprocessmin = new BigDecimal(df.format(loadingmin.add(cuttingmin).add(apsProcessOperationDo.getSinglerollweight().multiply(BigDecimal.valueOf(1000000000)).divide(prowidth.multiply(thickness).multiply(workspeed).multiply(aluminumdensity), 2, BigDecimal.ROUND_HALF_UP))));
                                        apsProcessOperationDo.setOnceprocessmin(onceprocessmin);
                                        apsProcessOperationDo.setProcesstotaltime(new BigDecimal(df.format(BigDecimal.valueOf(apsProcessOperationDo.getPlanprocessrall()).multiply(onceprocessmin))));
                                    } else if (apsProcessOperationDo.getTimeway().equals("40")) {
                                        //如果计时方式=按单次加工时长计时，计划作业时长=(上料时长+下料时长+单次加工时长)*计划加工卷数
                                        apsProcessOperationDo.setProcesstotaltime(new BigDecimal(df.format(loadingmin.add(cuttingmin).add(apsProcessOperationDo.getOnceprocessmin()).multiply(BigDecimal.valueOf(apsProcessOperationDo.getPlanprocessrall())))));
                                    }
                                }
                            } else {
                                apsProcessOperationDo.setPlanprocessrall(0);
                            }
                            apsProcessOperationDo.setUnfinishroll(planInRall);
                            apsProcessOperationDo.setBlankid(blanckdata.getStr("ID"));
                            apsProcessOperationDo.setCraftstepid(apsCraftRouteStepDo1.getId());
                            if (outMaterDo.getThickrule().equals("自定义") || outMaterDo.getWidthrule().equals("自定义") || outMaterDo.getLengthrule().equals("自定义")) {
                                apsProcessOperationDo.setChangeinmeter("1");//输入物料可编辑
                            }

                            //本道工序信息
                            previousProcessVo.setProcessId(processId);
                            previousProcessVo.setProcessName(apsProcessOperationDo.getProcessname());
                            previousProcessVo.setPreviousstepid(apsCraftRouteStepDo1.getId());
                            previousProcessVo.setPlanprocessrall(apsProcessOperationDo.getPlanprocessrall());

                            //本道工序的输出
                            List<ApsCraftRouteOutMaterRequestDo> apsCraftRouteOutMaterRequestDo = apsCraftRouteOutMaterRequestDoList.stream().filter(omd -> apsCraftRouteStepDo1.getId().equals(omd.getCraftstepid())).collect(Collectors.toList());
                            if (apsCraftRouteOutMaterRequestDo.size() == 0) {
                                return R.error("工艺步骤" + apsCraftRouteStepDo1.getProcessname() + "没输出");
                            }
                            ApsProcessOperationOutMaterDo apsProcessOperationOutMaterDo = BeanUtil.toBean(apsCraftRouteOutMaterRequestDo.get(0), ApsProcessOperationOutMaterDo.class);
                            apsProcessOperationOutMaterDo.setId(SecurityUtil.getUUID());
                            String outProducttype = apsProcessOperationOutMaterDo.getProducttype();
                            if (apsProcessOperationOutMaterDo.getProducttyperule().equals("不变")) {
                                outProducttype = outMaterDo.getProducttype() == null ? "" : outMaterDo.getProducttype();
                                apsProcessOperationOutMaterDo.setProducttypeid(outMaterDo.getProducttypeid() == null ? "" : outMaterDo.getProducttypeid());
                                apsProcessOperationOutMaterDo.setProducttype(outProducttype);
                            }
                            String outMeter = apsProcessOperationOutMaterDo.getMetal();
                            if (apsProcessOperationOutMaterDo.getMetalrule().equals("不变")) {
                                outMeter = outMaterDo.getMetal() == null ? "" : outMaterDo.getMetal();
                                apsProcessOperationOutMaterDo.setMetal(outMeter);
                            }
                            String outMetalstate = apsProcessOperationOutMaterDo.getMetalstate();
                            if (apsProcessOperationOutMaterDo.getMetalstaterule().equals("不变")) {
                                outMetalstate = outMaterDo.getMetalstate() == null ? "" : outMaterDo.getMetalstate();
                                apsProcessOperationOutMaterDo.setMetalstate(outMetalstate);
                            }
                            BigDecimal tval = changeSize(outMaterDo.getThickness(), apsProcessOperationOutMaterDo.getThickrule(), apsProcessOperationOutMaterDo.getThickchange(), apsProcessOperationOutMaterDo.getThickness());
                            apsProcessOperationOutMaterDo.setThickness(tval);
                            BigDecimal wval = changeSize(outMaterDo.getProwidth(), apsProcessOperationOutMaterDo.getWidthrule(), apsProcessOperationOutMaterDo.getWidthchange(), apsProcessOperationOutMaterDo.getProwidth());
                            apsProcessOperationOutMaterDo.setProwidth(wval);
                            BigDecimal lval = changeSize(outMaterDo.getProlength(), apsProcessOperationOutMaterDo.getLengthrule(), apsProcessOperationOutMaterDo.getLengthchange(), apsProcessOperationOutMaterDo.getProlength());
                            apsProcessOperationOutMaterDo.setProlength(lval);
//                            apsProcessOperationOutMaterDo.setRipcutnum(1);
//                            apsProcessOperationOutMaterDo.setCrosscutnum(1);
                            apsProcessOperationOutMaterDo.setOutval(1);
                            apsProcessOperationOutMaterDo.setPlanrollnum(apsProcessOperationDo.getPlanprocessrall());
                            //输入单卷重*输出宽度/输入宽度
                            String singlerollweight = df.format(outMaterDo.getSinglerollweight().multiply(wval == null ? BigDecimal.valueOf(1) : wval).divide(outMaterDo.getProwidth() == null ? BigDecimal.valueOf(1) : outMaterDo.getProwidth(), 3, BigDecimal.ROUND_HALF_UP));
                            apsProcessOperationOutMaterDo.setSinglerollweight(new BigDecimal(singlerollweight));
                            apsProcessOperationOutMaterDo.setNumunit(blanckdata.getStr("NUMBERUNIT"));
                            apsProcessOperationOutMaterDo.setPlanstockrollnum(0);
                            //没有后道工序作业，计划成品卷数=计划输出卷数-计划备料卷数
                            if (StringUtils.isBlank(apsCraftRouteStepDo.getNextstepid())) {
                                apsProcessOperationOutMaterDo.setPlanprodrollnum(apsProcessOperationDo.getPlanprocessrall());
                            } else {
                                apsProcessOperationOutMaterDo.setPlanprodrollnum(0);
                            }
                            apsProcessOperationOutMaterDo.setMainid(processId);
                            apsProcessOperationOutMaterDo.setBlankid(blanckdata.getStr("ID"));
                            //输出物料
                            String outputMeter = getOutMeterInfo(outProducttype, outMeter, outMetalstate, tval, wval, lval, apsProcessOperationOutMaterDo.getThickoffset(), apsProcessOperationOutMaterDo.getWidthoffset(), apsProcessOperationOutMaterDo.getLengthoffset()) + singlerollweight + UNIT_MAP.getOrDefault(blanckdata.getStr("NUMBERUNIT"), "");
                            apsProcessOperationOutMaterDo.setOutputmaterial(outputMeter + "*" + blanckdata.getInt("ROLLNUM") + "卷");
                            apsProcessOperationDo.setPlanoutput("[1]" + outputMeter + "*" + blanckdata.getInt("ROLLNUM") + "卷");
                            //输出成品
                            /*
                            如果没有后道工序作业，则成品卷数=计划输出卷数 - 计划备料卷数，
                            如果有后道工序作业，则成品卷数=计划成品卷数，
                            如果成品卷数=0，则自动填入=（空）
                            如果成品卷>0，则自动填入=“{输出物料的输入物料描述} * {成品卷数}卷”
                             */
                            String outputfinishproduct = "";
                            if (StringUtils.isBlank(apsCraftRouteStepDo1.getNextstepid())) {
                                //如果没有后道工序作业，则自动填入=“{输出物料的输入物料描述} * {计划输出卷数 - 计划备料卷数}卷”
                                outputfinishproduct = getInMeterInfo(outProducttype, outMeter, outMetalstate, tval, wval, lval) + apsProcessOperationOutMaterDo.getSinglerollweight() + UNIT_MAP.getOrDefault(apsProcessOperationOutMaterDo.getNumunit(), "") + " * " + blanckdata.getInt("ROLLNUM") + "卷";
                            }
                            if (apsProcessOperationOutMaterDo.getPlanprodrollnum() > 0) {
                                apsProcessOperationOutMaterDo.setOutputfinishproduct(outputfinishproduct);
                            }
                            apsProcessOperationOutMaterDo.setOutmaterrequest(outputMeter);
                            previousProcessVo.setApsProcessOperationOutMaterDo(apsProcessOperationOutMaterDo);


                            //本道工序的可选设备
                            List<ApsCraftRouteStepEquDo> apsCraftRouteStepEquDos = apsCraftRouteStepEquDoList.stream().filter(crse -> apsCraftRouteStepDo1.getId().equals(crse.getCraftstepid())).collect(Collectors.toList());
                            List<String> equIdList = new ArrayList<>();//设备
                            List<String> equGroupIdList = new ArrayList<>();//资源组
                            for (ApsCraftRouteStepEquDo apsCraftRouteStepEquDo : apsCraftRouteStepEquDos) {
                                ApsProcessOperationEquDo apsProcessOperationEquDo;
                                apsProcessOperationEquDo = BeanUtil.toBean(apsCraftRouteStepEquDo, ApsProcessOperationEquDo.class);
                                apsProcessOperationEquDo.setId(SecurityUtil.getUUID());
                                apsProcessOperationEquDo.setBlankid(blanckdata.getStr("ID"));
                                apsProcessOperationEquDo.setMainid(processId);
                                if (apsProcessOperationEquDo.getResourcetype().equals("资源组")) {
                                    if (!equGroupIdList.contains(apsProcessOperationEquDo.getResourceid())) {
                                        equGroupIdList.add(apsProcessOperationEquDo.getResourceid());
                                    }
                                } else {
                                    if (!equIdList.contains(apsProcessOperationEquDo.getResourceid())) {
                                        equIdList.add(apsProcessOperationEquDo.getResourceid());
                                    }
                                }

                                apsProcessOperationEquDoList.add(apsProcessOperationEquDo);
                            }
                            //可选设备IDS
                            if (equIdList.size() > 0 || equGroupIdList.size() > 0) {
                                apsProcessOperationDo.setCanchoosedeviceid(getChooseequids(equIdList, equGroupIdList));
                            }

                            //本道工序思维导图
                            List<SysMindMappingDo> sysMindMappingDoList1 = sysMindMappingDoList.stream().filter(mind -> mind.getId().equals(apsCraftRouteStepDo1.getId())).collect(Collectors.toList());
                            SysMindMappingDo sysMindMappingDo1 = sysMindMappingDoList1.get(0);
                            sysMindMappingDo1.setId(processId);
                            sysMindMappingDo1.setParentid(processVo.get(0).getProcessId());
                            sysMindMappingDo1.setBsid(blanckdata.getStr("ID"));
                            sysMindMappingDo1.setBstable("aps_process_operation");
                            JSONObject jsonObject = new JSONObject();
                            jsonObject.putOpt("craftStepId", apsCraftRouteStepDo1.getId());
                            sysMindMappingDo1.setRoption(jsonObject.toString());//存工艺路线的工艺步骤ID
                            sysMindMappingDos.add(sysMindMappingDo1);

                            newProcessIds.add(previousProcessVo);
                            apsProcessOperationDoList.add(apsProcessOperationDo);
                            apsProcessOperationOutMaterDoList.add(apsProcessOperationOutMaterDo);

                            overRouteStepIds.add(apsCraftRouteStepDo1.getId());
                        }
                    } else {
                        previousProcessVo = new PreviousProcessVo();
                        //首道工序
                        processId = SecurityUtil.getUUID();
                        String meterInput = getInMeterInfo(blanckdata.getStr("PRODUCTTYPE"), blanckdata.getStr("ALLOY"), blanckdata.getStr("ALLOYSTATUS"), blanckdata.getBigDecimal("THICKNESS"), blanckdata.getBigDecimal("PROWIDTH"), blanckdata.getBigDecimal("PROLENGTH"));
                        apsProcessOperationDo = BeanUtil.toBean(apsCraftRouteStepDo, ApsProcessOperationDo.class);
                        apsProcessOperationDo.setId(processId);
                        apsProcessOperationDo.setPlaninput(meterInput + blanckdata.getStr("SINGLEROLLWEIGHT") + UNIT_MAP.getOrDefault(blanckdata.getStr("NUMBERUNIT"), ""));
                        apsProcessOperationDo.setProducttypeid(blanckdata.getStr("PRODUCTTYPEID"));
                        apsProcessOperationDo.setProducttype(blanckdata.getStr("PRODUCTTYPE"));
                        apsProcessOperationDo.setMetal(blanckdata.getStr("ALLOY"));
                        apsProcessOperationDo.setMetalstate(blanckdata.getStr("ALLOYSTATUS"));
                        apsProcessOperationDo.setThickness(blanckdata.getBigDecimal("THICKNESS"));
                        apsProcessOperationDo.setProwidth(blanckdata.getBigDecimal("PROWIDTH"));
                        apsProcessOperationDo.setProlength(blanckdata.getBigDecimal("PROLENGTH"));
                        apsProcessOperationDo.setSinglerollweight(blanckdata.getBigDecimal("SINGLEROLLWEIGHT"));
                        apsProcessOperationDo.setPlaninrall(blanckdata.getInt("ROLLNUM"));
                        apsProcessOperationDo.setPlanprocessrall(blanckdata.getInt("ROLLNUM"));
                        apsProcessOperationDo.setUnfinishroll(blanckdata.getInt("ROLLNUM"));
                        apsProcessOperationDo.setBlankid(blanckdata.getStr("ID"));
                        apsProcessOperationDo.setCraftstepid(apsCraftRouteStepDo.getId());

                        if (!apsProcessOperationDo.getProcessway().equals("合并加工")) {
                            BigDecimal loadingmin = apsProcessOperationDo.getLoadingmin() == null ? BigDecimal.valueOf(0) : apsProcessOperationDo.getLoadingmin();
                            BigDecimal cuttingmin = apsProcessOperationDo.getCuttingmin() == null ? BigDecimal.valueOf(0) : apsProcessOperationDo.getCuttingmin();
                            if (apsProcessOperationDo.getTimeway().equals("10")) {
                                //如果计时方式=按设备运转速度计时，计划作业时长=计划加工卷数*(上料时长+下料时长+(输入单卷重/（输入物料宽度/1000*输入物料厚度/1000*设备运转速度/1000*铝的密度）))
                                BigDecimal prowidth = apsProcessOperationDo.getProwidth() == null ? BigDecimal.valueOf(1) : apsProcessOperationDo.getProwidth();
                                BigDecimal thickness = apsProcessOperationDo.getThickness() == null ? BigDecimal.valueOf(1) : apsProcessOperationDo.getThickness();
                                BigDecimal workspeed = apsProcessOperationDo.getWorkspeed() == null ? BigDecimal.valueOf(1) : apsProcessOperationDo.getWorkspeed();
                                BigDecimal onceprocessmin = new BigDecimal(df.format(loadingmin.add(cuttingmin).add(apsProcessOperationDo.getSinglerollweight().multiply(BigDecimal.valueOf(1000000000)).divide(prowidth.multiply(thickness).multiply(workspeed).multiply(aluminumdensity), 2, BigDecimal.ROUND_HALF_UP))));
                                apsProcessOperationDo.setOnceprocessmin(onceprocessmin);
                                apsProcessOperationDo.setProcesstotaltime(new BigDecimal(df.format(BigDecimal.valueOf(apsProcessOperationDo.getPlanprocessrall()).multiply(onceprocessmin))));
                            } else if (apsProcessOperationDo.getTimeway().equals("40")) {
                                //如果计时方式=按单次加工时长计时，计划作业时长=(上料时长+下料时长+单次加工时长)*计划加工卷数
                                apsProcessOperationDo.setProcesstotaltime(new BigDecimal(df.format(loadingmin.add(cuttingmin).add(apsProcessOperationDo.getOnceprocessmin()).multiply(BigDecimal.valueOf(apsProcessOperationDo.getPlanprocessrall())))));
                            }
                        }

                        //本道工序信息
                        previousProcessVo.setProcessId(processId);
                        previousProcessVo.setProcessName(apsProcessOperationDo.getProcessname());
                        previousProcessVo.setPreviousstepid(apsCraftRouteStepDo.getId());
                        previousProcessVo.setPlanprocessrall(blanckdata.getInt("ROLLNUM"));

                        //本道工序的输出
                        List<ApsCraftRouteOutMaterRequestDo> apsCraftRouteOutMaterRequestDo = apsCraftRouteOutMaterRequestDoList.stream().filter(omd -> apsCraftRouteStepDo.getId().equals(omd.getCraftstepid())).collect(Collectors.toList());
                        if (apsCraftRouteOutMaterRequestDo.size() == 0) {
                            return R.error("工艺步骤" + apsCraftRouteStepDo.getProcessname() + "没输出");
                        }
                        ApsProcessOperationOutMaterDo apsProcessOperationOutMaterDo = BeanUtil.toBean(apsCraftRouteOutMaterRequestDo.get(0), ApsProcessOperationOutMaterDo.class);
                        apsProcessOperationOutMaterDo.setId(SecurityUtil.getUUID());
                        String outProducttype = apsProcessOperationOutMaterDo.getProducttype();
                        if (apsProcessOperationOutMaterDo.getProducttyperule().equals("不变")) {
                            outProducttype = blanckdata.getStr("PRODUCTTYPE") == null ? "" : blanckdata.getStr("PRODUCTTYPE");
                            apsProcessOperationOutMaterDo.setProducttypeid(blanckdata.getStr("PRODUCTTYPEID") == null ? "" : blanckdata.getStr("PRODUCTTYPEID"));
                            apsProcessOperationOutMaterDo.setProducttype(outProducttype);
                        }
                        String outMeter = apsProcessOperationOutMaterDo.getMetal();
                        if (apsProcessOperationOutMaterDo.getMetalrule().equals("不变")) {
                            outMeter = blanckdata.getStr("ALLOY") == null ? "" : blanckdata.getStr("ALLOY");
                            apsProcessOperationOutMaterDo.setMetal(outMeter);
                        }
                        String outMetalstate = apsProcessOperationOutMaterDo.getMetalstate();
                        if (apsProcessOperationOutMaterDo.getMetalstaterule().equals("不变")) {
                            outMetalstate = blanckdata.getStr("ALLOYSTATUS") == null ? "" : blanckdata.getStr("ALLOYSTATUS");
                            apsProcessOperationOutMaterDo.setMetalstate(outMetalstate);
                        }
                        BigDecimal tval = changeSize(blanckdata.getBigDecimal("THICKNESS"), apsProcessOperationOutMaterDo.getThickrule(), apsProcessOperationOutMaterDo.getThickchange(), apsProcessOperationOutMaterDo.getThickness());
                        apsProcessOperationOutMaterDo.setThickness(tval);
                        BigDecimal wval = changeSize(blanckdata.getBigDecimal("PROWIDTH"), apsProcessOperationOutMaterDo.getWidthrule(), apsProcessOperationOutMaterDo.getWidthchange(), apsProcessOperationOutMaterDo.getProwidth());
                        apsProcessOperationOutMaterDo.setProwidth(wval);
                        BigDecimal lval = changeSize(blanckdata.getBigDecimal("PROLENGTH"), apsProcessOperationOutMaterDo.getLengthrule(), apsProcessOperationOutMaterDo.getLengthchange(), apsProcessOperationOutMaterDo.getProlength());
                        apsProcessOperationOutMaterDo.setProlength(lval);
//                        apsProcessOperationOutMaterDo.setRipcutnum(1);
//                        apsProcessOperationOutMaterDo.setCrosscutnum(1);
                        apsProcessOperationOutMaterDo.setOutval(1);
                        apsProcessOperationOutMaterDo.setPlanrollnum(blanckdata.getInt("ROLLNUM"));
                        //输入单卷重*输出宽度/输入宽度
                        String singlerollweight = df.format(blanckdata.getBigDecimal("SINGLEROLLWEIGHT").multiply(wval == null ? BigDecimal.valueOf(1) : wval).divide(blanckdata.getBigDecimal("PROWIDTH") == null ? BigDecimal.valueOf(1) : blanckdata.getBigDecimal("PROWIDTH"), 3, BigDecimal.ROUND_HALF_UP));
                        apsProcessOperationOutMaterDo.setSinglerollweight(new BigDecimal(singlerollweight));
                        apsProcessOperationOutMaterDo.setNumunit(blanckdata.getStr("NUMBERUNIT"));
                        apsProcessOperationOutMaterDo.setPlanstockrollnum(0);
                        apsProcessOperationOutMaterDo.setMainid(processId);
                        apsProcessOperationOutMaterDo.setBlankid(blanckdata.getStr("ID"));
                        //输出物料
                        String outputMeter = getOutMeterInfo(outProducttype, outMeter, outMetalstate, tval, wval, lval, apsProcessOperationOutMaterDo.getThickoffset(), apsProcessOperationOutMaterDo.getWidthoffset(), apsProcessOperationOutMaterDo.getLengthoffset()) + singlerollweight + UNIT_MAP.getOrDefault(blanckdata.getStr("NUMBERUNIT"), "");
                        apsProcessOperationOutMaterDo.setOutputmaterial(outputMeter + "*" + blanckdata.getInt("ROLLNUM") + "卷");
                        apsProcessOperationDo.setPlanoutput("[1]" + outputMeter + "*" + blanckdata.getInt("ROLLNUM") + "卷");
                        //输出成品
                        /*
                        如果没有后道工序作业，则成品卷数=计划输出卷数 - 计划备料卷数，
                        如果有后道工序作业，则成品卷数=计划成品卷数，
                        如果成品卷数=0，则自动填入=（空）
                        如果成品卷>0，则自动填入=“{输出物料的输入物料描述} * {成品卷数}卷”
                         */
                        String outputfinishproduct = "";
                        if (StringUtils.isBlank(apsCraftRouteStepDo.getNextstepid())) {
                            //如果没有后道工序作业，则自动填入=“{输出物料的输入物料描述} * {计划输出卷数 - 计划备料卷数}卷”
                            outputfinishproduct = getInMeterInfo(outProducttype, outMeter, outMetalstate, tval, wval, lval) + apsProcessOperationOutMaterDo.getSinglerollweight() + UNIT_MAP.getOrDefault(apsProcessOperationOutMaterDo.getNumunit(), "") + " * " + blanckdata.getInt("ROLLNUM") + "卷";
                            apsProcessOperationOutMaterDo.setPlanprodrollnum(blanckdata.getInt("ROLLNUM"));
                        } else {
                            apsProcessOperationOutMaterDo.setPlanprodrollnum(0);
                        }
                        if (apsProcessOperationOutMaterDo.getPlanprodrollnum() > 0) {
                            apsProcessOperationOutMaterDo.setOutputfinishproduct(outputfinishproduct);
                        }
                        apsProcessOperationOutMaterDo.setOutmaterrequest(outputMeter);

                        previousProcessVo.setApsProcessOperationOutMaterDo(apsProcessOperationOutMaterDo);

                        //本道工序的可选设备
                        List<ApsCraftRouteStepEquDo> apsCraftRouteStepEquDos = apsCraftRouteStepEquDoList.stream().filter(crse -> apsCraftRouteStepDo.getId().equals(crse.getCraftstepid())).collect(Collectors.toList());
                        List<String> equIdList = new ArrayList<>();//设备
                        List<String> equGroupIdList = new ArrayList<>();//资源组
                        for (ApsCraftRouteStepEquDo apsCraftRouteStepEquDo : apsCraftRouteStepEquDos) {
                            ApsProcessOperationEquDo apsProcessOperationEquDo;
                            apsProcessOperationEquDo = BeanUtil.toBean(apsCraftRouteStepEquDo, ApsProcessOperationEquDo.class);
                            apsProcessOperationEquDo.setId(SecurityUtil.getUUID());
                            apsProcessOperationEquDo.setBlankid(blanckdata.getStr("ID"));
                            apsProcessOperationEquDo.setMainid(processId);
                            if (apsProcessOperationEquDo.getResourcetype().equals("资源组")) {
                                if (!equGroupIdList.contains(apsProcessOperationEquDo.getResourceid())) {
                                    equGroupIdList.add(apsProcessOperationEquDo.getResourceid());
                                }
                            } else {
                                if (!equIdList.contains(apsProcessOperationEquDo.getResourceid())) {
                                    equIdList.add(apsProcessOperationEquDo.getResourceid());
                                }
                            }

                            apsProcessOperationEquDoList.add(apsProcessOperationEquDo);
                        }
                        //可选设备IDS
                        if (equIdList.size() > 0 || equGroupIdList.size() > 0) {
                            apsProcessOperationDo.setCanchoosedeviceid(getChooseequids(equIdList, equGroupIdList));
                        }

                        //本道工序思维导图
                        List<SysMindMappingDo> sysMindMappingDoList1 = sysMindMappingDoList.stream().filter(mind -> mind.getId().equals(apsCraftRouteStepDo.getId())).collect(Collectors.toList());
                        SysMindMappingDo sysMindMappingDo1 = sysMindMappingDoList1.get(0);
                        sysMindMappingDo1.setId(processId);
                        sysMindMappingDo1.setParentid(mindStrId);
                        sysMindMappingDo1.setBsid(blanckdata.getStr("ID"));
                        sysMindMappingDo1.setBstable("aps_process_operation");
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.putOpt("craftStepId", apsCraftRouteStepDo.getId());
                        sysMindMappingDo1.setRoption(jsonObject.toString());//存工艺路线的工艺步骤ID
                        sysMindMappingDos.add(sysMindMappingDo1);

                        newProcessIds.add(previousProcessVo);
                        apsProcessOperationDoList.add(apsProcessOperationDo);
                        apsProcessOperationOutMaterDoList.add(apsProcessOperationOutMaterDo);
                    }
                }
            }

            boolean bool1 = apsProcessOperationService.saveOrUpdateBatch(apsProcessOperationDoList);
            boolean bool2 = apsProcessOperationOutMaterService.saveOrUpdateBatch(apsProcessOperationOutMaterDoList);
            boolean bool3 = true;
            if (apsProcessOperationEquDoList.size() > 0) {
                bool3 = apsProcessOperationEquService.saveOrUpdateBatch(apsProcessOperationEquDoList);
            }
            boolean bool4 = sysMindMappingService.saveOrUpdateBatch(sysMindMappingDos);

            if (bool1 && bool2 && bool3 && bool4) {
                //更新坯料计划的所选工艺路线相关信息
                ApsCraftRouteDo apsCraftRouteDo = apsCraftRouteService.getById(craftrouteid);
                apsBlankOrderService.update(new LambdaUpdateWrapper<ApsBlankOrderDo>()
                        .eq(ApsBlankOrderDo::getId, blanckdata.getStr("ID"))
                        .set(ApsBlankOrderDo::getCraftrouteid, craftrouteid)
                        .set(ApsBlankOrderDo::getRouteproducttypeid, apsCraftRouteDo.getProducttype())
                        .set(ApsBlankOrderDo::getRoutemetal, apsCraftRouteDo.getMetal())
                        .set(ApsBlankOrderDo::getRoutemetalstate, apsCraftRouteDo.getMetalstate())
                        .set(ApsBlankOrderDo::getRoutethinckstr, apsCraftRouteDo.getThickstr())
                        .set(ApsBlankOrderDo::getRoutethickend, apsCraftRouteDo.getThickend())
                        .set(ApsBlankOrderDo::getRoutewodthstr, apsCraftRouteDo.getWidthstr())
                        .set(ApsBlankOrderDo::getRoutewidthend, apsCraftRouteDo.getWidthend())
                        .set(ApsBlankOrderDo::getRoutelengthstr, apsCraftRouteDo.getLengthstr())
                        .set(ApsBlankOrderDo::getRoutelengthend, apsCraftRouteDo.getLengthend())
                );
                R r = new R();
                r.setCode("200");
                r.setData(apsCraftRouteDo);
                return r;
            } else {
                return R.error();
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("选择工艺路线异常:" + e.getMessage());
            return R.error();
        }
    }

    /*
    选择历史工艺路线后续操作
     */
    @Override
    @Transactional
    public R chooseHistoryRoute(Map<String, Object> params) {
        JSONObject blanckdata = new JSONObject(params.get("BLANKDATA"));
        String newblankid = params.get("NEWBLANKID").toString();
        String craftrouteid = params.get("CRAFTROUTEID").toString();

        // 获取排程参数设置
        List<ApsScheduleConfigDo> apsConfigs = apsScheduleConfigService.list();
        BigDecimal aluminumdensity = apsConfigs.get(0).getAluminumdensity();

        //先清空之前的相关数据
        Map<String, Object> blanckMap = new HashMap<>();
        blanckMap.put("BLANKID", blanckdata.getStr("ID"));
        clearCraftRoute(blanckMap);

        //选择新的坯料计划的工序作业、可选设备、输出、思维导图
        Map<String, Object> map = new HashMap<>();
        map.put("BLANKID", newblankid);
        List<ApsProcessOperationDo> apsProcessOperationDos = apsProcessOperationService.listByMap(map).stream().collect(Collectors.toList());
        Collections.sort(apsProcessOperationDos, Comparator.comparingInt(ApsProcessOperationDo::getLevel));
        Collections.sort(apsProcessOperationDos, Comparator.comparing(ApsProcessOperationDo::getCreatedate));
        List<ApsProcessOperationOutMaterDo> apsProcessOperationOutMaterDos = apsProcessOperationOutMaterService.listByMap(map).stream().collect(Collectors.toList());
        List<ApsProcessOperationEquDo> apsProcessOperationEquDos = apsProcessOperationEquService.listByMap(map).stream().collect(Collectors.toList());

        //要新建的实体集合
        List<String> overProcessIds = new ArrayList<>();
        List<PreviousProcessVo> newProcessIds = new ArrayList<>();//前道工序信息
        List<ApsProcessOperationDo> apsProcessOperationDoList = new ArrayList<>();
        List<ApsProcessOperationOutMaterDo> apsProcessOperationOutMaterDoList = new ArrayList<>();
        List<ApsProcessOperationEquDo> apsProcessOperationEquDoList = new ArrayList<>();
        List<SysMindMappingDo> sysMindMappingDoList = new ArrayList<>();

        Map<String, Object> mindMap = new HashMap<>();
        mindMap.put("BSID", newblankid);
        List<SysMindMappingDo> sysMindMappingDos = sysMindMappingService.listByMap(mindMap).stream().collect(Collectors.toList());
        Collections.sort(sysMindMappingDos, Comparator.comparing(SysMindMappingDo::getTreecode, Comparator.nullsFirst(Comparator.naturalOrder())));
        if (sysMindMappingDos.size() == 0) {
            return R.error("工艺路线思维导图不存在");
        }
        SysMindMappingDo sysMindMappingDo = BeanUtil.toBean(sysMindMappingDos.get(0), SysMindMappingDo.class);
        String mindStrId = SecurityUtil.getUUID();
        sysMindMappingDo.setId(mindStrId);
        sysMindMappingDo.setBsid(blanckdata.getStr("ID"));
        sysMindMappingDo.setBstable("aps_process_operation");
        sysMindMappingDoList.add(sysMindMappingDo);

        for (ApsProcessOperationDo apsProcessOperationDo : apsProcessOperationDos) {
            if (overProcessIds.contains(apsProcessOperationDo.getId())) {
                continue;
            } else {
                String processId;
                ApsProcessOperationDo processOperationDo;
                PreviousProcessVo previousProcessVo;
                if (StringUtils.isNotBlank(apsProcessOperationDo.getPreviousprocessid())) {
                    //后面工序
                    List<ApsProcessOperationDo> apsProcessOperationDos1 = apsProcessOperationDos.stream().filter(acrs -> apsProcessOperationDo.getPreviousprocessid().equals(acrs.getPreviousprocessid())).collect(Collectors.toList());
                    Collections.sort(apsProcessOperationDos1, Comparator.comparing(ApsProcessOperationDo::getCreatedate));
                    for (ApsProcessOperationDo apsProcessOperationDo1 : apsProcessOperationDos1) {
                        previousProcessVo = new PreviousProcessVo();
                        processId = SecurityUtil.getUUID();
                        processOperationDo = BeanUtil.toBean(apsProcessOperationDo1, ApsProcessOperationDo.class);
                        processOperationDo.setId(processId);
                        processOperationDo.setBlankid(blanckdata.getStr("ID"));
                        processOperationDo.setNextprocessid(null);

                        //前道工序输出
                        List<PreviousProcessVo> processVo = newProcessIds.stream().filter(pro -> pro.getPreviousstepid().equals(apsProcessOperationDo1.getPreviousprocessid())).collect(Collectors.toList());
                        List<ApsProcessOperationOutMaterDo> outMaterDos = processVo.get(0).getApsProcessOperationOutMaterDos().stream().filter(out -> out.getRoption().equals(apsProcessOperationDo1.getPlaninputid())).collect(Collectors.toList());
                        ApsProcessOperationOutMaterDo outMaterDo = outMaterDos.get(0);
                        processOperationDo.setPreviousprocessid(processVo.get(0).getProcessId());
                        processOperationDo.setPlaninputid(outMaterDo.getId());
                        String meterInput = getInMeterInfo(outMaterDo.getProducttype(), outMaterDo.getMetal(), outMaterDo.getMetalstate(), outMaterDo.getThickness(), outMaterDo.getProwidth(), outMaterDo.getProlength());
                        processOperationDo.setPlaninput(meterInput + outMaterDo.getSinglerollweight() + UNIT_MAP.getOrDefault(outMaterDo.getNumunit(), ""));
                        processOperationDo.setProducttypeid(outMaterDo.getProducttypeid());
                        processOperationDo.setProducttype(outMaterDo.getProducttype());
                        processOperationDo.setMetal(outMaterDo.getMetal());
                        processOperationDo.setMetalstate(outMaterDo.getMetalstate());
                        processOperationDo.setThickness(outMaterDo.getThickness());
                        processOperationDo.setProwidth(outMaterDo.getProwidth());
                        processOperationDo.setProlength(outMaterDo.getProlength());
                        processOperationDo.setSinglerollweight(outMaterDo.getSinglerollweight());
                        Integer planInRall = outMaterDo.getPlanrollnum() - outMaterDo.getPlanstockrollnum() - outMaterDo.getPlanprodrollnum();
                        processOperationDo.setPlaninrall(planInRall);
                        //输入物料ID对应前道工序作业输出物料只有一个后道工序作业），则不可编辑，自动计算=计划输入卷数
                        if (apsProcessOperationDos1.size() == 1) {
                            processOperationDo.setPlanprocessrall(processVo.get(0).getPlanprocessrall());
                            if (!processOperationDo.getProcessway().equals("合并加工")) {
                                BigDecimal loadingmin = processOperationDo.getLoadingmin() == null ? BigDecimal.valueOf(0) : processOperationDo.getLoadingmin();
                                BigDecimal cuttingmin = processOperationDo.getCuttingmin() == null ? BigDecimal.valueOf(0) : processOperationDo.getCuttingmin();
                                if (processOperationDo.getTimeway().equals("10")) {
                                    //如果计时方式=按设备运转速度计时，计划作业时长=计划加工卷数*(上料时长+下料时长+(输入单卷重/（输入物料宽度/1000*输入物料厚度/1000*设备运转速度/1000*铝的密度）))
                                    BigDecimal prowidth = processOperationDo.getProwidth() == null ? BigDecimal.valueOf(1) : processOperationDo.getProwidth();
                                    BigDecimal thickness = processOperationDo.getThickness() == null ? BigDecimal.valueOf(1) : processOperationDo.getThickness();
                                    BigDecimal workspeed = processOperationDo.getWorkspeed() == null ? BigDecimal.valueOf(1) : processOperationDo.getWorkspeed();
                                    BigDecimal onceprocessmin = new BigDecimal(df.format(loadingmin.add(cuttingmin).add(processOperationDo.getSinglerollweight().multiply(BigDecimal.valueOf(1000000000)).divide(prowidth.multiply(thickness).multiply(workspeed).multiply(aluminumdensity), 2, BigDecimal.ROUND_HALF_UP))));
                                    processOperationDo.setOnceprocessmin(onceprocessmin);
                                    processOperationDo.setProcesstotaltime(new BigDecimal(df.format(BigDecimal.valueOf(processOperationDo.getPlanprocessrall()).multiply(onceprocessmin))));
                                } else if (processOperationDo.getTimeway().equals("40")) {
                                    //如果计时方式=按单次加工时长计时，计划作业时长=(上料时长+下料时长+单次加工时长)*计划加工卷数
                                    processOperationDo.setProcesstotaltime(new BigDecimal(df.format(loadingmin.add(cuttingmin).add(processOperationDo.getOnceprocessmin()).multiply(BigDecimal.valueOf(processOperationDo.getPlanprocessrall())))));
                                }
                            }
                        } else {
                            processOperationDo.setPlanprocessrall(0);
                        }
                        processOperationDo.setUnfinishroll(planInRall - processOperationDo.getCheckoutroll());

                        //更新前道工序的后道工序
                        ApsProcessOperationDo aDo = apsProcessOperationDoList.stream().filter(qtr -> processVo.get(0).getProcessId().equals(qtr.getId())).findAny().orElse(null);
                        if (StringUtils.isBlank(aDo.getNextprocessid())) {
                            aDo.setNextprocessid(processId);
                        } else {
                            aDo.setNextprocessid(aDo.getNextprocessid() + "," + processId);
                        }

                        //本道工序信息
                        previousProcessVo.setProcessId(processId);
                        previousProcessVo.setPreviousstepid(apsProcessOperationDo1.getId());
                        previousProcessVo.setPlanprocessrall(processOperationDo.getPlanprocessrall());

                        //本道工序的输出
                        List<ApsProcessOperationOutMaterDo> apsProcessOperationOutMaterDos1 = apsProcessOperationOutMaterDos.stream().filter(omd -> apsProcessOperationDo1.getId().equals(omd.getMainid())).collect(Collectors.toList());
                        if (apsProcessOperationOutMaterDos1.size() == 0) {
                            return R.error("工艺步骤" + apsProcessOperationDo1.getProcessname() + "没输出");
                        }
                        List<String> planoutputList = new ArrayList<>();
                        for (ApsProcessOperationOutMaterDo apsProcessOperationOutMaterDo : apsProcessOperationOutMaterDos1) {
                            ApsProcessOperationOutMaterDo processOperationOutMaterDo = BeanUtil.toBean(apsProcessOperationOutMaterDo, ApsProcessOperationOutMaterDo.class);
                            processOperationOutMaterDo.setRoption(apsProcessOperationOutMaterDo.getId());
                            processOperationOutMaterDo.setId(SecurityUtil.getUUID());

                            String outProducttype = apsProcessOperationOutMaterDo.getProducttype();
                            if (apsProcessOperationOutMaterDo.getProducttyperule().equals("不变")) {
                                outProducttype = outMaterDo.getProducttype() == null ? "" : outMaterDo.getProducttype();
                                processOperationOutMaterDo.setProducttypeid(outMaterDo.getProducttypeid() == null ? "" : outMaterDo.getProducttypeid());
                                processOperationOutMaterDo.setProducttype(outProducttype);
                            }
                            String outMeter = apsProcessOperationOutMaterDo.getMetal();
                            if (apsProcessOperationOutMaterDo.getMetalrule().equals("不变")) {
                                outMeter = outMaterDo.getMetal() == null ? "" : outMaterDo.getMetal();
                                processOperationOutMaterDo.setMetal(outMeter);
                            }
                            String outMetalstate = apsProcessOperationOutMaterDo.getMetalstate();
                            if (apsProcessOperationOutMaterDo.getMetalstaterule().equals("不变")) {
                                outMetalstate = outMaterDo.getMetalstate() == null ? "" : outMaterDo.getMetalstate();
                                processOperationOutMaterDo.setMetalstate(outMetalstate);
                            }
                            BigDecimal tval = changeSize(outMaterDo.getThickness(), apsProcessOperationOutMaterDo.getThickrule(), apsProcessOperationOutMaterDo.getThickchange(), apsProcessOperationOutMaterDo.getThickness());
                            processOperationOutMaterDo.setThickness(tval);
                            BigDecimal wval = changeSize(outMaterDo.getProwidth(), apsProcessOperationOutMaterDo.getWidthrule(), apsProcessOperationOutMaterDo.getWidthchange(), apsProcessOperationOutMaterDo.getProwidth());
                            processOperationOutMaterDo.setProwidth(wval);
                            BigDecimal lval = changeSize(outMaterDo.getProlength(), apsProcessOperationOutMaterDo.getLengthrule(), apsProcessOperationOutMaterDo.getLengthchange(), apsProcessOperationOutMaterDo.getProlength());
                            processOperationOutMaterDo.setProlength(lval);
                            processOperationOutMaterDo.setPlanrollnum(processOperationDo.getPlanprocessrall() * apsProcessOperationOutMaterDo.getOutval());
                            //输入单卷重*输出宽度/输入宽度
                            String singlerollweight = df.format(outMaterDo.getSinglerollweight().multiply(wval == null ? BigDecimal.valueOf(1) : wval).divide(outMaterDo.getProwidth() == null ? BigDecimal.valueOf(1) : outMaterDo.getProwidth(), 3, BigDecimal.ROUND_HALF_UP));
                            processOperationOutMaterDo.setSinglerollweight(new BigDecimal(singlerollweight));
                            processOperationOutMaterDo.setNumunit(blanckdata.getStr("NUMBERUNIT"));
                            //没有后道工序作业，计划成品卷数=计划输出卷数-计划备料卷数
                            if (StringUtils.isBlank(apsProcessOperationDo.getNextprocessid())) {
                                processOperationOutMaterDo.setPlanprodrollnum(processOperationDo.getPlanprocessrall());
                            } else {
                                processOperationOutMaterDo.setPlanprodrollnum(0);
                            }
                            //输出物料
                            String outputMeter = getOutMeterInfo(outProducttype, outMeter, outMetalstate, tval, wval, lval, processOperationOutMaterDo.getThickoffset(), processOperationOutMaterDo.getWidthoffset(), processOperationOutMaterDo.getLengthoffset()) + singlerollweight + UNIT_MAP.getOrDefault(blanckdata.getStr("NUMBERUNIT"), "");
                            processOperationOutMaterDo.setOutputmaterial(outputMeter + "*" + (planInRall * processOperationOutMaterDo.getOutval()) + "卷");
                            planoutputList.add(outputMeter + "*" + (planInRall * processOperationOutMaterDo.getOutval()) + "卷");
                            String outputfinishproduct = "";
                            Integer planprodrollnum = 0;
                            if (StringUtils.isBlank(apsProcessOperationDo.getNextprocessid())) {
                                planprodrollnum = (planInRall * processOperationOutMaterDo.getOutval()) - processOperationOutMaterDo.getPlanstockrollnum();
                                //没有后道工序作业，计划成品卷数=计划输出卷数-计划备料卷数
                                processOperationOutMaterDo.setPlanprodrollnum(processOperationOutMaterDo.getPlanrollnum() - processOperationOutMaterDo.getPlanstockrollnum());
                            } else {
                                planprodrollnum = processOperationOutMaterDo.getPlanprodrollnum();
                            }
                            if (processOperationOutMaterDo.getPlanprodrollnum() > 0) {
                                outputfinishproduct = getInMeterInfo(outProducttype, outMeter, outMetalstate, tval, wval, lval) + processOperationOutMaterDo.getSinglerollweight() + UNIT_MAP.getOrDefault(processOperationOutMaterDo.getNumunit(), "") + " * " + planprodrollnum + "卷";
                            }
                            processOperationOutMaterDo.setOutputfinishproduct(outputfinishproduct);
                            processOperationOutMaterDo.setOutmaterrequest(outputMeter);
                            processOperationOutMaterDo.setMainid(processId);
                            processOperationOutMaterDo.setBlankid(blanckdata.getStr("ID"));
                            apsProcessOperationOutMaterDoList.add(processOperationOutMaterDo);
                        }
                        previousProcessVo.setApsProcessOperationOutMaterDos(apsProcessOperationOutMaterDoList);

                        //本道工序的可选设备
                        List<ApsProcessOperationEquDo> apsProcessOperationEquDos1 = apsProcessOperationEquDos.stream().filter(crse -> apsProcessOperationDo1.getId().equals(crse.getMainid())).collect(Collectors.toList());
                        for (ApsProcessOperationEquDo apsProcessOperationEquDo : apsProcessOperationEquDos1) {
                            ApsProcessOperationEquDo processOperationEquDo = BeanUtil.toBean(apsProcessOperationEquDo, ApsProcessOperationEquDo.class);
                            processOperationEquDo.setId(SecurityUtil.getUUID());
                            processOperationEquDo.setMainid(processId);
                            processOperationEquDo.setBlankid(blanckdata.getStr("ID"));
                            apsProcessOperationEquDoList.add(processOperationEquDo);
                        }

                        //本道工序思维导图
                        List<SysMindMappingDo> sysMindMappingDos1 = sysMindMappingDos.stream().filter(mind -> mind.getId().equals(apsProcessOperationDo1.getId())).collect(Collectors.toList());
                        SysMindMappingDo sysMindMappingDo1 = sysMindMappingDos1.get(0);
                        sysMindMappingDo1.setId(processId);
                        sysMindMappingDo1.setParentid(processVo.get(0).getProcessId());
                        sysMindMappingDo1.setBsid(blanckdata.getStr("ID"));
                        sysMindMappingDo1.setBstable("aps_process_operation");
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.putOpt("craftStepId", apsProcessOperationDo1.getId());
                        sysMindMappingDo1.setRoption(jsonObject.toString());//存工艺路线的工艺步骤ID
                        sysMindMappingDoList.add(sysMindMappingDo1);

                        newProcessIds.add(previousProcessVo);

                        StringBuffer planoutsb = new StringBuffer();
                        Collections.sort(planoutputList);
                        Integer outIndex = 1;
                        if (planoutputList.size() == 1) {
                            planoutsb.append("[1]" + planoutputList.get(0));
                        } else {
                            for (String planout : planoutputList) {
                                planoutsb.append("[" + outIndex + "]" + planout + "/n");
                                outIndex++;
                            }
                        }
                        processOperationDo.setPlanoutput(planoutsb.toString());
                        apsProcessOperationDoList.add(processOperationDo);

                        overProcessIds.add(apsProcessOperationDo1.getId());
                    }
                } else {
                    previousProcessVo = new PreviousProcessVo();
                    //首道工序
                    processId = SecurityUtil.getUUID();
                    String meterInput = getInMeterInfo(blanckdata.getStr("PRODUCTTYPE"), blanckdata.getStr("ALLOY"), blanckdata.getStr("ALLOYSTATUS"), blanckdata.getBigDecimal("THICKNESS"), blanckdata.getBigDecimal("PROWIDTH"), blanckdata.getBigDecimal("PROLENGTH"));
                    processOperationDo = BeanUtil.toBean(apsProcessOperationDo, ApsProcessOperationDo.class);
                    processOperationDo.setId(processId);
                    processOperationDo.setPlaninput(meterInput + blanckdata.getStr("SINGLEROLLWEIGHT") + UNIT_MAP.getOrDefault(blanckdata.getStr("NUMBERUNIT"), ""));
                    processOperationDo.setMetalstate(blanckdata.getStr("ALLOYSTATUS"));
                    processOperationDo.setProwidth(blanckdata.getBigDecimal("PROWIDTH"));
                    processOperationDo.setProlength(blanckdata.getBigDecimal("PROLENGTH"));
                    processOperationDo.setSinglerollweight(blanckdata.getBigDecimal("SINGLEROLLWEIGHT"));
                    processOperationDo.setPlaninrall(blanckdata.getInt("ROLLNUM"));
                    processOperationDo.setPlanprocessrall(blanckdata.getInt("ROLLNUM"));
                    processOperationDo.setUnfinishroll(blanckdata.getInt("ROLLNUM"));
                    processOperationDo.setBlankid(blanckdata.getStr("ID"));
                    processOperationDo.setNextprocessid(null);

                    if (!processOperationDo.getProcessway().equals("合并加工")) {
                        BigDecimal loadingmin = processOperationDo.getLoadingmin() == null ? BigDecimal.valueOf(0) : processOperationDo.getLoadingmin();
                        BigDecimal cuttingmin = processOperationDo.getCuttingmin() == null ? BigDecimal.valueOf(0) : processOperationDo.getCuttingmin();
                        if (processOperationDo.getTimeway().equals("10")) {
                            //如果计时方式=按设备运转速度计时，计划作业时长=计划加工卷数*(上料时长+下料时长+(输入单卷重/（输入物料宽度/1000*输入物料厚度/1000*设备运转速度/1000*铝的密度）))
                            BigDecimal prowidth = processOperationDo.getProwidth() == null ? BigDecimal.valueOf(1) : processOperationDo.getProwidth();
                            BigDecimal thickness = processOperationDo.getThickness() == null ? BigDecimal.valueOf(1) : processOperationDo.getThickness();
                            BigDecimal workspeed = processOperationDo.getWorkspeed() == null ? BigDecimal.valueOf(1) : processOperationDo.getWorkspeed();
                            BigDecimal onceprocessmin = new BigDecimal(df.format(loadingmin.add(cuttingmin).add(processOperationDo.getSinglerollweight().multiply(BigDecimal.valueOf(1000000000)).divide(prowidth.multiply(thickness).multiply(workspeed).multiply(aluminumdensity), 2, BigDecimal.ROUND_HALF_UP))));
                            processOperationDo.setOnceprocessmin(onceprocessmin);
                            processOperationDo.setProcesstotaltime(new BigDecimal(df.format(BigDecimal.valueOf(processOperationDo.getPlanprocessrall()).multiply(onceprocessmin))));
                        } else if (processOperationDo.getTimeway().equals("40")) {
                            //如果计时方式=按单次加工时长计时，计划作业时长=(上料时长+下料时长+单次加工时长)*计划加工卷数
                            processOperationDo.setProcesstotaltime(new BigDecimal(df.format(loadingmin.add(cuttingmin).add(processOperationDo.getOnceprocessmin()).multiply(BigDecimal.valueOf(processOperationDo.getPlanprocessrall())))));
                        }
                    }

                    //本道工序信息
                    previousProcessVo.setProcessId(processId);
                    previousProcessVo.setPreviousstepid(apsProcessOperationDo.getId());
                    previousProcessVo.setPlanprocessrall(blanckdata.getInt("ROLLNUM"));

                    //本道工序的输出
                    List<ApsProcessOperationOutMaterDo> apsProcessOperationOutMaterDos1 = apsProcessOperationOutMaterDos.stream().filter(omd -> apsProcessOperationDo.getId().equals(omd.getMainid())).collect(Collectors.toList());
                    if (apsProcessOperationOutMaterDos1.size() == 0) {
                        return R.error("工艺步骤" + apsProcessOperationDo.getProcessname() + "没输出");
                    }
                    List<String> planoutputList = new ArrayList<>();
                    for (ApsProcessOperationOutMaterDo apsProcessOperationOutMaterDo : apsProcessOperationOutMaterDos1) {
                        ApsProcessOperationOutMaterDo processOperationOutMaterDo = BeanUtil.toBean(apsProcessOperationOutMaterDo, ApsProcessOperationOutMaterDo.class);
                        processOperationOutMaterDo.setId(SecurityUtil.getUUID());
                        processOperationOutMaterDo.setRoption(apsProcessOperationOutMaterDo.getId());
                        String outProducttype = apsProcessOperationOutMaterDo.getProducttype();
                        if (apsProcessOperationOutMaterDo.getProducttyperule().equals("不变")) {
                            outProducttype = blanckdata.getStr("PRODUCTTYPE") == null ? "" : blanckdata.getStr("PRODUCTTYPE");
                            processOperationOutMaterDo.setProducttypeid(blanckdata.getStr("PRODUCTTYPEID") == null ? "" : blanckdata.getStr("PRODUCTTYPEID"));
                            processOperationOutMaterDo.setProducttype(outProducttype);
                        }
                        String outMeter = apsProcessOperationOutMaterDo.getMetal();
                        if (apsProcessOperationOutMaterDo.getMetalrule().equals("不变")) {
                            outMeter = blanckdata.getStr("ALLOY") == null ? "" : blanckdata.getStr("ALLOY");
                            processOperationOutMaterDo.setMetal(outMeter);
                        }
                        String outMetalstate = apsProcessOperationOutMaterDo.getMetalstate();
                        if (apsProcessOperationOutMaterDo.getMetalstaterule().equals("不变")) {
                            outMetalstate = blanckdata.getStr("ALLOYSTATUS") == null ? "" : blanckdata.getStr("ALLOYSTATUS");
                            processOperationOutMaterDo.setMetalstate(outMetalstate);
                        }
                        BigDecimal tval = changeSize(blanckdata.getBigDecimal("THICKNESS"), apsProcessOperationOutMaterDo.getThickrule(), apsProcessOperationOutMaterDo.getThickchange(), apsProcessOperationOutMaterDo.getThickness());
                        processOperationOutMaterDo.setThickness(tval);
                        BigDecimal wval = changeSize(blanckdata.getBigDecimal("PROWIDTH"), apsProcessOperationOutMaterDo.getWidthrule(), apsProcessOperationOutMaterDo.getWidthchange(), apsProcessOperationOutMaterDo.getProwidth());
                        processOperationOutMaterDo.setProwidth(wval);
                        BigDecimal lval = changeSize(blanckdata.getBigDecimal("PROLENGTH"), apsProcessOperationOutMaterDo.getLengthrule(), apsProcessOperationOutMaterDo.getLengthchange(), apsProcessOperationOutMaterDo.getProlength());
                        processOperationOutMaterDo.setProlength(lval);
                        processOperationOutMaterDo.setPlanrollnum(blanckdata.getInt("ROLLNUM"));
                        //输入单卷重*输出宽度/输入宽度
                        String singlerollweight = df.format(blanckdata.getBigDecimal("SINGLEROLLWEIGHT").multiply(wval == null ? BigDecimal.valueOf(1) : wval).divide(blanckdata.getBigDecimal("PROWIDTH") == null ? BigDecimal.valueOf(1) : blanckdata.getBigDecimal("PROWIDTH"), 3, BigDecimal.ROUND_HALF_UP));
                        processOperationOutMaterDo.setSinglerollweight(new BigDecimal(singlerollweight));
                        processOperationOutMaterDo.setNumunit(blanckdata.getStr("NUMBERUNIT"));
                        //输出物料
                        String outputMeter = getOutMeterInfo(outProducttype, outMeter, outMetalstate, tval, wval, lval, apsProcessOperationOutMaterDo.getThickoffset(), apsProcessOperationOutMaterDo.getWidthoffset(), apsProcessOperationOutMaterDo.getLengthoffset()) + singlerollweight + UNIT_MAP.getOrDefault(blanckdata.getStr("NUMBERUNIT"), "");
                        processOperationOutMaterDo.setOutputmaterial(outputMeter + "*" + blanckdata.getInt("ROLLNUM") + "卷");
                        planoutputList.add(outputMeter + "*" + blanckdata.getInt("ROLLNUM") + "卷");
                        processOperationOutMaterDo.setMainid(processId);
                        processOperationOutMaterDo.setBlankid(blanckdata.getStr("ID"));
                        apsProcessOperationOutMaterDoList.add(processOperationOutMaterDo);
                    }
                    previousProcessVo.setApsProcessOperationOutMaterDos(apsProcessOperationOutMaterDoList);

                    //本道工序的可选设备
                    List<ApsProcessOperationEquDo> apsProcessOperationEquDos1 = apsProcessOperationEquDos.stream().filter(omd -> apsProcessOperationDo.getId().equals(omd.getMainid())).collect(Collectors.toList());
                    for (ApsProcessOperationEquDo apsProcessOperationEquDo : apsProcessOperationEquDos1) {
                        ApsProcessOperationEquDo processOperationEquDo = BeanUtil.toBean(apsProcessOperationEquDo, ApsProcessOperationEquDo.class);
                        processOperationEquDo.setId(SecurityUtil.getUUID());
                        processOperationEquDo.setMainid(processId);
                        processOperationEquDo.setBlankid(blanckdata.getStr("ID"));
                        apsProcessOperationEquDoList.add(processOperationEquDo);
                    }

                    //本道工序思维导图
                    List<SysMindMappingDo> sysMindMappingDos1 = sysMindMappingDos.stream().filter(mind -> mind.getId().equals(apsProcessOperationDo.getId())).collect(Collectors.toList());
                    SysMindMappingDo sysMindMappingDo1 = sysMindMappingDos1.get(0);
                    sysMindMappingDo1.setId(processId);
                    sysMindMappingDo1.setParentid(mindStrId);
                    sysMindMappingDo1.setBsid(blanckdata.getStr("ID"));
                    sysMindMappingDo1.setBstable("aps_process_operation");
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.putOpt("craftStepId", apsProcessOperationDo.getId());
                    sysMindMappingDo1.setRoption(jsonObject.toString());//存工艺路线的工艺步骤ID
                    sysMindMappingDoList.add(sysMindMappingDo1);

                    newProcessIds.add(previousProcessVo);

                    StringBuffer planoutsb = new StringBuffer();
                    Collections.sort(planoutputList);
                    Integer outIndex = 1;
                    if (planoutputList.size() == 1) {
                        planoutsb.append("[1]" + planoutputList.get(0));
                    } else {
                        for (String planout : planoutputList) {
                            planoutsb.append("[" + outIndex + "]" + planout + "/n");
                            outIndex++;
                        }
                    }
                    processOperationDo.setPlanoutput(planoutsb.toString());
                    apsProcessOperationDoList.add(processOperationDo);
                }
            }
        }

        boolean bool1 = apsProcessOperationService.saveOrUpdateBatch(apsProcessOperationDoList);
        boolean bool2 = apsProcessOperationOutMaterService.saveOrUpdateBatch(apsProcessOperationOutMaterDoList);
        boolean bool3 = apsProcessOperationEquService.saveOrUpdateBatch(apsProcessOperationEquDoList);
        boolean bool4 = sysMindMappingService.saveOrUpdateBatch(sysMindMappingDoList);
        if (bool1 && bool2 && bool3 && bool4) {
            //更新坯料计划的所选工艺路线相关信息
            ApsCraftRouteDo apsCraftRouteDo = apsCraftRouteService.getById(craftrouteid);
            apsBlankOrderService.update(new LambdaUpdateWrapper<ApsBlankOrderDo>()
                    .eq(ApsBlankOrderDo::getId, blanckdata.getStr("ID"))
                    .set(ApsBlankOrderDo::getCraftrouteid, craftrouteid)
                    .set(ApsBlankOrderDo::getRouteproducttypeid, apsCraftRouteDo.getProducttype())
                    .set(ApsBlankOrderDo::getRoutemetal, apsCraftRouteDo.getMetal())
                    .set(ApsBlankOrderDo::getRoutemetalstate, apsCraftRouteDo.getMetalstate())
                    .set(ApsBlankOrderDo::getRoutethinckstr, apsCraftRouteDo.getThickstr())
                    .set(ApsBlankOrderDo::getRoutethickend, apsCraftRouteDo.getThickend())
                    .set(ApsBlankOrderDo::getRoutewodthstr, apsCraftRouteDo.getWidthstr())
                    .set(ApsBlankOrderDo::getRoutewidthend, apsCraftRouteDo.getWidthend())
                    .set(ApsBlankOrderDo::getRoutelengthstr, apsCraftRouteDo.getLengthstr())
                    .set(ApsBlankOrderDo::getRoutelengthend, apsCraftRouteDo.getLengthend())
            );
            R r = new R();
            r.setCode("200");
            r.setData(apsCraftRouteDo);
            return r;
        } else {
            return R.error();
        }
    }

    /*
    清除工艺路线
     */
    @Override
    @Transactional
    public void clearCraftRoute(Map<String, Object> params) {
        String blankid = params.get("BLANKID").toString();
        //坯料计划去掉选择的工艺路线ID
        apsBlankOrderService.update(new LambdaUpdateWrapper<ApsBlankOrderDo>()
                .eq(ApsBlankOrderDo::getId, blankid)
                .set(ApsBlankOrderDo::getCraftrouteid, null)
                .set(ApsBlankOrderDo::getRouteproducttypeid, null)
                .set(ApsBlankOrderDo::getRoutemetal, null)
                .set(ApsBlankOrderDo::getRoutemetalstate, null)
                .set(ApsBlankOrderDo::getRoutethinckstr, null)
                .set(ApsBlankOrderDo::getRoutethickend, null)
                .set(ApsBlankOrderDo::getRoutewodthstr, null)
                .set(ApsBlankOrderDo::getRoutewidthend, null)
                .set(ApsBlankOrderDo::getRoutelengthstr, null)
                .set(ApsBlankOrderDo::getRoutelengthend, null)
        );
        //工序作业
        apsProcessOperationDao.updateProcessOperation(blankid);
        //工序作业输出物料
        apsProcessOperationDao.updateProcessOperationOutMeter(blankid);
        //工序作业可选设备
        apsProcessOperationDao.updateProcessOperationOEqu(blankid);
        //工序作业思维导图
        apsProcessOperationDao.updateSysMindMapping(blankid);

        //更新状态
        CommonUpdateProductionStatusReq req = new CommonUpdateProductionStatusReq();
        req.setProcessOperationId(blankid);
        apsProcessOperationProcessEquService.updateProductionStatus(req);
    }

    @Override
    public R checkOperation(Map<String, Object> params) {
        String blankId;
        try {
            blankId = params.get("BLANKID").toString();
        } catch (Exception e) {
            e.printStackTrace();
            return R.error("请输入正确的坯料计划ID");
        }
        Boolean checkDeviceAndOrgCode = false;
        try {
            if (params.containsKey("checkDeviceAndOrgCode")) {
                checkDeviceAndOrgCode = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //查询坯料计划对应的工序作业
        List<ApsProcessOperationDo> apsProcessOperationList = this.baseMapper.selectList(new QueryWrapper<ApsProcessOperationDo>().lambda().eq(ApsProcessOperationDo::getBlankid, blankId));
        //判断工序作业是否为空，为空表示没有选择工艺路线
        if (apsProcessOperationList.size() <= 0) {
            return R.error("请选择工艺路线");
        }
        //查询坯料计划对应的输出物料
        List<ApsProcessOperationOutMaterDo> apsProcessOperationOutMaterList = apsProcessOperationOutMaterService.getBaseMapper().selectList(new QueryWrapper<ApsProcessOperationOutMaterDo>().lambda().eq(ApsProcessOperationOutMaterDo::getBlankid, blankId));

        //如果有前道工序作业，并且该工序输入物料ID不是前道工序作业的输出物料ID，错误提示：{工序}{工序显示名}的输入物料不存在，请重新选择

        //遍历工序作业
        for (ApsProcessOperationDo apsProcessOperationDo : apsProcessOperationList) {
            //如果有前道工序
            if (ObjectUtil.isNotEmpty(apsProcessOperationDo.getPreviousprocessid())) {
                //获取当前工序的输入物料ID
                String planInputId = apsProcessOperationDo.getPlaninputid();

                //获取前道工序的输出物料的ID list
                List<String> previousProcessOutMaterialIdList = apsProcessOperationOutMaterList.stream().filter(item -> item.getMainid().equals(apsProcessOperationDo.getPreviousprocessid())).map(ApsProcessOperationOutMaterDo::getId).collect(Collectors.toList());
                //该工序输入物料ID不是前道工序作业的输出物料ID
                if (!previousProcessOutMaterialIdList.contains(planInputId)) {
                    return R.error(apsProcessOperationDo.getProcess() + apsProcessOperationDo.getProcessname() + "的输入物料不存在，请重新选择");
                }
            }
        }

        //检查该工序作业所有输出物料，如果(计划输出卷数-计划备料卷数-计划成品卷数)不等于所有后道工序作业计划加工卷数合计；错误提示：{工序}{工序显示名}的{输出物料} 计划输出卷数-计划备料卷数-计划成品卷数必须等于所有后道工序作业计划加工卷数合计
        //遍历输出物料
        for (ApsProcessOperationOutMaterDo apsProcessOperationOutMaterDo : apsProcessOperationOutMaterList) {
            //查询使用此输出物料的工序作业
            List<ApsProcessOperationDo> processList = apsProcessOperationList.stream().filter(item -> ObjectUtil.isNotEmpty(item.getPlaninputid()) && item.getPlaninputid().equals(apsProcessOperationOutMaterDo.getId())).collect(Collectors.toList());
            if (processList.size() > 0) {
                //遍历工序作业，计算 计划加工卷数合计
                int planProcessRollAll = 0;
                for (ApsProcessOperationDo apsProcessOperationDo : processList) {
                    planProcessRollAll += apsProcessOperationDo.getPlanprocessrall();
                }
                //计算输出物料的 (计划输出卷数-计划备料卷数-计划成品卷数)值
                int outputRollAll = apsProcessOperationOutMaterDo.getPlanrollnum() - apsProcessOperationOutMaterDo.getPlanstockrollnum() - apsProcessOperationOutMaterDo.getPlanprodrollnum();
                if (planProcessRollAll != outputRollAll) {
                    //根据输出物料查询其工序信息
                    ApsProcessOperationDo apsProcessOperationDo = apsProcessOperationList.stream().filter(item -> item.getId().equals(apsProcessOperationOutMaterDo.getMainid())).findFirst().get();
                    return R.error(apsProcessOperationDo.getProcess() + apsProcessOperationDo.getProcessname() + "的" + apsProcessOperationOutMaterDo.getOutputmaterial() + " 计划输出卷数-计划备料卷数-计划成品卷数必须等于所有后道工序作业计划加工卷数合计");
                }
            }
        }
        //校验工序作业明细的加工设备和加工车间的代号是否为空
        if (checkDeviceAndOrgCode) {
            //查询坯料计划对应的所有工序作业明细
            List<ApsProcessOperationProcessEquDo> list = apsProcessOperationProcessEquService.list(new QueryWrapper<ApsProcessOperationProcessEquDo>().lambda().eq(ApsProcessOperationProcessEquDo::getBlankid, blankId));
            //获取所有工序作业明细的加工设备
            Set<String> deviceIds = list.stream().filter(item -> ObjectUtil.isNotEmpty(item.getProcessdeviceid())).map(ApsProcessOperationProcessEquDo::getProcessdeviceid).collect(Collectors.toSet());
            //查询设备对应的代号
            List<AspCheckItemsDo> deviceList = aspCheckItemsService.list(new QueryWrapper<AspCheckItemsDo>().lambda().in(AspCheckItemsDo::getId, deviceIds));
            //组装成map类型，以便筛选和查询
            Map<String, Object> deviceMap = new HashMap<>();
            for (AspCheckItemsDo aspCheckItemsDo : deviceList) {
                deviceMap.put(aspCheckItemsDo.getId(), aspCheckItemsDo.getEquipmentcode());
            }
            //获取所有工序作业明细的加工车间
            Set<String> workShopIds = list.stream().filter(item -> ObjectUtil.isNotEmpty(item.getProcessworkshopid())).map(ApsProcessOperationProcessEquDo::getProcessworkshopid).collect(Collectors.toSet());
            //查询车间对应的代号
            List<SysOrganizationDo> workSopList = sysOrganizationService.list(new QueryWrapper<SysOrganizationDo>().lambda().in(SysOrganizationDo::getId, workShopIds));
            //组装成map类型，以便筛选和查询
            Map<String, Object> workShopMap = new HashMap<>();
            for (SysOrganizationDo sysOrganizationDo : workSopList) {
                workShopMap.put(sysOrganizationDo.getId(), sysOrganizationDo.getRoption());
            }


            /**
             * 检查所有是否坯料工序=是的工序作业
             * 如果坯料计划的坯料类型=铸轧，并且（工序作业的加工设备代号为空，或者加工设备代号不是2位），
             * 则错误提示：铸轧坯料加工设备{加工车间}/{加工设备}的代号需要是2位；
             * 如果坯料计划的坯料类型=热轧，并且（工序作业的加工设备代号为空，或者加工设备代号不是1位），
             * 则错误提示：热轧坯料加工设备{加工车间}/{加工设备}的代号需要是1位；
             * 如果工序作业的加工车间代号为空，或者不是1位，则错误提示：加工车间{加工车间}代号不能为空
             */
            //查询坯料计划
            ApsBlankOrderDo apsBlankOrderDo = apsBlankOrderService.getById(blankId);
            //遍历查询是否有工序没有对应的设备代号和车间代号
            for (ApsProcessOperationProcessEquDo equDo : list) {
                //查询工序作业
                ApsProcessOperationDo apsProcessOperationDo = apsProcessOperationList.stream().filter(item -> item.getId().equals(equDo.getProcessid())).findFirst().orElse(null);

                if (ObjectUtil.isEmpty(apsProcessOperationDo)) {
                    return R.error("未找到对应工序作业明细，请检查是否正在排程");
                }

                //检查所有是否坯料工序=是的工序作业
                if (ObjectUtil.isNotEmpty(apsProcessOperationDo.getIfblankprocess()) && apsProcessOperationDo.getIfblankprocess().equals("是")) {
                    //校验设备代号
                    if (ObjectUtil.isNotEmpty(equDo.getProcessdeviceid())) {
                        if (deviceMap.containsKey(equDo.getProcessdeviceid())) {
                            //校验设备代号位数
                            if (ObjectUtil.isEmpty(deviceMap.get(equDo.getProcessdeviceid()))) {
                                return R.error(apsProcessOperationDo.getProcess() + apsProcessOperationDo.getProcessname() + "的加工设备" + equDo.getProcessdevice() + "代号不能为空");
                            }
                            String deviceCode = deviceMap.get(equDo.getProcessdeviceid()).toString();

                            //如果坯料计划的坯料类型=铸轧,并且（工序作业的加工设备代号为空，或者加工设备代号不是2位）
                            if (apsBlankOrderDo.getBlanktype().equals("铸轧")
                                    && (ObjectUtil.isEmpty(deviceCode) || deviceCode.length() != 2)) {
                                return R.error("铸轧坯料加工设备" + equDo.getProcessworkshop() + "/" + equDo.getProcessdevice() + "的代号需要是2位");
                            }
                            //如果坯料计划的坯料类型=热轧，并且（工序作业的加工设备代号为空，或者加工设备代号不是1位）
                            if (apsBlankOrderDo.getBlanktype().equals("热轧")
                                    && (ObjectUtil.isEmpty(deviceCode) || deviceCode.length() != 1)) {
                                return R.error("热轧坯料加工设备" + equDo.getProcessworkshop() + "/" + equDo.getProcessdevice() + "的代号需要是1位");
                            }
                        }

                    }
                    //校验车间代号
                    if (ObjectUtil.isNotEmpty(equDo.getProcessworkshopid())) {
                        if (workShopMap.containsKey(equDo.getProcessworkshopid())) {
                            if (ObjectUtil.isEmpty(workShopMap.get(equDo.getProcessworkshopid()))) {
                                return R.error("加工车间" + equDo.getProcessworkshop() + "代号不能为空");
                            }
                            String workShopCode = workShopMap.get(equDo.getProcessworkshopid()).toString();
                            if (ObjectUtil.isEmpty(workShopCode) || workShopCode.length() != 1) {
                                return R.error("加工车间" + equDo.getProcessworkshop() + "代号不能为空");
                            }
                        }
                    }
                }
            }

        }
        return R.ok();

    }


    /*
    更新后面所有工序信息
     */
    @Override
    @Transactional
    public R resetProcessOperation(List<ApsProcessOperationOutMaterDo> apsProcessOperationOutMaterDoList) {
        List<ApsProcessOperationOutMaterDo> operationOutMaterDos = new ArrayList<>();//递归的数据源
        try {
            // 获取排程参数设置
            List<ApsScheduleConfigDo> apsConfigs = apsScheduleConfigService.list();
            BigDecimal aluminumdensity = apsConfigs.get(0).getAluminumdensity();
//            List<ApsProcessOperationDo> processOperationDos = apsProcessOperationDao.getProcessOperation(apsProcessOperationOutMaterDoList.get(0).getBlankid());
            //该坯料计划所有的工序及输出
            Map<String, Object> map = new HashMap<>();
            map.put("BLANKID", apsProcessOperationOutMaterDoList.get(0).getBlankid());
            List<ApsProcessOperationDo> processOperationDoList = apsProcessOperationService.listByMap(map).stream().collect(Collectors.toList());
            List<ApsProcessOperationOutMaterDo> processOperationOutMaterDoList = apsProcessOperationOutMaterService.listByMap(map).stream().collect(Collectors.toList());

            List<ApsProcessOperationDo> apsProcessOperationDoList = new ArrayList<>();
            List<ApsProcessOperationOutMaterDo> apsProcessOperationOutMaterDoNewList = new ArrayList<>();
            for (ApsProcessOperationOutMaterDo apsProcessOperationOutMaterDo : apsProcessOperationOutMaterDoList) {
                //这个输出的所有下道工序
                List<ApsProcessOperationDo> apsProcessOperationDos = processOperationDoList.stream().filter(apo -> apsProcessOperationOutMaterDo.getId().equals(apo.getPlaninputid())).collect(Collectors.toList());
                for (ApsProcessOperationDo apsProcessOperationDo : apsProcessOperationDos) {
                    //更新输入
                    apsProcessOperationDo.setProducttypeid(apsProcessOperationOutMaterDo.getProducttypeid() == null ? "" : apsProcessOperationOutMaterDo.getProducttypeid());
                    apsProcessOperationDo.setProducttype(apsProcessOperationOutMaterDo.getProducttype() == null ? "" : apsProcessOperationOutMaterDo.getProducttype());
                    apsProcessOperationDo.setMetal(apsProcessOperationOutMaterDo.getMetal() == null ? "" : apsProcessOperationOutMaterDo.getMetal());
                    apsProcessOperationDo.setMetalstate(apsProcessOperationOutMaterDo.getMetalstate() == null ? "" : apsProcessOperationOutMaterDo.getMetalstate());

                    apsProcessOperationDo.setThickness(apsProcessOperationOutMaterDo.getThickness());
                    apsProcessOperationDo.setProwidth(apsProcessOperationOutMaterDo.getProwidth());
                    apsProcessOperationDo.setProlength(apsProcessOperationOutMaterDo.getProlength());
                    apsProcessOperationDo.setSinglerollweight(apsProcessOperationOutMaterDo.getSinglerollweight());
                    Integer planinrall = apsProcessOperationOutMaterDo.getPlanrollnum() - apsProcessOperationOutMaterDo.getPlanstockrollnum() - apsProcessOperationOutMaterDo.getPlanprodrollnum();
                    apsProcessOperationDo.setPlaninrall(planinrall);
                    //输入物料ID对应前道工序作业输出物料只有一个后道工序作业），则不可编辑，自动计算=计划输入卷数
                    if (apsProcessOperationDos.size() == 1) {
                        apsProcessOperationDo.setPlanprocessrall(planinrall);
                        if (!apsProcessOperationDo.getProcessway().equals("合并加工")) {
                            BigDecimal loadingmin = apsProcessOperationDo.getLoadingmin() == null ? BigDecimal.valueOf(0) : apsProcessOperationDo.getLoadingmin();
                            BigDecimal cuttingmin = apsProcessOperationDo.getCuttingmin() == null ? BigDecimal.valueOf(0) : apsProcessOperationDo.getCuttingmin();
                            if (apsProcessOperationDo.getTimeway().equals("10")) {
                                //如果计时方式=按设备运转速度计时，计划作业时长=计划加工卷数*(上料时长+下料时长+(输入单卷重/（输入物料宽度/1000*输入物料厚度/1000*设备运转速度/1000*铝的密度）))
                                BigDecimal prowidth = apsProcessOperationDo.getProwidth() == null ? BigDecimal.valueOf(1) : apsProcessOperationDo.getProwidth();
                                BigDecimal thickness = apsProcessOperationDo.getThickness() == null ? BigDecimal.valueOf(1) : apsProcessOperationDo.getThickness();
                                BigDecimal workspeed = apsProcessOperationDo.getWorkspeed() == null ? BigDecimal.valueOf(1) : apsProcessOperationDo.getWorkspeed();
                                BigDecimal onceprocessmin = new BigDecimal(df.format(loadingmin.add(cuttingmin).add(apsProcessOperationDo.getSinglerollweight().multiply(BigDecimal.valueOf(1000000000)).divide(prowidth.multiply(thickness).multiply(workspeed).multiply(aluminumdensity), 2, BigDecimal.ROUND_HALF_UP))));
                                apsProcessOperationDo.setOnceprocessmin(onceprocessmin);
                                apsProcessOperationDo.setProcesstotaltime(new BigDecimal(df.format(BigDecimal.valueOf(apsProcessOperationDo.getPlanprocessrall()).multiply(onceprocessmin))));
                            } else if (apsProcessOperationDo.getTimeway().equals("40")) {
                                //如果计时方式=按单次加工时长计时，计划作业时长=(上料时长+下料时长+单次加工时长)*计划加工卷数
                                apsProcessOperationDo.setProcesstotaltime(new BigDecimal(df.format(loadingmin.add(cuttingmin).add(apsProcessOperationDo.getOnceprocessmin()).multiply(BigDecimal.valueOf(apsProcessOperationDo.getPlanprocessrall())))));
                            }
                        }
//                        ApsProcessOperationDo operationDo = processOperationDos.stream().filter(item -> item.getId().equals(apsProcessOperationDo.getPreviousprocessid())).findFirst().get();
//                        apsProcessOperationDo.setPlanprocessrall(operationDo.getPlanprocessrall());
                    }
                    apsProcessOperationDo.setUnfinishroll(planinrall - apsProcessOperationDo.getCheckoutroll());

                    //判断输出是否满足后续的输入
                    if ((apsProcessOperationDo.getThickstr() != null && apsProcessOperationOutMaterDo.getThickness() != null && apsProcessOperationDo.getThickstr().compareTo(apsProcessOperationOutMaterDo.getThickness()) > 0) || (apsProcessOperationDo.getThickend() != null && apsProcessOperationOutMaterDo.getThickness() != null && apsProcessOperationDo.getThickend().compareTo(apsProcessOperationOutMaterDo.getThickness()) < 0) || (apsProcessOperationDo.getWidthstr() != null && apsProcessOperationOutMaterDo.getProwidth() != null && apsProcessOperationDo.getWidthstr().compareTo(apsProcessOperationOutMaterDo.getProwidth()) > 0) || (apsProcessOperationDo.getWidthend() != null && apsProcessOperationOutMaterDo.getProwidth() != null && apsProcessOperationDo.getWidthend().compareTo(apsProcessOperationOutMaterDo.getProwidth()) < 0) || (apsProcessOperationDo.getLengthstr() != null && apsProcessOperationOutMaterDo.getProlength() != null && apsProcessOperationDo.getLengthstr().compareTo(apsProcessOperationOutMaterDo.getProlength()) > 0) || (apsProcessOperationDo.getLengthend() != null && apsProcessOperationOutMaterDo.getProlength() != null && apsProcessOperationDo.getLengthend().compareTo(apsProcessOperationOutMaterDo.getProlength()) < 0)) {
                        apsProcessOperationDo.setPlaninputid("");
                        apsProcessOperationDo.setPlaninput("");
                    } else {
                        String meterInput = getInMeterInfo(apsProcessOperationOutMaterDo.getProducttype(), apsProcessOperationOutMaterDo.getMetal(), apsProcessOperationOutMaterDo.getMetalstate(), apsProcessOperationOutMaterDo.getThickness(), apsProcessOperationOutMaterDo.getProwidth(), apsProcessOperationOutMaterDo.getProlength());
                        apsProcessOperationDo.setPlaninput(meterInput + apsProcessOperationOutMaterDo.getSinglerollweight() + UNIT_MAP.getOrDefault(apsProcessOperationOutMaterDo.getNumunit(), ""));
                    }

                    //输出
                    List<ApsProcessOperationOutMaterDo> apsProcessOperationOutMaterDoList1 = processOperationOutMaterDoList.stream().filter(apoom -> apsProcessOperationDo.getId().equals(apoom.getMainid())).collect(Collectors.toList());
                    List<String> planoutputList = new ArrayList<>();
                    for (ApsProcessOperationOutMaterDo apsProcessOperationOutMaterDo1 : apsProcessOperationOutMaterDoList1) {
                        String outProducttype = apsProcessOperationOutMaterDo1.getProducttype();
                        if (apsProcessOperationOutMaterDo1.getProducttyperule().equals("不变")) {
                            apsProcessOperationOutMaterDo1.setProducttypeid(apsProcessOperationOutMaterDo.getProducttypeid() == null ? "" : apsProcessOperationOutMaterDo.getProducttypeid());
                            outProducttype = apsProcessOperationOutMaterDo.getProducttype() == null ? "" : apsProcessOperationOutMaterDo.getProducttype();
                            apsProcessOperationOutMaterDo1.setProducttype(outProducttype);
                        }
                        String outMeter = apsProcessOperationOutMaterDo1.getMetal();
                        if (apsProcessOperationOutMaterDo1.getMetalrule().equals("不变")) {
                            outMeter = apsProcessOperationOutMaterDo.getMetal() == null ? "" : apsProcessOperationOutMaterDo.getMetal();
                            apsProcessOperationOutMaterDo1.setMetal(outMeter);
                        }
                        String outMetalstate = apsProcessOperationOutMaterDo1.getMetalstate();
                        if (apsProcessOperationOutMaterDo1.getMetalstaterule().equals("不变")) {
                            outMetalstate = apsProcessOperationOutMaterDo.getMetalstate() == null ? "" : apsProcessOperationOutMaterDo.getMetalstate();
                            apsProcessOperationOutMaterDo1.setMetalstate(outMetalstate);
                        }

                        BigDecimal tval = changeSize(apsProcessOperationOutMaterDo.getThickness(), apsProcessOperationOutMaterDo1.getThickrule(), apsProcessOperationOutMaterDo1.getThickchange(), apsProcessOperationOutMaterDo1.getThickness());
                        apsProcessOperationOutMaterDo1.setThickness(tval);
                        BigDecimal wval = changeSize(apsProcessOperationOutMaterDo.getProwidth(), apsProcessOperationOutMaterDo1.getWidthrule(), apsProcessOperationOutMaterDo1.getWidthchange(), apsProcessOperationOutMaterDo1.getProwidth());
                        apsProcessOperationOutMaterDo1.setProwidth(wval);
                        BigDecimal lval = changeSize(apsProcessOperationOutMaterDo.getProlength(), apsProcessOperationOutMaterDo1.getLengthrule(), apsProcessOperationOutMaterDo1.getLengthchange(), apsProcessOperationOutMaterDo1.getProlength());
                        apsProcessOperationOutMaterDo1.setProlength(lval);
                        apsProcessOperationOutMaterDo1.setPlanrollnum(apsProcessOperationDo.getPlanprocessrall() * apsProcessOperationOutMaterDo1.getOutval());
                        //输入单卷重*输出宽度/输入宽度
                        String singlerollweight = df.format(apsProcessOperationOutMaterDo.getSinglerollweight().multiply(wval == null ? BigDecimal.valueOf(1) : wval).divide(apsProcessOperationOutMaterDo.getProwidth() == null ? BigDecimal.valueOf(1) : apsProcessOperationOutMaterDo.getProwidth(), 3, BigDecimal.ROUND_HALF_UP));
                        apsProcessOperationOutMaterDo1.setSinglerollweight(new BigDecimal(singlerollweight));
                        //输出物料
                        String outputMeter = getOutMeterInfo(outProducttype, outMeter, outMetalstate, tval, wval, lval, apsProcessOperationOutMaterDo1.getThickoffset(), apsProcessOperationOutMaterDo1.getWidthoffset(), apsProcessOperationOutMaterDo.getLengthoffset()) + singlerollweight + UNIT_MAP.getOrDefault(apsProcessOperationDo.getNumunit(), "");
                        apsProcessOperationOutMaterDo1.setOutputmaterial(outputMeter + "*" + (planinrall * apsProcessOperationOutMaterDo1.getOutval()) + "卷");
                        planoutputList.add(outputMeter + "*" + (planinrall * apsProcessOperationOutMaterDo1.getOutval()) + "卷");
                        apsProcessOperationOutMaterDo1.setOutmaterrequest(outputMeter);
                        //输出成品
                        /*
                        如果没有后道工序作业，则成品卷数=计划输出卷数 - 计划备料卷数，
                        如果有后道工序作业，则成品卷数=计划成品卷数，
                        如果成品卷数=0，则自动填入=（空）
                        如果成品卷>0，则自动填入=“{输出物料的输入物料描述} * {成品卷数}卷”
                         */
                        String outputfinishproduct = "";
                        Integer planprodrollnum = 0;
                        if (StringUtils.isBlank(apsProcessOperationDo.getNextprocessid())) {
                            planprodrollnum = (planinrall * apsProcessOperationOutMaterDo1.getOutval()) - apsProcessOperationOutMaterDo1.getPlanstockrollnum();
                            //没有后道工序作业，计划成品卷数=计划输出卷数-计划备料卷数
                            apsProcessOperationOutMaterDo1.setPlanprodrollnum(apsProcessOperationOutMaterDo1.getPlanrollnum() - apsProcessOperationOutMaterDo1.getPlanstockrollnum());
                        } else {
                            planprodrollnum = apsProcessOperationOutMaterDo1.getPlanprodrollnum();
                        }
                        if (apsProcessOperationOutMaterDo1.getPlanprodrollnum() > 0) {
                            outputfinishproduct = getInMeterInfo(outProducttype, outMeter, outMetalstate, tval, wval, lval) + apsProcessOperationOutMaterDo1.getSinglerollweight() + UNIT_MAP.getOrDefault(apsProcessOperationOutMaterDo1.getNumunit(), "") + " * " + planprodrollnum + "卷";
                        }
                        apsProcessOperationOutMaterDo1.setOutputfinishproduct(outputfinishproduct);

                        apsProcessOperationOutMaterDoNewList.add(apsProcessOperationOutMaterDo1);
                        if (StringUtils.isNotBlank(apsProcessOperationDo.getNextprocessid())) {
                            operationOutMaterDos.add(apsProcessOperationOutMaterDo1);
                        }
                    }

                    StringBuffer planoutsb = new StringBuffer();
                    Collections.sort(planoutputList);
                    Integer outIndex = 1;
                    if (planoutputList.size() == 1) {
                        planoutsb.append("[1]" + planoutputList.get(0));
                    } else {
                        for (String planout : planoutputList) {
                            planoutsb.append("[" + outIndex + "]" + planout + "/n");
                            outIndex++;
                        }
                    }
                    apsProcessOperationDo.setPlanoutput(planoutsb.toString());
                    apsProcessOperationDo.setInputunqualifiedroll(apsProcessOperationOutMaterDo.getFailrollnum());

                    apsProcessOperationDoList.add(apsProcessOperationDo);
                }
            }

            boolean bool1 = false;
            boolean bool2 = false;
            if (apsProcessOperationDoList.size() > 0) {
                bool1 = apsProcessOperationService.saveOrUpdateBatch(apsProcessOperationDoList);
            }
            if (apsProcessOperationOutMaterDoNewList.size() > 0) {
                bool2 = apsProcessOperationOutMaterService.saveOrUpdateBatch(apsProcessOperationOutMaterDoNewList);
            }

            //更新状态
            CommonUpdateProductionStatusReq req = new CommonUpdateProductionStatusReq();
            req.setProcessOperationId(apsProcessOperationOutMaterDoList.get(0).getMainid());
            apsProcessOperationProcessEquService.updateProductionStatus(req);

            if (bool1 && bool2) {
                if (operationOutMaterDos.size() > 0) {
                    resetProcessOperation(operationOutMaterDos);
                }
                return R.ok();
            } else {
                log.info("更新后面所有工序信息异常");
                return R.error();
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("更新后面所有工序信息异常");
            return R.error();
        }
    }

    @Override
    @Transactional
    public R updateBorrowProcess(Map<String, Object> params) {
        String processId;
        try {
            processId = params.get("processId").toString();
        } catch (Exception e) {
            e.printStackTrace();
            return R.error("入参有误");
        }

        String orderId = "";

        //迭代更新当前工序作业及其所有后续工序
        orderId = updateProcessByProcessId(processId, orderId);

        //完成后更新生产状态
        CommonUpdateProductionStatusReq commonUpdateProductionStatusReq = new CommonUpdateProductionStatusReq();
        commonUpdateProductionStatusReq.setProcessOperationId(processId);
        apsProcessOperationProcessEquService.updateProductionStatus(commonUpdateProductionStatusReq);

        //更新订单的状态
        apsProductionOrderDao.changeOrderById(orderId);
        return R.ok();
    }

    /**
     * 工序作业备份
     *
     * @return
     */
    @Override
    public R backupProcessOperation() {
        SysUserVo currentUser = CXCommonUtils.getCurrentUser();
        ApsUtils.checkScheduling(currentUser);
        // 先删除
        ApsUtils.clearBackup(currentUser);
        List<ApsProcessOperationDo> apsProcessOperationDos = apsProcessOperationDao.selectList(
                new LambdaQueryWrapper<ApsProcessOperationDo>()
                        .in(ApsProcessOperationDo::getProcessstatus, "20"));
        // 再备份
        List<String> collect = apsProcessOperationDos.stream().map(ApsProcessOperationDo::getId).collect(Collectors.toList());
        apsProcessOperationBackupDao.processOperationBackup(collect,
                currentUser == null ? "" : currentUser.getId(),
                currentUser == null ? "" : currentUser.getName());
        apsProcessOperationProcessEquBackupDao.processOperationEquCopy(collect,
                currentUser == null ? "" : currentUser.getId(),
                currentUser == null ? "" : currentUser.getName());
        return R.ok();
    }

    /**
     * 工序作业恢复备份
     *
     * @return
     */
    @Override
    public R backupRestoreProcessOperation() {
        log.debug("开始恢复工序作业备份信息");
        SysUserVo currentUser = CXCommonUtils.getCurrentUser();
        ApsUtils.checkScheduling(currentUser);
        String factoryId = null;
        if (currentUser != null) {
            List<SysOrganizationVo> organizationDoList = currentUser.getOrganizationDoList();
            factoryId = organizationDoList.stream()
                    .filter(org -> MINUS_ONE.equals(org.getPid()))
                    .map(SysOrganizationDo::getId)
                    .distinct()
                    .collect(Collectors.joining(","));

            if (StringUtils.isBlank(factoryId)) {
                factoryId = organizationDoList.stream().map(info -> info.getFullpid().split(",")[1]).distinct()
                        .collect(Collectors.joining(","));
            }
        }
        List<ApsProcessOperationProcessEquBackupDo> apsProcessOperationProcessEquBackupDos = apsProcessOperationProcessEquBackupDao
                .selectList(new LambdaQueryWrapper<ApsProcessOperationProcessEquBackupDo>()
                        .eq(StringUtils.isNotBlank(factoryId), ApsProcessOperationProcessEquBackupDo::getTenantid, factoryId));
        List<ApsProcessOperationBackupDo> apsProcessOperationBackupDos = apsProcessOperationBackupDao.selectList(new LambdaQueryWrapper<ApsProcessOperationBackupDo>()
                .eq(StringUtils.isNotBlank(factoryId), ApsProcessOperationBackupDo::getTenantid, factoryId));
        List<ApsProcessOperationDo> saveList = new ArrayList<>();
        List<ApsProcessOperationProcessEquDo> equSaveList = new ArrayList<>();
        apsProcessOperationProcessEquBackupDos.forEach(data -> {
            ApsProcessOperationProcessEquDo equDo = new ApsProcessOperationProcessEquDo();
            BeanUtils.copyProperties(data, equDo);
            equSaveList.add(equDo);
        });
        apsProcessOperationBackupDos.forEach(data -> {
            ApsProcessOperationDo operationDo = new ApsProcessOperationDo();
            BeanUtils.copyProperties(data, operationDo);
            saveList.add(operationDo);
        });
        if (!saveList.isEmpty()) {
            apsProcessOperationService.saveOrUpdateBatch(saveList, 100);
        }
        if (!equSaveList.isEmpty()) {
            apsProcessOperationProcessEquService.saveOrUpdateBatch(equSaveList, 100);
        }
        return R.ok();
    }

    /**
     * 忽略冲突
     *
     * @param ids
     * @return
     */
    @Override
    public R cancelConflict(List<String> ids) {
        ApsUtils.checkScheduling(null);
        List<String> collect = ids.stream().filter(StringUtils::isNotBlank).collect(Collectors.toList());
        if (collect.isEmpty()) {
            log.error("参数异常");
            return R.error("参数异常");
        }
        List<ApsProcessOperationProcessEquDo> list = apsProcessOperationProcessEquService.list(new LambdaQueryWrapper<ApsProcessOperationProcessEquDo>()
                .in(ApsProcessOperationProcessEquDo::getProcessid, ids)
                .eq(BaseDo::getDeleted, "0"));
        if (list.isEmpty()) {
            log.error("无法根据工序作业ID:{} 获取到工序作业明细", ids);
            return R.error("无法找到工序作业明细");
        }
        list.forEach(info -> {
            info.setConflictdes("");
            if (StringUtils.isBlank(info.getConflictdes()) && StringUtils.isBlank(info.getSoftconflictdes())) {
                info.setHasconflict(LOCKMARK_N);
            } else {
                info.setHasconflict(LOCKMARK_Y);
            }
        });
        apsProcessOperationProcessEquService.updateBatchById(list);
        return R.ok();
    }

    /**
     * 坯料计划修改卷数和单卷重后，更新工序作业相关信息
     */
    @Override
    @Transactional
    public R updateProcess(Map<String, Object> params) {
        List<ApsProcessOperationOutMaterDo> operationOutMaterDos = new ArrayList<>();//递归的数据源
        JSONObject blanckdata = new JSONObject(params.get("BLANKDATA"));
        //首道工序
        Map<String, Object> map = new HashMap<>();
        map.put("BLANKID", blanckdata.getStr("ID"));
        map.put("PREVIOUSPROCESSID", null);
        ApsProcessOperationDo apsProcessOperationDo = apsProcessOperationService.listByMap(map).stream().findFirst().orElse(null);

        //首道工序输出
        Map<String, Object> outmap = new HashMap<>();
        outmap.put("BLANKID", blanckdata.getStr("ID"));
        outmap.put("MAINID", apsProcessOperationDo.getId());
//        List<ApsProcessOperationOutMaterDo> apsProcessOperationOutMaterDos =apsProcessOperationOutMaterService.listByMap(outmap).stream().collect(Collectors.toList());
        ApsProcessOperationOutMaterDo apsProcessOperationOutMaterDo = apsProcessOperationOutMaterService.listByMap(outmap).stream().findFirst().orElse(null);

        // 获取排程参数设置
        List<ApsScheduleConfigDo> apsConfigs = apsScheduleConfigService.list();
        BigDecimal aluminumdensity = apsConfigs.get(0).getAluminumdensity();

        //更新工序输入
        String meterInput = getInMeterInfo(blanckdata.getStr("PRODUCTTYPE"), blanckdata.getStr("ALLOY"), blanckdata.getStr("ALLOYSTATUS"), blanckdata.getBigDecimal("THICKNESS"), blanckdata.getBigDecimal("PROWIDTH"), blanckdata.getBigDecimal("PROLENGTH"));
        apsProcessOperationDo.setPlaninput(meterInput + blanckdata.getStr("SINGLEROLLWEIGHT") + UNIT_MAP.getOrDefault(blanckdata.getStr("NUMBERUNIT"), ""));
        apsProcessOperationDo.setProducttypeid(blanckdata.getStr("PRODUCTTYPEID"));
        apsProcessOperationDo.setProducttype(blanckdata.getStr("PRODUCTTYPE"));
        apsProcessOperationDo.setMetal(blanckdata.getStr("ALLOY"));
        apsProcessOperationDo.setMetalstate(blanckdata.getStr("ALLOYSTATUS"));
        apsProcessOperationDo.setThickness(blanckdata.getBigDecimal("THICKNESS"));
        apsProcessOperationDo.setProwidth(blanckdata.getBigDecimal("PROWIDTH"));
        apsProcessOperationDo.setProlength(blanckdata.getBigDecimal("PROLENGTH"));
        Integer rollnum = blanckdata.getInt("ROLLNUM");
        BigDecimal singlerollweight = blanckdata.getBigDecimal("SINGLEROLLWEIGHT");
        apsProcessOperationDo.setSinglerollweight(singlerollweight);
        apsProcessOperationDo.setPlaninrall(rollnum);
        apsProcessOperationDo.setPlanprocessrall(rollnum);
        apsProcessOperationDo.setUnfinishroll(rollnum - apsProcessOperationDo.getReportroll());

        if (!apsProcessOperationDo.getProcessway().equals("合并加工")) {
            BigDecimal loadingmin = apsProcessOperationDo.getLoadingmin() == null ? BigDecimal.valueOf(0) : apsProcessOperationDo.getLoadingmin();
            BigDecimal cuttingmin = apsProcessOperationDo.getCuttingmin() == null ? BigDecimal.valueOf(0) : apsProcessOperationDo.getCuttingmin();
            if (apsProcessOperationDo.getTimeway().equals("10")) {
                //如果计时方式=按设备运转速度计时，计划作业时长=计划加工卷数*(上料时长+下料时长+(输入单卷重/（输入物料宽度/1000*输入物料厚度/1000*设备运转速度/1000*铝的密度）))
                BigDecimal prowidth = apsProcessOperationDo.getProwidth() == null ? BigDecimal.valueOf(1) : apsProcessOperationDo.getProwidth();
                BigDecimal thickness = apsProcessOperationDo.getThickness() == null ? BigDecimal.valueOf(1) : apsProcessOperationDo.getThickness();
                BigDecimal workspeed = apsProcessOperationDo.getWorkspeed() == null ? BigDecimal.valueOf(1) : apsProcessOperationDo.getWorkspeed();
                BigDecimal onceprocessmin = new BigDecimal(df.format(loadingmin.add(cuttingmin).add(singlerollweight.multiply(BigDecimal.valueOf(1000000000)).divide(prowidth.multiply(thickness).multiply(workspeed).multiply(aluminumdensity), 2, BigDecimal.ROUND_HALF_UP))));
                apsProcessOperationDo.setOnceprocessmin(onceprocessmin);
                apsProcessOperationDo.setProcesstotaltime(new BigDecimal(df.format(BigDecimal.valueOf(apsProcessOperationDo.getPlanprocessrall()).multiply(onceprocessmin))));
            } else if (apsProcessOperationDo.getTimeway().equals("40")) {
                //如果计时方式=按单次加工时长计时，计划作业时长=(上料时长+下料时长+单次加工时长)*计划加工卷数
                apsProcessOperationDo.setProcesstotaltime(new BigDecimal(df.format(loadingmin.add(cuttingmin).add(apsProcessOperationDo.getOnceprocessmin()).multiply(BigDecimal.valueOf(rollnum)))));
            }
        }

        //更新工序输出
        String outProducttype = apsProcessOperationOutMaterDo.getProducttype();
        if (apsProcessOperationOutMaterDo.getProducttyperule().equals("不变")) {
            outProducttype = blanckdata.getStr("PRODUCTTYPE") == null ? "" : blanckdata.getStr("PRODUCTTYPE");
            apsProcessOperationOutMaterDo.setProducttypeid(blanckdata.getStr("PRODUCTTYPEID") == null ? "" : blanckdata.getStr("PRODUCTTYPEID"));
            apsProcessOperationOutMaterDo.setProducttype(outProducttype);
        }
        String outMeter = apsProcessOperationOutMaterDo.getMetal();
        if (apsProcessOperationOutMaterDo.getMetalrule().equals("不变")) {
            outMeter = blanckdata.getStr("ALLOY") == null ? "" : blanckdata.getStr("ALLOY");
            apsProcessOperationOutMaterDo.setMetal(outMeter);
        }
        String outMetalstate = apsProcessOperationOutMaterDo.getMetalstate();
        if (apsProcessOperationOutMaterDo.getMetalstaterule().equals("不变")) {
            outMetalstate = blanckdata.getStr("ALLOYSTATUS") == null ? "" : blanckdata.getStr("ALLOYSTATUS");
            apsProcessOperationOutMaterDo.setMetalstate(outMetalstate);
        }
        BigDecimal tval = changeSize(blanckdata.getBigDecimal("THICKNESS"), apsProcessOperationOutMaterDo.getThickrule(), apsProcessOperationOutMaterDo.getThickchange(), apsProcessOperationOutMaterDo.getThickness());
        apsProcessOperationOutMaterDo.setThickness(tval);
        BigDecimal wval = changeSize(blanckdata.getBigDecimal("PROWIDTH"), apsProcessOperationOutMaterDo.getWidthrule(), apsProcessOperationOutMaterDo.getWidthchange(), apsProcessOperationOutMaterDo.getProwidth());
        apsProcessOperationOutMaterDo.setProwidth(wval);
        BigDecimal lval = changeSize(blanckdata.getBigDecimal("PROLENGTH"), apsProcessOperationOutMaterDo.getLengthrule(), apsProcessOperationOutMaterDo.getLengthchange(), apsProcessOperationOutMaterDo.getProlength());
        apsProcessOperationOutMaterDo.setProlength(lval);
        apsProcessOperationOutMaterDo.setPlanrollnum(rollnum);
        //输入单卷重*输出宽度/输入宽度
        String outsinglerollweight = df.format(singlerollweight.multiply(apsProcessOperationOutMaterDo.getProwidth() == null ? BigDecimal.valueOf(1) : apsProcessOperationOutMaterDo.getProwidth()).divide(apsProcessOperationDo.getProwidth() == null ? BigDecimal.valueOf(1) : apsProcessOperationDo.getProwidth(), 3, BigDecimal.ROUND_HALF_UP));
        apsProcessOperationOutMaterDo.setSinglerollweight(new BigDecimal(outsinglerollweight));
        //输出物料
        String outputMeter = getOutMeterInfo(apsProcessOperationOutMaterDo.getProducttype(), apsProcessOperationOutMaterDo.getMetal(), apsProcessOperationOutMaterDo.getMetalstate(), apsProcessOperationOutMaterDo.getThickness(), apsProcessOperationOutMaterDo.getProwidth(), apsProcessOperationOutMaterDo.getProlength(), apsProcessOperationOutMaterDo.getThickoffset(), apsProcessOperationOutMaterDo.getWidthoffset(), apsProcessOperationOutMaterDo.getLengthoffset()) + singlerollweight + UNIT_MAP.getOrDefault(apsProcessOperationOutMaterDo.getNumunit(), "");
        apsProcessOperationOutMaterDo.setOutputmaterial(outputMeter + "*" + rollnum + "卷");
        apsProcessOperationDo.setPlanoutput("[1]" + outputMeter + "*" + rollnum + "卷");
        //输出成品
                        /*
                        如果没有后道工序作业，则成品卷数=计划输出卷数 - 计划备料卷数，
                        如果有后道工序作业，则成品卷数=计划成品卷数，
                        如果成品卷数=0，则自动填入=（空）
                        如果成品卷>0，则自动填入=“{输出物料的输入物料描述} * {成品卷数}卷”
                         */
        String outputfinishproduct = "";
        if (StringUtils.isBlank(apsProcessOperationDo.getNextprocessid())) {
            //如果没有后道工序作业，则自动填入=“{输出物料的输入物料描述} * {计划输出卷数 - 计划备料卷数}卷”
            outputfinishproduct = getInMeterInfo(apsProcessOperationOutMaterDo.getProducttype(), apsProcessOperationOutMaterDo.getMetal(), apsProcessOperationOutMaterDo.getMetalstate(), apsProcessOperationOutMaterDo.getThickness(), apsProcessOperationOutMaterDo.getProwidth(), apsProcessOperationOutMaterDo.getProlength()) + apsProcessOperationOutMaterDo.getSinglerollweight() + UNIT_MAP.getOrDefault(apsProcessOperationOutMaterDo.getNumunit(), "") + " * " + rollnum + "卷";
            apsProcessOperationOutMaterDo.setPlanprodrollnum(rollnum);
        }
        if (apsProcessOperationOutMaterDo.getPlanprodrollnum() > 0) {
            apsProcessOperationOutMaterDo.setOutputfinishproduct(outputfinishproduct);
        }
        apsProcessOperationOutMaterDo.setOutmaterrequest(outputMeter);

        if (StringUtils.isNotBlank(apsProcessOperationDo.getNextprocessid())) {
            operationOutMaterDos.add(apsProcessOperationOutMaterDo);
        }

        boolean bool1 = apsProcessOperationService.saveOrUpdate(apsProcessOperationDo);
        boolean bool2 = apsProcessOperationOutMaterService.saveOrUpdate(apsProcessOperationOutMaterDo);
        if (bool1 && bool2) {
            if (operationOutMaterDos.size() > 0) {
                resetProcessOperation(operationOutMaterDos);
            }
            return R.ok();
        } else {
            return R.error();
        }
    }

    //根据工序ID更新，明细和工序的状态
    private String updateProcessByProcessId(String processId, String orderId) {
        //=============迭代开始，更新当前工序及其明细==================

        //查询当前工序作业详情
        ApsProcessOperationDo apsProcessOperationDo = apsProcessOperationService.getById(processId);

        if (ObjectUtil.isEmpty(orderId)) {
            //工序作业所属坯料计划
            String blankid = apsProcessOperationDo.getBlankid();
            //查询坯料计划的所属订单ID
            ApsBlankOrderDo apsBlankOrderDo = apsBlankOrderService.getById(blankid);
            orderId = apsBlankOrderDo.getProductionorderid();
        }


        ApsProcessOperationDo previousProcessOperation = null;
        if (ObjectUtil.isNotEmpty(apsProcessOperationDo.getPreviousprocessid())) {
            //查询上道工序作业详情
            previousProcessOperation = apsProcessOperationService.getById(apsProcessOperationDo.getPreviousprocessid());
        }


        //查询当前工序的所有作业明细
        List<ApsProcessOperationProcessEquDo> list = apsProcessOperationProcessEquService.list(new QueryWrapper<ApsProcessOperationProcessEquDo>().lambda().eq(ApsProcessOperationProcessEquDo::getProcessid, processId));

        //所有需要更新的工序作业明细
        List<ApsProcessOperationProcessEquDo> needUpdateProcessEquList = new LinkedList<>();

        //获取任一作业明细的ID，用于更新工序作业
        String processOperationProcessEquId = "";
        //遍历作业明细
        for (ApsProcessOperationProcessEquDo apsProcessOperationProcessEquDo : list) {
            if (ObjectUtil.isEmpty(processOperationProcessEquId)) {
                processOperationProcessEquId = apsProcessOperationProcessEquDo.getId();
            }


            //创建待更新对象
            ApsProcessOperationProcessEquDo needUpdate = new ApsProcessOperationProcessEquDo();
            needUpdate.setId(apsProcessOperationProcessEquDo.getId());

            /**
             * 完工状态
             * 如果未完工卷数=0，
             * 或者（有上道工序作业，并且上道工序作业已完工状态=已完工，并且作业明细待加工料卷批次号数量-工序作业已取消卷数<=0，并且已开工卷数=已检验卷数），则=已完工
             * 如果未完工卷数>0，并且（没有上道工序作业，或者上道工序作业已完工状态=未完工，或者作业明细待加工料卷批次号数量-工序作业已取消卷数>0，或者已开工卷数不等于已检验卷数），则=未完工
             */
            //先判断未完工卷数

            Integer unfinishroll = apsProcessOperationProcessEquDo.getUnfinishroll();
            if (ObjectUtil.isEmpty(unfinishroll)) {
                needUpdate.setClosestatus("未完工");
            }
            if (ObjectUtil.isNotEmpty(unfinishroll) && unfinishroll == 0) {
                needUpdate.setClosestatus("已完工");
            }
            //有上道工序作业 && 上道工序作业已完工状态=已完工 && 作业明细待加工料卷批次号数量-工序作业已取消卷数<=0 && 已开工卷数=已检验卷数
            if (ObjectUtil.isNotEmpty(apsProcessOperationDo.getPreviousprocessid())
                    && (ObjectUtil.isNotEmpty(previousProcessOperation) && previousProcessOperation.getClosestatus().equals("已完工"))
                    && (ObjectUtil.isNotEmpty(apsProcessOperationProcessEquDo.getBachmaterialprocess()) && (apsProcessOperationProcessEquDo.getBachmaterialprocess().split(",").length - apsProcessOperationDo.getCancelroll()) <= 0)
                    && apsProcessOperationProcessEquDo.getStartingroll().equals(apsProcessOperationProcessEquDo.getCheckoutroll())) {
                needUpdate.setClosestatus("已完工");
            }
            if (ObjectUtil.isNotEmpty(unfinishroll) && unfinishroll > 0) {
                //没有上道工序作业 || 上道工序作业已完工状态=未完工 || 作业明细待加工料卷批次号数量-工序作业已取消卷数>0 || 已开工卷数不等于已检验卷数
                if (ObjectUtil.isEmpty(apsProcessOperationDo.getPreviousprocessid())
                        || (ObjectUtil.isNotEmpty(previousProcessOperation) && previousProcessOperation.getClosestatus().equals("未完工"))
                        || (ObjectUtil.isNotEmpty(apsProcessOperationProcessEquDo.getBachmaterialprocess()) && (apsProcessOperationProcessEquDo.getBachmaterialprocess().split(",").length - apsProcessOperationDo.getCancelroll()) > 0)
                        || !apsProcessOperationProcessEquDo.getStartingroll().equals(apsProcessOperationProcessEquDo.getCheckoutroll())) {
                    needUpdate.setClosestatus("未完工");
                }
            }

            //作业状态
            /**
             * 如果已开工卷数=0，则=待开工；
             * 如果已开工卷数>0，并且完工状态=未完工，则=加工中；（先更新完工状态）
             * 如果未完工卷数=0，并且完工状态=已完工，则=已完工（先更新完工状态）
             */
            if (apsProcessOperationProcessEquDo.getStartingroll() == 0) {
                needUpdate.setWorkstatus("待开工");
            }
            if (apsProcessOperationProcessEquDo.getStartingroll() > 0 && needUpdate.getClosestatus().equals("未完工")) {
                needUpdate.setWorkstatus("加工中");
            }
            if (ObjectUtil.isNotEmpty(unfinishroll) && unfinishroll == 0 && needUpdate.getClosestatus().equals("已完工")) {
                needUpdate.setWorkstatus("已完工");
            }

            needUpdateProcessEquList.add(needUpdate);

        }
        //更新
        if (needUpdateProcessEquList.size() > 0) {
            apsProcessOperationProcessEquService.updateBatchById(needUpdateProcessEquList);
        }
        //================作业明细更新完毕===================

        if (ObjectUtil.isNotEmpty(processOperationProcessEquId)) {
            //更新工序作业
            apsProcessOperationProcessEquService.updateProcessByProcessEquId(processOperationProcessEquId);
        }

        //===============当前工序及其明细更新完毕===============
        //===============判断是否存在下道工序，如果有，则继续更新工序，开始迭代，没有则结束迭代=================
        if (ObjectUtil.isNotEmpty(apsProcessOperationDo.getNextprocessid())) {
            String[] nextProcessIdList = apsProcessOperationDo.getNextprocessid().split(",");
            for (String nextProcessId : nextProcessIdList) {
                updateProcessByProcessId(nextProcessId, orderId);
            }
        }
        return orderId;
    }

    /*
    工艺步骤管理/输入物料描述
     */
    private String getInMeterInfo(String producttype, String metal, String metalstate, BigDecimal thickness, BigDecimal prowidth, BigDecimal prolength) {
        String res = "";
        StringBuilder resStr = new StringBuilder();
        StringBuilder resSizeStr = new StringBuilder();
        if (StringUtils.isNotBlank(metal)) {
            resStr.append(metal);
        }
        if (StringUtils.isNotBlank(metalstate)) {
            resStr.append(metalstate);
        }
        if (StringUtils.isNotBlank(producttype)) {
            resStr.append(producttype);
        }
        if (thickness != null) {
            resSizeStr.append("厚" + df.format(thickness) + "*");
        }
        if (prowidth != null) {
            resSizeStr.append("宽" + df.format(prowidth) + "*");
        }
        if (prolength != null) {
            resSizeStr.append("长" + df.format(prolength) + "*");
        }

        if (StringUtils.isBlank(resSizeStr.toString())) {
            res = resStr.toString();
        } else {
            res = (StringUtils.isBlank(resStr.toString()) ? "" : (resStr.toString() + " ")) + resSizeStr.toString().substring(0, resSizeStr.toString().length() - 1) + "mm";
        }

        return res + " ";
    }

    /*
    工艺步骤管理/输出物料描述
     */
    private String getOutMeterInfo(String producttype, String metal, String metalstate, BigDecimal thickness, BigDecimal prowidth, BigDecimal prolength, String thickoffset, String widthoffset, String lengthoffset) {
        String res = "";
        StringBuilder resStr = new StringBuilder();
        StringBuilder resSizeStr = new StringBuilder();
        if (StringUtils.isNotBlank(metal)) {
            resStr.append(metal);
        }
        if (StringUtils.isNotBlank(metalstate)) {
            resStr.append(metalstate);
        }
        if (StringUtils.isNotBlank(producttype)) {
            resStr.append(producttype);
        }
        if (thickness != null) {
            resSizeStr.append("厚" + df.format(thickness) + (thickoffset == null ? "" : thickoffset) + "*");
        }
        if (prowidth != null) {
            resSizeStr.append("宽" + df.format(prowidth) + (widthoffset == null ? "" : widthoffset) + "*");
        }
        if (prolength != null) {
            resSizeStr.append("长" + df.format(prolength) + (lengthoffset == null ? "" : lengthoffset) + "*");
        }

        if (StringUtils.isBlank(resSizeStr.toString())) {
            res = resStr.toString();
        } else {
            res = (StringUtils.isBlank(resStr.toString()) ? "" : (resStr.toString() + " ")) + resSizeStr.toString().substring(0, resSizeStr.toString().length() - 1) + "mm";
        }

        return res + " ";
    }

    /*
    长宽高的计算规则
     */
    private BigDecimal changeSize(BigDecimal oldVal, String countRule, BigDecimal changeVal, BigDecimal curVal) {
        BigDecimal newVal = null;
        if (!StringUtils.isNotBlank(countRule)) {
            return oldVal;
        }
        if (!countRule.equals("自定义") && oldVal != null) {
            if (countRule.equals("=")) {
                newVal = changeVal;
            } else if (countRule.equals("+")) {
                newVal = oldVal.add(changeVal);
            } else if (countRule.equals("-")) {
                newVal = oldVal.subtract(changeVal);
            } else if (countRule.equals("0")) {
                newVal = oldVal;
            }
        }
        if (countRule.equals("自定义")) {
            newVal = curVal;
        }
        return newVal;
    }

    /*
    获取可选设备IDS
     */
    private String getChooseequids(List<String> equIds, List<String> equGroupIds) {
        //资源组下所有的设备IDS
        if (equGroupIds.size() > 0) {
            List<Map<String, Object>> equGroupIdList = apsProcessOperationDao.getEquGroupIds();
            for (String groupid : equGroupIds) {
                List<Map<String, Object>> equGroupIds1 = equGroupIdList.stream().filter(equgroup -> equgroup.get("MAINID").toString().equals(groupid)).collect(Collectors.toList());
                if (equGroupIds1.size() > 0) {
                    String equIdStr = equGroupIds1.get(0).get("EQUIDS").toString();
                    for (String equid : Arrays.asList(equIdStr.split(","))) {
                        if (!equIds.contains(equid)) {
                            equIds.add(equid);
                        }
                    }
                }
            }
        }
        return String.join(",", equIds);
    }
}
