lxp
2025-03-12 11af23e0c7976eed1211ba2ca0beae3a12e19310
cnas-require/src/main/java/com/ruoyi/requier/service/impl/InsOrderPlanServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,2784 @@
package com.ruoyi.requier.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.data.*;
import com.deepoove.poi.data.style.Style;
import com.deepoove.poi.util.TableTools;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.basic.mapper.StandardProductListMapper;
import com.ruoyi.basic.service.StandardTemplateService;
import com.ruoyi.basic.vo.StandardProductVO;
import com.ruoyi.common.constant.ExchangeConstants;
import com.ruoyi.common.constant.RouterKeyConstants;
import com.ruoyi.common.core.domain.entity.Custom;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.User;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.JackSonUtil;
import com.ruoyi.common.utils.QueryWrappers;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.exception.ErrorException;
import com.ruoyi.framework.util.MatrixToImageWriter;
import com.ruoyi.framework.util.RedisUtil;
import com.ruoyi.inspect.dto.*;
import com.ruoyi.inspect.mapper.*;
import com.ruoyi.inspect.pojo.*;
import com.ruoyi.inspect.service.InsBushingService;
import com.ruoyi.inspect.service.InsOrderService;
import com.ruoyi.inspect.service.InsUnPassService;
import com.ruoyi.inspect.service.impl.InsOrderServiceImpl;
import com.ruoyi.framework.util.SheetWriteHandlerUtil;
import com.ruoyi.inspect.vo.*;
import com.ruoyi.performance.mapper.AuxiliaryOutputWorkingHoursMapper;
import com.ruoyi.performance.mapper.PerformanceShiftMapper;
import com.ruoyi.performance.mapper.ShiftTimeMapper;
import com.ruoyi.requier.handler.*;
import com.ruoyi.requier.pojo.InformationNotification;
import com.ruoyi.requier.service.InformationNotificationService;
import com.ruoyi.requier.service.InsOrderPlanService;
import com.ruoyi.system.mapper.CustomMapper;
import com.ruoyi.system.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
 * æ£€éªŒä»»åŠ¡-业务实现层
 */
@Service
@Slf4j
public class InsOrderPlanServiceImpl extends ServiceImpl<InsOrderMapper, InsOrder> implements InsOrderPlanService {
    // æŠ¥å‘Šæ‰«ç è·¯å¾„
    @Value("${phoneQrCode}")
    private String phoneQrCode;
    @Resource
    private InsReportServiceImpl insReportService;
    @Resource
    private InsSampleMapper insSampleMapper;
    @Resource
    private InsSampleUserMapper insSampleUserMapper;
    @Resource
    private InsOrderMapper insOrderMapper;
    @Resource
    private InsOrderService insOrderService;
    @Resource
    private InsOrderServiceImpl insOrderServiceImpl;
    @Resource
    private StandardTemplateService standardTemplateService;
    @Resource
    private InsOrderStateMapper insOrderStateMapper;
    @Resource
    private InsProductMapper insProductMapper;
    @Resource
    private ShiftTimeMapper shiftTimeMapper;
    @Resource
    private PerformanceShiftMapper performanceShiftMapper;
    @Resource
    private StandardProductListMapper standardProductListMapper;
    @Value("${wordUrl}")
    private String wordUrl;
    @Value("${twoCode}")
    private String twoCode;
    @Resource
    private InsReportMapper insReportMapper;
    @Resource
    private InsProductResultMapper insProductResultMapper;
    @Resource
    private InsProductUserMapper insProductUserMapper;
    @Resource
    private InsUnPassService insUnPassService;
    @Resource
    AuxiliaryOutputWorkingHoursMapper auxiliaryOutputWorkingHoursMapper;
    @Resource
    private InformationNotificationService informationNotificationService;
    @Resource
    private UserMapper userMapper;
    @Resource
    private CustomMapper customMapper;
    @Value("${file.path}")
    private String imgUrl;
    @Resource
    private InsBushingService insBushingService;
    @Resource
    private InsBushingMapper insBushingMapper;
    @Resource
    private InsFiberMapper insFiberMapper;
    @Resource
    private InsFibersMapper insFibersMapper;
    @Resource
    private InsOrderFileMapper insOrderFileMapper;
    @Resource
    private InsReportApproveConfigMapper insReportApproveConfigMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    private ReentrantLock lock = new ReentrantLock();
    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Override
    public void exportInsOrderPlanResult(Map<String, Object> data, HttpServletResponse response) {
        List<Map<String,Object>> dataList = new ArrayList<>();
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            Object o = getTabHeader(data.get("sonLaboratory").toString(), data.get("samples").toString()).get("tableHeader");// èŽ·å–åŠ¨æ€è¡¨å¤´
            List<Map<String, Object>>  tableHeader = objectMapper.readValue(JSONUtil.toJsonStr(o), new TypeReference<List<Map<String, Object>>>() {
            });// è¡¨å¤´æ•°æ®
            Map<String, Object> table = objectMapper.readValue(JSONUtil.toJsonStr(data.get("trendsTable")), new TypeReference<Map<String, Object>>() {
            });
            List<Map<String, Object>> trendsTable = getInsOrderPlanList(table); // è¡¨æ ¼æ•°æ®
            for (Map<String, Object> trend : trendsTable) {
                Map<String, Object> addMap = new HashMap<>();
                addMap.put("委托单号", trend.get("entrustCode"));
                addMap.put("样品编号", trend.get("sampleCode"));
                addMap.put("管色标", trend.get("bushing"));
                addMap.put("光纤带色标", trend.get("fibers"));
                addMap.put("光纤色标", trend.get("fiber"));
                addMap.put("检验项目分类", trend.get("inspectionItem"));
                addMap.put("创建人", trend.get("userName"));
                addMap.put("检测时间", trend.get("insTime"));
                addMap.put("下发时间", trend.get("sendTime"));
                for (Map<String, Object> map : tableHeader) {
                    if(Objects.isNull(trend.get(map.get("prop").toString())) || Objects.equals(trend.get(map.get("prop").toString()),"null")) {
                        addMap.put(map.get("label").toString(), "");
                    }else {
                        addMap.put(map.get("label").toString(), trend.get(map.get("prop").toString()));
                    }
                }
                dataList.add(addMap);
            }
            List<List<String>> head = head(tableHeader);
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("UTF-8");
            String fileName = URLEncoder.encode("检验结果", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                    new HorizontalCellStyleStrategy(getHeadStyle((short) 12),new WriteCellStyle());
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                    .registerWriteHandler(new SheetWriteHandlerUtil(data.get("samples").toString(),head.size()))
                    .useDefaultStyle(true).relativeHeadRowIndex(1)
                    .registerWriteHandler(horizontalCellStyleStrategy)
                    .build();
            WriteSheet mainSheet = EasyExcel.writerSheet("Sheet0").head(head).build();
            excelWriter.write(dataList(head,dataList), mainSheet);
            // å…³é—­æµ
            excelWriter.finish();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * åŠ¨æ€è¡¨å¤´
     * @param tableHeader
     * @return
     */
    private List<List<String>> head(List<Map<String, Object>>  tableHeader) {
        List<List<String>> list = new ArrayList<>();
        List<String> head0 = new ArrayList<>();
        head0.add("委托单号");
        List<String> head1 = new ArrayList<>();
        head1.add("样品编号");
        List<String> head2 = new ArrayList<>();
        head2.add("检验项目分类");
        List<String> head3 = new ArrayList<>();
        head3.add("创建人");
        List<String> head4 = new ArrayList<>();
        head4.add("检测时间");
        List<String> head5 = new ArrayList<>();
        head5.add("下发时间");
        List<String> head6 = new ArrayList<>();
        head6.add("管色标");
        List<String> head7 = new ArrayList<>();
        head7.add("光纤带色标");
        List<String> head8 = new ArrayList<>();
        head8.add("光纤色标");
        list.add(head0);
        list.add(head1);
        list.add(head6);
        list.add(head7);
        list.add(head8);
        list.add(head2);
        list.add(head3);
        list.add(head4);
        list.add(head5);
        for (Map<String, Object> map : tableHeader) {
            List<String> head = new ArrayList<>();
            head.add(map.get("label").toString());
            list.add(head);
        }
        return list.stream().distinct().collect(Collectors.toList());
    }
    /**
     * excel导出数据
     * @param head
     * @param dataList
     * @return
     */
    private List<List<Object>> dataList(List<List<String>> head,List<Map<String,Object>> dataList) {
        List<List<Object>> list = new ArrayList<>();
        for(Map<String, Object> map : dataList) {
            List<Object> addList = new ArrayList<>();
            for(List<String> k : head) {
                if(map.containsKey(k.get(0))) {
                    addList.add(map.get(k.get(0)));
                }
            }
            list.add(addList);
        }
        return list;
    }
    /**
     * å¤´çš„ç­–ç•¥
     * @return
     */
    public  WriteCellStyle getHeadStyle(Short size){
        // å¤´çš„ç­–ç•¥
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // èƒŒæ™¯é¢œè‰²
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // å­—体
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontName("黑体");//设置字体名字
        headWriteFont.setFontHeightInPoints(size);//设置字体大小
        headWriteFont.setBold(true);//字体加粗
        headWriteCellStyle.setWriteFont(headWriteFont); //在样式用应用设置的字体;
        return headWriteCellStyle;
    }
    @Override
    public List<Map<String, Object>> getInsOrderPlanList(Map<String,Object> data) {
        String sampleType = data.get("sampleType").toString();
        String sonLaboratory = data.get("sonLaboratory").toString();
        String entrustCode = data.get("entrustCode").toString();
        Integer createUser = null;
        String name = "";
        if(StringUtils.isNotBlank(data.get("createUser").toString())) {
             createUser = Integer.parseInt(data.get("createUser").toString());
             name = userMapper.selectById(createUser).getName();
        }
        String sampleCode = data.get("sampleCode").toString();
        String startTime = "";
        String endTime = "";
        List<Map<String, Object>> maps = new ArrayList<>();
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            if(StringUtils.isNotBlank(data.get("insTime").toString()) && !Objects.isNull(data.get("insTime"))) {
                List insTime = objectMapper.readValue(JSONUtil.toJsonStr(data.get("insTime")), List.class);
                startTime = insTime.get(0).toString();
                endTime = insTime.get(1).toString();
            }
            // è¡¨å¤´ä¿¡æ¯
            List<Map<String, Object>> headerS = objectMapper.readValue(JSONUtil.toJsonStr(data.get("headerS")), new TypeReference<List<Map<String, Object>>>() {
            });
            // åˆ¤æ–­æ˜¯å¦æ˜¯æ¸©åº¦å¾ªçޝ
            if(sampleType.equals("温度循环")) {
                List<ExportInsProductVO> insOrderTemList = insOrderMapper.getInsOrderTemList(entrustCode, sampleCode, startTime, endTime,name);
                List<TemperatureCycling> temList = insOrderServiceImpl.getTemList(insOrderTemList);
                for (TemperatureCycling map : temList) {
                    Map<String, Object> resultMap = new HashMap<>();
                    resultMap.put("entrustCode", map.getEntrustCode()); //委托单号
                    resultMap.put("sampleCode", map.getSampleCode()); //样品编号
                    resultMap.put("bushing", map.getBushColor()); //套管
                    resultMap.put("fiber", map.getColor()); //光纤
                    resultMap.put("fibers", map.getCode()); //光纤带
                    resultMap.put("userName", map.getCheckName()); //检验人
                    resultMap.put("insTime", map.getInsTime()); //检测时间
                    resultMap.put("sendTime", map.getSendTime()); //下发时间
                    resultMap.put("inspectionItem", map.getSample()); //检验项目
                    //温度循环子项
                    resultMap.put("inspectionItems", map.getInspectionItem());
                    resultMap.put("inspectionItemSubclass", map.getInspectionItemSubclass());
                    resultMap.put("attenuationCoefficient1310", map.getAttenuationCoefficient1310());
                    resultMap.put("attenuationDifference1", map.getAttenuationDifference1());
                    resultMap.put("attenuationDifference2", map.getAttenuationDifference2());
                    resultMap.put("attenuationCoefficient1625", map.getAttenuationCoefficient1625());
                    resultMap.put("attenuationDifference3", map.getAttenuationDifference3());
                    resultMap.put("attenuationCoefficient1383", map.getAttenuationCoefficient1383());
                    resultMap.put("attenuationDifference4", map.getAttenuationDifference4());
                    resultMap.put("attenuationCoefficient1490", map.getAttenuationCoefficient1490());
                    resultMap.put("attenuationDifference5", map.getAttenuationDifference5());
                    resultMap.put("attenuationDifferenceMax", map.getAttenuationDifferenceMax());
                    resultMap.put("insResult", map.getInsResult());
                    maps.add(resultMap);
                }
            }
            else {
                List<Map<String, Object>> insOrderPlanList = baseMapper.getInsOrderPlanList(sonLaboratory, entrustCode, sampleCode, createUser, startTime, endTime,sampleType);
                for (Map<String, Object> map : insOrderPlanList) {
                    Map<String, Object> resultMap = new HashMap<>();
                    resultMap.put("entrustCode", map.get("entrustCode")); //委托单号
                    resultMap.put("sampleCode", map.get("sampleCode")); //样品编号
                    resultMap.put("bushing", map.get("bushing")); //套管
                    resultMap.put("fiber", map.get("fiber")); //光纤
                    resultMap.put("fibers", map.get("fibers")); //光纤带
                    resultMap.put("userName", map.get("userName")); //创建人
                    resultMap.put("insTime", map.get("insTime")); //检测时间
                    resultMap.put("sendTime", map.get("sendTime")); //下发时间
                    resultMap.put("inspectionItem", map.get("inspectionItem")); //检验项目
                    // æŸ¥çœ‹è¡¨å¤´æ˜¯å¦å­˜åœ¨å­é¡¹
                    List<Map<String, Object>> collect = headerS.stream().filter(item ->
                                    item.get("label").toString().equals(map.get("inspectionItemSubclass").toString()))
                            .collect(Collectors.toList());
                    // æœ‰å°±å–子项 æ²¡æœ‰å°±å–父项
                    if(!collect.isEmpty() && !Objects.isNull(collect)) {
                        resultMap.put(collect.get(0).get("prop").toString(), map.get("lastValue"));//检验子项目  æ£€éªŒç»“æžœ
                    }else {
                        List<Map<String, Object>> collect1 = headerS.stream().filter(item ->
                                        item.get("label").toString().equals(map.get("inspectionItem").toString()))
                                .collect(Collectors.toList());
                        if(!collect1.isEmpty() && !Objects.isNull(collect1)) {
                            resultMap.put(collect1.get(0).get("prop").toString(), map.get("lastValue"));//检验项目  æ£€éªŒç»“æžœ
                        }
                    }
                    maps.add(resultMap);
                }
            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        return  maps.stream().distinct().collect(Collectors.toList());
    }
    /**
     * èŽ·å–å½“å‰ç”¨æˆ·çš„å®žéªŒå®¤
     * @return
     */
    private String getCurrentUserLaboratory(){
        // èŽ·å–å½“å‰äººæ‰€åœ¨å®žéªŒå®¤
        Integer userId = SecurityUtils.getUserId().intValue();
        String departLimsId = userMapper.selectById(userId).getDepartLimsId();
        String laboratory = "";
        if(StringUtils.isNotBlank(departLimsId)) {
            String[] split = departLimsId.split(",");
            for (String s : split) {
                if (StringUtils.isNotBlank(s) && (!Arrays.asList("1","22").contains(s))) {
                    laboratory = insOrderMapper.getDepartment(Integer.parseInt(s));
                }
            }
        }
        return laboratory;
    }
    /**
     * å¯¼å‡ºå§”托费用
     * @param data æ•°æ®
     */
    @Override
    public void exportCommissionFees(Map<String, Object> data,HttpServletResponse response) {
        String laboratory = getCurrentUserLaboratory();
        // æ—¥æœŸæ ¼å¼åŒ–
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String start = LocalDateTime.of(
                LocalDate.parse(data.get("startTime").toString(),
                        dateTimeFormatter),LocalTime.of(00, 00, 00)
        ).toString();
        String end = LocalDateTime.of(
                LocalDate.parse(data.get("endTime").toString(),
                        dateTimeFormatter),LocalTime.of(23, 59, 59)
        ).toString();
        // èŽ·å–æ•°æ®
        String company = data.get("company").toString();
        List<CommissionFeesDto> list = insOrderMapper.selectCommissionFees(laboratory,company, start, end);
        list = list.stream().map(dto -> {
            Set<String> uniqueTags = new HashSet<>();
            if (dto.getInsItem().contains(",")) {
                for (String s : dto.getInsItem().split(",")) {
                    uniqueTags.add(s.split("@")[0]);
                }
            } else {
                uniqueTags.add(dto.getInsItem().split("@")[0]);
            }
            dto.setInsItem(uniqueTags.toString());
            return dto;
        }).collect(Collectors.toList());
        try {
            String fileName = URLEncoder.encode(laboratory+"委托费用统计", "UTF-8");
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-disposition", "attachment;filename=" + fileName + ".xlsx");
            // æ–°å»ºExcelWriter
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(),CommissionFeesDto.class).build();
            // æ ¹æ®å§”托单位进行sheet分类
            Map<String, List<CommissionFeesDto>> collect = list.stream().collect(Collectors.groupingBy(CommissionFeesDto::getCompany));
            Iterator<Map.Entry<String, List<CommissionFeesDto>>> iterator = collect.entrySet().iterator();
            int i = 0;
            while(iterator.hasNext()) {
                Map.Entry<String, List<CommissionFeesDto>> entry = iterator.next();
                WriteSheet writeSheet = EasyExcel.writerSheet(i, entry.getKey()).build();
                excelWriter.write(entry.getValue(), writeSheet);
                i++;
            }
//            WriteSheet writeSheet = EasyExcel.writerSheet().head(CommissionFeesDto.class).build();
//            excelWriter.write(list, writeSheet);
            // å°†æ•°æ®å†™å…¥
            excelWriter.finish();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @Override
    public void exportUnInsProducts(UnInsProductsDTO unInsProductsDTO, HttpServletResponse response) {
        String laboratory = getCurrentUserLaboratory();
        //日期格式化
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDateTime startDateTime = LocalDateTime.of(LocalDate.parse(unInsProductsDTO.getStartDate(),dateTimeFormatter),LocalTime.MIN);
        LocalDateTime endDateTime = LocalDateTime.of(LocalDate.parse(unInsProductsDTO.getEndDate(),dateTimeFormatter),LocalTime.MAX);
        // èŽ·å–æ•°æ®
        List<UnInsProductsVO> list = baseMapper.selectUnInsProducts(laboratory, startDateTime, endDateTime,unInsProductsDTO);
        try {
            String fileName = URLEncoder.encode(laboratory+"待检任务统计", "UTF-8");
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-disposition", "attachment;filename=" + fileName + ".xlsx");
            // æ–°å»ºExcelWriter
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
            WriteSheet writeSheet = EasyExcel.writerSheet().head(UnInsProductsVO.class).build();
            excelWriter.write(list, writeSheet);
            // å…³é—­æµ
            excelWriter.finish();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    @Override
    public IPage<TasksShowDto> tasksShow(Page page, String sonLaboratory) {
        IPage tasksShow = insOrderMapper.getTasksShow(page, sonLaboratory);
        return tasksShow;
    }
    @Override
    public int getCurrentMonthPlanTotalBySonLaboratory(String sonLaboratory,LocalDateTime startTime, LocalDateTime endTime) {
        if(StringUtils.isNotBlank(sonLaboratory)){
            if(Objects.isNull(startTime) || Objects.isNull(endTime)) {
                //获取当月的开始和结束时间
                // å½“月的开始时间(第一天 00:00:00)
                startTime = LocalDate.now()
                        .withDayOfMonth(1)
                        .atStartOfDay();
                // å½“月的结束时间(最后一天 23:59:59.999999999)
                endTime = LocalDate.now()
                        .with(TemporalAdjusters.lastDayOfMonth())
                        .atTime(LocalTime.MAX);
            }
            //查询当月该子试验室的总任务条数
            return baseMapper.selectPlanCountBySonLaboratory(sonLaboratory,startTime,endTime);
        }
        return 0;
    }
    @Override
    public Map<String, Object> getTabHeader(String sonLaboratory,String samples) {
        Map<String, Object> resultMap = new HashMap<>();
        List<String> list = new ArrayList<>();
        List<Map<String, Object>> maps = new ArrayList<>();
        if(StringUtils.isNotBlank(samples)) {
            samples = "[" + "\"" + samples + "\"";
        }
        List<Map<String, Object>> tabHeader = baseMapper.getTabHeader(sonLaboratory,samples);
        ObjectMapper objectMapper = new ObjectMapper();
        Long count = 1l;
        for (Map<String, Object> map : tabHeader) {
            try {
                List<List<String>> sample = objectMapper.readValue(JSONUtil.toJsonStr(map.get("sample").toString()), new TypeReference<List<List<String>>>() {
                });
                // èŽ·å–tab页表头
                for (List<String> strings : sample) {
                        list.add(strings.get(0));
                }
                // èŽ·å–è¡¨æ ¼è¡¨å¤´
                if(StringUtils.isNotBlank(samples)) {
                    if(map.containsKey("inspectionItemSubclass")) {
                        if(StringUtils.isNotBlank(map.get("inspectionItemSubclass").toString())) {
                            HashMap<String, Object> map1 = new HashMap<>();
                            map1.put("label", map.get("inspectionItemSubclass").toString());  // label
                            map1.put("prop","lastValue"+count); // prop
                            maps.add(map1);
                        }else {
                            HashMap<String, Object> map1 = new HashMap<>();
                            map1.put("label", map.get("inspectionItem").toString());  // label
                            map1.put("prop","lastValue"+count); // prop
                            maps.add(map1);
                        }
                    }else {
                        HashMap<String, Object> map1 = new HashMap<>();
                        map1.put("label", map.get("inspectionItem").toString());  // label
                        map1.put("prop","lastValue"+count); // prop
                        maps.add(map1);
                    }
                    count++;
                }
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }
        if (samples.contains("温度循环")){
            addElementToMaps(maps, "循环次数", "inspectionItems");
            addElementToMaps(maps, "温度点", "inspectionItemSubclass");
            addElementToMaps(maps, "衰减系数1310", "attenuationCoefficient1310");
            addElementToMaps(maps, "衰减差1", "attenuationDifference1");
            addElementToMaps(maps, "衰减系数1550", "attenuationCoefficient1550");
            addElementToMaps(maps, "衰减差2", "attenuationDifference2");
            addElementToMaps(maps, "衰减系数1625", "attenuationCoefficient1625");
            addElementToMaps(maps, "衰减差3", "attenuationDifference3");
            addElementToMaps(maps, "衰减1383", "attenuationCoefficient1383");
            addElementToMaps(maps, "衰减差4", "attenuationDifference4");
            addElementToMaps(maps, "衰减1490", "attenuationCoefficient1490");
            addElementToMaps(maps, "衰减差5", "attenuationDifference5");
            addElementToMaps(maps, "衰减差Max", "attenuationDifferenceMax");
            addElementToMaps(maps, "是否合格", "insResult");
        }
        Map<String, Map<String, Object>> uniqueByLabel = maps.stream()
                .collect(Collectors.toMap(
                        map -> (String) map.get("label"),
                        map -> map,
                        (existing, replacement) -> existing, // ä¿ç•™ç¬¬ä¸€ä¸ªé‡åˆ°çš„Map
                        LinkedHashMap::new
                ));
        // å°†ç»“果转换回List<Map<String, Object>>
        List<Map<String, Object>> collect1 = new ArrayList<>(uniqueByLabel.values());
//        List<Map<String, Object>> collect1 = maps.stream().distinct().collect(Collectors.toList());
        List<String> collect = list.stream().distinct().collect(Collectors.toList());
        collect.add("温度循环");
        resultMap.put("tabHeader", collect);
        resultMap.put("tableHeader", collect1);
        return resultMap;
    }
    private static void addElementToMaps(List<Map<String, Object>> maps, String label, String prop) {
        Map<String, Object> map = new HashMap<>();
        map.put("label", label);
        map.put("prop", prop);
        maps.add(map);
    }
    @Override
    public IPage<InsOrderPlanVO> selectInsOrderPlanList(Page page, InsOrderPlanDTO insOrderPlanDTO) {
        User user = userMapper.selectById(SecurityUtils.getUserId());//当前登录的人
        //获取当前人所属实验室id
        String departLimsId = user.getDepartLimsId();
        String laboratory = null;
        if (ObjectUtils.isNotEmpty(departLimsId) && !departLimsId.isEmpty()) {
            String[] split = departLimsId.split(",");
            //查询对应架构名称(通信实验室,电力实验室,检测办)
            String departLims = baseMapper.seldepLimsId(Integer.parseInt(split[split.length - 1]));
            if (departLims.contains("实验室")) {
                laboratory = departLims;
            }
        }
        String checkName = null;
        String userName = null;
        if (ObjectUtil.isNotEmpty(insOrderPlanDTO.getUserId())) {
            userName = userMapper.selectById(SecurityUtils.getUserId()).getName();
            if(Objects.equals(insOrderPlanDTO.getInsState(),"3")) {
                userName = "";
                checkName = userMapper.selectById(SecurityUtils.getUserId()).getName();
            }
            insOrderPlanDTO.setUserId(null);
        }
        InsOrderPlanDTO planDTO = new InsOrderPlanDTO();
        QueryWrapper<InsOrderPlanDTO> wrappers = QueryWrappers.queryWrappers(planDTO);
        IPage<InsOrderPlanVO> insOrderPage = insSampleMapper.findInsSampleAndOrder(
                page,
                userName,
                checkName,
                insOrderPlanDTO.getSonLaboratory(),
                insOrderPlanDTO.getSample(),
                insOrderPlanDTO.getSampleCode(),
                laboratory,
                insOrderPlanDTO.getEntrustCode(),
                insOrderPlanDTO.getInsState(),
                wrappers,
                insOrderPlanDTO.getSendTimeRange()
                );
        return insOrderPage;
    }
    @Override
    public IPage<InsOrderPlanTaskSwitchVo> inspectionOrderDetailsTaskSwitching(Page page, InsOrderPlanDTO insOrderPlanDTO) {
        Integer userId = SecurityUtils.getUserId().intValue();
        User user = userMapper.selectById(userId);//当前登录的人
        //获取当前人所属实验室id
        String departLimsId = user.getDepartLimsId();
        String laboratory = null;
        if (ObjectUtils.isNotEmpty(departLimsId) && !departLimsId.equals("")) {
            String[] split = departLimsId.split(",");
            //查询对应架构名称(通信实验室,电力实验室,检测办)
            String departLims = baseMapper.seldepLimsId(Integer.parseInt(split[split.length - 1]));
            if (departLims.contains("实验室")) {
                laboratory = departLims;
            }
        }
        if (ObjectUtil.isNotEmpty(insOrderPlanDTO.getUserId())) {
            insOrderPlanDTO.setUserId(userId.longValue());
        }
        String sonLaboratory = insOrderPlanDTO.getSonLaboratory();//试验室
        IPage<InsOrderPlanTaskSwitchVo> insOrderPage = insSampleMapper.inspectionOrderDetailsTaskSwitching(page, QueryWrappers.queryWrappers(insOrderPlanDTO), userId, sonLaboratory, laboratory);
        return insOrderPage;
    }
    //认领任务
    @Override
    public boolean claimInsOrderPlan(InsOrderPlanDTO entity) {
        if (Objects.isNull(entity)) {
            return false;
        }
        Integer userId = SecurityUtils.getUserId().intValue();
        InsSampleUser insSampleUser = new InsSampleUser(entity.getInsSampleId().intValue(), userId, 0, entity.getSonLaboratory());
        return insSampleUserMapper.insert(insSampleUser) > 0;
    }
    @Override
    public Map<String, Object> doInsOrder(Integer id, String laboratory) {
//        InsOrder insOrder = new InsOrder();
//        insOrder.setId(id);
        InsOrder order = insOrderMapper.selectById(id);
        InsOrderState insOrderState = insOrderStateMapper.selectOne(new LambdaQueryWrapper<InsOrderState>()
                .eq(InsOrderState::getInsOrderId, id)
                .eq(InsOrderState::getLaboratory, laboratory));
        if (BeanUtil.isEmpty(insOrderState.getInsTime())) {
            order.setInsTime(LocalDateTime.now());
            insOrderMapper.updateById(order);
            insOrderStateMapper.update(null, Wrappers.<InsOrderState>lambdaUpdate().eq(InsOrderState::getInsOrderId, id).eq(InsOrderState::getLaboratory, laboratory).set(InsOrderState::getInsTime, LocalDateTime.now()).set(InsOrderState::getInsState, 1));
        }
        Map<String, Object> map = insOrderService.getInsOrderAndSample(id, laboratory);
        List<SampleProductDto> list = JSON.parseArray(JSON.toJSONString(map.get("sampleProduct")), SampleProductDto.class);
        for (SampleProductDto samples : list) {
            if (BeanUtil.isEmpty(samples.getInsProduct())) continue;
            samples.setBushing(insBushingService.selectBushingBySampleId(samples.getId()));
        }
        map.put("sampleProduct", list.stream().sorted(Comparator.comparing(SampleProductDto::getId)).collect(Collectors.toList()));
        return map;
    }
    @Override
    public List<InsProduct> getInsProduct(Integer id, Integer type, String laboratory, HttpServletRequest request) {
        List<InsProduct> insProducts = new ArrayList<>();
        switch (type) {
            case 0:
                //样品
                insProducts = insSampleMapper.getInsProduct1(id, laboratory);
                if(!insProducts.isEmpty()) {
                    boolean flag = false;
                    for(InsProduct insProduct : insProducts) {
                        if("温度循环".equals(insProduct.getInspectionItem())) {
                            flag = true;
                            break;
                        }
                    }
                    if(flag) {
                        insProducts = insSampleMapper.getInsProduct5(id, laboratory);
                    }
                }
                break;
            case 1:
                //光纤带
                insProducts = insSampleMapper.getInsProduct2(id, laboratory);
                break;
            case 2:
                //光纤
                insProducts = insSampleMapper.getInsProduct3(id, laboratory);
                break;
            case 3:
                //套管
                insProducts = insSampleMapper.getInsProduct4(id, laboratory);
                break;
        }
        //如果是大样品下的项目为空,那么查询第一个光纤的项目
        if (ObjectUtils.isEmpty(insProducts) && type == 0) {
            //查询第一个光纤的id
            List<InsFiber> insFibers = insFiberMapper.selectList(Wrappers.<InsFiber>lambdaQuery()
                    .eq(InsFiber::getInsBushingId, insBushingMapper.selectList(Wrappers.<InsBushing>lambdaQuery()
                            .eq(InsBushing::getInsSampleId, id)
                            .isNotNull(InsBushing::getStandNum)
                            .isNotNull(InsBushing::getTestNum)).get(0).getId()));
            if(CollectionUtils.isNotEmpty(insFibers)) {
                insProducts = insSampleMapper.getInsProduct3(insFibers.get(0).getId(),laboratory);
            }
            // å¦‚果光纤下的项目为空,那么查询第一个光纤带的项目
            else {
                List<InsFibers> insFibersS = insFibersMapper.selectList(Wrappers.<InsFibers>lambdaQuery()
                        .eq(InsFibers::getInsBushingId, insBushingMapper.selectList(Wrappers.<InsBushing>lambdaQuery()
                                .eq(InsBushing::getInsSampleId, id)
                                .isNotNull(InsBushing::getTestNum)
                        ).get(0).getId()));
                //如果光纤带不为空,查询光纤带下是否配有光纤
                if(!insFibersS.isEmpty()){
                    List<InsFiber> insFiberList = insFiberMapper.selectList(Wrappers.<InsFiber>lambdaQuery().eq(InsFiber::getInsFibersId, insFibersS.get(0).getId()));
                    if(!insFiberList.isEmpty()){
                        insProducts = insSampleMapper.getInsProduct3(insFiberList.get(0).getId(),laboratory);
                    }else{
                        insProducts = insSampleMapper.getInsProduct6(insFibersS.get(0).getId(),laboratory);
                    }
                }
            }
        }
        Set<Integer> set = new HashSet<>();
        Map<Integer, String> map2 = new HashMap<>();
        if (BeanUtil.isEmpty(insProducts)) return null;
        getTemplateThing(set, map2, insProducts);
        return insProducts;
    }
    @Override
    public List<String> checkSubmitPlan(Integer orderId, String laboratory,String temperature,String humidity) {
        List<String> collect = new ArrayList<>();
        List<InsSample> insSamples = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery().eq(InsSample::getInsOrderId, orderId).select(InsSample::getId));
        List<Integer> ids = insSamples.stream().map(InsSample::getId).collect(Collectors.toList());
        List<InsProduct> insProducts = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                .in(InsProduct::getInsSampleId, ids)
                .eq(InsProduct::getSonLaboratory, laboratory)
                .eq(InsProduct::getState, 1)
                .eq(InsProduct::getInsResult, 0));
        if (insProducts.size() > 0) {
            collect = insProducts.stream().map(insProduct -> {
                return insProduct.getInspectionItem() + "-" + insProduct.getInspectionItemSubclass();
            }).collect(Collectors.toList());
            insProductMapper.update(null,new LambdaUpdateWrapper<InsProduct>()
                    .set(InsProduct::getTemperature,temperature)
                    .set(InsProduct::getHumidity,humidity)
                    .in(InsProduct::getInsSampleId,ids));
        }
        return collect;
    }
    @Override
    public IPage<InsOrderFile> getFileList(Page page, InsOrderFile insOrderFile) {
        Integer insOrderId = insOrderFile.getInsOrderId();
        insOrderFile.setInsOrderId(null);
        IPage<InsOrderFile> insOrderFileIPage = insOrderFileMapper.getFileList(page, QueryWrappers.queryWrappers(insOrderFile),insOrderId);
        return insOrderFileIPage;
    }
    @Override
    public int uploadFile(Integer orderId, MultipartFile file) {
        String urlString;
        String pathName;
        String path;
        String filename = file.getOriginalFilename();
        String contentType = file.getContentType();
        InsOrderFile insOrderFile = new InsOrderFile();
        insOrderFile.setInsOrderId(orderId);
        insOrderFile.setFileName(filename);
        if (contentType != null && contentType.startsWith("image/")) {
            // æ˜¯å›¾ç‰‡
            path = imgUrl;
            insOrderFile.setType(1);
        } else {
            // æ˜¯æ–‡ä»¶
            path = wordUrl;
            insOrderFile.setType(2);
        }
        try {
            File realpath = new File(path);
            if (!realpath.exists()) {
                realpath.mkdirs();
            }
            pathName = UUID.randomUUID() + "_" + file.getOriginalFilename();
            urlString = realpath + "/" + pathName;
            file.transferTo(new File(urlString));
            insOrderFile.setFileUrl(pathName);
            return insOrderFileMapper.insert(insOrderFile);
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("附件上传错误");
            return 0;
        }
    }
    //切换记录模版查询检验内容
    @Override
    public Map<String, Object> getReportModel(Integer sampleId, String sonLaboratory) {
        Map<String, Object> map = new HashMap<>();
        //先查出套管
        List<InsBushing> insBushings = insBushingMapper.selectList(Wrappers.<InsBushing>lambdaQuery().eq(InsBushing::getInsSampleId, sampleId));
        List<InsFibersVO> fibers = new ArrayList<>();
        List<InsFiber> fiber = new ArrayList<>();
        List<InsBushing> bush = new ArrayList<>();
        for (InsBushing insBushing : insBushings) {
            //保存套管(松套管)
            List<InsProduct> insProductsByBush = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                    .eq(InsProduct::getInsBushId, insBushing.getId())
                    .eq(InsProduct::getSonLaboratory,sonLaboratory)
                    .eq(InsProduct::getState,1)
                    .and(i->i.like(InsProduct::getInspectionItem,"松套管")
                            .or()
                            .like(InsProduct::getInspectionItemSubclass,"松套管"))
            );
            List<Integer> collectByBush = insProductsByBush.stream()
                    .map(InsProduct::getInsResult)
                    .filter(sm -> ObjectUtils.isNotEmpty(sm) && sm != 2).collect(Collectors.toList());
            //1:已检验,0:未检验,2:在检
            int bushState = 0;
            if(insProductsByBush.size() == collectByBush.size()){
                bushState = 1;
            }else if(!collectByBush.isEmpty() && collectByBush.size()<insProductsByBush.size()){
                bushState = 2;
            }
            insBushing.setState(bushState);
            if(!insProductsByBush.isEmpty()){
                bush.add(insBushing);
            }
            //再查询出所有的光纤带
            List<InsFibers> insFibers = insFibersMapper.selectList(Wrappers.<InsFibers>lambdaQuery().eq(InsFibers::getInsBushingId, insBushing.getId()));
            List<InsFiber> insFiberList = insFiberMapper.selectList(Wrappers.<InsFiber>lambdaQuery().eq(InsFiber::getInsBushingId, insBushing.getId()));
            if (CollectionUtils.isNotEmpty(insFibers)) {
                for (InsFibers insFiberS : insFibers) {
                    //查询光纤带下的光纤配置
                    List<InsFiber> fiberList = insFiberMapper.selectList(Wrappers.<InsFiber>lambdaQuery().eq(InsFiber::getInsFibersId, insFiberS.getId()));
                    if(fiberList.isEmpty()){
                        List<InsProduct> insProducts = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                                .eq(InsProduct::getState,1)
                                .eq(InsProduct::getSonLaboratory,sonLaboratory)
                                .eq(InsProduct::getInsFibersId, insFiberS.getId()));
                        // è¿‡æ»¤å…‰çº¤æŽ¥å¤´æŸè€—
                        if(CollectionUtils.isNotEmpty(insProducts)) {
                            insProducts = insProducts.stream().filter(item -> !item.getInspectionItem().equals("光纤接头损耗")).collect(Collectors.toList());
                        }
                        //设置套管的检验状态
                        insFiberS.setState(getInsState(insProducts));
                        InsFibersVO insFibersVO = new InsFibersVO();
                        BeanUtil.copyProperties(insFiberS,insFibersVO);
                        insFibersVO.setIsExistProduct(!insProducts.isEmpty());//是否存在检验项
                        insFibersVO.setBushingColor(insBushing.getColor());
                        //如果光纤带下的项目没有光纤接头损耗项目,才添加光纤带信息
                        if(CollectionUtils.isNotEmpty(insProducts)) {
                            fibers.add(insFibersVO);
                        }
                    }else{
                        InsFibersVO insFibersVO = new InsFibersVO();
                        BeanUtil.copyProperties(insFiberS,insFibersVO);
                        insFibersVO.setBushingColor(insBushing.getColor());
                        //查询光纤带下的检验项
                        List<InsProduct> fibersProducts = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                                .eq(InsProduct::getState,1)
                                .eq(InsProduct::getSonLaboratory,sonLaboratory)
                                .eq(InsProduct::getInsFibersId, insFiberS.getId()));
                        insFibersVO.setIsExistProduct(!fibersProducts.isEmpty());//是否存在检验项
                        if(!fibersProducts.isEmpty()){
                            //设置光纤带色标的检验状态
                            insFibersVO.setState(getInsState(fibersProducts));
                        }
                        //添加光纤带信息
                        fibers.add(insFibersVO);
                        for (InsFiber insFiber : fiberList) {
                            List<InsProduct> insProducts = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                                    .eq(InsProduct::getState,1)
                                    .eq(InsProduct::getSonLaboratory,sonLaboratory)
                                    .eq(InsProduct::getInsFiberId, insFiber.getId()));
                            // è¿‡æ»¤å…‰çº¤æŽ¥å¤´æŸè€—
                            if(CollectionUtils.isNotEmpty(insProducts)) {
                                insProducts = insProducts.stream().filter(item -> !item.getInspectionItem().equals("光纤接头损耗")).collect(Collectors.toList());
                            }
                            //设置光纤色标的检验状态
                            insFiber.setState(getInsState(insProducts));
                            //如果光纤下的项目没有光纤接头损耗项目,才添加光纤信息
                            if(CollectionUtils.isNotEmpty(insProducts)) {
                                fiber.add(insFiber);
                            }
                        }
                    }
                }
            }
            //如果套管下没有光纤带就只有光纤了
            else if (CollectionUtils.isNotEmpty(insFiberList)) {
                for (InsFiber insFiber : insFiberList) {
                    List<InsProduct> insProducts = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                            .eq(InsProduct::getState,1)
                            .eq(InsProduct::getSonLaboratory,sonLaboratory)
                            .eq(InsProduct::getInsFiberId, insFiber.getId()));
                    // è¿‡æ»¤å…‰çº¤æŽ¥å¤´æŸè€—
                    if(CollectionUtils.isNotEmpty(insProducts)) {
                        insProducts = insProducts.stream().filter(item -> !item.getInspectionItem().equals("光纤接头损耗")).collect(Collectors.toList());
                    }
                    //设置光纤色标的检验状态
                    insFiber.setState(getInsState(insProducts));
                    if(CollectionUtils.isNotEmpty(insProducts)){
                        fiber.add(insFiber);
                    }
                }
            }
        }
        map.put("光纤带", fibers);
        map.put("光纤", fiber);
        map.put("套管", bush);
        return map;
    }
    /**
     * åˆ¤æ–­æ£€éªŒé¡¹æ˜¯å¦æ£€æµ‹å®Œï¼Œè¿”回检测状态
     * @param insProducts
     * @return
     */
    private Integer getInsState(List<InsProduct> insProducts){
        List<Integer> collect = insProducts.stream().map(InsProduct::getInsResult)
                .filter(sm -> ObjectUtils.isNotEmpty(sm) && sm != 2).collect(Collectors.toList());
        if (insProducts.size() == collect.size()) {
            return 1;//已检验
        } else if(!collect.isEmpty() && collect.size()<insProducts.size()){
            return 2;//在检验
        }
        return 0;//未检验
    }
    //温度循环查看列表数据(包括通过样品id,循环次数,温度,循环次数进行筛选)
    @Override
    public Map<String, Object> temCycle(Integer sampleId, String inspectionItem, String inspectionItemSubclass) {
        Map<String, Object> map = new HashMap<>();
        //样品信息
        SampleVo sampleVo = insSampleMapper.getDetailById(sampleId);
        map.put("sampleVo", sampleVo);
        List<ProductVo> productVos = new ArrayList<>();
        //先查出这个样品下有哪些管色标,光纤带,光纤色标
        //先查出套管
        List<InsBushing> insBushings = insBushingMapper.selectList(Wrappers.<InsBushing>lambdaQuery().eq(InsBushing::getInsSampleId, sampleId));
        if (insBushings.size() > 0) {
            //通信--温度循环
            for (InsBushing insBushing : insBushings) {
                //再查询出所有的光纤带
                List<InsFibers> insFibers = insFibersMapper.selectList(Wrappers.<InsFibers>lambdaQuery().eq(InsFibers::getInsBushingId, insBushing.getId()));
                if (CollectionUtils.isNotEmpty(insFibers)) {
                    for (InsFibers insFiber : insFibers) {
                        //查出光纤带下所有的光纤
                        List<InsFiber> fiberList = insFiberMapper.selectList(Wrappers.<InsFiber>lambdaQuery().eq(InsFiber::getInsFibersId, insFiber.getId()));
                        for (InsFiber fiber : fiberList) {
                            //再根据关联的光纤配置的id和循环次数和温度和样品id进行查询检验项目
                            List<InsProduct> insProducts = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                                    .eq(InsProduct::getInsSampleId, sampleId)
                                    .eq(InsProduct::getInspectionItem, inspectionItem)
                                    .eq(InsProduct::getInspectionItemSubclass, inspectionItemSubclass)
                                    .eq(InsProduct::getInsFiberId, fiber.getId()));
                            for (InsProduct insProduct : insProducts) {
                                InsProductResult insProductResult = insProductResultMapper.selectOne(Wrappers.<InsProductResult>lambdaQuery()
                                        .eq(InsProductResult::getInsProductId, insProduct.getId()));
                                ProductVo productVo = new ProductVo();
                                productVo.setCode(insFiber.getCode());
                                productVo.setColor(fiber.getColor());
                                productVo.setBushColor(insBushing.getColor());
                                if (ObjectUtils.isNotEmpty(insProductResult)) {
                                    insProduct.setInsProductResult(insProductResult);
                                }
                                //求同等条件下1次循环20度常温的计算值
                                InsProductResult insProductResult1 = insProductResultMapper.selectOne(Wrappers.<InsProductResult>lambdaQuery().eq(InsProductResult::getInsProductId, insProductMapper.selectOne(Wrappers.<InsProduct>lambdaQuery()
                                        .eq(InsProduct::getInsSampleId, sampleId)
                                        .eq(InsProduct::getInspectionItem, "1")
                                        .eq(InsProduct::getInspectionItemSubclass, "20℃(常温)")
                                        .eq(InsProduct::getInspectionItemClass, insProduct.getInspectionItemClass())
                                        .eq(InsProduct::getInsFiberId, fiber.getId())).getId()));
                                if (ObjectUtils.isNotEmpty(insProductResult1) && !insProductResult1.getComValue().equals("[]")) {
                                    String[] splitStr = insProductResult1.getComValue().split(":");
                                    insProduct.setComplue(splitStr[splitStr.length-1].split("\"")[1]);
                                }
                                productVo.setInsProduct(insProduct);
                                productVos.add(productVo);
                            }
                        }
                    }
                } else {
                    //如果套管下没有光纤带就只有光纤了
                    List<InsFiber> insFiberList = insFiberMapper.selectList(Wrappers.<InsFiber>lambdaQuery().eq(InsFiber::getInsBushingId, insBushing.getId()));
                    for (InsFiber fiber : insFiberList) {
                        //再根据关联的光纤配置的id和循环次数和温度和样品id进行查询检验项目
                        List<InsProduct> insProducts = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                                .eq(InsProduct::getInsSampleId, sampleId)
                                .eq(InsProduct::getInspectionItem, inspectionItem)
                                .eq(InsProduct::getInspectionItemSubclass, inspectionItemSubclass)
                                .eq(InsProduct::getInsFiberId, fiber.getId()));
                        for (InsProduct insProduct : insProducts) {
                            InsProductResult insProductResult = insProductResultMapper.selectOne(Wrappers.<InsProductResult>lambdaQuery().eq(InsProductResult::getInsProductId, insProduct.getId()));
                            ProductVo productVo = new ProductVo();
                            productVo.setCode("-");
                            productVo.setColor(fiber.getColor());
                            productVo.setBushColor(fiber.getBushColor());
                            insProduct.setInsProductResult(insProductResult);
                            //求同等条件下1次循环20度常温的计算值
                            InsProductResult insProductResult1 = insProductResultMapper.selectOne(Wrappers.<InsProductResult>lambdaQuery().eq(InsProductResult::getInsProductId, insProductMapper.selectOne(Wrappers.<InsProduct>lambdaQuery()
                                    .eq(InsProduct::getInsSampleId, sampleId)
                                    .eq(InsProduct::getInspectionItem, "1")
                                    .eq(InsProduct::getInspectionItemSubclass, "20℃(常温)")
                                    .eq(InsProduct::getInspectionItemClass, insProduct.getInspectionItemClass())
                                    .eq(InsProduct::getInsFiberId, fiber.getId())).getId()));
                            if (ObjectUtils.isNotEmpty(insProductResult1) && !insProductResult1.getComValue().equals("[]")) {
                                String[] splitStr = insProductResult1.getComValue().split(":");
                                insProduct.setComplue(splitStr[splitStr.length-1].split("\"")[1]);
                            }
                            productVo.setInsProduct(insProduct);
                            productVos.add(productVo);
                        }
                    }
                }
            }
            productVos = productVos.stream().sorted(Comparator.comparing(productVo -> productVo.getInsProduct().getInspectionItemClass())).collect(Collectors.toList());
        } else {
            //电力--热循环和温升试验
            List<InsProduct> insProducts = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                    .eq(InsProduct::getInsSampleId, sampleId)
                    .eq(InsProduct::getInspectionItem, inspectionItem));
            for (InsProduct insProduct : insProducts) {
                InsProductResult insProductResult = insProductResultMapper.selectOne(Wrappers.<InsProductResult>lambdaQuery().eq(InsProductResult::getInsProductId, insProduct.getId()));
                ProductVo productVo = new ProductVo();
                if (ObjectUtils.isNotEmpty(insProductResult)) {
                    insProduct.setInsProductResult(insProductResult);
                }
                productVo.setInsProduct(insProduct);
                productVos.add(productVo);
            }
        }
        map.put("productVos", productVos);
        return map;
    }
    @Override
    public List<String> upPlanUser2(Integer orderId) {
        List<Integer> sampleId = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery().eq(InsSample::getInsOrderId, orderId)).stream().map(InsSample::getId).collect(Collectors.toList());
        List<String> sonLaboratory = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery().eq(InsProduct::getState, 1).in(InsProduct::getInsSampleId, sampleId)).stream().map(InsProduct::getSonLaboratory).distinct().collect(Collectors.toList());
        return sonLaboratory;
    }
    @Override
    public Map<String, Object> getSagTemperatureProducts(Integer sampleId) {
        Map<String, Object> map = new HashMap<>();
        //样品信息
        SampleVo sampleVo = insSampleMapper.getDetailById(sampleId);
        map.put("sampleVo", sampleVo);
        //电力:弧垂-温度特殊项
        List<ProductVo> productVos = new ArrayList<>();
        List<InsProduct> insProducts = insProductMapper.findSagTemperatureProducts(sampleId,"弧垂-温度");
        for (InsProduct insProduct : insProducts) {
            InsProductResult insProductResult = insProductResultMapper.selectOne(Wrappers.<InsProductResult>lambdaQuery().eq(InsProductResult::getInsProductId, insProduct.getId()));
            ProductVo productVo = new ProductVo();
            if (ObjectUtils.isNotEmpty(insProductResult)) {
                insProduct.setInsProductResult(insProductResult);
            }
            productVo.setInsProduct(insProduct);
            productVos.add(productVo);
        }
        map.put("productVos", productVos);
        return map;
    }
    @Override
    public Map<String, Object> getSampleInfoByOrderId(Integer orderId,String sonLaboratory) {
        Map<String, Object> map = new HashMap<>();
        if(!Objects.isNull(orderId)){
            //检验内容对象
            List<InsProductVO> insProductVOS = insProductMapper.selectProductByOrderId(orderId,sonLaboratory);
            //根据样品id分组
            Map<Integer, List<InsProductVO>> groupMap = insProductVOS.stream().collect(Collectors.groupingBy(InsProductVO::getSampleId));
            List<InsProductVO> sampleList = new ArrayList<>();
            for (Integer key : groupMap.keySet()) {
                AtomicInteger insSum = new AtomicInteger(0);
                List<String> inspectNameList = new ArrayList<>();
                InsProductVO insProductVO = new InsProductVO();
                groupMap.get(key).forEach(k->{
                    if(StringUtils.isNotBlank(k.getInspectName())){
                        insSum.getAndIncrement();
                        inspectNameList.add(k.getInspectName());
                    }
                    insProductVO.setId(k.getSampleId());
                    insProductVO.setSampleCode(k.getSampleCode());
                });
                if(CollectionUtils.isEmpty(inspectNameList)){
                    insProductVO.setState(0);
                }else if(inspectNameList.size() < groupMap.get(key).size()){
                    insProductVO.setState(1);
                }else if(inspectNameList.size() == groupMap.get(key).size()){
                    insProductVO.setState(2);
                }
                insProductVO.setInspectName(inspectNameList.stream().distinct().collect(Collectors.joining(",")));
                sampleList.add(insProductVO);
            }
            map.put("insSamples",sampleList);
            map.put("insProductVOS",insProductVOS);
        }
        return map;
    }
    @Override
    @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public void saveInsContext(Map<String, Object> insContext, Integer currentTable, Integer currentSampleId, Integer orderId, String sonLaboratory, Boolean isDelete) {
        try{
            if(lock.tryLock(10,TimeUnit.SECONDS)){
                Integer userId = SecurityUtils.getUserId().intValue();
                insContext.forEach((k, v) -> {
                    JSONObject jo = JSON.parseObject(JSON.toJSONString(v));
                    InsProduct insProduct = new InsProduct();
                    insProduct.setId(Integer.parseInt(k));
                    InsProduct product = insProductMapper.selectById(insProduct.getId());
                    if (currentTable.equals(product.getTemplateId()) && currentSampleId.equals(product.getInsSampleId())) {
                        List<InsProductResult> oldResults = insProductResultMapper.selectList(Wrappers.<InsProductResult>lambdaQuery()
                                .eq(InsProductResult::getInsProductId, insProduct.getId()));
                        InsProductResult newResult = new InsProductResult();
                        if (CollectionUtils.isNotEmpty(oldResults)) {
                            BeanUtil.copyProperties(oldResults.get(0), newResult);
                        }
                        newResult.setInsProductId(Integer.parseInt(k));
                        /*校验一下result表*/
                        if (oldResults.size() > 1) {
                            for (int i = 1; i < oldResults.size(); i++) {
                                insProductResultMapper.deleteById(oldResults.get(i));
                            }
                        }
                        // ä¿å­˜çš„æ•°æ®å°æ•°ä½æ•°å¿…须大于等于tell最大的小数位数
                        String tells = product.getTell();
                        Integer digit = null;
                        if(StringUtils.isEmpty(tells)) {
                            digit = -1;
                        }else {
                            // æ‰¾åˆ°å°æ•°ä½æ•°æœ€å¤šçš„æ•°å€¼
                            Map<String, Object> stringObjectMap = maxDecimalNumber(tells);
                            digit = Integer.parseInt(stringObjectMap.get("maxNumber").toString());
                        }
                        if (!Arrays.asList("应力应变","振动疲劳").contains(product.getInspectionItem())) {
                            //检验值
                            if (jo.get("insValue") != null) {
                                JSONArray jsonArray = JSON.parseArray(JSON.toJSONString(jo.get("insValue")));
                                List<Map<String, Object>> iv = new ArrayList<>();
                                for (Object o : jsonArray) {
                                    JSONObject insValue = JSON.parseObject(JSON.toJSONString(o));
                                    Map<String, Object> map = new HashMap<>();
                                    String val = "";
                                    if(Objects.nonNull(JSON.parseObject(JSON.toJSONString(insValue.get("v"))).get("v"))){
                                        val = JSON.parseObject(JSON.toJSONString(insValue.get("v"))).get("v").toString();
                                    }
                                    // å¦‚果可以转换为数字,就要进行位数的比较
                                    map.put("v", completion(val, digit));
                                    map.put("r", JSON.toJSONString(insValue.get("r")));
                                    map.put("c", JSON.toJSONString(insValue.get("c")));
                                    map.put("w", insValue.get("w"));
                                    try {
                                        if ((insValue.get("u") == null || insValue.get("u").equals("")) && StrUtil.isNotEmpty(val)) {
                                            map.put("u", userId + "");
                                        } else {
                                            map.put("u", insValue.get("u"));
                                        }
                                        iv.add(map);
                                    } catch (Exception e) {
                                    }
                                }
                                newResult.setInsValue(JSON.toJSONString(iv));
                            }
                        }
                        if (!Arrays.asList("应力应变","振动疲劳").contains(product.getInspectionItem())) {
                            //计算值
                            if (jo.get("comValue") != null && !Objects.equals(jo.get("comValue"), "")) {
                                JSONArray jsonArray2 = JSON.parseArray(JSON.toJSONString(jo.get("comValue")));
                                List<Map<String, Object>> cv = new ArrayList<>();
                                for (Object o : jsonArray2) {
                                    JSONObject comValue = JSON.parseObject(JSON.toJSONString(o));
                                    Map<String, Object> map = new HashMap<>();
                                    map.put("r", JSON.toJSONString(comValue.get("r")));
                                    map.put("c", JSON.toJSONString(comValue.get("c")));
                                    // å¦‚果可以转换为数字,就要进行位数的比较
                                    map.put("v", completion(JSON.parseObject(JSON.toJSONString(comValue.get("v"))).get("v").toString(), digit));
                                    cv.add(map);
                                }
                                newResult.setComValue(JSON.toJSONString(cv));
                            }
                        }
                        //最终值
                        try {
                            JSONObject resValue = JSON.parseObject(JSON.toJSONString(jo.get("resValue")));
                            if (resValue.get("v") != null) {
                                Object o = JSON.parseObject(JSON.toJSONString(resValue.get("v"))).get("v");
                                // å¦‚果可以转换为数字,就要进行位数的比较
                                insProduct.setLastValue(completion(o.equals("") ? null : (o.toString()), digit));
                            }
                        } catch (Exception e) {
                            insProduct.setLastValue("");//''
                        }
                        //设备编号
                        if (jo.get("equipValue") != null) {
                            JSONArray jsonArray2 = JSON.parseArray(JSON.toJSONString(jo.get("equipValue")));
                            List<Map<String, Object>> ev = new ArrayList<>();
                            for (Object o : jsonArray2) {
                                JSONObject equipValue = JSON.parseObject(JSON.toJSONString(o));
                                Map<String, Object> map = new HashMap<>();
                                map.put("v", JSON.parseObject(JSON.toJSONString(equipValue.get("v"))).get("v"));
                                ev.add(map);
                            }
                            newResult.setEquipValue(JSON.toJSONString(ev));
                        }
                        //设备名称
                        if (jo.get("equipName") != null) {
                            JSONArray jsonArray2 = JSON.parseArray(JSON.toJSONString(jo.get("equipName")));
                            List<Map<String, Object>> ev = new ArrayList<>();
                            for (Object o : jsonArray2) {
                                JSONObject equipValue = JSON.parseObject(JSON.toJSONString(o));
                                Map<String, Object> map = new HashMap<>();
                                map.put("v", JSON.parseObject(JSON.toJSONString(equipValue.get("v"))).get("v"));
                                ev.add(map);
                            }
                            newResult.setEquipName(JSON.toJSONString(ev));
                        }
                        //结论
                        try {
                            JSONObject insResult = JSON.parseObject(JSON.toJSONString(jo.get("insResult")));
                            String ir = JSON.parseObject(JSON.toJSONString(insResult.get("v"))).get("v") + "";
                            insProduct.setInsResult(Integer.parseInt(ir));
                            if (product.getInspectionItem().equals("热循环") || product.getInspectionItem().equals("温升试验")) {
                                List<Integer> collect = insProductMapper.selectList(new LambdaQueryWrapper<InsProduct>()
                                                .eq(InsProduct::getSpecialItemParentId, product.getId())).stream()
                                        .map(InsProduct::getInsResult)
                                        .collect(Collectors.toList());
                                if (collect.contains(null)) {
                                    insProduct.setInsResult(2);
                                } else if (collect.contains(0)) {
                                    insProduct.setInsResult(0);
                                } else {
                                    insProduct.setInsResult(1);
                                }
                            }
                        } catch (Exception e) {
                            insProduct.setInsResult(2);//待定
                            if (product.getInspectionItem().equals("应力应变") && product.getInspectionItemSubclass().equals("弹性模量")
                                    && Arrays.asList("/", "-").contains(product.getAsk())) {
                                insProduct.setInsResult(3);// ä¸åˆ¤å®š
                            }
                            // å¦‚果是弧垂的结论也改为不判定
                            if(product.getInspectionItem().equals("弧垂-温度")) {
                                insProduct.setInsResult(3);// ä¸åˆ¤å®š
                            }
                        }
                        if (Objects.isNull(newResult.getId())) {
                            newResult.setCreateUser(userId);
                            newResult.setUpdateUser(userId);
                            insProductResultMapper.insert(newResult);
                        } else {
                            newResult.setUpdateUser(userId);
                            newResult.setUpdateTime(LocalDateTime.now());
                            insProductResultMapper.updateById(newResult);
                        }
                        /*如果是第一次选择设备信息,且还有其余样品也有同一个检验项目,那么所有样品的该项目都用这个设备信息*/
                        //先查询是否还有其余样品
                        Integer insSampleId = product.getInsSampleId();
                        List<InsSample> insSamples = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery().eq(InsSample::getInsOrderId, insSampleMapper.selectById(insSampleId).getInsOrderId()));
                        //如果有多个样品或者是不是采集类型就同一个设备
                        if (insSamples.size() > 1 && !product.getInspectionItemType().equals("1")) {
                            //存在其余样品,查询是否有同一种检验项目
                            for (InsSample sample : insSamples.stream().filter(insSample -> !insSample.getId().equals(insSampleId)).collect(Collectors.toList())) {
                                InsProduct product1 = insProductMapper.selectOne(Wrappers.<InsProduct>lambdaQuery()
                                        .eq(InsProduct::getState, 1)
                                        .eq(InsProduct::getInsSampleId, sample.getId())
                                        .eq(InsProduct::getInspectionItem, product.getInspectionItem())
                                        .eq(InsProduct::getInspectionItemEn, product.getInspectionItemEn())
                                        .eq(InsProduct::getInspectionItemSubclass, product.getInspectionItemSubclass())
                                        .eq(InsProduct::getInspectionItemSubclassEn, product.getInspectionItemSubclassEn())
                                        .eq(InsProduct::getTemplateId, product.getTemplateId())
                                        .eq(InsProduct::getStandardMethodListId, product.getStandardMethodListId())
                                        .eq(InsProduct::getInsBushId, product.getInsBushId())
                                        .eq(InsProduct::getInsFibersId, product.getInsFibersId())
                                        .eq(InsProduct::getInsFiberId, product.getInsFiberId())
                                );
                                if (ObjectUtils.isNotEmpty(product1)) {
                                    //如果存在项目,查询是否有表
                                    InsProductResult productResult = insProductResultMapper.selectOne(Wrappers.<InsProductResult>lambdaQuery()
                                            .eq(InsProductResult::getInsProductId, product1.getId()));
                                    if (ObjectUtils.isEmpty(productResult)) {
                                        //没有表新建表
                                        productResult = new InsProductResult();
                                        productResult.setInsProductId(product1.getId());
                                        productResult.setEquipValue(newResult.getEquipValue());
                                        productResult.setEquipName(newResult.getEquipValue());
                                        productResult.setCreateUser(userId);
                                        productResult.setUpdateUser(userId);
                                        insProductResultMapper.insert(productResult);
                                    } else if (ObjectUtils.isEmpty(productResult.getEquipValue())) {
                                        //有表判断是否有设备
                                        productResult.setEquipValue(newResult.getEquipValue());
                                        productResult.setEquipName(newResult.getEquipValue());
                                        productResult.setUpdateUser(userId);
                                        productResult.setUpdateTime(LocalDateTime.now());
                                        insProductResultMapper.updateById(productResult);
                                    }
                                }
                            }
                        }
                        insProduct.setUpdateUser(userId);
                        insProductMapper.updateById(insProduct);
                        // å½“前样品是否是光纤配置的光纤接头损耗
                        if ((!Objects.isNull(product.getInsFiberId()) || !Objects.isNull(product.getInsFibersId())) && product.getInspectionItem().equals("光纤接头损耗")) {
                            // æŸ¥æ‰¾åŒæ ·å“ä¸‹çš„光纤或光纤带的光纤接头损耗
                            List<InsProduct> insProducts = insProductMapper.selectList(new LambdaQueryWrapper<InsProduct>()
                                    .eq(InsProduct::getInsSampleId, product.getInsSampleId())
                                    .eq(InsProduct::getInspectionItem, product.getInspectionItem())
                                    .eq(InsProduct::getInspectionItemSubclass, product.getInspectionItemSubclass())
                                    .and(item -> item
                                            .isNotNull(InsProduct::getInsFiberId)
                                            .or()
                                            .isNotNull(InsProduct::getInsFibersId)));
                            // è¦å¤åˆ¶çš„result
                            InsProductResult copyResult = insProductResultMapper.selectOne(new LambdaQueryWrapper<InsProductResult>()
                                    .eq(InsProductResult::getInsProductId, product.getId()));
                            for (InsProduct insProduct1 : insProducts) {
                                InsProduct copyInsProduct = insProductMapper.selectById(product.getId()); // å¤åˆ¶çš„insProduct
                                if (!insProduct1.getId().equals(copyInsProduct.getId())) {
                                    copyInsProduct.setId(insProduct1.getId()); // å°†å¤åˆ¶çš„insProduct的id设置为被复制的id
                                    copyInsProduct.setInsFibersId(insProduct1.getInsFibersId()); // å…‰çº¤å¸¦id
                                    copyInsProduct.setInsFiberId(insProduct1.getInsFiberId()); // å…‰çº¤id
                                    copyInsProduct.setInsBushId(insProduct1.getInsBushId()); // å¥—管id
                                    insProductMapper.updateById(copyInsProduct);
                                    // èµ‹å€¼insProductResult
                                    InsProductResult insProductResult = insProductResultMapper.selectOne(new LambdaQueryWrapper<InsProductResult>()
                                            .eq(InsProductResult::getInsProductId, insProduct1.getId()));
                                    if (Objects.isNull(insProductResult)) {
                                        copyResult.setId(null);
                                        copyResult.setInsProductId(insProduct1.getId());
                                        insProductResultMapper.insert(copyResult);
                                    } else {
                                        copyResult.setId(insProductResult.getId());
                                        copyResult.setInsProductId(insProduct1.getId());
                                        insProductResultMapper.updateById(copyResult);
                                    }
                                }
                            }
                        }
                        insProductUserMapper.insert(new InsProductUser(null, userId, LocalDateTime.now(), insProduct.getId()));
                        insProduct = insProductMapper.selectById(insProduct);
                        //查询检验单信息
                        InsSample insSample = insSampleMapper.selectById(insProduct.getInsSampleId());
                        InsOrder insOrder = insOrderMapper.selectById(insSample.getInsOrderId());
                        //查询父检验项
                        InsProduct parentInsProduct;
                        if (ObjectUtil.isNotNull(insProduct.getSpecialItemParentId())) {
                            parentInsProduct = insProductMapper.selectById(insProduct.getSpecialItemParentId());
                        } else {
                            parentInsProduct = null;
                        }
                        if (!Objects.isNull(parentInsProduct)) {
                            if ("温升试验".equals(parentInsProduct.getInspectionItem()) || "热循环".equals(parentInsProduct.getInspectionItem())) {
                                // æ¸©å‡è¯•验以及热循环的删除
                                if (isDelete) {
                                    String inspectionItem = insProduct.getInspectionItem();
                                    List<InsProduct> insProducts = insProductMapper.selectList(new LambdaQueryWrapper<InsProduct>()
                                                    .eq(InsProduct::getSpecialItemParentId, parentInsProduct.getId()))
                                            .stream()
                                            .filter(item -> item.getInspectionItem().equals(inspectionItem)).collect(Collectors.toList());
                                    for (InsProduct insProduct1 : insProducts) {
                                        InsProductResult insProductResult = insProductResultMapper.selectOne(new LambdaQueryWrapper<InsProductResult>()
                                                .eq(InsProductResult::getInsProductId, insProduct1.getId()));
                                        if (!Objects.isNull(insProductResult)) {
                                            if (insProductResult.getInsProductId().equals(Integer.parseInt(k))) {
                                                continue;
                                            }
                                            String insValue = insProductResult.getInsValue();
                                            List<Map> maps = com.alibaba.fastjson2.JSON.parseArray(insValue, Map.class);
                                            if (maps.size() > 1) {
                                                maps.remove(maps.size() - 1);
                                                insProductResult.setInsValue(com.alibaba.fastjson2.JSON.toJSONString(maps));
                                                insProductResultMapper.updateById(insProductResult);
                                            }
                                        }
                                    }
                                }
                                // æ¸©å‡è¯•验以及热循环查询
                                // çƒ­å¾ªçŽ¯æ‰€æœ‰å­é¡¹
                                List<InsProduct> c = insProductMapper.selectList(new LambdaQueryWrapper<InsProduct>()
                                        .eq(InsProduct::getSpecialItemParentId, parentInsProduct.getId()));
                                //通过inspectionItem分组
                                Map<String, List<InsProduct>> collect1 = c.stream().collect(Collectors.groupingBy(InsProduct::getInspectionItem));
                                HashMap<Integer, InsProductResult> map1 = new HashMap<>();
                                Integer maxKey = Integer.MIN_VALUE;
                                for (Map.Entry<String, List<InsProduct>> m : collect1.entrySet()) {
                                    List<InsProduct> thermalCycleCollect = m.getValue();
                                    if (!thermalCycleCollect.isEmpty()) {
                                        for (InsProduct product1 : thermalCycleCollect) {
                                            InsProductResult insProductResult = insProductResultMapper.selectOne(Wrappers.<InsProductResult>lambdaQuery()
                                                    .eq(InsProductResult::getInsProductId, product1.getId()));
                                            if (!Objects.isNull(insProductResult)) {
                                                List<Map> maps = com.alibaba.fastjson2.JSON.parseArray(insProductResult.getInsValue(), Map.class);
                                                map1.put(maps.size(), insProductResult);
                                            }
                                            if (!map1.isEmpty()) {
                                                for (Map.Entry<Integer, InsProductResult> entry : map1.entrySet()) {
                                                    if (entry.getKey() > maxKey) {
                                                        maxKey = entry.getKey();
                                                    }
                                                }
                                            }
                                        }
                                        if (maxKey != Integer.MIN_VALUE) {
                                            InsProductResult insProductResult = map1.get(maxKey);
                                            List<Map> maps = com.alibaba.fastjson2.JSON.parseArray(insProductResult.getInsValue(), Map.class);
                                            maps.get(maps.size() - 1).put("v", "");//最后一个值为空
                                            if (maps.get(maps.size() - 1).containsKey("w")) {
                                                maps.get(maps.size() - 1).put("w", "");
                                            }
                                            for (InsProduct product1 : thermalCycleCollect) {
                                                InsProductResult insProductResult1 = insProductResultMapper.selectOne(Wrappers.<InsProductResult>lambdaQuery()
                                                        .eq(InsProductResult::getInsProductId, product1.getId()));
                                                if (!Objects.isNull(insProductResult1)) {
                                                    if (!insProductResult1.getInsProductId().equals(insProductResult.getInsProductId())) {
                                                        List<Map> maps1 = com.alibaba.fastjson2.JSON.parseArray(insProductResult1.getInsValue(), Map.class);
                                                        if (maps1.size() < maxKey) {
                                                            int number = maxKey - maps1.size();
                                                            for (int i = 0; i < number; i++) {
                                                                maps1.add(maps.get(maps.size() - 1));
                                                            }
                                                            insProductResult1.setInsValue(com.alibaba.fastjson2.JSON.toJSONString(maps1));
                                                            insProductResultMapper.updateById(insProductResult1);
                                                        }
                                                    }
                                                } else {
                                                    if (maxKey != Integer.MIN_VALUE) {
                                                        InsProductResult insProductResult2 = map1.get(maxKey);
                                                        List<Map> maps1 = com.alibaba.fastjson2.JSON.parseArray(insProductResult2.getInsValue(), Map.class);
                                                        for (Map map : maps1) {
                                                            map.put("v", "");
                                                            if (map.containsKey("w")) {
                                                                map.put("w", "");
                                                            }
                                                        }
                                                        insProductResult2.setInsValue(com.alibaba.fastjson2.JSON.toJSONString(maps1));
                                                        insProductResult2.setId(null);
                                                        insProductResult2.setInsProductId(product1.getId());
                                                        insProductResultMapper.insert(insProductResult2);
                                                    }
                                                }
                                            }
                                            maxKey = Integer.MIN_VALUE;
                                            map1.clear();
                                        }
                                    }
                                }
                                // å¦‚果是导线温度的值更新,那么就要判断耐张和接续是否合格
                                InsProduct insProduct1 = insProductMapper.selectById(Integer.parseInt(k));
                                if (insProduct1.getInspectionItemSubclass().equals("导线温度")) {
                                    // æ ¹æ®çˆ¶id以及检验项来查找同一循环下的耐张和接续
                                    List<InsProduct> insProducts2 = insProductMapper.selectList(new LambdaQueryWrapper<InsProduct>()
                                            .eq(InsProduct::getSpecialItemParentId, parentInsProduct.getId())
                                            .eq(InsProduct::getInspectionItem, insProduct1.getInspectionItem()));
                                    List<Double> wire = new ArrayList<>(); // å¯¼çº¿æ¸©åº¦çš„值
                                    List<Double> strain = new ArrayList<>(); // è€å¼ çš„值
                                    List<Double> joint = new ArrayList<>(); // æŽ¥ç»­çš„值
                                    boolean strainFlag = true; // è€å¼ æ˜¯å¦åˆæ ¼
                                    boolean jointFlag = true; // æŽ¥ç»­æ˜¯å¦åˆæ ¼
                                    boolean strainPending = false; // æ˜¯å¦æœ‰å¾…定
                                    boolean jointPending = false; // æ˜¯å¦æœ‰å¾…定
                                    for (InsProduct insProduct2 : insProducts2) {
                                        if (insProduct2.getInspectionItemSubclass().equals("导线温度")) {
                                            String insValue = "";
                                            InsProductResult insProductResult = insProductResultMapper.selectOne(new LambdaQueryWrapper<InsProductResult>()
                                                    .eq(InsProductResult::getInsProductId, insProduct2.getId()));
                                            if (!Objects.isNull(insProductResult)) {
                                                insValue = insProductResult.getInsValue();
                                                List<Map> maps = com.alibaba.fastjson2.JSON.parseArray(insValue, Map.class);
                                                if (maps.size() > 0) {
                                                    for (Map map : maps) {
                                                        if (Strings.isNotEmpty(map.get("v").toString())) {
                                                            wire.add(Double.parseDouble(map.get("v").toString()));
                                                        } else {
                                                            wire.add(-1.0);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                        if (insProduct2.getInspectionItemSubclass().equals("耐张温度")) {
                                            String insValue = "";
                                            InsProductResult insProductResult = insProductResultMapper.selectOne(new LambdaQueryWrapper<InsProductResult>()
                                                    .eq(InsProductResult::getInsProductId, insProduct2.getId()));
                                            if (!Objects.isNull(insProductResult)) {
                                                insValue = insProductResult.getInsValue();
                                                List<Map> maps = com.alibaba.fastjson2.JSON.parseArray(insValue, Map.class);
                                                if (maps.size() > 0) {
                                                    for (Map map : maps) {
                                                        if (Strings.isNotEmpty(map.get("v").toString())) {
                                                            strain.add(Double.parseDouble(map.get("v").toString()));
                                                        } else {
                                                            strain.add(-1.0);
                                                        }
                                                    }
                                                }
                                            } else {
                                                strain.add(-1.0);
                                            }
                                        }
                                        if (insProduct2.getInspectionItemSubclass().equals("接续温度")) {
                                            String insValue = "";
                                            InsProductResult insProductResult = insProductResultMapper.selectOne(new LambdaQueryWrapper<InsProductResult>()
                                                    .eq(InsProductResult::getInsProductId, insProduct2.getId()));
                                            if (!Objects.isNull(insProductResult)) {
                                                insValue = insProductResult.getInsValue();
                                                List<Map> maps = com.alibaba.fastjson2.JSON.parseArray(insValue, Map.class);
                                                if (maps.size() > 0) {
                                                    for (Map map : maps) {
                                                        if (Strings.isNotEmpty(map.get("v").toString())) {
                                                            joint.add(Double.parseDouble(map.get("v").toString()));
                                                        } else {
                                                            joint.add(-1.0);
                                                        }
                                                    }
                                                }
                                            } else {
                                                joint.add(-1.0);
                                            }
                                        }
                                    }
                                    // å¦‚果导线温度的值大于耐张和接续的值,那么就是合格
                                    if (!strain.isEmpty() && !wire.isEmpty() && (strain.size() == wire.size())) {
                                        if (wire.contains(-1.0) || strain.contains(-1.0)) {
                                            insProductMapper.update(null, new LambdaUpdateWrapper<InsProduct>()
                                                    .set(InsProduct::getInsResult, 2)
                                                    .eq(InsProduct::getSpecialItemParentId, parentInsProduct.getId())
                                                    .eq(InsProduct::getInspectionItem, insProduct1.getInspectionItem())
                                                    .eq(InsProduct::getInspectionItemSubclass, "耐张温度"));
                                            strainPending = true;
                                        } else {
                                            for (int i = 0; i < wire.size(); i++) {
                                                if (wire.get(i) <= strain.get(i)) {
                                                    strainFlag = false;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    if (joint.size() > 0 && wire.size() > 0 && (joint.size() == wire.size())) {
                                        if (wire.contains(-1.0) || joint.contains(-1.0)) {
                                            insProductMapper.update(null, new LambdaUpdateWrapper<InsProduct>()
                                                    .set(InsProduct::getInsResult, 2)
                                                    .eq(InsProduct::getSpecialItemParentId, parentInsProduct.getId())
                                                    .eq(InsProduct::getInspectionItem, insProduct1.getInspectionItem())
                                                    .eq(InsProduct::getInspectionItemSubclass, "接续温度"));
                                            jointPending = true;
                                        } else {
                                            for (int i = 0; i < wire.size(); i++) {
                                                if (wire.get(i) <= joint.get(i)) {
                                                    jointFlag = false;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                    if (!strainPending) {
                                        if (strainFlag) {
                                            insProductMapper.update(null, new LambdaUpdateWrapper<InsProduct>()
                                                    .set(InsProduct::getInsResult, 1)
                                                    .eq(InsProduct::getSpecialItemParentId, parentInsProduct.getId())
                                                    .eq(InsProduct::getInspectionItem, insProduct1.getInspectionItem())
                                                    .eq(InsProduct::getInspectionItemSubclass, "耐张温度"));
                                        } else {
                                            insProductMapper.update(null, new LambdaUpdateWrapper<InsProduct>()
                                                    .set(InsProduct::getInsResult, 0)
                                                    .eq(InsProduct::getSpecialItemParentId, parentInsProduct.getId())
                                                    .eq(InsProduct::getInspectionItem, insProduct1.getInspectionItem())
                                                    .eq(InsProduct::getInspectionItemSubclass, "耐张温度"));
                                        }
                                    }
                                    if (!jointPending) {
                                        if (jointFlag) {
                                            insProductMapper.update(null, new LambdaUpdateWrapper<InsProduct>()
                                                    .set(InsProduct::getInsResult, 1)
                                                    .eq(InsProduct::getSpecialItemParentId, parentInsProduct.getId())
                                                    .eq(InsProduct::getInspectionItem, insProduct1.getInspectionItem())
                                                    .eq(InsProduct::getInspectionItemSubclass, "接续温度"));
                                        } else {
                                            insProductMapper.update(null, new LambdaUpdateWrapper<InsProduct>()
                                                    .set(InsProduct::getInsResult, 0)
                                                    .eq(InsProduct::getSpecialItemParentId, parentInsProduct.getId())
                                                    .eq(InsProduct::getInspectionItem, insProduct1.getInspectionItem())
                                                    .eq(InsProduct::getInspectionItemSubclass, "接续温度"));
                                        }
                                    }
                                }
                                // æŸ¥æ‰¾æ˜¯å¦æœ‰æœªæ£€æµ‹çš„æ¬¡æ•°
                                List<Integer> insResult = Arrays.asList(0, 1, 3);
                                List<InsProduct> insProducts = insProductMapper.selectList(new LambdaQueryWrapper<InsProduct>()
                                        .eq(InsProduct::getSpecialItemParentId, parentInsProduct.getId())
                                        .and(w -> w.notIn(InsProduct::getInsResult, insResult)
                                                .or()
                                                .isNull(InsProduct::getInsResult)));
                                if (insProducts.isEmpty()) {
                                    List<InsProduct> insProducts1 = insProductMapper.selectList(new LambdaQueryWrapper<InsProduct>()
                                            .eq(InsProduct::getSpecialItemParentId, parentInsProduct.getId())
                                            .eq(InsProduct::getInsResult, 0));
                                    if (!insProducts1.isEmpty()) {
                                        insProductMapper.update(null, new LambdaUpdateWrapper<InsProduct>()
                                                .set(InsProduct::getInsResult, 0)
                                                .eq(InsProduct::getId, parentInsProduct.getId()));
                                    } else {
                                        insProductMapper.update(null, new LambdaUpdateWrapper<InsProduct>()
                                                .set(InsProduct::getInsResult, 1)
                                                .eq(InsProduct::getId, parentInsProduct.getId()));
                                    }
                                }
                            }
                        }
                        //添加工时记录
                        InsProduct finalInsProduct = insProduct;
                        WorkTimeDTO workTimeDTO = new WorkTimeDTO(userId, insOrder, insSample, finalInsProduct, parentInsProduct, currentSampleId, k, oldResults, newResult);
                        String jsonStr;
                        try {
                            jsonStr = JackSonUtil.marshal(workTimeDTO);
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                        String routerKey;
                        switch (sonLaboratory){
                            case "材料试验室":
                                routerKey = RouterKeyConstants.CL_KEY;
                                break;
                            case "机械性能试验室":
                                routerKey = RouterKeyConstants.JX_KEY;
                                break;
                            case "电力试验室":
                                routerKey = RouterKeyConstants.DL_KEY;
                                break;
                            default:
                                routerKey = RouterKeyConstants.GX_KEY;
                                break;
                        }
                        sendQueueMessage(ExchangeConstants.WORK_TIME_EXCHANGE,routerKey,jsonStr);
                        insSample.setInsState(1);
                        //未检验的检验项数量
                        Long unInsCount = insProductMapper.selectCount(Wrappers.<InsProduct>lambdaQuery()
                                .eq(InsProduct::getInsSampleId, insSample.getId())
                                .and(wrapper -> wrapper
                                        .isNull(InsProduct::getInsResult)
                                        .or()
                                        .eq(InsProduct::getInsResult, 2)
                                ));
                        if (0 == unInsCount) {
                            insSample.setInsState(2);
                        }
                        insSampleMapper.updateById(insSample);
                        /*校验一下result表*/
                        List<InsProductResult> insProductResults = insProductResultMapper.selectList(Wrappers.<InsProductResult>lambdaQuery()
                                .eq(InsProductResult::getInsProductId, insProduct.getId()));
                        if (insProductResults.size() > 1) {
                            for (int i = 1; i < insProductResults.size(); i++) {
                                insProductResultMapper.deleteById(insProductResults.get(i));
                            }
                        }
                    }
                });
                String sampleIdStr = insContext.keySet().stream().findFirst().orElse(null);
                if (sampleIdStr != null) {
                    int count = insProductMapper.selectInsProductCountByOrderId(orderId);
                    if (count == 0) {
                        insOrderStateMapper.update(new InsOrderState(), Wrappers.<InsOrderState>lambdaUpdate()
                                .eq(InsOrderState::getInsOrderId, orderId)
                                .eq(InsOrderState::getLaboratory, sonLaboratory)
                                .set(InsOrderState::getInsState, 2));
                        insOrderMapper.update(null, new LambdaUpdateWrapper<InsOrder>()
                                .set(InsOrder::getState, 4)
                                .eq(InsOrder::getId, orderId));
                    } else {
                        insOrderStateMapper.update(new InsOrderState(), Wrappers.<InsOrderState>lambdaUpdate()
                                .eq(InsOrderState::getInsOrderId, orderId)
                                .eq(InsOrderState::getLaboratory, sonLaboratory)
                                .set(InsOrderState::getInsState, 1));
                        insOrderMapper.update(null, new LambdaUpdateWrapper<InsOrder>()
                                .set(InsOrder::getInsState, 1)
                                .eq(InsOrder::getId, orderId));
                    }
                }
            }
        }catch (Exception e){
            log.error("工时计算失败-->当前样品ID:{},检验详情:{}",currentSampleId,insContext);
            throw new RuntimeException(e);
        }finally {
            if(lock.isLocked())lock.unlock();
        }
    }
    /**
     * æŸ¥æ‰¾å°æ•°ä½æ•°æœ€å¤šçš„æ•°å€¼
     */
    public Map<String,Object> maxDecimalNumber(String tells) {
        HashMap<String, Object> map = new HashMap<>();
        Pattern pattern = Pattern.compile("[-+]?\\d*\\.?\\d+");
        Matcher matcher = pattern.matcher(tells);
        String tell = "";
        Integer maxNumber = 0;
        while (matcher.find()) {
            String group = matcher.group();
            Integer length = 0;
            if(group.contains(".")) {
                 length = group.split("\\.")[1].length();
            }else {
                length = 0;
            }
            if(length > maxNumber) {
                maxNumber = length;
                tell = group;
            }
        }
        map.put("tell",tell);
        map.put("maxNumber",maxNumber);
        return map;
    }
    /**
     * å°æ•°ä½æ•°çš„补全
     */
    public String completion(String value, Integer digit) {
        if(NumberUtil.isDouble(value)) {
            int length = 0;
            String[] splits = value.split("\\.");
            if(splits.length>1){
                length = splits[1].length();
            }
            if(digit > length) {
                int difference =  digit - length;
                for (int i = 0; i < difference; i++) {
                    value += "0";
                }
            }
        }
        return value;
    }
    //交接
    @Override
    public int upPlanUser(Integer userId, Integer orderId, String sonLaboratory) {
        InsSampleUser insSampleUser = new InsSampleUser();
        insSampleUser.setUserId(userId);
        insSampleUser.setInsSampleId(orderId);
        insSampleUser.setState(0);
        insSampleUser.setSonLaboratory(sonLaboratory);
        return insSampleUserMapper.insert(insSampleUser);
    }
    //根据单元格的文本内容计算实际行高
    private int estimateCellHeight(CellRenderData cellRenderData) {
        // å‡è®¾é»˜è®¤è¡Œé«˜æ˜¯40
        int defaultHeight = 40;
        // èŽ·å–å•å…ƒæ ¼ä¸­çš„æ‰€æœ‰æ®µè½
        List<ParagraphRenderData> paragraphs = cellRenderData.getParagraphs();
        int estimatedHeight = 0;
        try {
            // éåŽ†æ®µè½ï¼Œä¼°ç®—æ¯ä¸ªæ®µè½çš„é«˜åº¦
            for (ParagraphRenderData paragraph : paragraphs) {
                List<RenderData> contents = paragraph.getContents();
                for (RenderData content : contents) {
                    if (content instanceof TextRenderData) {
                        TextRenderData text = (TextRenderData) content;
                        Style style = text.getStyle();
                        // å‡è®¾æ¯è¡Œæ–‡æœ¬çš„高度为字体大小的1.2倍
                        Double fontSize = Objects.isNull(style.getFontSize()) ? 12.0 : style.getFontSize();
                        int lines = (int) Math.ceil(text.getText().length() / 15.0); // å‡è®¾æ¯è¡Œçº¦15个字符
                        int textHeight = (int) (fontSize * 1.2 * lines);
                        // ç´¯åŠ æ®µè½çš„é«˜åº¦
                        estimatedHeight += textHeight;
                    }
                }
            }
        }catch (Exception ignored){}
        // è¿”回最大值,确保高度不低于默认高度
        return Math.max(estimatedHeight, defaultHeight);
    }
    /**
     * å‘送队列消息
     * @param exchange   äº¤æ¢æœºåç§°
     * @param routerKey è·¯ç”±ä¸»é”®
     * @param jsonStr   æ¶ˆæ¯å†…容
     */
    public void sendQueueMessage(String exchange,String routerKey,String jsonStr){
        rabbitTemplate.convertAndSend(exchange,routerKey,jsonStr);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int verifyPlan(Integer orderId, String laboratory, Integer type, String tell) {
        int num = (type == 1 ? 5 : 4);
        LocalDateTime now = LocalDateTime.now();
        insOrderStateMapper.update(null, Wrappers.<InsOrderState>lambdaUpdate().eq(InsOrderState::getInsOrderId, orderId).eq(InsOrderState::getLaboratory, laboratory).set(InsOrderState::getInsTime, now).set(InsOrderState::getInsState, num).set(InsOrderState::getVerifyTell, tell).set(InsOrderState::getVerifyUser, SecurityUtils.getUserId()));
        Long count = insOrderStateMapper.selectCount(Wrappers.<InsOrderState>lambdaQuery().eq(InsOrderState::getInsOrderId, orderId).ne(InsOrderState::getInsState, 5));
        if (count == 0 && num == 5) {
            List<InsUnPass> insUnPasses = new ArrayList<>();
            /*样品下的项目只要有一个项目不合格则检验结果为0,否则为1*/
            //这里的insSamples是订单下的所有样品包括("/")
            List<InsSample> insSamples = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery().eq(InsSample::getInsOrderId, orderId));
            for (InsSample insSample : insSamples) {
                List<InsProduct> insProducts = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery().eq(InsProduct::getInsSampleId, insSample.getId()).eq(InsProduct::getState, 1));
                List<Integer> results = insProducts.stream().map(InsProduct::getInsResult).filter(Objects::nonNull).collect(Collectors.toList());
                if (results.contains(0)) {
                    insSample.setInsResult(0);
                } else {
                    insSample.setInsResult(1);
                }
                insSampleMapper.updateById(insSample);
                /*复核通过后,将不合格的项目信息添加到ins_un_pass表中*/
                for (InsProduct insProduct : insProducts) {
                    if (insProduct.getInsResult() == 0) {
                        InsUnPass insUnPass = new InsUnPass();
                        insUnPass.setId(null);
                        insUnPass.setModel(insSample.getModel());
                        insUnPass.setSample(insSample.getSample());
                        insUnPass.setInspectionItem(insProduct.getInspectionItem());
                        insUnPass.setInspectionItemSubclass(insProduct.getInspectionItemSubclass());
                        insUnPass.setLastValue(insProduct.getLastValue());
                        insUnPass.setEntrustCode(insOrderMapper.selectById(orderId).getEntrustCode());
                        List<Integer> userIds = insProductUserMapper.selectList(Wrappers.<InsProductUser>lambdaQuery().eq(InsProductUser::getInsProductId, insProduct.getId())).stream().map(InsProductUser::getCreateUser).distinct().collect(Collectors.toList());
                        if(!userIds.isEmpty()){
                            String name = userMapper.selectBatchIds(userIds).stream().map(User::getName).collect(Collectors.joining(","));
                            insUnPass.setName(name);
                            insUnPasses.add(insUnPass);
                        }
                    }
                }
            }
            insUnPassService.saveBatch(insUnPasses);
            InsOrder insOrder = insOrderMapper.selectById(orderId);
            String oldSampleStr = insOrder.getSample();
            //samples是过滤掉没有检验项目的样品
            List<SampleProductDto> samples = insSampleMapper.selectSampleProductListByOrderId(orderId);
            //查询订单下的去重后的样品名称
            List<String> unqeSampleList = samples.stream().map(InsSample::getSample).distinct().collect(Collectors.toList());
            if(unqeSampleList.size()==1){
                insOrder.setSample(unqeSampleList.get(0));
            }
            InsReport insReport = new InsReport();
            insReport.setCode(insOrder.getEntrustCode());
            insReport.setInsOrderId(orderId);
            List<Map<String, Object>> tables = new ArrayList<>();
            Set<String> standardMethod = new HashSet<>();
            Set<String> deviceSet = new HashSet<>();
            Set<String> models = new HashSet<>();
            AtomicReference<Integer> productSize = new AtomicReference<>(0);
            String[] monthNames = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
            Set<String> resultCh = new HashSet<>();
            Set<String> resultEn = new HashSet<>();
            //获取检验项目数量
            Set<String> unEqualSet = new HashSet<>();
            //电力试验室:钢材/铝材样品型号
            List<String> modelDl = new ArrayList<>();
            /*基础报告(根据绘制的原始记录模版形成)*/
            BasicReportHandler basicReportHandler = new BasicReportHandler(baseMapper, this,insSampleMapper);
            basicReportHandler.doWrite(samples,insReport,tables,standardMethod,models,unEqualSet,modelDl,deviceSet);
            productSize.getAndSet(unEqualSet.size());
            String sampleStr = insOrder.getSample();
            if(!modelDl.isEmpty()){
                String model = modelDl.stream().distinct().findFirst().orElse("");
                sampleStr += model;
            }
            /*光纤接头损耗的报告样式*/
            //查询订单下所有样品的检验项目,如果有光纤接头损耗则重新构建表格
            List<Map<String, Object>> tables4 = new ArrayList<>();
            //当前订单下的所有检验项
            List<InsProduct> insProducts0 = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                    .eq(InsProduct::getState, 1)
                    .in(InsProduct::getInsSampleId, insSamples.stream().map(InsSample::getId).distinct().collect(Collectors.toList())));
            if (insProducts0.stream().map(InsProduct::getInspectionItem).collect(Collectors.toList()).contains("光纤接头损耗")){
                //处理光纤接头损耗报告
                FiberOpticConnectorLossReportHandler lossReportHandler = new FiberOpticConnectorLossReportHandler(insProductMapper);
                lossReportHandler.doWrite(insProducts0,insSamples,insReport,tables4);
            }
            String url;
            try {
                InputStream inputStream = this.getClass().getResourceAsStream("/static/report-template.docx");
                File file = File.createTempFile("temp", ".tmp");
                OutputStream outputStream = new FileOutputStream(file);
                IOUtils.copy(inputStream, outputStream);
                url = file.getAbsolutePath();
            } catch (FileNotFoundException e) {
                throw new ErrorException("找不到模板文件");
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            StringBuilder standardMethod2 = new StringBuilder();
            for (String s : standardMethod) {
                standardMethod2.append("、").append(s);
            }
            standardMethod2.replace(0, 1, "");
            tables.forEach(table -> {
                table.put("tableSize", tables.size() + 1);
            });
            List<DeviceVO> deviceList = new ArrayList<>();
            if (!deviceSet.isEmpty()) {
                deviceSet.forEach(d->deviceList.add(insOrderMapper.selectDeviceList(d)));
            }
            Map<String, String> codeStr = new HashMap<>();
            codeStr.put("报告编号", insReport.getCode());
            codeStr.put("样品名称", insOrder.getSample());
            codeStr.put("规格型号", samples.get(0).getModel());
            codeStr.put("发放日期", now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            String codePath;
            try {
                String content = phoneQrCode+ insOrder.getEntrustCode() + "&type=word";
                codePath = new MatrixToImageWriter().code(content, twoCode);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            String modelStr = "";
            for (String model : models) {
                modelStr += "," + model;
            }
            String finalModelStr = modelStr;
            String sampleEn = insSampleMapper.getSampleEn(insOrder.getSample());
            insOrder.setSample(sampleStr);
            String orderType = insOrderMapper.getEnumLabelByValue(insOrder.getOrderType());
            String formType = insOrderMapper.getEnumLabelByValue(insOrder.getFormType());
            ConfigureBuilder builder = Configure.builder();
            builder.useSpringEL(true);
            List<DeviceVO> finalDeviceList = deviceList;
            Integer userId = insSampleUserMapper.selectOne(Wrappers.<InsSampleUser>lambdaQuery()
                    .eq(InsSampleUser::getInsSampleId, orderId)
                    .eq(InsSampleUser::getState,0)
                    .orderByDesc(InsSampleUser::getCreateTime)
                    .last("limit 1")).getUserId();
            String signatureUrl;
            try {
                signatureUrl = userMapper.selectById(userId).getSignatureUrl();
            } catch (Exception e) {
                throw new ErrorException("找不到检验人的签名");
            }
            if (ObjectUtils.isEmpty(signatureUrl) || signatureUrl.isEmpty()) {
                throw new ErrorException("找不到检验人的签名");
            }
            //如果是中天科技软微缆厂(02),报告展示委托单位为中天科技光缆总厂(01)
            Custom custom = customMapper.selectById(insOrder.getCompanyId());
            if(!Objects.isNull(custom) && Objects.equals("中天科技软微缆厂",custom.getCompany())){
                //中天科技光缆总厂客户信息
                custom = customMapper.selectOne(Wrappers.<Custom>lambdaQuery()
                        .eq(Custom::getCompany,"中天科技光缆总厂")
                        .eq(Custom::getCode2,"01").last("limit 1"));
            }
            //合格数量
            long qualifiedCount = insProducts0.stream().filter(f->f.getInsResult()==1).count();
            //格式化不合格项目
            joinUnqualifiedItemChars(resultCh,resultEn,insProducts0);
            String resultChStr = "依据委托要求,所检项目均符合要求。";
            String resultEnStr = "According to commissioned requirements, all the tested items meet the requirements.";
            if (!resultCh.isEmpty() && qualifiedCount>0) {
                resultChStr = "依据委托要求," + String.join("、",resultCh) + "所检项目不符合要求,其余所检项目均符合要求。";
                resultEnStr = "According to commissioned requirements," + String.join("、",resultEn) + " these inspected items do not meet the requirements, all other inspected items meet the requirements.";
            }else if(!resultCh.isEmpty() && qualifiedCount==0){
                resultChStr = "依据委托要求,所检项目均不符合要求。";
                resultEnStr = "According to commissioned requirements, all the tested items do not meet the requirements.";
            }
            //光纤附件表格数据
            List<Map<String, Object>> tables2 = new ArrayList<>();
            //松套管附件表格数据
            List<Map<String, Object>> tables5 = new ArrayList<>();
            //尺寸参数附件表格数据
            List<Map<String, Object>> tables6 = new ArrayList<>();
            /*光纤配置的检验报告*/
            //先判断是否有光纤配置
            List<InsProduct> insProducts = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                    .eq(InsProduct::getState, 1)
                    .in(InsProduct::getInsSampleId, insSamples.stream().map(InsSample::getId).distinct().collect(Collectors.toList()))
                    .and(i->i.isNull(InsProduct::getInspectionItemClass).or().eq(InsProduct::getInspectionItemClass,""))
                    );//用检验分项字段区别光纤配置与温度循环
            //查询全色谱,过滤色标并排序
            List<String> colorList = DictUtils.getDictCache("色标").stream()
                    .sorted(Comparator.comparing(SysDictData::getDictSort))
                    .map(SysDictData::getDictValue)
                    .collect(Collectors.toList());
            //松套管附件处理
            long piperCount = insProducts.stream().filter(f->!Objects.isNull(f.getInsBushId())).count();
            if(piperCount>0){
                PiperConfigReportHandler piperConfigReportHandler = new PiperConfigReportHandler(insProductMapper);
                piperConfigReportHandler.doWrite(samples,insReport,tables5,colorList);
            }
            //过滤有光纤配置的项目
            long fiberCount = insProducts.stream().filter(f->!Objects.isNull(f.getInsFiberId())).count();
            FiberConfigReportHandler lossReportHandler = new FiberConfigReportHandler(insProductMapper,insSampleMapper);
            if (fiberCount>0) {
                lossReportHandler.doWrite(samples,insReport,tables2,colorList);
            } else{
                //排除光纤接头损耗和尺寸参数
                List<InsProduct> filterLists = insProducts.stream()
                        .filter(f->!Arrays.asList("光纤接头损耗","尺寸参数","温度循环").contains(f.getInspectionItem())&&f.getSonLaboratory().equals("光纤试验室")).collect(Collectors.toList());
                lossReportHandler.writeFiberEnclosureTableRow(filterLists,tables2,insReport);
            }
            //过滤有光纤带配置的项目
            long fibersCount = insProducts.stream().filter(f->!Objects.isNull(f.getInsFibersId())).count();
            FiberOpticRibbonReportHandler fiberOpticRibbonReportHandler = new FiberOpticRibbonReportHandler(insProductMapper,insSampleMapper);
            if (fibersCount>0) {
                fiberOpticRibbonReportHandler.doWrite(samples,insReport,tables6,colorList);
            } else{
                //过滤尺寸参数项目
                List<InsProductFiberVO> productList = new ArrayList<>();
                insSamples.stream()
                        .map(InsSample::getId).distinct()
                        .forEach(id->productList.addAll(insProductMapper.selectProductBySampleId(id)));
                List<InsProductFiberVO> vos = productList.stream().filter(f->f.getInspectionItem().equals("尺寸参数")).collect(Collectors.toList());
                if(!vos.isEmpty()){
                    fiberOpticRibbonReportHandler.writeFiberOpticRibbonEnclosureTableRow(vos,tables6,insReport);
                }
            }
            tables2.forEach(table2 -> table2.put("tableSize2", tables2.size()));
            tables5.forEach(table5 -> table5.put("tableSize5", tables5.size()));
            tables6.forEach(table6 -> table6.put("tableSize6", tables6.size()));
            /*温度循环的检验报告*/
            //先判断是否有温度循环
            List<InsProduct> insProducts3 = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                    .eq(InsProduct::getState, 1)
                    .in(InsProduct::getInsSampleId, insSamples.stream().map(InsSample::getId).distinct().collect(Collectors.toList()))
                    .isNotNull(InsProduct::getSpecialItemParentId)  //区分常规项目
                    .isNotNull(InsProduct::getInspectionItemClass)//用检验分项字段区别光纤配置与温度循环
                    .isNotNull(InsProduct::getInsFiberId)); //用光纤区别热循环和温度循环
            List<Map<String, Object>> tables3 = new ArrayList<>();
            if (!insProducts3.isEmpty()) {
                //处理温度循环报告
                TemperatureCyclingReportHandler1 cyclingReportHandler = new TemperatureCyclingReportHandler1(insProductMapper, insFiberMapper, insProductResultMapper);
                cyclingReportHandler.doWrite(samples,insReport,tables3);
            }
            /*温升试验的检验报告*/
            List<InsProduct> insProducts1 = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                    .eq(InsProduct::getState, 1)
                    .in(InsProduct::getInsSampleId, insSamples.stream().map(InsSample::getId).distinct().collect(Collectors.toList()))
                    .isNotNull(InsProduct::getSpecialItemParentId)  //区分常规项目
                    .isNull(InsProduct::getInspectionItemClass)//用检验分项字段区别温升试验与热循环
                    .isNull(InsProduct::getInsFiberId) //用光纤区别温升试验和温度循环
                    .eq(InsProduct::getInspectionItem, "1")); //温升试验的循环只有1次
            if (!insProducts1.isEmpty()) {
                //处理温升试验报告
                TemperatureTestReportHandler testReportHandler = new TemperatureTestReportHandler(insProductMapper, insProductResultMapper);
                testReportHandler.doWrite(samples,insReport,tables3);
            }
            /*热循环的检验报告*/
            List<InsProduct> insProducts2 = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                    .eq(InsProduct::getState, 1)
                    .in(InsProduct::getInsSampleId, insSamples.stream().map(InsSample::getId).distinct().collect(Collectors.toList()))
                    .isNotNull(InsProduct::getSpecialItemParentId)  //区分常规项目
                    .isNotNull(InsProduct::getInspectionItemClass)//用检验分项字段区别温升试验与热循环
                    .isNull(InsProduct::getInsFiberId)); //用光纤区别热循环和温度循环
            if (!insProducts2.isEmpty()) {
                //处理热循环报告
                ThermalCycleReportHandler cycleReportHandler = new ThermalCycleReportHandler(insProductMapper, insProductResultMapper);
                cycleReportHandler.doWrite(samples,insReport,tables3);
            }
            //单根垂直燃烧的检验报告
            tables3.forEach(table3 -> {
                table3.put("tableSize3", tables3.size());
            });
            /*获取附件图片类型*/
            List<Map<String, Object>> images = new ArrayList<>();
            List<InsOrderFile> insOrderFiles = insOrderFileMapper.selectList(Wrappers.<InsOrderFile>lambdaQuery().eq(InsOrderFile::getType, 1).eq(InsOrderFile::getInsOrderId, orderId));
            if (CollectionUtils.isNotEmpty(insOrderFiles)) {
                insOrderFiles.forEach(insOrderFile -> {
                    Map<String, Object> image = new HashMap<>();
                    PictureRenderData pictureRenderData = Pictures.ofLocal(imgUrl + "/" + insOrderFile.getFileUrl()).sizeInCm(17, 20).create();
                    image.put("url", pictureRenderData);
                    image.put("report", insReport);
                    images.add(image);
                });
            }
            //委托人和电话字段判断
            if (ObjectUtils.isEmpty(insOrder.getPrepareUser())) {
                insOrder.setPrepareUser("/");
            }
            if (ObjectUtils.isEmpty(insOrder.getPhone())) {
                insOrder.setPhone("/");
            }
            //查询审批签名配置
            Map<String,Object> urlMap = insReportApproveConfigMapper.selectApprovalConfigByLaboratory(insOrder.getLaboratory());
            String writeUrl = imgUrl + "/" + (Objects.isNull(urlMap.get("writeUrl"))?"":urlMap.get("writeUrl").toString());//编制人签名url
            String examineUrl = imgUrl + "/" +  (Objects.isNull(urlMap.get("examineUrl"))?"":urlMap.get("examineUrl").toString());//审核人签名url
            String ratifyUrl = imgUrl + "/" +  (Objects.isNull(urlMap.get("ratifyUrl"))?"":urlMap.get("ratifyUrl").toString());//批准人签名url
            //获取场所的报告专用章
            String sealUrl;
            try {
                sealUrl = insReportMapper.getLaboratoryByName(insOrder.getLaboratory());
            } catch (Exception e) {
                throw new ErrorException("找不到报告专用章");
            }
            //检验项目的环境
            InsProduct insProduct = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery().eq(InsProduct::getState, 1).eq(InsProduct::getInsSampleId, samples.get(0).getId())).get(0);
            String environment = "";
            environment = (ObjectUtils.isNotEmpty(insProduct.getTemperature()) ? insProduct.getTemperature() + "℃ " : "") + (ObjectUtils.isNotEmpty(insProduct.getHumidity()) ? insProduct.getHumidity() + "%" : "");
            String finalEnvironment = environment;
            Custom finalCustom = custom;
            String finalSealUrl = imgUrl + "/" +sealUrl;
            String finalResultChStr = resultChStr;
            String finalResultEnStr = resultEnStr;
            ZipSecureFile.setMinInflateRatio(0.001);
            XWPFTemplate template = XWPFTemplate.compile(url, builder.build()).render(
                    new HashMap<String, Object>() {{
                        put("order", insOrder);
                        put("report", insReport);
                        put("environment", finalEnvironment);
                        put("custom", finalCustom);
                        put("sampleSize", samples.size());
                        put("tables", tables);
                        put("tableSize", tables.size() + 1);
                        put("tables2", tables2.isEmpty()?null:tables2);
                        put("tableSize2", tables2.size());
                        put("tables3", tables3.isEmpty()?null:tables3);
                        put("tableSize3", tables3.size());
                        put("tables4", tables4.isEmpty()?null:tables4);
                        put("tableSize4", tables4.size());
                        put("tables5", tables5.isEmpty()?null:tables5);
                        put("tableSize5", tables5.size());
                        put("tables6", tables6.isEmpty()?null:tables6);
                        put("tableSize6", tables6.size());
                        put("standardMethod", (standardMethod2.toString().equals("null") ? "" : standardMethod2));
                        put("deviceList", finalDeviceList);
                        put("twoCode", Pictures.ofLocal(codePath).create());
                        put("models", finalModelStr.replace(",", ""));
                        put("productSize", productSize);
                        put("createTime", now.format(DateTimeFormatter.ofPattern("yyyyå¹´MM月dd日")));
                        put("createTimeEn", monthNames[now.getMonthValue() - 1] + " " + now.getDayOfMonth() + ", " + now.getYear());
                        put("insTime", insOrder.getInsTime().format(DateTimeFormatter.ofPattern("yyyyå¹´MM月dd日")));
                        put("insTimeEn", monthNames[insOrder.getInsTime().getMonthValue() - 1] + " " + insOrder.getInsTime().getDayOfMonth() + ", " + insOrder.getInsTime().getYear());
                        put("writeUrl", new FilePictureRenderData(100,50, writeUrl));
                        put("insUrl", new FilePictureRenderData(100,50,imgUrl + "/" + signatureUrl));
                        put("images", images.isEmpty()?null:images);
                        put("examineUrl", new FilePictureRenderData(100,50,examineUrl));
                        put("ratifyUrl", new FilePictureRenderData(100,50,ratifyUrl));
                        put("sampleEn", sampleEn);
                        put("orderType", orderType);
                        put("getTime", insOrder.getExamineTime().format(DateTimeFormatter.ofPattern("yyyyå¹´MM月dd日")));
                        put("getTimeEn", monthNames[insOrder.getExamineTime().getMonthValue() - 1] + " " + insOrder.getExamineTime().getDayOfMonth() + ", " + insOrder.getExamineTime().getYear());
                        put("seal1", new FilePictureRenderData(600,600, finalSealUrl));
                        put("seal2", new FilePictureRenderData(600,600, finalSealUrl));
                        put("formTypeCh", formType);
                        put("formTypeEn", insOrder.getFormType());
                        put("resultCh", finalResultChStr);
                        put("resultEn", finalResultEnStr);
                    }});
            // æ›´æ–°æ•°æ®åº“中的签发日期
            insOrderService.update(Wrappers.<InsOrder>lambdaUpdate()
                    .eq(InsOrder::getId, insOrder.getId())
                    .set(InsOrder::getIssuingDate, now));
            try {
                String name = insReport.getCode().replace("/", "") + ".docx";
                template.writeAndClose(Files.newOutputStream(Paths.get(wordUrl + "/" + name)));
                insReport.setUrl("/word/" + name);
                insReport.setIsExamine(-9);//未审核状态为-9
                insReport.setIsRatify(-9);//未批准状态为-9
                insReportMapper.insert(insReport);
                insOrder.setInsState(5);
                insOrder.setSample(oldSampleStr);
                insOrderMapper.updateById(insOrder);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            // å¤„理合并单元格的问题
            String path = wordUrl + "/" + insReport.getCode().replace("/", "") + ".docx";
            // word è½¬ pdf
            String tempUrlPdf = insReportService.wordToPdfTemp((StrUtil.isBlank(insReport.getUrlS()) ? insReport.getUrl() : insReport.getUrlS()).replace("/word", wordUrl));
            insReportMapper.update(null,new LambdaUpdateWrapper<InsReport>()
                    .set(InsReport::getTempUrlPdf,tempUrlPdf)
                    .eq(InsReport::getId,insReport.getId()));
            try {
                ZipSecureFile.setMinInflateRatio(0.0001);//解决附件文件过大引发的ZipBom异常
                FileInputStream stream = new FileInputStream(path);
                XWPFDocument document = new XWPFDocument(stream);
                List<XWPFTable> xwpfTables = document.getTables();
                for (int i = 0; i < xwpfTables.size(); i++) {
                    Set<String> set1 = new HashSet<>();
                    Map<String, Map<String, Integer>> maps = new HashMap<>();
                    for (int j = 0; j < xwpfTables.get(i).getRows().size(); j++) {
                        for (int k = 0; k < xwpfTables.get(i).getRows().get(j).getTableCells().size(); k++) {
                            if (xwpfTables.get(i).getRows().get(j).getTableCells().get(k).getText().indexOf("∑") > -1) {
                                String[] split = xwpfTables.get(i).getRows().get(j).getTableCells().get(k).getText().split("∑");
                                if (set1.add(split[1])) {
                                    Map<String, Integer> map = new HashMap<>();
                                    map.put("sr", j);
                                    map.put("sc", k);
                                    map.put("er", j + 0);
                                    map.put("ec", k + 0);
                                    maps.put(split[1], map);
                                } else {
                                    Map<String, Integer> map1 = maps.get(split[1]);
                                    if (j == map1.get("sr")) {
                                        map1.put("ec", map1.get("ec") + 1);
                                    } else if (k == map1.get("sc")) {
                                        map1.put("er", map1.get("er") + 1);
                                    }
                                }
                                String str = xwpfTables.get(i).getRows().get(j).getTableCells().get(k).getText().split("∑")[0];
                                xwpfTables.get(i).getRows().get(j).getTableCells().get(k).removeParagraph(0);
                                xwpfTables.get(i).getRows().get(j).getTableCells().get(k).setText(str);
                                xwpfTables.get(i).getRows().get(j).getTableCells().get(k).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
                                xwpfTables.get(i).getRows().get(j).getTableCells().get(k).getParagraphArray(0).setAlignment(ParagraphAlignment.CENTER);
                            }
                        }
                    }
                    // å•元格排序, é¿å…æ ¼å¼é”™ä¹±
                    List<Map.Entry<String, Map<String, Integer>>> entries = new ArrayList<>(maps.entrySet());
                    entries.sort((o1, o2) -> o1.getValue().get("sc") - o2.getValue().get("sc"));
                    // æŒ‰ç…§é¡ºåºæ·»åŠ è¿›é›†åˆ
                    List<String> list = new ArrayList<>();
                    for (Map.Entry<String, Map<String, Integer>> entry : entries) {
                        list.add(entry.getKey());
                    }
                /*List<String> list = new ArrayList<>();
                for (String s : maps.keySet()) {
                    list.add(s);
                }*/
                    for (int a = list.size() - 1; a >= 0; a--) {
                        Map<String, Integer> v = maps.get(list.get(a));
                        for (int j = 0; j < v.get("er") - v.get("sr") + 1; j++) {
                            if (v.get("ec") > v.get("sc")) {
                                try {
                                    TableTools.mergeCellsHorizonal(xwpfTables.get(i), v.get("sr") + j, v.get("sc"), v.get("ec"));
                                } catch (Exception e) {
                                }
                            }
                        }
                        if (v.get("er") > v.get("sr")) {
                            try {
                                TableTools.mergeCellsVertically(xwpfTables.get(i), v.get("sc"), v.get("sr"), v.get("er"));
                            } catch (Exception e) {
                            }
                        }
                    }
                }
                FileOutputStream fileOutputStream = new FileOutputStream(path);
                document.write(fileOutputStream);
                fileOutputStream.close();
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            //处理中英文换行的问题
            try {
                FileInputStream stream1 = new FileInputStream(path);
                XWPFDocument document1 = new XWPFDocument(stream1);
                List<XWPFTable> xwpfTables1 = document1.getTables();
                for (int i = 1; i < xwpfTables1.size() - (deviceList == null ? 1 : 2); i++) {
                    for (int j = 0; j < xwpfTables1.get(i).getRows().size(); j++) {
                        for (int k = 0; k < xwpfTables1.get(i).getRows().get(j).getTableCells().size(); k++) {
                            if (xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).getText().contains("@")) {
                                String text = xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).getText();
                                String[] split = text.split("@");
                                xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).removeParagraph(0);
                                XWPFParagraph xwpfParagraph = xwpfTables1.get(i).getRows().get(j).getTableCells().get(k).addParagraph();
                                XWPFRun run = xwpfParagraph.createRun();
                                run.setText(split.length>0?split[0]:"");
                                if (split.length>1 && ObjectUtils.isNotNull(split[1])) {
                                    run.addBreak();
                                    run.setText(split[1]);
                                }
                                xwpfParagraph.setAlignment(ParagraphAlignment.CENTER);
                            }
                        }
                    }
                }
                FileOutputStream fileOutputStream1 = new FileOutputStream(path);
                document1.write(fileOutputStream1);
                fileOutputStream1.close();
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } else if(num != 5) {
            //复核不通过将把复核的负责人去掉
            Integer id = insSampleUserMapper.selectOne(Wrappers.<InsSampleUser>lambdaQuery().eq(InsSampleUser::getInsSampleId, orderId).orderByDesc(InsSampleUser::getId).last("limit 1")).getId();
            insSampleUserMapper.deleteById(id);
        }
        return 1;
    }
    /**
     * æ ¼å¼åŒ–不合格项目字符串
     * @param resultCh ä¸åˆæ ¼é¡¹ç›®ä¸­æ–‡åˆ—表
     * @param resultEn ä¸åˆæ ¼é¡¹ç›®è‹±æ–‡åˆ—表
     * @param insProducts0 æ£€éªŒé¡¹åˆ—表
     */
    private void joinUnqualifiedItemChars(Set<String> resultCh, Set<String> resultEn, List<InsProduct> insProducts0) {
        if(!insProducts0.isEmpty()){
            insProducts0.stream().filter(f->f.getInsResult()==0).forEach(e->{
                String chinaStr = String.join("-",e.getInspectionItem(),e.getInspectionItemSubclass());
                String englishStr = String.join("-",e.getInspectionItemEn(),e.getInspectionItemSubclassEn());
                resultCh.add(chinaStr);
                resultEn.add(englishStr);
            });
        }
    }
    public void getTemplateThing
            (Set<Integer> set, Map<Integer, String> map2, List<InsProduct> insProducts) {
        for (InsProduct product : insProducts) {
            if (product.getSpecialItemParentId()!=null) {
                product.setTemplate(new ArrayList<>());
                continue;
            }
            String thing = null;
            if (product.getSpecialItemParentId() == null && set.add(product.getTemplateId())) {
                map2.put(product.getTemplateId(), standardTemplateService.getStandTempThingById(product.getTemplateId()) + "");
                thing = map2.get(product.getTemplateId());
            }
            if (StrUtil.isNotEmpty(thing)) {
                JSONObject sheet = JSON.parseObject(JSON.toJSONString(JSON.parseArray(JSON.toJSONString(JSON.parseObject(thing).get("data"))).get(0)));
                JSONObject config = JSON.parseObject(JSON.toJSONString(sheet.get("config")));
                List<JSONObject> cellData = JSON.parseArray(JSON.toJSONString(sheet.get("celldata")), JSONObject.class);
                Map<String, Object> style = new HashMap<>();
                style.put("rowlen", config.get("rowlen"));
                style.put("columnlen", config.get("columnlen"));
                product.setTemplate(cellData);
                product.setStyle(style);
                product.setTemplateName(standardTemplateService.getStandTempNameById(product.getTemplateId()));
            }
        }
    }
    @Override
    public int submitPlan(Integer orderId, String laboratory, Integer verifyUser, String entrustCode) {
        List<InsSample> insSamples = insSampleMapper.selectList(Wrappers.<InsSample>lambdaQuery().eq(InsSample::getInsOrderId, orderId).select(InsSample::getId));
        List<Integer> ids = insSamples.stream().map(a -> a.getId()).collect(Collectors.toList());
        List<InsProduct> insProducts = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                .in(InsProduct::getInsSampleId, ids)
                .eq(InsProduct::getSonLaboratory, laboratory)
                .eq(InsProduct::getState, 1)
                .and(wrapper -> wrapper
                        .isNull(InsProduct::getInsResult)
                        .or()
                        .eq(InsProduct::getInsResult, 2)
                )
                .isNull(InsProduct::getInsFiberId)
                .isNull(InsProduct::getInsFibersId));
        insProducts.addAll(insProductMapper.selectFiberInsProduct(ids, laboratory));
        if (insProducts.size() > 0) {
            String str = "";
            HashSet<String> set = new HashSet<>();
            int count = 0;
            for (InsProduct product : insProducts) {
                //如果是光缆的温度循环
                if (product.getInspectionItem().equals("温度循环") && insOrderMapper.selectById(orderId).getSampleType().equals("光缆")) {
                    //查询那些循环温度的检验项目的结论是否全部检验
                    List<InsProduct> insProductList = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery().eq(InsProduct::getInsSampleId, product.getInsSampleId())
                            .isNotNull(InsProduct::getInsFiberId).like(InsProduct::getInspectionItemSubclass, "℃"));
                    List<Integer> collect = insProductList.stream().filter(insProduct -> insProduct.getInsResult() != null).map(InsProduct::getInsResult).collect(Collectors.toList());
                    List<Integer> tt = new ArrayList<>();
                    tt.add(1);
                    if (collect.contains(0)) {
                        product.setLastValue("不合格");
                        product.setInsResult(0);
                    } else if (collect.size() == insProductList.size() && collect.stream().distinct().collect(Collectors.toList()).containsAll(tt)) {
                        product.setLastValue("合格");
                        product.setInsResult(1);
                    }
                    insProductMapper.updateById(product);
                }
                //如果是热循环或者是温升试验
                else if (product.getInspectionItem().equals("热循环") || product.getInspectionItem().equals("温升试验")) {
                    //查询这些项目下的其他检验项目是否全部检验
                    List<InsProduct> insProductList = insProductMapper.selectList(Wrappers.<InsProduct>lambdaQuery()
                            .eq(InsProduct::getInsSampleId, product.getInsSampleId())
                            .like(InsProduct::getInspectionItemSubclass, "温度"));
                    List<Integer> collect = insProductList.stream().filter(insProduct -> insProduct.getInsResult() != null).map(InsProduct::getInsResult).collect(Collectors.toList());
                    List<Integer> tt = new ArrayList<>();
                    tt.add(1);
                    if (collect.contains(0)) {
                        product.setLastValue("不合格");
                        product.setInsResult(0);
                    } else if (collect.size() == insProductList.size() && collect.stream().distinct().collect(Collectors.toList()).containsAll(tt)) {
                        product.setLastValue("合格");
                        product.setInsResult(1);
                    }
                    insProductMapper.updateById(product);
                }
                //如果是电力的应力应变检验项目或者是疲劳试验,结论改成不判定
                else if (product.getInspectionItem().equals("应力应变") || product.getInspectionItem().contains("疲劳试验")){
                    product.setInsResult(3);
                    insProductMapper.updateById(product);
                }
                //如果是防振锤功率特性试验
                else if (product.getInspectionItem().equals("防振锤功率特性试验")){
                    product.setInsResult(1);//默认合格
                    //需要去判断填写的检验数据是否有不合格
                    InsProductResult insProductResult = insProductResultMapper.selectOne(Wrappers.<InsProductResult>lambdaQuery().eq(InsProductResult::getInsProductId, product.getId()));
                    cn.hutool.json.JSONObject jsonObject = new cn.hutool.json.JSONObject(insProductResult.getComValue());
                    // æ£€æŸ¥ arr2
                    cn.hutool.json.JSONArray arr2 = jsonObject.getJSONArray("arr2");
                    for (int i = 0; i < arr2.size(); i++) {
                        cn.hutool.json.JSONObject obj = arr2.getJSONObject(i);
                            if (obj.getInt("state") == 2) {
                                product.setInsResult(0);
                                break;
                            }
                    }
                    // æ£€æŸ¥ arr3
                    cn.hutool.json.JSONArray arr3 = jsonObject.getJSONArray("arr3");
                    for (int i = 0; i < arr3.size(); i++) {
                        cn.hutool.json.JSONObject obj = arr3.getJSONObject(i);
                            if (obj.getInt("state") == 2) {
                                product.setInsResult(0);
                                break;
                            }
                    }
                    insProductMapper.updateById(product);
                }
                else {
                    String  notDetected = product.getInspectionItem() + " " + product.getInspectionItemSubclass();
                    if(!set.contains(notDetected)) {
                        count++;
                        str += "<br/>" + count + ":" + product.getInspectionItem() + " " + product.getInspectionItemSubclass() + "<br/>";
                        set.add(notDetected);
                    }
                }
            }
            if (ObjectUtils.isNotEmpty(str)) {
                throw new ErrorException("<strong>存在待检验的项目:</strong><br/>" + str);
            }
        }
        insOrderStateMapper.update(null, Wrappers.<InsOrderState>lambdaUpdate().eq(InsOrderState::getInsOrderId, orderId).eq(InsOrderState::getLaboratory, laboratory).set(InsOrderState::getInsTime, LocalDateTime.now()).set(InsOrderState::getInsState, 3).set(InsOrderState::getVerifyUser, verifyUser));
        Integer userId = SecurityUtils.getUserId().intValue();
        InformationNotification info = new InformationNotification();
        info.setCreateUser(insProductMapper.selectUserById(userId).get("name"));
        info.setMessageType("2");
        info.setTheme("复核通知");
        info.setContent("您有一条检验任务待复核消息");
        info.setSenderId(userId);
        info.setConsigneeId(verifyUser);
        info.setViewStatus(false);
        info.setJumpPath("b1-inspect-order-plan");
        informationNotificationService.addInformationNotification(info);
        //复核人--检验单相关负责人
        InsSampleUser insSampleUser = new InsSampleUser();
        insSampleUser.setUserId(verifyUser);
        insSampleUser.setInsSampleId(orderId);
        insSampleUser.setState(1);
        insSampleUser.setSonLaboratory(laboratory);
        insSampleUserMapper.insert(insSampleUser);
        /*校验一下result表*/
        CompletableFuture.supplyAsync(() -> {
            List<Integer> ips = insProducts.stream().map(InsProduct::getId).distinct().collect(Collectors.toList());
            for (Integer ip : ips) {
                List<InsProductResult> insProductResults = insProductResultMapper.selectList(Wrappers.<InsProductResult>lambdaQuery()
                        .eq(InsProductResult::getInsProductId, ip));
                if (insProductResults.size() > 1) {
                    for (int i = 1; i < insProductResults.size(); i++) {
                        insProductResultMapper.deleteById(insProductResults.get(i));
                    }
                }
            }
            return null;
        });
        // åˆ é™¤æ•°é‡‡é‡‡é›†æ¬¡æ•°
        String key = "frequency" + ":" + entrustCode + ":*";
        RedisUtil.delsLike(key);
        return 1;
    }
    @Override
    public List<String> getEquipName(Integer orderId,String sonLaboratory) {
        List<Integer> ids = insSampleMapper.selectList(new LambdaQueryWrapper<InsSample>()
                        .eq(InsSample::getInsOrderId, orderId))
                .stream()
                .map(InsSample::getId)
                .collect(Collectors.toList());
        // æŸ¥çœ‹å•子是否选择了设备
        List<String> strList = new ArrayList<>();
        HashSet<String> set = new HashSet<>();
        List<InsProduct> productList = insProductMapper.selectList(new LambdaQueryWrapper<InsProduct>()
                .in(InsProduct::getInsSampleId, ids)
                .eq(InsProduct::getSonLaboratory, sonLaboratory)
                .eq(InsProduct::getState, 1));
        if (CollectionUtils.isNotEmpty(productList)) {
            List<InsProduct> collect = productList.stream()
                    .filter(item -> Objects.isNull(item.getSpecialItemParentId()) || StringUtils.isEmpty(item.getSpecialItemParentId()+""))
                    .collect(Collectors.toList());
            for (InsProduct product : collect) {
                InsProductResult insProductResult = insProductResultMapper.selectOne(new LambdaQueryWrapper<InsProductResult>()
                        .eq(InsProductResult::getInsProductId, product.getId()));
                if(Objects.nonNull(insProductResult)){
                    if(Objects.isNull(insProductResult.getEquipName()) || StringUtils.isEmpty(insProductResult.getEquipName())) {
                        strList.add(product.getInspectionItem() + " " + product.getInspectionItemSubclass());
                    }else {
                        List<Map> maps = JSONArray.parseArray(insProductResult.getEquipName(), Map.class);
                        if(CollectionUtils.isNotEmpty(maps)) {
                            List<Map> mapList = maps.stream().filter(item -> StringUtils.isEmpty(item.get("v") + "")).collect(Collectors.toList());
                            if(mapList.size() == maps.size()) {
                                strList.add(product.getInspectionItem() + " " + product.getInspectionItemSubclass());
                            }
//                            for (Map map : maps) {
//                                if(StringUtils.isEmpty(map.get("v")+"")){
//                                    strList.add(product.getInspectionItem() + " " + product.getInspectionItemSubclass());
//                                }
//                            }
                        }else {
                            strList.add(product.getInspectionItem() + " " + product.getInspectionItemSubclass());
                        }
                    }
                }
            }
        }
        return strList.stream().distinct().collect(Collectors.toList());
    }
    @Override
    @Transactional(rollbackFor = Exception.class,isolation = Isolation.READ_COMMITTED)
    public int saveInsContext2(InsProductResultDTO insProductResult) {
        Integer userId = SecurityUtils.getUserId().intValue();
        try {
            //检验结果
            Map<String,Object> insValueMap = JackSonUtil.unmarshal(insProductResult.getInsValue(), Map.class);
            //saveInsContext2方法有多个模板调用,需根据模板名称分开处理
            switch (insProductResult.getTemplateName()){
                case "架空地线应力应变":
                    //保存弹性模量和检验结论
                    if(Objects.nonNull(insValueMap.get("elasticityModulus"))){
                        String elasticityModulus = insValueMap.get("elasticityModulus").toString();
                        insProductMapper.update(null,Wrappers.<InsProduct>lambdaUpdate()
                                .set(InsProduct::getInsResult,3)//结论设为不判定
                                .set(InsProduct::getElasticityModulus,elasticityModulus)
                                .eq(InsProduct::getId,insProductResult.getInsProductId())
                        );
                    }
                    //删除弹性模量key
                    insValueMap.remove("elasticityModulus");
                    insProductResult.setInsValue(JackSonUtil.marshal(insValueMap));
                    break;
                case "疲劳试验":
                    //保存检验结果
                    if(Objects.nonNull(insValueMap.get("damage"))){
                        String damage = insValueMap.get("damage").toString();
                        Integer insResult = "符合".equals(damage)?1:0;
                        insProductMapper.update(null,Wrappers.<InsProduct>lambdaUpdate()
                                .set(InsProduct::getInsResult,insResult)
                                .set(InsProduct::getLastValue,damage)
                                .eq(InsProduct::getId,insProductResult.getInsProductId())
                        );
                    }
                    break;
            }
            List<InsProductResult> oldResults = new ArrayList<>();
            InsProductResult insProductResult1 = insProductResultMapper.selectOne(new LambdaQueryWrapper<InsProductResult>().eq(InsProductResult::getInsProductId, insProductResult.getInsProductId()));
            //新增或更新检验记录
            if (ObjectUtils.isNull(insProductResult1)){
                insProductResultMapper.insert(insProductResult);
            }else {
                insProductResult.setId(insProductResult1.getId());
                oldResults.add(insProductResult1);
                insProductResultMapper.updateById(insProductResult);
            }
            //添加工时记录
            InsOrder insOrder = insOrderMapper.selectById(insProductResult.getOrderId());
            InsSample insSample = insSampleMapper.selectById(insProductResult.getSampleId());
            InsProduct insProduct = insProductMapper.selectById(insProductResult.getInsProductId());
            InsProductResult newInsResult = new InsProductResult();
            BeanUtil.copyProperties(insProductResult,newInsResult);
            WorkTimeDTO workTimeDTO = new WorkTimeDTO(userId,insOrder,insSample,insProduct,null,insProductResult.getSampleId(), String.valueOf(insProductResult.getInsProductId()),oldResults ,newInsResult);
            String jsonStr = JackSonUtil.marshal(workTimeDTO);
            //计算工时
            //TODO:该方法目前只有电力用,默认路由使用电力的
            sendQueueMessage(ExchangeConstants.WORK_TIME_EXCHANGE,RouterKeyConstants.DL_KEY,jsonStr);
        }catch (Exception e){
            throw new RuntimeException(e);
        }
        return 0;
    }
    // èŽ·å–ä¸¤ä¸ªlocalDateTime的每一天
    public static List<LocalDateTime> getLocalDateTimesBetween(LocalDateTime start, LocalDateTime end) {
        List<LocalDateTime> localDateTimes = new ArrayList<>();
        LocalDate currentDate = start.toLocalDate();
        LocalDateTime currentLocalDateTime = start;
        while (!currentDate.isAfter(end.toLocalDate())) {
            localDateTimes.add(currentLocalDateTime);
            currentLocalDateTime = currentLocalDateTime.plusDays(1);
            currentDate = currentDate.plusDays(1);
        }
        return localDateTimes;
    }
    /**
     * æŸ¥è¯¢æ£€éªŒé¡¹å¯¹åº”标准库配置的工时信息
     * @param insProduct
     * @return
     */
    public StandardProductVO getInspectWorkHourAndGroup(InsProduct insProduct){
        StandardProductVO standardProductVO = new StandardProductVO();
        if(!Objects.isNull(insProduct)){
            //查询对应标准库
            List<StandardProductVO> productVO = standardProductListMapper.getStandardProductByInsProduct(
                    insProduct.getLaboratory(),
                    insProduct.getSampleType(),
                    insProduct.getSample(),
                    insProduct.getModel(),
                    insProduct.getInspectionItem(),
                    insProduct.getInspectionItemSubclass(),
                    insProduct.getSonLaboratory(),
                    insProduct.getStandardMethodListId());
            if(!productVO.isEmpty()){
                standardProductVO = productVO.get(0);
            }
            //有区间的检验项,取检验项存的工时信息
            if(StringUtils.isNotBlank(insProduct.getSection()) && StringUtils.isNotBlank(standardProductVO.getSection())){
                try {
                    ObjectMapper objectMapper = new ObjectMapper();
                    //区间设置
                    List<String> sectionList = (List<String>)objectMapper.readValue(standardProductVO.getSection(), List.class);
                    //选中区间的下标
                    int i = sectionList.indexOf(insProduct.getSection());
                    //获取对应下标的工时和工时分组
                    List<Double> hourList = (List<Double>)objectMapper.readValue(standardProductVO.getManHour(), List.class);
                    standardProductVO.setManHour(String.valueOf(hourList.get(i)));
                } catch (JsonProcessingException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return standardProductVO;
    }
    public static String getWeek(String dayStr) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date date = sdf.parse(dayStr);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
            int day = calendar.get(Calendar.DAY_OF_MONTH);
            return getWeekDay(dayOfWeek);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public static String getWeekDay(int dayOfWeek) {
        switch (dayOfWeek) {
            case Calendar.MONDAY:
                return "周一";
            case Calendar.TUESDAY:
                return "周二";
            case Calendar.WEDNESDAY:
                return "周三";
            case Calendar.THURSDAY:
                return "周四";
            case Calendar.FRIDAY:
                return "周五";
            case Calendar.SATURDAY:
                return "周六";
            case Calendar.SUNDAY:
                return "周日";
            default:
                return "未知";
        }
    }
}