package com.sw.mes.yb.production.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.sw.mes.base.global.GlobalSwitch;
import com.sw.mes.base.global.GlobalSwitchNamespace;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.entity.SysLog;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.base.system.service.SysLogService;
import com.sw.mes.core.annotation.ServiceLogs;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.constant.ScheduleConstants;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.enums.SeedMassageEnum;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.utils.IpUtils;
import com.sw.mes.dingTalk.service.DingTalkService;
import com.sw.mes.inspect.entity.YbInspectData;
import com.sw.mes.inspect.service.YbInspectDataService;
import com.sw.mes.mmcs.service.MMcsInterfaceService;
import com.sw.mes.mqtt.service.NotificationService;
import com.sw.mes.quartz.entity.SysJob;
import com.sw.mes.quartz.service.SysJobService;
import com.sw.mes.quartz.util.CronUtils;
import com.sw.mes.yb.ipc.service.impl.MaterialOperationClickServiceImpl;
import com.sw.mes.yb.mcs.service.YbMesToMcsService;
import com.sw.mes.yb.production.dao.AgainTaskDao;
import com.sw.mes.yb.production.dto.AgainTask.AgainTaskDto;
import com.sw.mes.yb.production.dto.AgainTask.ConfirmWeightDto;
import com.sw.mes.yb.production.dto.AgainTaskDetail.AgainTaskDetailDto;
import com.sw.mes.yb.production.dto.AlloyWeightDto;
import com.sw.mes.yb.production.dto.MeasuringTheAlloyDto;
import com.sw.mes.yb.production.entity.*;
import com.sw.mes.yb.production.notification.AgainTaskMessage;
import com.sw.mes.yb.production.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.*;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.*;


/**
 * @Author 李儒
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@Service
@Transactional
public class AgainTaskServiceImpl extends BaseServiceImpl<AgainTask> implements AgainTaskService {
    AgainTaskDao dao;

    @Autowired
    private AgainTaskDetailService againTaskDetailService;

    @Autowired
    private DictionaryItemService dictionaryItemService;

    @Autowired
    private NotificationService notificationService;

    @Autowired
    private SysJobService sysJobService;
    @Autowired
    private WeightInputDetailService weightInputDetailService;

    @Autowired
    @Lazy
    private LongCrystalService longCrystalService;

    @Value("${rms.url}")
    public String url;

    @Value("${fls.url}")
    public String furl;

    @Autowired
    @Lazy
    private InputFurnaceDetailService inputFurnaceDetailService;

    @Autowired
    private ProductionResistivityService productionResistivityService;
    //
    @Autowired
    @Lazy
    private YbInspectDataService inspectDataBaseService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private SysLogService sysLogService;

    @Autowired
    private LoadingTaskService loadingTaskService;

    @Autowired
    private BlastFurnaceDetailService blastFurnaceDetailService;

    @Autowired
    @Lazy
    private MMcsInterfaceService mMcsInterfaceService;

    @Autowired
    private  DingTalkService dingTalkService;

    @Autowired
    private YbMesToMcsService mesToMcsService;

    @Autowired
    public void setDao(AgainTaskDao dao) {
        super.setBaseDao(dao);
        this.dao = dao;
    }


    @Override
    public void saveOrUpdate(AgainTask againTask) {
        super.saveOrUpdate(againTask);
//        ThreadManager.getThreadPollProxy().execute(new Runnable() {
//            @Override
//            public void run() {
//                test(againTask);
//            }
//        });

    }

    @ServiceLogs(description = "配合金数据下发")
    public void test(AgainTask againTask) {
        if ((againTask.getRawStatus() == 3 || againTask.getRawStatus() == 4)) {
            MeasuringTheAlloyDto measuringTheAlloyDto = new MeasuringTheAlloyDto();
            List<BlastFurnaceDetail> blastFurnaceDetailList = new ArrayList<>();
//            List<Map<String, String>> list = new ArrayList<>();
            //初始复投需要查询初始装料记录
            if (againTask.getRawType() == 1) {
                //根据炉次号查询配料任务表
                List<LoadingTask> loadingTasks = loadingTaskService.findByLotNo(againTask.getLotNo());
                //根据配料任务ID查询配料明细
                if (null != loadingTasks && loadingTasks.size() > 0) {
                    Long id = loadingTasks.get(0).getId();
                    blastFurnaceDetailList = blastFurnaceDetailService.getBlastFurnaceDetailList(id);
                }
            }
            //根据设备号查询目标电阻率及小头电阻率
            List<ProductionResistivity> resistivity = getResistivity(againTask.getEquipmentCode());
            //根据复投次数确定目标电阻率及小头电阻率
            ProductionResistivity selectResistivity = getSelectResistivity(resistivity, againTask);
            //根据炉次号查询补掺镓量  t_temp_radial_centre检验数据库中最新01段的头中心补偿电阻率
            String tTempRadialCentre = getTRadialCentre(againTask);
            //根据复投任务ID查询完工的灌料任务
            List<AgainTaskDetail> againTaskDetailList = getAgainTaskDetail(againTask.getId());
            //根据灌料任务ID查询灌料明细
            List<InputFurnaceDetail> materialDetailList = getMaterialDetailed(againTaskDetailList);

            Map[] ararys = new Map[materialDetailList.size() + blastFurnaceDetailList.size()];
            if (null != materialDetailList && materialDetailList.size() > 0) {

                for (int i = 0; i < materialDetailList.size(); i++) {
                    InputFurnaceDetail inputFurnaceDetail = materialDetailList.get(i);

                    Map<String, Object> map1 = new HashMap<>();
                    map1.put(inputFurnaceDetail.getMaterialName() + "|" + inputFurnaceDetail.getProductCode(), inputFurnaceDetail.getWeight());
                    ararys[i] = map1;
                }
                if (null != blastFurnaceDetailList && blastFurnaceDetailList.size() > 0) {
                    for (int i = materialDetailList.size(); i < materialDetailList.size() + blastFurnaceDetailList.size(); i++) {
                        BlastFurnaceDetail blastFurnaceDetail = blastFurnaceDetailList.get(i - materialDetailList.size());
                        Map<String, Object> map1 = new HashMap<>();
                        map1.put(blastFurnaceDetail.getMaterialName() + "|" + blastFurnaceDetail.getProductCode(), blastFurnaceDetail.getWeight());
                        ararys[i] = map1;
                    }
                }
            }

            measuringTheAlloyDto.setHeats(againTask.getLotNo());
            measuringTheAlloyDto.setMonth(againTaskDetailList.get(0).getRawCreate().toString().substring(5, 7));
            if (againTask.getDopant().equals("G")) {
                measuringTheAlloyDto.setRawMaterial("掺镓");
            } else if (againTask.getDopant().equals("X")) {
                measuringTheAlloyDto.setRawMaterial("U料");
            } else if (againTask.getDopant().equals("P")) {
                measuringTheAlloyDto.setRawMaterial("掺磷");
            } else {
                measuringTheAlloyDto.setRawMaterial("掺硼");
            }
            if (againTask.getSpecs().equals("295")) {
                measuringTheAlloyDto.setSpec("G12");
            }
//            //根据设备编号查询此设备对应的热场
//            String specs = null;
//            List<EquipmentAccessory> equipmentAccessories = equipmentAccessoryService.findByDeviceCode(againTask.getEquipmentCode());
//            if(null!=equipmentAccessories&&equipmentAccessories.size()>0){
//                for (EquipmentAccessory equipmentAccessory : equipmentAccessories) {
//                    String name = equipmentAccessory.getMaterial().getName();
//                    if(name.contains("炭炭坩埚")){
//                        specs = equipmentAccessory.getMaterial().getNorms();
//                        break;
//                    }
//                }
//            }

//            if (specs.contains("36")) {
                measuringTheAlloyDto.setThermalFieldType("680");
                measuringTheAlloyDto.setMaxWeight("920KG");
//            } else {
//                measuringTheAlloyDto.setThermalFieldType("750");
//                measuringTheAlloyDto.setMaxWeight("1050KG");
//            }
            measuringTheAlloyDto.setFurnaceType("160S");
            measuringTheAlloyDto.setRecastNum(String.valueOf(againTask.getAgainNum()));
            measuringTheAlloyDto.setRemaining(String.valueOf(againTask.getSurplusWeigth()));
            measuringTheAlloyDto.setGalliumAddition(tTempRadialCentre);
            if (null != selectResistivity) {
                measuringTheAlloyDto.setTargetResistivity(selectResistivity.getTargetResistivity());
                measuringTheAlloyDto.setLastTargetResistivity(selectResistivity.getLastTargetResistivity());
            }
            measuringTheAlloyDto.setMaterial(JSON.toJSONString(ararys));
            //给RMS下发数据
            JSONObject jsonObject = sendToRms(measuringTheAlloyDto);
            Integer status = jsonObject.getInteger("status");
            JSONObject jsonObject1 = jsonObject.getJSONObject("result");
            String content = JSON.toJSONString(measuringTheAlloyDto);
            String result = JSON.toJSONString(jsonObject);
            String name = "MES->RMS下发配合金数据接口";
            saveSysLog(status, "RMS", content, result, name, url);
            if (null != jsonObject1) {
                double res = jsonObject1.getDoubleValue("res");
                String alloyWeight = String.valueOf(res);
                //给FLS下发配合金数据
                sendToFls(alloyWeight, measuringTheAlloyDto.getRawMaterial(), measuringTheAlloyDto.getHeats());
            }
        }
    }

    private void saveSysLog(Integer status, String system, String content, String result, String name, String url) {
        SysLog syslog = new SysLog();
        syslog.setCreateTime(new Date());
        if (null != status && status == 200 && url.contains("http://10.221.237.173:8080/")) {
            syslog.setType("info");
        } else if (null != status && status == 100 && url.contains("http://10.221.237.143:8082/")) {
            syslog.setType("info");
        } else {
            syslog.setType("error");
        }
        syslog.setCreateUserId(BaseContextHandler.getUserID());
        syslog.setCreateUserName(system);
        syslog.setContent(JSON.toJSONString(content));
        syslog.setResult(result);
        syslog.setCreateUserId(-1);
        syslog.setStatus(status);
        syslog.setName(name);
        syslog.setServerAddr(url);
        syslog.setReqType("POST");
        syslog.setReqIp(IpUtils.getLocalIP());
        sysLogService.save(syslog);
    }

    private List<AgainTaskDetail> getAgainTaskDetail(Long Id) {
        List<AgainTaskDetail> byAgainTaskId = againTaskDetailService.findByAgainTaskId(Id);
        return byAgainTaskId;
    }

    private List<InputFurnaceDetail> getMaterialDetailed(List<AgainTaskDetail> againTaskDetailList) {
        if (null != againTaskDetailList && againTaskDetailList.size() > 0) {
            for (AgainTaskDetail againTaskDetail : againTaskDetailList) {
                List<InputFurnaceDetail> byAgainTaskDetailId = inputFurnaceDetailService.findByAgainTaskDetailId(againTaskDetail.getId());
                return byAgainTaskDetailId;
            }
        }
        return null;
    }

    private List<ProductionResistivity> getResistivity(String equipmentCode) {
        List<ProductionResistivity> productionResistivityList = productionResistivityService.findByEquipmentCode(equipmentCode);
        return productionResistivityList;
    }

    private ProductionResistivity getSelectResistivity(List<ProductionResistivity> resistivity, AgainTask againTask) {
        if (null != resistivity && resistivity.size() > 0) {
            for (ProductionResistivity productionResistivity : resistivity) {
                if (null == productionResistivity.getAgainNum()) {
                    return productionResistivity;
                }
                if (null != productionResistivity && productionResistivity.getAgainNum().contains(String.valueOf(againTask.getAgainNum()))) {
                    return productionResistivity;
                }
            }
        }
        return null;
    }

    //美科暂时无用
    private String getTRadialCentre(AgainTask againTask) {
        List<YbInspectData> inspectDataBaseList = inspectDataBaseService.findByLotNo(againTask.getLotNo());
        inspectDataBaseList.sort(Comparator.comparing(YbInspectData::getCreateTime).reversed());
        if (null != inspectDataBaseList && inspectDataBaseList.size() > 0) {
            for (YbInspectData inspectDataBase : inspectDataBaseList) {
                if (inspectDataBase.getSectionNo().length() >= 22 && inspectDataBase.getSectionNo().substring(21).equals("1")) {
                    if (null != inspectDataBase.getTRadialCentre()) {
                        return String.valueOf(inspectDataBase.getTRadialCentre());
                    }
                    return null;
                }
            }
        }
        return null;
    }


    private JSONObject sendToRms(MeasuringTheAlloyDto measuringTheAlloyDto) {
        String data = JSON.toJSONString(measuringTheAlloyDto);
        String rmsUrl = url + "resistivity/calculation";
        JSONObject jsonObject = send(data, rmsUrl);
        return jsonObject;
    }


    private JSONObject send(String data, String url) {
        HttpHeaders headers = new HttpHeaders();
        MediaType mediaType = MediaType.parseMediaType("application/json; charset=UTF-8");
        headers.setContentType(mediaType);
        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
        HttpEntity<String> httpEntity = new HttpEntity<>(data, headers);
        ((SimpleClientHttpRequestFactory) restTemplate.getRequestFactory()).setReadTimeout(60000);
        //使用exchange请求接口
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
        String body = exchange.getBody();
        JSONObject jsonObject = JSONObject.parseObject(body);
        return jsonObject;
    }


    public void sendToFls(String alloyWeight, String alloyType, String deviceNo) {
        AlloyWeightDto alloyWeightDto = new AlloyWeightDto();
        Date date = new Date();
        String code = String.valueOf(date.getTime());
        alloyWeightDto.setTaskCode(code);
        alloyWeightDto.setAlloyType(alloyType);
        alloyWeightDto.setDeviceNo(deviceNo);
        alloyWeightDto.setAlloyWeight(alloyWeight);
        String flsUrl = furl + "mes/sendAlloyInfo";
        String data = JSON.toJSONString(alloyWeightDto);
        JSONObject jsonObject = send(data, flsUrl);

        Integer status = jsonObject.getInteger("code");
        String content = JSON.toJSONString(alloyWeightDto);
        String result = JSON.toJSONString(jsonObject);
        String name = "MES->FLS下发配合金数据";
        saveSysLog(status, "FLS", content, result, name, furl);
    }


    @Override
    public void createChildTask(AgainTask entity, ConfirmWeightDto dto, Integer tongNum, Integer carrierNum) throws Exception {
        BeanUtils.copyProperties(dto, entity, "series");

        Date currentDate = new Date();

        entity.setAgainPailNum(tongNum);
        entity.setOperationTime(currentDate);
        entity.setCarrierNum(carrierNum);
        // 是否完结加料
        if(null != dto.getIsFillEnd()){
            entity.setIsFillEnd(dto.getIsFillEnd());
        }

        //每车投料时间间隔
        int feedingTaskTime = getDicMinuteTime("FeedingTask", "每车投料时间间隔", 60);
        //todo 投料时间间隔优化
        String equipmentCode = entity.getEquipmentCode();
        List<LongCrystal> byEquipmentCode = longCrystalService.findByEquipmentCode(equipmentCode);
        if(null != byEquipmentCode && byEquipmentCode.size() > 0){
            LongCrystal longCrystal = byEquipmentCode.get(0);
            String windUp = longCrystal.getWindUp();
            if(windUp.equals("N1")){
                feedingTaskTime = feedingTaskTime - 30;
            }
        }
        //任务延时时间
        int delayTime = getDicMinuteTime("DelayTime", "复投车时间间隔", 30);

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(currentDate);


        Calendar delayCalendar = Calendar.getInstance();
        delayCalendar.setTime(currentDate);

        long preDetailId = 0;

        // 创建桶的子任务
        Map<Integer, Integer> splittings = dto.getSplittings();
        for (int i = 1; i <= carrierNum; i++) {
            Integer one_weight = splittings.get(i * 2 - 1);
            Integer two_weight = splittings.get(i * 2);

            String pailNum = (i * 2 - 1) + "";
            int againWeigth = one_weight;
            String taskWeigths = one_weight + "";
            int count = 1;
            if (two_weight != null) {
                pailNum += "," + (i * 2);
                againWeigth += two_weight;
                taskWeigths += "," + two_weight;
                count += 1;
            }

            AgainTaskDetail child = new AgainTaskDetail();
            child.setFurnaceType(entity.getFurnaceType());
            child.setAgainTaskId(entity.getId());
            child.setAgainPailNum(entity.getAgainPailNum());
            child.setEquipmentCode(entity.getEquipmentCode());
            child.setLotNo(entity.getLotNo());
            child.setSeries(entity.getSeries());
            child.setArea(entity.getArea());
            child.setSapNo(entity.getSapNo());
            child.setProductCode(entity.getProductCode());
            child.setProductGrade(entity.getProductGrade());
            child.setSpecs(entity.getSpecs());
            child.setDopant(entity.getDopant());
            child.setProductType(entity.getProductType());
            child.setRawType(entity.getRawType());
            child.setRecipeId(entity.getRecipeId());
            child.setWeigthId(entity.getWeigthId());
            child.setTaskWeigths(taskWeigths);
            child.setRawCreate(currentDate);
            child.setCarrierSort(i);
            child.setPailNum(pailNum);
            child.setNum(count);
            //下次是否完结标识
            if(null != dto.getIsNextEnd()){
                child.setIsNextEnd(dto.getIsNextEnd());
            }

            // 是否完结加料
            if(null != dto.getIsFillEnd()){
                child.setIsFillEnd(dto.getIsFillEnd());
            }

            //复投次数
            child.setAgainNum(entity.getAgainNum());
            child.setIsDone(entity.getIsDone());

            //child.setAgainPailNum(tongNum);
            child.setPreDetailId(preDetailId);
            child.setAgainWeigth(BigDecimal.valueOf(againWeigth));
            if (i == 1) {
                calendar.add(Calendar.MINUTE, feedingTaskTime);
                child.setAgainTime(calendar.getTime());//预计复投时间
                child.setRawStatus(AgainTaskDetailDto.rawStatus_0);
                child.setDelayedStartTime(delayCalendar.getTime());

                //保存灌料任务
                againTaskDetailService.saveOrUpdate(child);

                //下发生产任务接口 装罐料下发
                if (GlobalSwitch.enable(GlobalSwitchNamespace.NAMESPACE_AUTOMATION, "CanningMaterial", false)) {
                    mesToMcsService.issueMoInterface(child);
                }

//                //发送MQTT通知
                MaterialOperationClickServiceImpl.sendAgainTaskDetailMessage(child, notificationService);
            } else {
                calendar.add(Calendar.MINUTE, feedingTaskTime);
                child.setAgainTime(calendar.getTime());//预计复投时间
                child.setRawStatus(AgainTaskDetailDto.rawStatus_0);

                //延时任务发起时间
                delayCalendar.add(Calendar.MINUTE, delayTime);
                child.setDelayedStartTime(delayCalendar.getTime());

                //保存灌料任务
                againTaskDetailService.saveOrUpdate(child);


                String cronExpression = CronUtils.getCronExpression(child.getDelayedStartTime());
                SysJob job = new SysJob();
                job.setJobName("glTask:" + child.getLotNo() + "-" + child.getId());
                job.setJobGroup("灌料");
                job.setInvokeTarget("delayStartTask.glTask('" + child.getLotNo() + "'," + child.getId() + "L)");
                job.setCronExpression(cronExpression);
                job.setExpireTime(child.getDelayedStartTime());
                job.setCreateBy("EAP");
                job.setMisfirePolicy(ScheduleConstants.MISFIRE_DEFAULT);
                job.setConcurrent("0");
                job.setStatus(ScheduleConstants.Status.NORMAL.getValue());
                sysJobService.startJob(job);
            }

            preDetailId = child.getId();


        }
        // 设置生产状态
        entity.setRawStatus(AgainTaskDto.rawStatus_1);
        saveOrUpdate(entity);

        //添加操作记录
        WeightInputDetail weightInputDetail = new WeightInputDetail();
        weightInputDetail.setAgainWeigth(dto.getAgainWeigth());
        weightInputDetail.setArea(dto.getModuleName());
        weightInputDetail.setClassNo(dto.getClassNo());
        weightInputDetail.setSeries(dto.getSeries());
        weightInputDetail.setSurplusWeigth(dto.getSurplusWeigth());
        weightInputDetail.setTaskId(dto.getId());
        weightInputDetail.setTeamGroup(dto.getClassName());
        weightInputDetail.setTotalUseWeigth(dto.getTotalUseWeigth());
        weightInputDetail.setUserName(dto.getUserName());
        weightInputDetail.setRemark(JSON.toJSONString(dto.getSplittings()));
        weightInputDetailService.saveOrUpdate(weightInputDetail);
//        seedMessage(entity, dto);

    }


    private Map<String, Integer> calculateWeight(Integer weightRatio, Integer weightBucket) {
        Map<String, Integer> map = new HashMap<>();
        //总重
        BigDecimal weightBucket1 = new BigDecimal(Integer.parseInt(weightBucket.toString()));
        //比例
        BigDecimal ratio = new BigDecimal(Integer.parseInt(weightRatio.toString()));
        BigDecimal tempRatio = ratio.divide(new BigDecimal("1000"));
        //算出配料重量(五舍六入)
        BigDecimal weight = weightBucket1.multiply(tempRatio).setScale(0,BigDecimal.ROUND_HALF_DOWN).multiply(new BigDecimal("10"));
        //取余
        BigDecimal[] result1 = weight.divideAndRemainder(new BigDecimal("40"));
        Integer bucketForty = Integer.parseInt(result1[0].toString());
        BigDecimal remainder = result1[1];
        BigDecimal[] result2 = remainder.divideAndRemainder(new BigDecimal("10"));
        Integer bucketTen = Integer.parseInt(result2[0].toString());
        map.put("weight",Integer.parseInt(weight.toString()));
        map.put("bucketForty",bucketForty);
        map.put("bucketTen",bucketTen);
        return map;
    }

    @Override
    public AgainTask getByEquipmentLastTask(String equimentCode, String lotNo) {
        return dao.getByEquipmentLastTask(equimentCode, lotNo);
    }

    @Override
    public AgainTask getByLotNoAndAgainNum(Integer againNum, String lotNo) {
        return dao.getByLotNoAndAgainNum(againNum,lotNo);
    }

    @Override
    public AgainTask getByEquipmentAndStateLastTask(String equimentCode, String lotNo, Integer rawStatus) {
        return dao.getByEquipmentAndStateLastTask(equimentCode, lotNo, rawStatus);
    }


    private Integer getDicMinuteTime(String themeValue, String name, int defValue) {
        int time = 0;
        try {
            //设置预计初始复投时间
            DictionaryItem dic = dictionaryItemService.findByThemeValueAndNameAndEnable(themeValue, name, true);
            if (dic != null) {
                time = Integer.valueOf(dic.getValue());
            } else {
                time = defValue;
            }
        } catch (Exception e) {
            time = defValue;
        }
        return time;
    }

    @Override
    public List<AgainTask> findByLotNo(String lotNo) {
        return dao.findByLotNo(lotNo);
    }

    @Override
    public List<AgainTask> findByLotNoAndAgainNum(String lotNo, Integer againNum) {
        return dao.findByLotNoAndAgainNum(lotNo, againNum);
    }

    @Override
    public AgainTask getByRepeatOpenTask(String equipmentCode, String lotNo) {
        return dao.getByRepeatOpenTask(equipmentCode, lotNo);
    }

    @Override
    public InputFurnaceBurden saveInputFurnaceBurden(List<AgainTaskDetail> againTaskDetails) {
        if (null != againTaskDetails && againTaskDetails.size() > 0) {
//            List<InputFurnaceBurden> inputFurnaceBurdens = inputFurnaceBurdenService.findByAgainTaskDetailId(againTaskDetails.get(0).getId());
            againTaskDetails.sort(Comparator.comparing(AgainTaskDetail::getId));
            AgainTaskDetail againTaskDetail = againTaskDetails.get(0);
            InputFurnaceBurden inputFurnaceBurden = new InputFurnaceBurden();
            inputFurnaceBurden.setAgainTaskDetailId(againTaskDetail.getId());
            inputFurnaceBurden.setEquipmentCode(againTaskDetail.getEquipmentCode());
            inputFurnaceBurden.setLotNo(againTaskDetail.getLotNo());
            inputFurnaceBurden.setSeries(againTaskDetail.getSeries());
            inputFurnaceBurden.setArea(againTaskDetail.getArea());
            inputFurnaceBurden.setRawType(againTaskDetail.getRawType());
            inputFurnaceBurden.setFurnaceType(againTaskDetail.getFurnaceType());
            inputFurnaceBurden.setSapNo(againTaskDetail.getSapNo());
            inputFurnaceBurden.setProductCode(againTaskDetail.getProductCode());
            inputFurnaceBurden.setProductGrade(againTaskDetail.getProductGrade());
            inputFurnaceBurden.setSpecs(againTaskDetail.getSpecs());
            inputFurnaceBurden.setDopant(againTaskDetail.getDopant());
            inputFurnaceBurden.setProductType(againTaskDetail.getProductType());
            //开始灌料时间
            inputFurnaceBurden.setStartTime(againTaskDetail.getAgainTime());
            //灌料人
            String name = BaseContextHandler.getUsername();
            inputFurnaceBurden.setUserName(name);
            //班次
            String classNo = BaseContextHandler.getUserClassNo();
            inputFurnaceBurden.setClassNo(classNo);
            //班组
            String classGroup = BaseContextHandler.getUserTeamGroup();
            inputFurnaceBurden.setTeamGroup(classGroup);
            //灌料桶数
            Integer count = againTaskDetails.get(0).getAgainPailNum();
            inputFurnaceBurden.setPailNum(count);
            //结束灌料时间
            Date endDate = new Date();
            inputFurnaceBurden.setEndTime(endDate);
            return inputFurnaceBurden;
        }
        return null;
    }

    @Override
    public void cancelTask(Long id, String cause) {
        AgainTask entity = this.get(id);
        if (entity.getRawStatus().equals(AgainTaskDto.rawStatus_0)) {
            entity.setRawStatus(AgainTaskDto.rawStatus_2);
            entity.setOperationCause(cause);
            entity.setUserName(BaseContextHandler.getUsername());
            entity.setOperationTime(new Date());
            this.saveOrUpdate(entity);
            //下发取消生产任务接口 装罐料下发
            if (GlobalSwitch.enable(GlobalSwitchNamespace.NAMESPACE_AUTOMATION, "CanningMaterial", false)) {
                mesToMcsService.cancelMoDistributionInterface(entity);
            }
        } else {
            throw new BusinessException("非新建状态不能取消此任务");
        }
    }

    @Override
    public void repeatOpenTask(Long id) {
        AgainTask task = this.get(id);
        if (task.getRawStatus().equals(AgainTaskDto.rawStatus_2) || task.getRawStatus().equals(AgainTaskDto.rawStatus_5)) {

            //验证是否已重新叫料
            boolean isDoubleTask = doubleTaskValidate(task);
            if (isDoubleTask) {
                throw new BusinessException("相同炉次已存在叫料任务");
            }

            //创建新任务
            AgainTask newTask = new AgainTask(task, AgainTaskDto.rawStatus_0);
            newTask.setUserName(BaseContextHandler.getUsername());
            this.saveOrUpdate(newTask);

            //下发生产任务接口
            //mMcsInterfaceService.issueMoInterface(newTask);

            //发送MQTT通知
            AgainTaskMessage message = new AgainTaskMessage();
            message.setArea(newTask.getArea());
            message.setEquipmentCode(newTask.getEquipmentCode());
            message.setId(newTask.getId());
            message.setLotNo(newTask.getLotNo());
            message.setSeries(newTask.getSeries());
            notificationService.sendNotification(message);
        } else {
            throw new BusinessException("非取消状态无法重复叫料");
        }
    }

    @Override
    public List<AgainTask> findSuccessByLotNoAndAgainNum(String lotNo, Integer againNum) {
        return dao.findSuccessByLotNoAndAgainNum(lotNo,againNum);
    }

    @Override
    public List<AgainTask> findByLotNoList(List<String> lotNo) {
        return dao.findByLotNoList(lotNo);
    }

    @Override
    public List<AgainTask> findSuccessByEquipmentCodeAndAgainNum(String equipmentCode, Integer againNum) {
        return dao.findSuccessByEquipmentCodeAndAgainNum(equipmentCode, againNum);
    }

    @Override
    public AgainTask findByEquipmentCode(String code) {
        return dao.findByEquipmentCode(code);
    }

    @Override
    public List<AgainTask> findSuccessByLotNo(String lotNo) {
        return dao.findSuccessByLotNo(lotNo);
    }

    @Override
    public  List<InputFurnaceDetail> findByLotNoAndProductCode(String lotNo, String code) {
        return dao.findByLotNoAndProductCode(lotNo,code);
    }

    // 根据炉次号查询最新已完成的复投任务
    @Override
    public AgainTask findCompletedTopByLotNo(String lotNo) {
        return dao.findCompletedTopByLotNo(lotNo);
    }

    @Override
    public AgainTask findCompletedTopByEquipmentCode(String equipmentCode) {
        return dao.findCompletedTopByEquipmentCode(equipmentCode);
    }

    @Override
    public AgainTask findCompletedByLotNoAndAgainNum(String lotNo, Integer againNum) {
        return dao.findCompletedByLotNoAndAgainNum(lotNo, againNum);
    }

    @Override
    public List<AgainTask> findNormalTasks(String lotNo, Integer againNum) {
        return dao.findNormalByLotNoAndAgainNum(lotNo, againNum);
    }

    /**
     * 多次叫料验证
     **/
    private boolean doubleTaskValidate(AgainTask task) {
        boolean isDoubleTask = false;
        List<AgainTask> allLotNoTask = this.findByLotNoAndAgainNum(task.getLotNo(), task.getAgainNum());
        for (AgainTask againTask : allLotNoTask) {
            if (!againTask.getRawStatus().equals(AgainTaskDto.rawStatus_2) && !againTask.getRawStatus().equals(AgainTaskDto.rawStatus_5)) {
                isDoubleTask = true;
                break;
            }
        }
        return isDoubleTask;
    }
}
