package com.sw.mes.fb.turnstore.controller;


import com.alibaba.excel.EasyExcelFactory;
import com.sw.mes.base.factory.material.entity.MaterialModel;
import com.sw.mes.base.factory.material.service.MaterialModelService;
import com.sw.mes.base.global.GlobalSwitch;
import com.sw.mes.base.global.GlobalSwitchNamespace;
import com.sw.mes.base.workinprocess.entity.PlanProcessingOrder;
import com.sw.mes.base.workinprocess.service.PlanProcessingOrderService;
import com.sw.mes.core.api.system.YbFeignClients;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.dto.FbTurnstoreTrayItemDto;
import com.sw.mes.core.entity.FbCheckOutData;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.enums.SectionIndexRangeEnum;
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.fb.checkout.service.FbCheckOutDataService;
import com.sw.mes.fb.turnstore.dto.ExportFbTurnstoreTrayItemDto;
import com.sw.mes.fb.turnstore.entity.FbTurnstoreTray;
import com.sw.mes.fb.turnstore.entity.FbTurnstoreTrayItem;
import com.sw.mes.fb.turnstore.service.FbTurnstoreTrayItemService;
import com.sw.mes.fb.turnstore.service.FbTurnstoreTrayService;
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.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@RestController
@RequestMapping("/FbTurnstoreTrayItem")
@Slf4j
@Api(description = "方棒组托详情接口")
public class FbTurnstoreTrayItemController {
    @Autowired
    ModelMapper modelMapper;

    @Autowired
    private FbTurnstoreTrayService fbTurnstoreTrayService;

    @Autowired
    private FbTurnstoreTrayItemService fbTurnstoreTrayItemService;

    @Autowired
    private PlanProcessingOrderService planProcessingOrderService;

    @Autowired
    private FbCheckOutDataService fbCheckOutDataService;

    @Autowired
    private MaterialModelService materialModelService;

    @Autowired
    private YbFeignClients ybFeignClients;

    @ApiOperation(value = "分页查询方棒组托详情列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rows", value = "行数", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "page", value = "页码", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "search_EQ_trayId", value = "主表id", dataType = "integer", paramType = "query"),
            @ApiImplicitParam(name = "search_EQ_sectionNo", value = "晶段编号", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_EQ_trayNo", value = "托号", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_LIKE_sectionNo", value = "炉台号", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_EQ_state", value = "入库状态", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_GTE_time", value = "组托时间", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_LTE_time", value = "组托时间", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_GTE_toWmsTime", value = "入综计时间", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_LTE_toWmsTime", value = "入综计时间", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_GTE_operationTime", value = "操作/确认时间", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_LTE_operationTime", value = "操作/确认时间", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_GTE_confirmTime", value = "确认时间", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_LTE_confirmTime", value = "确认时间", dataType = "string", paramType = "query"),
    })
    @GetMapping("/listByPage")
    public Result<ResponsePage<FbTurnstoreTrayItemDto>> listByPage(ServletRequest request, @ApiIgnore RequestPage requestPage) {
        Specification<FbTurnstoreTrayItem> specification = DynamicSpecifications.bySearchFilter(request, FbTurnstoreTrayItem.class);
        Page<FbTurnstoreTrayItem> page = fbTurnstoreTrayItemService.findByExample(specification, PageUtil.createPageable(requestPage));
        //做一个物料缓存
        Map<String, String> materialCache = new HashMap<>();
        List<FbTurnstoreTrayItemDto> dtos = page.getContent().stream()
                .map(entity -> {
                    FbTurnstoreTrayItemDto dto = toLazyDto(entity);
                    FbCheckOutData fbCheckOutData = fbCheckOutDataService.findDataByFbSectionNo(dto.getSectionNo());
                    if (null != fbCheckOutData) {
                        //TCentreLife 头少子
                        dto.setLife(fbCheckOutData.getMeanCarrierLifetimeA());
                        //w少子
                        dto.setWLife(fbCheckOutData.getMeanCarrierLifetimeB());
                        //头电阻 TRadialCentre tRadialCentre
                        dto.setTRadialCentre(fbCheckOutData.getMeanResistivityA());
                        //尾电阻
                        dto.setWRadialCentre(fbCheckOutData.getMeanResistivityB());
                        //有效长度
                        dto.setInstoreLengthFb(fbCheckOutData.getInstoreLengthFb());
                        //炉台号
                        dto.setEquipmentCode(fbCheckOutData.getFbSectionNo().substring(SectionIndexRangeEnum.炉台号.getBeginIndex(), SectionIndexRangeEnum.炉台号.getEndIndex()));
                    }
                    if (null != entity.getMaterialNumber()) {
                        MaterialModel materialModel = materialModelService.findByCode(entity.getMaterialNumber());
                        if (null != materialModel) {
                            dto.setMaterialDesc(materialModel.getName());
                        }
                    }
                    return dto;
                })
                .collect(Collectors.toList());
        ResponsePage responsePage = new ResponsePage(dtos, page.getTotalElements());
        return ResultGenerator.success(responsePage);
    }

    @ApiOperation(value = "获取所有方棒组托详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "search_EQ_trayId", value = "主表id", dataType = "integer", paramType = "query"),
    })
    @GetMapping("/listAll")
    public Result<List<FbTurnstoreTrayItemDto>> listAll(ServletRequest request) {
        Specification<FbTurnstoreTrayItem> specification = DynamicSpecifications.bySearchFilter(request, FbTurnstoreTrayItem.class);
        List<FbTurnstoreTrayItem> fbTurnstoreTrayItems = fbTurnstoreTrayItemService.findByExampleSort(specification, Sort.by("orderNum"));
        List<FbTurnstoreTrayItemDto> fbTurnstoreTrayItemDtos = fbTurnstoreTrayItems.stream()
                .map(this::toLazyDto)
                .collect(Collectors.toList());
        //优化下代码，改成批量查询
        List<String> sectionIds = new ArrayList<>();
        for (FbTurnstoreTrayItemDto dto : fbTurnstoreTrayItemDtos) {
            sectionIds.add(dto.getSectionNo());
        }
        //做一个物料缓存
        Map<String, String> materialCache = new HashMap<>();
        List<FbCheckOutData> fbCheckOutDataList = fbCheckOutDataService.findCheckOutDataByFbSectionNoIns(sectionIds);
        Map<String, FbCheckOutData> resultMap = fbCheckOutDataList.stream().collect(Collectors.toMap(FbCheckOutData::getFbSectionNo, item -> item));
        fbTurnstoreTrayItemDtos.forEach(item -> {// fixme 补齐明细数据
            FbCheckOutData fbCheckOutData = resultMap.get(item.getSectionNo());
            if (Objects.nonNull(fbCheckOutData)) {
                //TCentreLife 头少子
                item.setLife(fbCheckOutData.getMeanCarrierLifetimeA());
                //w少子
                item.setWLife(fbCheckOutData.getMeanCarrierLifetimeB());
                //头电阻 TRadialCentre tRadialCentre
                item.setTRadialCentre(fbCheckOutData.getMeanResistivityA());
                //尾电阻
                item.setWRadialCentre(fbCheckOutData.getMeanResistivityB());
                //有效长度
                item.setEffectiveLength(fbCheckOutData.getInstoreLengthFb());
            }
            if (null != item.getMaterialNumber()) {
                if (!materialCache.containsKey(item.getMaterialNumber())) {//没有命中缓存的时候去查一下
                    MaterialModel materialModel = materialModelService.findByCode(item.getMaterialNumber());
                    if (null != materialModel) {
                        item.setMaterialDesc(materialModel.getName());
                        materialCache.put(item.getMaterialNumber(), materialModel.getName());
                    }
                } else {
                    item.setMaterialDesc(materialCache.get(item.getMaterialNumber()));
                }
            }
        });
        return ResultGenerator.success(fbTurnstoreTrayItemDtos);
    }

    @ApiOperation(value = "方棒组托详情详细信息")
    @GetMapping("/{id}")
    public Result<FbTurnstoreTrayItemDto> get(@PathVariable @ApiParam(value = "方棒组托详情id") Integer id) {
        FbTurnstoreTrayItem fbTurnstoreTrayItem = fbTurnstoreTrayItemService.get(id);
        if (null == fbTurnstoreTrayItem) {
            return ResultGenerator.fail("该方棒组托详情不存在");
        }
        return ResultGenerator.success(toEagerDto(fbTurnstoreTrayItem));
    }

    @ApiOperation(value = "创建方棒组托详情")
    @PostMapping("/create")
    public Result create(@RequestBody @Valid @ApiParam(value = "方棒组托详情对象") FbTurnstoreTrayItemDto fbTurnstoreTrayItemDto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        FbTurnstoreTrayItem fbTurnstoreTrayItem = fromDto(fbTurnstoreTrayItemDto);
        fbTurnstoreTrayItem.setFactoryName("5041");
        fbTurnstoreTrayItemService.saveOrUpdate(fbTurnstoreTrayItem);
        return ResultGenerator.success();
    }

    @ApiOperation(value = "更新方棒组托详情")
    @PostMapping("/update")
    public Result update(@RequestBody @Valid @ApiParam(value = "方棒组托详情") FbTurnstoreTrayItemDto dto, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResultGenerator.fail(bindingResult.getFieldError().getDefaultMessage());
        }
        if (dto.getId() == null) {
            return ResultGenerator.fail("id不能为空");
        }
        FbTurnstoreTrayItem entity = fbTurnstoreTrayItemService.get(dto.getId());
        if (entity == null) {
            return ResultGenerator.fail("原信息不存在");
        }
        try {
            FbTurnstoreTrayItem entityFromFto = fromDto(dto);
            entityFromFto.setFactoryName("5041");
            BeanUtils.copyProperties(entityFromFto, entity, BeanUtil.getIgnoreProperties(entityFromFto, null, null));
            fbTurnstoreTrayItemService.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 Integer[] ids) {
        for (Integer id : ids) {
            FbTurnstoreTrayItem trayItem = fbTurnstoreTrayItemService.get(id);
            if (null == trayItem) {
                return ResultGenerator.fail("原信息不存在");
            }
            if (0 != trayItem.getState()) {
                return ResultGenerator.fail("当前不处于待出库状态,不能进行删除,请刷新后再试");
            }
            //解锁组托状态
            PlanProcessingOrder planProcessingOrder = planProcessingOrderService.findByCode(trayItem.getSectionNo());
            planProcessingOrder.setStatus(EnumValuesFactory.PlanProcessingOrderStatus.加工中.getKey());
            planProcessingOrderService.saveOrUpdate(planProcessingOrder);
            String userName = BaseContextHandler.getUsername() == null ? "kong" : BaseContextHandler.getUsername();
            log.error("删除方棒组托详情.." + userName + " id:" + id);
            fbTurnstoreTrayItemService.delete(id);
        }
        return ResultGenerator.success();
    }

    /**
     * 晶科方棒组托明细导出
     *
     * @param request
     * @param requestPage
     * @param response
     */
    @ApiOperation(value = "导出方棒组托明细")
    @ApiImplicitParams(@ApiImplicitParam(name = "search_EQ_trayNo", value = "托号", dataType = "String", paramType = "query"))
    @GetMapping("/export")
    public void export(ServletRequest request, @ApiIgnore RequestPage requestPage, HttpServletResponse response) {

        if (GlobalSwitch.enable(GlobalSwitchNamespace.NAMESPACE_COMMON_SWITCH, "fb_turn_export_new", false)) {
            exportMultiThread(request, requestPage, response);
            return;
        }

        try {
            Specification<FbTurnstoreTrayItem> specification = DynamicSpecifications.bySearchFilter(request, FbTurnstoreTrayItem.class);
            List<FbTurnstoreTrayItem> fbTurnstoreTrayItemList = fbTurnstoreTrayItemService.findByExampleSort(specification, null);
            //每50个一批进行查询
            int batchSize = 50;
            List<String> sectionIds = new ArrayList<>(batchSize);
            List<FbCheckOutData> tmpList = new ArrayList<>();
            int i = 0;
            for (FbTurnstoreTrayItem item : fbTurnstoreTrayItemList) {
                sectionIds.add(item.getSectionNo());
                i++;
                if (i % batchSize == 0) {//一批提交一下
                    //查询接口
                    List<FbCheckOutData> fbCheckOutDataList = fbCheckOutDataService.findCheckOutDataByFbSectionNoIns(sectionIds);
                    if (!CollectionUtils.isEmpty(fbCheckOutDataList)) {
                        tmpList.addAll(fbCheckOutDataList);
                    }
                    //清空数据
                    sectionIds.clear();
                }
            }
            if (sectionIds.size() > 0) {
                List<FbCheckOutData> fbCheckOutDataList = fbCheckOutDataService.findCheckOutDataByFbSectionNoIns(sectionIds);
                if (!CollectionUtils.isEmpty(fbCheckOutDataList)) {
                    tmpList.addAll(fbCheckOutDataList);
                }
            }
            log.info("size:{} tmpSize:{} fbTurnstoreTrayItemList.Size:{}", i, tmpList.size(), fbTurnstoreTrayItemList.size());
            //构建map
            //Map<String, FbCheckOutData> fbCheckOutDataMap = tmpList.stream().collect(Collectors.toMap(FbCheckOutData::getFbSectionNo, entry -> entry));
            Map<String, FbCheckOutData> fbCheckOutDataMap = new HashMap<>(tmpList.size());
            for (FbCheckOutData checkOutData : tmpList) {
                if (!fbCheckOutDataMap.containsKey(checkOutData.getFbSectionNo())) {
                    fbCheckOutDataMap.put(checkOutData.getFbSectionNo(), checkOutData);
                }
            }
            //做一个物料缓存
            Map<String, String> materialCache = new HashMap<>();
            Map<String, FbTurnstoreTray> trayMap = new HashMap<>();
            List<ExportFbTurnstoreTrayItemDto> dtos = fbTurnstoreTrayItemList.stream().map(entity -> {
                        ExportFbTurnstoreTrayItemDto exportFbTurnstoreTrayItemDto = toLazyExportDto(entity);
                        if (materialCache.containsKey(entity.getMaterialNumber())) {
                            exportFbTurnstoreTrayItemDto.setMaterialDesc(materialCache.get(entity.getMaterialNumber()));
                        } else {
                            MaterialModel materialModel = materialModelService.findByCode(entity.getMaterialNumber());
                            if (null != materialModel) {
                                exportFbTurnstoreTrayItemDto.setMaterialDesc(materialModel.getName());
                                materialCache.put(entity.getMaterialNumber(), materialModel.getName());
                            }
                        }
                        FbCheckOutData fbCheckOutData = fbCheckOutDataMap.get(entity.getSectionNo());
                        if (null != fbCheckOutData) {
                            //TCentreLife 头少子
                            exportFbTurnstoreTrayItemDto.setLife(fbCheckOutData.getMeanCarrierLifetimeA());
                            //w少子
                            exportFbTurnstoreTrayItemDto.setWlife(fbCheckOutData.getMeanCarrierLifetimeB());
                            //头电阻 TRadialCentre tRadialCentre
                            exportFbTurnstoreTrayItemDto.setTradialCentre(fbCheckOutData.getMeanResistivityA());
                            //尾电阻
                            exportFbTurnstoreTrayItemDto.setWradialCentre(fbCheckOutData.getMeanResistivityB());
                            //有效长度
                            exportFbTurnstoreTrayItemDto.setEffectiveLength(fbCheckOutData.getInstoreLengthFb());
                            //是否是完结
                            exportFbTurnstoreTrayItemDto.setIsDone(StringUtils.equals("是", fbCheckOutData.getClosureIdentification()) ? "是" : "否");
                            //重量
                            exportFbTurnstoreTrayItemDto.setTheoryWeightFb(fbCheckOutData.getTheoryWeightFb().setScale(3, RoundingMode.HALF_UP));
                            //头尾识别
                            exportFbTurnstoreTrayItemDto.setHeadTailRecognition(fbCheckOutData.getHeadTailRecognition());
                            //复投次数
                            exportFbTurnstoreTrayItemDto.setAgainNum(fbCheckOutData.getAgainNum());
                            //产品简称
                            exportFbTurnstoreTrayItemDto.setAbbreviation(fbCheckOutData.getAbbreviation());
                        }
                        //查询入库人和入库时间
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                        SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
                        if (trayMap.containsKey(entity.getTrayNo())) {
                            FbTurnstoreTray turnstoreTray = trayMap.get(entity.getTrayNo());
                            Date confirmTime = turnstoreTray.getConfirmTime();
                            exportFbTurnstoreTrayItemDto.setToWmsDate(confirmTime == null ? "" : dateFormat.format(confirmTime));
                            exportFbTurnstoreTrayItemDto.setToWmsTime(confirmTime == null ? "" : timeFormat.format(confirmTime));
                            exportFbTurnstoreTrayItemDto.setToWmsUser(turnstoreTray.getConfirmUser());
                        } else {
                            FbTurnstoreTray turnstoreTray = fbTurnstoreTrayService.findByTrayNo(entity.getTrayNo());
                            Date confirmTime = turnstoreTray.getConfirmTime();
                            exportFbTurnstoreTrayItemDto.setToWmsDate(confirmTime == null ? "" : dateFormat.format(confirmTime));
                            exportFbTurnstoreTrayItemDto.setToWmsTime(confirmTime == null ? "" : timeFormat.format(confirmTime));
                            exportFbTurnstoreTrayItemDto.setToWmsUser(turnstoreTray.getConfirmUser());
                            trayMap.put(entity.getTrayNo(), turnstoreTray);
                        }
                        exportFbTurnstoreTrayItemDto.setEquipmentCode(fbCheckOutData.getFbSectionNo().substring(SectionIndexRangeEnum.炉台号.getBeginIndex(), SectionIndexRangeEnum.炉台号.getEndIndex()));
                        return exportFbTurnstoreTrayItemDto;
                    }
            ).collect(Collectors.toList());

            BigDecimal total = new BigDecimal(0);
            for (ExportFbTurnstoreTrayItemDto item : dtos) {
                total = total.add(item.getTheoryWeightFb());
            }
            log.info("方棒取3位后的总重量：" + total);
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("方棒组托明细", String.valueOf(StandardCharsets.UTF_8)).replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            EasyExcelFactory.write(response.getOutputStream(), ExportFbTurnstoreTrayItemDto.class)
                    .sheet("方棒组托明细")
                    .doWrite(dtos);
        } catch (Exception e) {
            log.error("error_in_export_new..", e);
            throw new RuntimeException("方棒组托明细导出失败，错误信息：" + e.getMessage());
        }
    }

    private final ExecutorService es = Executors.newFixedThreadPool(20);

    @ApiOperation(value = "导出方棒组托明细")
    public void exportMultiThread(ServletRequest request, @ApiIgnore RequestPage requestPage, HttpServletResponse response) {
        try {
            Specification<FbTurnstoreTrayItem> specification = DynamicSpecifications.bySearchFilter(request, FbTurnstoreTrayItem.class);
            List<FbTurnstoreTrayItem> fbTurnstoreTrayItemList = fbTurnstoreTrayItemService.findByExampleSort(specification, null);
            //每50个一批进行查询
            int batchSize = 50;
            List<String> sectionIds = new CopyOnWriteArrayList<>();
            List<FbCheckOutData> tmpList = new CopyOnWriteArrayList<>();
            List<Future<List<FbCheckOutData>>> futures = new ArrayList<>();
            Set<String> trayNoSet = new HashSet<>();//托号缓存
            int i = 0;
            for (FbTurnstoreTrayItem item : fbTurnstoreTrayItemList) {
                trayNoSet.add(item.getTrayNo());
                sectionIds.add(item.getSectionNo());
                i++;
                if (i % batchSize == 0) {//一批提交一下
                    List<String> tmpIds = new ArrayList<>(sectionIds);//切换下引用
                    //提交任务
                    Future<List<FbCheckOutData>> future = es.submit(() -> {
                        //查询接口
                        return fbCheckOutDataService.findCheckOutDataByFbSectionNoIns(tmpIds);
                    });
                    futures.add(future);
                    //清空数据
                    sectionIds.clear();
                }
            }
            //这一步同步去调用，时间是一样的
            if (sectionIds.size() > 0) {
                List<FbCheckOutData> fbCheckOutDataList = fbCheckOutDataService.findCheckOutDataByFbSectionNoIns(sectionIds);
                if (!CollectionUtils.isEmpty(fbCheckOutDataList)) {
                    tmpList.addAll(fbCheckOutDataList);
                }
            }
            //阻塞去拿数据
            for (Future<List<FbCheckOutData>> future : futures) {
                List<FbCheckOutData> data = future.get(5, TimeUnit.SECONDS);
                if (!CollectionUtils.isEmpty(data)) {
                    tmpList.addAll(data);
                }
            }

            log.info("size:{} tmpSize:{} fbTurnstoreTrayItemList.Size:{}", i, tmpList.size(), fbTurnstoreTrayItemList.size());

            //构建map
            Map<String, FbCheckOutData> fbCheckOutDataMap = new HashMap<>(tmpList.size());
            for (FbCheckOutData checkOutData : tmpList) {
                if (!fbCheckOutDataMap.containsKey(checkOutData.getFbSectionNo())) {
                    fbCheckOutDataMap.put(checkOutData.getFbSectionNo(), checkOutData);
                }
            }

            //做一个物料缓存
            Map<String, String> materialCache = new HashMap<>();
            //托信息获取
            Map<String, FbTurnstoreTray> trayMap = fbTurnstoreTrayService.findByTrayNoList(new ArrayList<>(trayNoSet));
            //补全信息
            List<ExportFbTurnstoreTrayItemDto> dtos = fbTurnstoreTrayItemList.stream().map(entity -> {
                        ExportFbTurnstoreTrayItemDto exportFbTurnstoreTrayItemDto = toLazyExportDto(entity);
                        if (materialCache.containsKey(entity.getMaterialNumber())) {
                            exportFbTurnstoreTrayItemDto.setMaterialDesc(materialCache.get(entity.getMaterialNumber()));
                        } else {
                            MaterialModel materialModel = materialModelService.findByCode(entity.getMaterialNumber());
                            if (null != materialModel) {
                                exportFbTurnstoreTrayItemDto.setMaterialDesc(materialModel.getName());
                                materialCache.put(entity.getMaterialNumber(), materialModel.getName());
                            }
                        }
                        FbCheckOutData fbCheckOutData = fbCheckOutDataMap.get(entity.getSectionNo());
                        if (null != fbCheckOutData) {
                            //TCentreLife 头少子
                            exportFbTurnstoreTrayItemDto.setLife(fbCheckOutData.getMeanCarrierLifetimeA());
                            //w少子
                            exportFbTurnstoreTrayItemDto.setWlife(fbCheckOutData.getMeanCarrierLifetimeB());
                            //头电阻 TRadialCentre tRadialCentre
                            exportFbTurnstoreTrayItemDto.setTradialCentre(fbCheckOutData.getMeanResistivityA());
                            //尾电阻
                            exportFbTurnstoreTrayItemDto.setWradialCentre(fbCheckOutData.getMeanResistivityB());
                            //有效长度
                            exportFbTurnstoreTrayItemDto.setEffectiveLength(fbCheckOutData.getInstoreLengthFb());
                            //是否是完结
                            exportFbTurnstoreTrayItemDto.setIsDone(StringUtils.equals("是", fbCheckOutData.getClosureIdentification()) ? "是" : "否");
                            //重量
                            exportFbTurnstoreTrayItemDto.setTheoryWeightFb(fbCheckOutData.getTheoryWeightFb().setScale(3, RoundingMode.HALF_UP));
                            //头尾识别
                            exportFbTurnstoreTrayItemDto.setHeadTailRecognition(fbCheckOutData.getHeadTailRecognition());
                            //复投次数
                            exportFbTurnstoreTrayItemDto.setAgainNum(fbCheckOutData.getAgainNum());
                            //产品简称
                            exportFbTurnstoreTrayItemDto.setAbbreviation(fbCheckOutData.getAbbreviation());
                            //炉台号
                            exportFbTurnstoreTrayItemDto.setEquipmentCode(fbCheckOutData.getFbSectionNo().substring(SectionIndexRangeEnum.炉台号.getBeginIndex(), SectionIndexRangeEnum.炉台号.getEndIndex()));
                        }
                        //查询入库人和入库时间
                        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
                        SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
                        if (trayMap.containsKey(entity.getTrayNo())) {
                            FbTurnstoreTray turnstoreTray = trayMap.get(entity.getTrayNo());
                            Date confirmTime = turnstoreTray.getConfirmTime();
                            exportFbTurnstoreTrayItemDto.setToWmsDate(confirmTime == null ? "" : dateFormat.format(confirmTime));
                            exportFbTurnstoreTrayItemDto.setToWmsTime(confirmTime == null ? "" : timeFormat.format(confirmTime));
                            exportFbTurnstoreTrayItemDto.setToWmsUser(turnstoreTray.getConfirmUser());
                        }
                        return exportFbTurnstoreTrayItemDto;
                    }
            ).collect(Collectors.toList());

            BigDecimal total = new BigDecimal(0);
            for (ExportFbTurnstoreTrayItemDto item : dtos) {
                total = total.add(item.getTheoryWeightFb());
            }
            log.info("方棒取3位后的总重量：" + total);
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("方棒组托明细", String.valueOf(StandardCharsets.UTF_8)).replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            EasyExcelFactory.write(response.getOutputStream(), ExportFbTurnstoreTrayItemDto.class)
                    .sheet("方棒组托明细")
                    .doWrite(dtos);
        } catch (Exception e) {
            log.error("error_in_export_new..", e);
            throw new RuntimeException("方棒组托明细导出失败，错误信息：" + e.getMessage());
        }
    }


    private ExportFbTurnstoreTrayItemDto toLazyExportDto(FbTurnstoreTrayItem entity) {
        ExportFbTurnstoreTrayItemDto map = modelMapper.map(entity, ExportFbTurnstoreTrayItemDto.class);
        map.setFactoryName("5041");
        switch (entity.getState()) {
            case 1:
                map.setState("已入库");
                break;
            case 2:
                map.setState("待入库");
                break;
            case 3:
                map.setState("拒收");
                break;
            case 4:
                map.setState("已取消");
                break;
            default:
                map.setState("待出库");
                break;
        }
        return map;
    }

    @ApiOperation(value = "导出Excel")
    @GetMapping("/exportExcel")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "search_EQ_sectionNo", value = "晶段编号", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_EQ_trayNo", value = "托号", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_EQ_state", value = "入库状态", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_GTE_time", value = "组托时间", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_LTE_time", value = "组托时间", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_GTE_toWmsTime", value = "入综计时间", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_LTE_toWmsTime", value = "入综计时间", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_GTE_operationTime", value = "操作/确认时间", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_LTE_operationTime", value = "操作/确认时间", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_GTE_confirmTime", value = "确认时间", dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "search_LTE_confirmTime", value = "确认时间", dataType = "string", paramType = "query"),
    })
    public void exportExcel(HttpServletRequest request, HttpServletResponse resp) {
        fbTurnstoreTrayItemService.exportExcel(request, resp);
    }

    @ApiOperation(value = "根据组托明细id查询组托信息")
    @GetMapping("/findById")
    public Result<FbTurnstoreTrayItemDto> findById(@RequestParam(value = "id") Integer id) {
        if (null == id) {
            return ResultGenerator.fail("组托明细id不能为空");
        }
        FbTurnstoreTrayItem fbTurnstoreTrayItem = fbTurnstoreTrayItemService.get(id);
        return ResultGenerator.success(toEagerDto(fbTurnstoreTrayItem));
    }
    @ApiOperation(value = "根据晶编号查询组托信息")
    @GetMapping("/findBySectionNo")
    public Result<FbTurnstoreTrayItemDto> findBySectionNo(@RequestParam(value = "sectionNo") String sectionNo) {
        if (null == sectionNo) {
            return ResultGenerator.fail("晶编号不能为空");
        }
        FbTurnstoreTrayItem fbTurnstoreTrayItem = fbTurnstoreTrayItemService.findBySectionNo3(sectionNo);
        if (Objects.isNull(fbTurnstoreTrayItem)){
            return ResultGenerator.fail("该晶编号:"+sectionNo+"未在方棒组托明细中查到数据");
        }
        return ResultGenerator.success(toEagerDto(fbTurnstoreTrayItem));
    }


    public FbTurnstoreTrayItemDto toLazyDto(FbTurnstoreTrayItem entity) {
        return modelMapper.map(entity, FbTurnstoreTrayItemDto.class);
    }

    public FbTurnstoreTrayItemDto toEagerDto(FbTurnstoreTrayItem entity) {
        return modelMapper.map(entity, FbTurnstoreTrayItemDto.class);
    }

    public FbTurnstoreTrayItem fromDto(FbTurnstoreTrayItemDto dto) {
        return modelMapper.map(dto, FbTurnstoreTrayItem.class);
    }


}
