package com.sw.mes.yb.pad.controller;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.sw.mes.base.factory.init.entity.FactoryModel;
import com.sw.mes.base.factory.init.service.FactoryModelService;
import com.sw.mes.base.factory.inspect.entity.PaintingLine;
import com.sw.mes.base.global.GlobalSwitch;
import com.sw.mes.base.global.SwitchConfig;
import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.base.workinprocess.dao.PlanProcessingOrderDao;
import com.sw.mes.core.entity.CrystalLossRecord;
import com.sw.mes.base.workinprocess.entity.PlanProcessingOrder;
import com.sw.mes.base.workinprocess.service.CrystalLossRecordService;
import com.sw.mes.base.workinprocess.service.PlanProcessingOrderService;
import com.sw.mes.base.workinprocess.service.ProcessLogService;
import com.sw.mes.base.workinprocess.service.WipStorageService;
import com.sw.mes.core.annotation.TokenNotValidation;
import com.sw.mes.core.constant.Constants;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.enums.SeedMassageEnum;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.response.ResponsePage;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.core.utils.*;
import com.sw.mes.dingTalk.service.DingTalkService;
import com.sw.mes.yb.pad.dto.*;
import com.sw.mes.yb.pad.entity.ProductionPaintingLine;
import com.sw.mes.yb.pad.entity.ProductionPaintingLineDetailException;
import com.sw.mes.yb.pad.service.ProductionPaintingLineDetailExceptionService;
import com.sw.mes.yb.pad.service.ProductionPaintingLineService;
import com.sw.mes.yb.production.entity.InspectionRecord;
import com.sw.mes.yb.production.entity.LongCrystal;
import com.sw.mes.yb.production.service.CrystalBatchOperationService;
import com.sw.mes.yb.production.service.InspectionRecordService;
import com.sw.mes.yb.production.service.LongCrystalService;
import com.sw.mes.yb.turnstore.dao.ProductionBindingTrayDao;
import com.sw.mes.yb.turnstore.dto.BindingCrystalDto;
import com.sw.mes.yb.turnstore.entity.ProductionBindingTray;
import com.sw.mes.yb.turnstore.service.ProductionBindingTrayService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.ServletRequest;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.sw.mes.base.global.GlobalSwitchNamespace.CODE_SWITCH;


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@RestController
@RequestMapping("/ProductionPaintingLine")
@Slf4j
@Api(description = "划线记录接口")
public class ProductionPaintingLineController {
    @Autowired
    ModelMapper modelMapper;

    @Autowired
    private ProductionPaintingLineService productionPaintingLineService;

    @Autowired
    private LongCrystalService longCrystalService;

    @Autowired
    private PlanProcessingOrderDao planProcessingOrderDao;

    @Autowired
    private PlanProcessingOrderService planProcessingOrderService;

    @Autowired
    private InspectionRecordService inspectionRecordService;

    @Autowired
    private ProductionBindingTrayDao productionBindingTrayDao;

    @Autowired
    private ProductionBindingTrayService productionBindingTrayService;

    @Autowired
    private WipStorageService wipStorageService;

    @Autowired
    private DictionaryItemService dictionaryItemService;

    @Autowired
    private ProductionPaintingLineDetailExceptionService productionPaintingLineDetailExceptionService;

    @Autowired
    private CrystalBatchOperationService crystalBatchOperationService;

    @Autowired
    private ProcessLogService processLogService;

    @Autowired
    private CrystalLossRecordService crystalLossRecordService;

    @Autowired
    private DingTalkService dingTalkService;

    @Autowired
    private FactoryModelService factoryModelService;



    @ApiOperation(value = "获取划线长度")
    @GetMapping("/getCrystalInfo")
    public Result<LineInfoDto> getCrystalInfo(String crystalNo) {

        //根据长棒编号获取长棒信息，并且进行划线前的一些验证
        LineParamDataDto lineParamDto = getLongCrystal(crystalNo);
        if (null == lineParamDto.getLongCrystal()) {
            return ResultGenerator.fail("长晶棒产出记录为空！");
        }
        LineInfoDto lineInfoDto = modelMapper.map(lineParamDto.getLongCrystal(), LineInfoDto.class);
        if (StringUtils.isNotBlank(lineParamDto.getLongCrystal().getWindUp()) && (StringUtils.equals("W", lineParamDto.getLongCrystal().getWindUp()) || StringUtils.equals("V", lineParamDto.getLongCrystal().getWindUp()))) {
            lineInfoDto.setCompletionFlag(true);
        } else {
            lineInfoDto.setCompletionFlag(false);
        }
        // 添加高氧晶棒
        BigDecimal crystalCrucibleRotation = lineParamDto.getLongCrystal().getCrystalCrucibleRotation();
        if(null != crystalCrucibleRotation && crystalCrucibleRotation.compareTo(new BigDecimal(5)) > 0){
            lineInfoDto.setHighOxygen(1);
        }else {
            lineInfoDto.setHighOxygen(0);
        }
        InspectionRecord inspectionRecord = inspectionRecordService.findByLongCrystalId(lineParamDto.getLongCrystal().getId());
        if (inspectionRecord != null) {
            lineInfoDto.setAbnormal(inspectionRecord.getAbnormal());
        }
        return ResultGenerator.success(lineInfoDto);
    }


    /**
     * 根据长棒编号获取长棒信息，并且进行划线前的一些验证
     *
     * @param crystalNo 长棒编号
     * @return 长棒信息实体与理论重量系数
     */
    private LineParamDataDto getLongCrystal(String crystalNo) {
        wipStorageService.selectWipStorage(crystalNo, EnumValuesFactory.WipStorageCode.划线.getKey(), true);
        ProductionPaintingLine productionPaintingLines = productionPaintingLineService.findByCrystalNo(crystalNo);
        if (productionPaintingLines != null) {
            throw new BusinessException("当前单晶已画线，无法操作");
        }
        if (StringUtils.isBlank(crystalNo)) {
            throw new BusinessException("单晶编号参数不能为空");
        }
        LongCrystal longCrystal = longCrystalService.findByCrystalNo(crystalNo);
        if (longCrystal == null) {
            throw new BusinessException("单晶编号不存在");
        }
        //添加卡控 毛棒产出晶棒后 出炉时间卡控>9小时才可以进行划线作业。
        if (null == longCrystal.getGmtCreate()){
            throw new BusinessException("单晶编号:" + crystalNo + ",产出时间不存在！");
        }
        Date date = new Date();
        List<DictionaryItem> duration = dictionaryItemService.findByThemeValueAndEnable("duration", true);
        if(null != duration && duration.size() > 0){
            DictionaryItem dictionaryItem = duration.get(0);
            String value = dictionaryItem.getValue();
            long timeLong = Long.parseLong(value) * 60 * 1000;
            if (date.getTime() - longCrystal.getGmtCreate().getTime() < timeLong){
                throw new BusinessException("单晶编号:" + crystalNo + ",产出时间为： " + longCrystal.getGmtCreate() + ",产出时间小于【" + value + "】分钟！");
            }
        } else {
            if (date.getTime() - longCrystal.getGmtCreate().getTime() < 32400000){
                throw new BusinessException("单晶编号:" + crystalNo + ",产出时间为： " + longCrystal.getGmtCreate() + ",产出时间小于9小时！");
            }
        }
        //添加批次锁定校验
        crystalBatchOperationService.judgeCrystalNoIsLock(crystalNo, null, true);
        if (longCrystal.getLength() == null) {
            throw new BusinessException("该单晶的没有长度信息，请补充后重试");
        }
        if (longCrystal.getLength().longValue() <= 0) {
            throw new BusinessException("该单晶的长度小于等于0，请修正长棒信息后重试");
        }
        List<DictionaryItem> dictionaryItems = dictionaryItemService.findByThemeValueAndItemName(Constants.WEIGHT_RATIO, longCrystal.getSpecs(), true);
        if (dictionaryItems.size() == 0) {
            throw new BusinessException("请配置【" + longCrystal.getSpecs() + "】规格的理论重量系数");
        }
        BigDecimal weightLossCoefficient = NumberUtil.Object2BigDecimal(dictionaryItems.get(0).getValue());
        if (weightLossCoefficient == null || weightLossCoefficient.compareTo(new BigDecimal("1")) < 1) {
            throw new BusinessException("【" + dictionaryItems.get(0).getValue() + "】理论重量系数格式不正确，只能为大于0的数字类型");
        }
        //添加卡控，上一炉次未划线禁止划线
        LongCrystal deviceNoAndCreateTime = longCrystalService.findDeviceNoAndCreateTime(longCrystal.getEquipmentCode(), longCrystal.getGmtCreate(),EnumValuesFactory.CrystalStatus.已送验.getKey());
        if (null != deviceNoAndCreateTime){
            throw new BusinessException("该设备上一个送验单晶未划线，单晶编号为：" + deviceNoAndCreateTime.getCrystalNo());
        }

        LineParamDataDto lineParamDataDto = new LineParamDataDto();
        lineParamDataDto.setLongCrystal(longCrystal);
        lineParamDataDto.setWeightLossCoefficient(weightLossCoefficient);
        return lineParamDataDto;
    }

    @ApiOperation(value = "分页查询划线记录列表")
    @ApiImplicitParams({@ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"), @ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),})
    @GetMapping("/listByPage")
    public Result<ResponsePage<ProductionPaintingLineDto>> listByPage(ServletRequest request, @ApiIgnore RequestPage requestPage) {
        Specification<ProductionPaintingLine> specification = DynamicSpecifications.bySearchFilter(request, ProductionPaintingLine.class);
        Page<ProductionPaintingLine> page = productionPaintingLineService.findByExample(specification, PageUtil.createPageable(requestPage));
        List<ProductionPaintingLineDto> dtos = page.getContent().stream().map(entity -> toLazyDto(entity)).collect(Collectors.toList());
        //有效长度字段处理逻辑 划线有效长度逻辑修改：等于等径长度-划线去头长度-划线去尾长度
  /*      dtos.stream().forEach(dto->{
            if (null != dto.getIsometricLength() && dto.getIsometricLength().compareTo(BigDecimal.ZERO) != 0){
                dto.setValidLength(dto.getIsometricLength().subtract(Optional.ofNullable(dto.getNoTopLength()).orElse(BigDecimal.ZERO)).subtract(Optional.ofNullable(dto.getLineTailLength()).orElse(BigDecimal.ZERO)).setScale(2,BigDecimal.ROUND_HALF_DOWN));
            }
        });*/
        ResponsePage responsePage = new ResponsePage(dtos, page.getTotalElements());
        return ResultGenerator.success(responsePage);
    }

    @ApiOperation(value = "获取所有划线记录")
    @GetMapping("/listAll")
    public Result<List<ProductionPaintingLineDto>> listAll(ServletRequest request) {
        Specification<ProductionPaintingLine> specification = DynamicSpecifications.bySearchFilter(request, ProductionPaintingLine.class);
        List<ProductionPaintingLine> productionPaintingLines = productionPaintingLineService.findByExampleSort(specification, null);
        List<ProductionPaintingLineDto> productionPaintingLineDtos = productionPaintingLines.stream().map(productionPaintingLine -> toLazyDto(productionPaintingLine)).collect(Collectors.toList());
        return ResultGenerator.success(productionPaintingLineDtos);
    }

    @ApiOperation(value = "划线记录详细信息")
    @GetMapping("/{id}")
    public Result<ProductionPaintingLineDto> get(@PathVariable @ApiParam(value = "划线记录id") Long id) {
        ProductionPaintingLine productionPaintingLine = productionPaintingLineService.get(id);
        if (null != productionPaintingLine) {
            return ResultGenerator.fail("该划线记录不存在");
        }
        return ResultGenerator.success(toEagerDto(productionPaintingLine));
    }

    @ApiOperation(value = "创建划线记录")
    @PostMapping("/create")
//    @TokenNotValidation
    public Result<String> create(@RequestBody @Valid @ApiParam(value = "创建划线记录参数") DrawLineDto drawLineDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }

        //划线开始时间取当前系统时间
        drawLineDto.setStartTime(new Date());

        //根据长棒编号获取长棒信息，并且进行划线前的一些验证
        LineParamDataDto lineParamDto = getLongCrystal(drawLineDto.getCrystalNo());
        LineDetailedParamDto lineDetailedParamDto = new LineDetailedParamDto();
        int drawlinedetailLen = 0;

        BigDecimal effectiveLength = BigDecimal.ZERO;
        int count = 0;
        //正常晶段计数
        int segmentCount = 0;

        //头段位置
        Integer headIndex = null;

        //for (DrawLineDetailDto line : drawLineDto.getLineDetailedDtos()) {
        if (!CollectionUtils.isEmpty(drawLineDto.getLineDetailedDtos())) {
            List<DrawLineDetailDto> lineDetailedDtos = drawLineDto.getLineDetailedDtos();
            int size = lineDetailedDtos.size();
            for (int index = 0; index < size; index++) {
                DrawLineDetailDto line = lineDetailedDtos.get(index);
                if (line.getLength().compareTo(BigDecimal.ZERO) < 0) {
                    throw new RuntimeException("晶段的长度不能为负数：" + line.getLength());
                }
                drawlinedetailLen += line.getLength().intValue();

                if (line.getType() == 0 && line.getLength().compareTo(BigDecimal.ZERO) > 0) {
                    segmentCount++;
                    if (line.getSegmentNo().endsWith("T") || line.getSegmentNo().endsWith("R")) {
                        headIndex = index;
                    }
                }
                if (line.getType() == 0 || line.getType() == 1) {
                    effectiveLength = effectiveLength.add(line.getLength());
                }



          /*  //判断是否存在头片信息
            if(line.getSegmentNo().contains("TP") || line.getSegmentNo().substring(SectionIndexRangeEnum.炉区号.getEndIndex()).contains("1P")){
                count++;
            }*/
                //剔除尾片长度计算
                if (line.getType() == 1 && StringUtils.isNotBlank(line.getSegmentNo()) && StringUtils.equals("T", line.getSegmentNo().substring(2, 3))) {
                    drawlinedetailLen -= line.getLength().intValue();

                    effectiveLength = effectiveLength.subtract(line.getLength());
                }
            }
            if (null != headIndex && headIndex - 1 >= 0) {
                DrawLineDetailDto drawLineDetailDto = lineDetailedDtos.get(headIndex - 1);
                if (drawLineDetailDto.getType() == 1) {
                    drawlinedetailLen -= drawLineDetailDto.getLength().intValue();
                    effectiveLength = effectiveLength.subtract(drawLineDetailDto.getLength());
                }
            }
        }
        if (0 == drawLineDto.getEffectiveLength()) {
            lineParamDto.setEffectiveLength(effectiveLength);
        }

        //有正常晶段
        if (segmentCount > 0) {

            /*if(count == 0){
                throw new RuntimeException("缺少头片划线信息");
            }*/
            //需要扣除去头尾回收料
            if (null != drawLineDto.getHeadLen() && drawLineDto.getHeadLen().compareTo(BigDecimal.ZERO) > 0) {
                drawlinedetailLen -= drawLineDto.getHeadLen().intValue();
            }
            if (null != drawLineDto.getTailLen() && drawLineDto.getTailLen().compareTo(BigDecimal.ZERO) > 0) {
                drawlinedetailLen -= drawLineDto.getTailLen().intValue();
            }

            //校验画线长度和明细长度是否一致
            if (drawlinedetailLen != drawLineDto.getLength()) {
                throw new BusinessException(" 明细总长 " + drawlinedetailLen + "！=总长 " + drawLineDto.getLength());
            }
            modelMapper.map(drawLineDto, lineDetailedParamDto);
            lineDetailedParamDto.getLineDetailedDtos().stream().forEach(t -> {
                t.setSampleType(t.getType());
            });
            try {
                this.productionPaintingLineService.createAll(lineDetailedParamDto, lineParamDto.getLongCrystal(), lineParamDto.getWeightLossCoefficient(), lineParamDto);
            }catch (Exception e){
                log.info("划线异常日志：{}",e.getMessage());
                return ResultGenerator.fail(e.getMessage());
            }
            if (null != lineDetailedParamDto && lineDetailedParamDto.getTotalLength().compareTo(BigDecimal.ZERO) > 0){

              /*  StringBuffer lossReason = new StringBuffer();
                if (StringUtils.isNotBlank(drawLineDto.getTopCause())){
                    lossReason.append(drawLineDto.getTopCause()).append(":").append(drawLineDto.getNoTopLength()).append(";");
                }
                if (StringUtils.isNotBlank(drawLineDto.getEndCause())){
                    lossReason.append(drawLineDto.getEndCause()).append(":").append(drawLineDto.getLineTailLength()).append(";");
                }
                if (StringUtils.isNotBlank(lineDetailedParamDto.getMiddleAbnormalReason())){
                    lossReason.append(lineDetailedParamDto.getMiddleAbnormalReason()).append(";");
                }*/
                //处理数据
                try {
                    this.handleLossInfo(lineParamDto.getLongCrystal(),drawLineDto,lineDetailedParamDto.getTotalLength(),lineDetailedParamDto.getMiddleAbnormalReason());
                }catch (Exception e){
                    log.info("损耗上报异常：{}",e.getMessage());
                }
            }

        } else {

            //校验画线长度和明细长度是否一致
            if (drawlinedetailLen != drawLineDto.getLength()) {
                throw new BusinessException(" 明细总长 " + drawlinedetailLen + "！=总长 " + drawLineDto.getLength());
            }
            // 解绑
            List<ProductionBindingTray> bindingTrays = productionBindingTrayDao.findByCrystalNo(drawLineDto.getCrystalNo());
            if (null != bindingTrays && !CollectionUtils.isEmpty(bindingTrays) && !bindingTrays.get(0).getTrayNo().isEmpty()) {
                BindingCrystalDto bindingCrystalDto = new BindingCrystalDto();
                bindingCrystalDto.setCrystalNo(drawLineDto.getCrystalNo());
                bindingCrystalDto.setTrayNo(bindingTrays.get(0).getTrayNo());
                bindingCrystalDto.setReason("送验车解绑");
                try {
                    productionBindingTrayService.unbundlingCrystal(bindingCrystalDto);
                } catch (Exception e) {
                    log.info("划线异常日志：{}",e.getMessage());
                    return ResultGenerator.fail(e.getMessage());
                }
            }
            //回收料将有效长度清零
            lineParamDto.setEffectiveLength(BigDecimal.ZERO);
            /*if (null == drawLineDto.getScrapIdentification() || !drawLineDto.getScrapIdentification()){
                //工单废除
                List<PlanProcessingOrder> planProcessingOrders = planProcessingOrderDao.findByCodeOrderByIdDesc(drawLineDto.getCrystalNo());
                if (planProcessingOrders.size() == 0) {
                    throw new BusinessException("工单号【" + drawLineDto.getCrystalNo() + "】不存在");
                }
                PlanProcessingOrder planProcessingOrder = planProcessingOrders.get(0);
                planProcessingOrder.setStatus(EnumValuesFactory.PlanProcessingOrderStatus.已作废.getKey());
                planProcessingOrder.setRemarks("划线明细全是回收料，工单" + EnumValuesFactory.PlanProcessingOrderStatus.已作废.getValue());

                //创建报废履历
                processLogService.createProcessLog(planProcessingOrder.getId(), planProcessingOrder.getCode(), null, null, null, null, "【毛棒检验】：" + planProcessingOrder.getCode() + "->作废");
                planProcessingOrderService.saveOrUpdate(planProcessingOrder);
            }*/
            modelMapper.map(drawLineDto, lineDetailedParamDto);
            lineDetailedParamDto.getLineDetailedDtos().stream().forEach(t -> {
                t.setSampleType(t.getType());
            });
            lineDetailedParamDto.setEffectiveLength(0);
            try {
                this.productionPaintingLineService.createAll(lineDetailedParamDto, lineParamDto.getLongCrystal(), lineParamDto.getWeightLossCoefficient(), lineParamDto);
            }catch (Exception e){
                log.info("划线回收料异常日志：{}",e.getMessage());
                return ResultGenerator.fail(e.getMessage());
            }

            //处理数据
            try {
                this.handleLossInfo(lineParamDto.getLongCrystal(),drawLineDto,null,null);
            }catch (Exception e){
                log.info("损耗上报异常：{}",e.getMessage());
            }
        }
/*
        ThreadManager.getThreadPollProxy().execute(() ->{
            try {
                this.handleSapInfo(lineParamDto);
            }catch (Exception e){
                e.printStackTrace();
            }
        });*/

        try {
            SwitchConfig config = GlobalSwitch.switchConfig(CODE_SWITCH, "crystalWorkHour", false);
            if(config.isEnable()){
                LongCrystal longCrystal = longCrystalService.findByCrystalNo(drawLineDto.getCrystalNo());
                log.info("单晶工时报工编号：{}", drawLineDto.getCrystalNo());
                productionPaintingLineService.newReportSapLongCrystalHours(longCrystal);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("单晶工时：" + e.getMessage());
        }

        return ResultGenerator.success();
    }

    @ApiOperation(value = "生成编号（人工匹配）")
    @PostMapping("/getCrystalNoInfos")
    public Result<DrawLineDto> getCrystalNoInfos(@RequestBody DrawLineDto lineDetailedParamDto) {
        //根据长棒编号获取长棒信息，并且进行划线前的一些验证
        LineParamDataDto lineParamDto = getLongCrystal(lineDetailedParamDto.getCrystalNo());
        //productionPaintingLineService.getDrawlinginfos(lineDetailedParamDto, lineParamDto.getLongCrystal());
        productionPaintingLineService.getDrawlinginfosNew(lineDetailedParamDto);
        return ResultGenerator.success(lineDetailedParamDto);
    }

    @ApiOperation(value = "生成编号（MCS系统自动化匹配）")
    @PostMapping("/autoCrystalNoInfos")
    public Result<String> autoCrystalNoInfos(@Valid @RequestBody AutoDrawLineDto autoDrawLineDto) {
        log.info("MCS自动化自动画线入参：" + JSONObject.toJSONString(autoDrawLineDto));
        wipStorageService.selectWipStorage(autoDrawLineDto.getCrystalNo(), EnumValuesFactory.WipStorageCode.划线.getKey(), true);
        ProductionPaintingLine productionPaintingLines = productionPaintingLineService.findByCrystalNo(autoDrawLineDto.getCrystalNo());
        if (productionPaintingLines != null) {
            return ResultGenerator.fail("当前单晶已画线，无法操作");
        }
        DrawLineParamDto lineParamDto = new DrawLineParamDto();
        BeanUtils.copyProperties(autoDrawLineDto,lineParamDto);
        Result<DrawLineDto> drawLineDtoResult = productionPaintingLineService.matchDrawLineNew(lineParamDto);
        if(!drawLineDtoResult.getCode().equals(200)&& !ObjectUtils.isEmpty(drawLineDtoResult.getData())){
            productionPaintingLineService.sendWjbzToMcsForDeletePaintngLine(lineParamDto.getTrayNo());
            return ResultGenerator.fail("MCS自动化划线数据匹配失败，请检查数据"+JSONObject.toJSONString(autoDrawLineDto));
        }
        DrawLineDto drawLineDto = drawLineDtoResult.getData();
        Result<String> result = productionPaintingLineService.create(drawLineDto);
        log.info("MCS自动化划创建线明细入参："+JSONObject.toJSONString(drawLineDto));
        if(!result.getCode().equals(200)){
            productionPaintingLineService.sendWjbzToMcsForDeletePaintngLine(lineParamDto.getTrayNo());
            return ResultGenerator.fail("MCS自动化创建划线明细失败，请检查数据"+JSONObject.toJSONString(drawLineDto));
        }else {
            //成功之后需要通知MCS
            log.info("发送划线完结标志到MCS入参："+JSONObject.toJSONString(drawLineDto));
            productionPaintingLineService.sendWjbzToMcs(lineParamDto.getTrayNo());
        }
        return ResultGenerator.success(result.getData());
    }


    @ApiOperation(value = "获取划线规则数据（自动匹配画线）")
    @PostMapping("/findLineInfo")
    @TokenNotValidation
    public Result<DrawLineDto> getLineInfo(@RequestBody DrawLineParamDto lineParamDto) {
        log.info("自动画线入参：" + JSONObject.toJSONString(lineParamDto));
        wipStorageService.selectWipStorage(lineParamDto.getCrystalNo(), EnumValuesFactory.WipStorageCode.划线.getKey(), true);
        ProductionPaintingLine productionPaintingLines = productionPaintingLineService.findByCrystalNo(lineParamDto.getCrystalNo());
        if (productionPaintingLines != null) {
            return ResultGenerator.fail("当前单晶已画线，无法操作");
        }
        return productionPaintingLineService.matchDrawLineNew(lineParamDto);
    }

    /**
     * 根据晶体获取画线规则
     *
     * @param crystalNo
     * @return
     */
    @ApiOperation(value = "根据晶体获取画线规则")
    @GetMapping("/getDrawLineRuleList/{crystalNo}")
    public Result<List<PaintingLine>> getDrawLineRuleList(@PathVariable @ApiParam(value = "晶段编号") String crystalNo) {
        List<PaintingLine> paintingLineList = productionPaintingLineService.getDrawLineRuleList(crystalNo);
        if (CollectionUtils.isEmpty(paintingLineList)) {
            return ResultGenerator.fail("该晶体画线规划不存在");
        }
        return ResultGenerator.success(paintingLineList);
    }


    @ApiOperation(value = "返切划线异常详细信息")
    @GetMapping("/getLineException/{segmentNo}")
    public Result<List<ProductionPaintingLineDetailException>> getLineException(@PathVariable @ApiParam(value = "晶段编号") String segmentNo) {
        List<ProductionPaintingLineDetailException> bySegmentNo = productionPaintingLineDetailExceptionService.findBySegmentNo(segmentNo);
        if (CollectionUtils.isEmpty(bySegmentNo)) {
            return ResultGenerator.fail("该划线异常记录不存在");
        }
        return ResultGenerator.success(bySegmentNo);
    }


    @ApiOperation(value = "更新划线记录")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid @ApiParam(value = "划线记录") ProductionPaintingLineDto dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        if (dto.getId() == null) {
            return ResultGenerator.fail("id不能为空");
        }
        ProductionPaintingLine entity = productionPaintingLineService.get(dto.getId());
        if (entity == null) {
            return ResultGenerator.fail("原信息不存在");
        }
        try {
            ProductionPaintingLine entityfromFto = fromDto(dto);
            BeanUtils.copyProperties(entityfromFto, entity, BeanUtil.getIgnoreProperties(entityfromFto, null, null));
            productionPaintingLineService.saveOrUpdate(entity);
            return ResultGenerator.success();
        } catch (Exception e) {
            return ResultGenerator.fail(e.getMessage());
        }
    }

    @ApiOperation(value = "删除划线记录")
    @PostMapping("/delete")
    public Result remove(@ApiParam(value = "id集合,逗号分隔,如2,4", type = "query") @RequestParam Long[] ids) {
        for (Long id : ids) {
            // 注释部分放入deleteInfo方法中
//            ProductionPaintingLine productionPaintingLine = productionPaintingLineService.get(id);
//            LongCrystal byCrystalNo = longCrystalService.findByCrystalNo(productionPaintingLine.getCrystalNo());
//            if(null != byCrystalNo.getRodPulled() && byCrystalNo.getRodPulled() == 1){
//                return ResultGenerator.fail("长晶棒信息已被拉取，无法删除");
//            }
            productionPaintingLineService.deleteInfo(id);
        }
        return ResultGenerator.success();
    }


//	@ApiOperation(value = "获取划线段数")
//	@GetMapping("/findLineNum")
//	public Result getLineNum(@RequestParam String crystalNo) {
//
//		return this.productionPaintingLineService.getLineRule(crystalNo);
//	}
//
//
//	@ApiOperation(value = "获取样片数")
//	@GetMapping("/findPieceNum")
//	public Result getPieceNum(@RequestParam String crystalNo) {
//
//		return this.productionPaintingLineService.getPieceRule(crystalNo);
//	}


    @ApiOperation(value = "获取定向划线信息")
    @GetMapping("/findDirectional")
    public Result findDirectional() {
        return this.productionPaintingLineService.getDirectional();
    }

    @ApiOperation(value = "根据晶棒编号获取划线信息")
    @GetMapping("/findProductionPaintingLine")
    public Result<ProductionPaintingLine> findProductionPaintingLine(@RequestParam(value = "crystalNo") String crystalNo) {
        return ResultGenerator.success(this.productionPaintingLineService.findByCrystalNo(crystalNo));
    }

    @ApiOperation(value = "发送划线完结标志到MCS")
    @GetMapping("/sendWjbzToMcs")
    public Result sendWjbzToMcs(@RequestParam(value = "vehicleCode") String vehicleCode) {
        this.productionPaintingLineService.sendWjbzToMcs(vehicleCode);
        return ResultGenerator.success();
    }

    public ProductionPaintingLineDto toLazyDto(ProductionPaintingLine entity) {
        ProductionPaintingLineDto productionPaintingLineDto = modelMapper.map(entity, ProductionPaintingLineDto.class);
        if (null != productionPaintingLineDto.getValidLength()){
            productionPaintingLineDto.setEffectiveWeight(productionPaintingLineDto.getValidLength().divide(new BigDecimal(7.25),3,BigDecimal.ROUND_HALF_UP));
        }
        return productionPaintingLineDto;
    }

    public ProductionPaintingLineDto toEagerDto(ProductionPaintingLine entity) {
        ProductionPaintingLineDto dto = modelMapper.map(entity, ProductionPaintingLineDto.class);
        return dto;
    }

    public ProductionPaintingLine fromDto(ProductionPaintingLineDto dto) {
        return modelMapper.map(dto, ProductionPaintingLine.class);
    }

    private void handleLossInfo(LongCrystal longCrystal,DrawLineDto drawLineDto,BigDecimal lossLength,String lossReason){

        if (null != longCrystal && null != drawLineDto){
            CrystalLossRecord crystalLossRecord = new CrystalLossRecord();
            crystalLossRecord.setSectionNo(drawLineDto.getCrystalNo());
            crystalLossRecord.setCrystalNo(drawLineDto.getCrystalNo());
            crystalLossRecord.setLossProcessName(EnumValuesFactory.WipStorageCode.划线.getValue());
            crystalLossRecord.setMajorCategories(EnumValuesFactory.CrystalLossType.SINGLE_CRYSTAL_LOSS.getValue());
            if (null != lossLength){
                crystalLossRecord.setLossLength(lossLength);
                crystalLossRecord.setRodLength(new BigDecimal(drawLineDto.getLength()));
                crystalLossRecord.setRemainLength(crystalLossRecord.getRodLength().subtract(lossLength));
                crystalLossRecord.setLossType(lossReason);
            }else {
                crystalLossRecord.setLossLength(new BigDecimal(drawLineDto.getLength()));
                crystalLossRecord.setRodLength(crystalLossRecord.getLossLength());
                crystalLossRecord.setRemainLength(BigDecimal.ZERO);
                crystalLossRecord.setRemainWeight(BigDecimal.ZERO);
                crystalLossRecord.setLossType(drawLineDto.getAssessment());
            }
            if (null != crystalLossRecord.getLossLength()){
                //圆棒理论折算系数
                if (StringUtils.isNotBlank(longCrystal.getSpecs())){
                    DictionaryItem weightRatio = dictionaryItemService.findByThemeValueAndNameAndEnable("WeightRatio", longCrystal.getSpecs(), true);
                    if (null != weightRatio && StringUtils.isNotBlank(weightRatio.getValue())){
                        crystalLossRecord.setLossWeight(crystalLossRecord.getLossLength().divide(new BigDecimal(weightRatio.getValue()), 3, BigDecimal.ROUND_HALF_UP));
                        if (null != lossLength){
                            crystalLossRecord.setRemainWeight(crystalLossRecord.getRemainLength().divide(new BigDecimal(weightRatio.getValue()), 3, BigDecimal.ROUND_HALF_UP));
                        }
                    }
                }
            }
            crystalLossRecord.setCreateName(drawLineDto.getOperatorUser());
            crystalLossRecord.setArea(longCrystal.getSeries());
            FactoryModel factoryModel = factoryModelService.findByCode(longCrystal.getArea());
            if (null != factoryModel){
                crystalLossRecord.setWorkshop(factoryModel.getName());
            }

            if (null != drawLineDto.getEndTime()){
                crystalLossRecord.setCreateTime(drawLineDto.getEndTime());
            }else {
                crystalLossRecord.setCreateTime(new Date());
            }
            crystalLossRecord.setOperateRemark(drawLineDto.getRemarks());
            crystalLossRecord.setMaterialCode(longCrystal.getProductCode());
            crystalLossRecord.setMaterialName(longCrystal.getProductName());
            crystalLossRecord.setOrderNo(longCrystal.getOrderNo());
            crystalLossRecord.setSimpleName(longCrystal.getSimpleName());
            crystalLossRecord.setRodTime(crystalLossRecord.getCreateTime());
            crystalLossRecord.setRodInspector(drawLineDto.getOperatorUser());
            crystalLossRecordService.saveOrUpdate(crystalLossRecord);

            //发送钉钉

            StringBuffer content = new StringBuffer();
            content.append(". [MES推送]晶棒损耗:").append("\n");
            content.append(". ").append(drawLineDto.getCrystalNo()).append("\n");
            content.append(".时间：").append(DateUtil.formatDate1(drawLineDto.getEndTime())).append("\n");
            content.append(".单晶损耗").append("\n");
            content.append(".损耗工序：").append(EnumValuesFactory.WipStorageCode.划线.getValue()).append("\n");
            content.append(".损耗原因：").append(drawLineDto.getAssessment()).append("\n");
            content.append(".损耗长度：").append(drawLineDto.getLength()).append("\n");

            content.append(".剩余长度：0").append("\n");
            content.append(".录入人：").append(drawLineDto.getOperatorUser()).append("\n");
            content.append(".备注：").append(StringUtils.isNotBlank(drawLineDto.getRemarks()) ? drawLineDto.getRemarks(): "").append("\n");
            ArrayList<String> sceneList = new ArrayList<>();
            ArrayList<String> groupNameList = new ArrayList<>();
            sceneList.add("prod");
            String groupName = "切方长度损耗实时推送群";
            groupNameList.add(groupName);
            String source = "晶棒损耗";
            if(null == lossLength){
                dingTalkService.robotSeedMessage(String.valueOf(content), groupNameList, source, sceneList, SeedMassageEnum.GROUP);
            }
        }
    }


}
