utils008_fastjson中Feature类学习(更快描述某些属性)

使用Fastjson Feature描述个人爱好的示例
本文介绍了如何利用Fastjson的Feature特性,通过位运算操作实现快速表示个人爱好,如设置默认爱好、判断兴趣、添加和取消爱好,以及记录爱好情况。
package com.jingsong.test;

/**
 * @author jingsong
 * @date 2022/4/26 0:02
 * @desc com.alibaba.fastjson.parser.Feature
 * 该文件中提供了描述某一事物的方法,可以更快的描述某一事物的特征,下面为简单的学习
 */
public class JSONFeatureTest {
    public static void main(String[] args) {

        // 1. 位运算符复习 http://t.csdn.cn/Nuquy

        /*
           2. 假设某个人,可以拥有的爱好如Hobby
              可以使用某些数字来代表一个人有哪些爱好
               例如(二进制见Hobby类):
                    3  代表 [eat,run]
                    10 代表 [run,study]
                    21 代表 [eat,drink,sleep]
          */

        // 3. 获得固有爱好
        int defaultHobbies = Hobby.getDefaultHobbies();
        System.out.println("defaultHobbies = " + defaultHobbies);

        // 4. 判断是否有这个爱好
        boolean likeEat = Hobby.isLike(defaultHobbies, Hobby.eat);
        System.out.println("likeEat = " + likeEat);
        boolean likeShopping = Hobby.isLike(defaultHobbies, Hobby.shopping);
        System.out.println("likeShopping = " + likeShopping);

        // 5. 添加一个爱好
        int addHobby = Hobby.addHobby(defaultHobbies, Hobby.study);
        System.out.println("addHobby = " + addHobby);

        // 6. 取消一个爱好
        int cancelHobby = Hobby.cancelHobby(defaultHobbies, Hobby.sleep);
        System.out.println("cancelHobby = " + cancelHobby);

        // 7. 记录某个人的爱好
        int hobbies = Hobby.recordHobbies(Hobby.study, Hobby.sleep, Hobby.shopping, Hobby.run);
        System.out.println("hobbies = " + hobbies);
    }
}

enum Hobby {
                // mask
    eat,        // 00000001
    run,        // 00000010
    drink,      // 00000100
    study,      // 00001000
    sleep,      // 00010000
    shopping    // 00100000

    ;

    private final int mask;

    Hobby() {
        mask = (1 << ordinal());
    }


    public static boolean isLike(int hobbies, Hobby hobby) {
        return (hobby.mask & hobbies) != 0;
    }

    public static int getDefaultHobbies() {
        int defaultHobbies = 0;// 00000000
        defaultHobbies |= eat.mask; //  00000001 | 00000000 = 00000001
        defaultHobbies |= drink.mask;// 00000100 | 00000001 = 00000101
        defaultHobbies |= sleep.mask;// 00010000 | 00000101 = 00010101
        return defaultHobbies;
    }

    public static int addHobby(int hobbies, Hobby hobby) {
        return hobbies |= hobby.mask;
    }

    public static int cancelHobby(int hobbies, Hobby hobby) {
        return hobbies &= ~hobby.mask;
    }

    public static int recordHobbies(Hobby... hobbies) {
        int h = 0;
        for (Hobby hobby : hobbies) {
            h |= hobby.mask;
        }
        return h;
    }
}
package com.bs.lithoframe.service.reticle.service.impl; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.bs.lithoframe.service.kpimaintaintable.entity.TMainAlignApply; import com.bs.lithoframe.service.kpimaintaintable.entity.TMainOvlApply; import com.bs.lithoframe.service.kpimaintaintable.mapper.TMainAlignApplyMapper; import com.bs.lithoframe.service.kpimaintaintable.mapper.TMainOvlApplyMapper; import com.bs.lithoframe.service.mark.entity.MarkSizeSpec; import com.bs.lithoframe.service.mark.mapper.MaskSizeSpecMapper; import com.bs.lithoframe.service.mark.totalcount.entity.MarkTotalCount; import com.bs.lithoframe.service.mark.totalcount.mapper.MarkTotalCountMapper; import com.bs.lithoframe.service.reticle.commom.MarkSizeUtils; import com.bs.lithoframe.service.reticle.dto.FetchSheetDTO; import com.bs.lithoframe.service.reticle.dto.MarkAutoGenerateDTO; import com.bs.lithoframe.service.reticle.dto.MarkAutoGenerateLayerDTO; import com.bs.lithoframe.service.reticle.entity.*; import com.bs.lithoframe.service.reticle.mapper.*; import com.bs.lithoframe.service.reticle.service.ILfmsAsmlAlSizeSummaryService; import com.bs.lithoframe.service.reticle.strategy.SheetContext; import com.bs.lithoframe.service.reticle.vo.AsmlQueryMarkCountVO; import com.bs.platform.core.utils.JsonUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; /** * <p> * 服务实现 * </p> * * @author L3150243 PX * @since 2025-06-24 */ @Service @Slf4j @Transactional(rollbackFor = Exception.class) public class LfmsAsmlAlSizeSummaryServiceImpl extends ServiceImpl<LfmsAsmlAlSizeSummaryMapper, LfmsAsmlAlSizeSummary> implements ILfmsAsmlAlSizeSummaryService { @Resource private SheetContext sheetContext; @Resource private TMainAlignApplyMapper alignApplyMapper; @Resource private TMainOvlApplyMapper ovlApplyMapper; @Resource private MarkSizeUtils markSizeUtils; @Resource private LfmsAsmlAlSizeSummaryMapper asmlAlSizeSummaryMapper; @Resource private LfmsReticleMapper reticleMapper; @Resource private LfmsDesignRecordMapper designRecordMapper; @Resource private LfmsAsmlAlCellValueMapper asmlAlCellValueMapper; @Resource private LfmsAsmlAlDummySummaryMapper asmlAlDummySummaryMapper; @Resource private MarkTotalCountMapper totalCountMapper; @Resource private MaskSizeSpecMapper markSizeSpecMapper; /** * Mark Auto Generate按钮,做两件事 * 1、自动生成mark size summary * 2、自动生成cover layer * * @param dto * @return highlight信息 */ @Override // @Transactional(rollbackFor = Exception.class) public List<LfmsAsmlAlSizeSummary> markAutoGenerate(MarkAutoGenerateDTO dto) { log.info("Starting mark auto-generation. Parameters: {}", JsonUtil.toJSONString(dto)); // 1. 快速失败检查:无参考层时直接返回空结果 if (CollectionUtils.isEmpty(dto.getReferenceLayers())) { log.info("No reference layers selected. Skipping auto-generation."); return Collections.emptyList(); } // 2. 获取当前层尺寸摘要数据 List<LfmsAsmlAlSizeSummary> currentSummaries = fetchCurrentSizeSummaries(dto); if (CollectionUtils.isEmpty(currentSummaries)) { log.warn("No size summaries found for the specified layers"); return Collections.emptyList(); } // 3. 执行核心生成逻辑 return processGeneration(dto, currentSummaries); } private List<LfmsAsmlAlSizeSummary> processGeneration(MarkAutoGenerateDTO dto, List<LfmsAsmlAlSizeSummary> currentSummaries) { List<LfmsAsmlAlSizeSummary> results = new ArrayList<>(); // 3.1 生成KPI数据 List<LfmsAsmlAlSizeSummary> kpiResults = this.sizeSummaryAutoGenerate(dto, currentSummaries); if (!CollectionUtils.isEmpty(kpiResults)) { results.addAll(kpiResults); } // 3.2 生成覆盖层数据 List<LfmsAsmlAlSizeSummary> coverLayers = this.coverLayerAutoGenerate(dto, currentSummaries); if (!CollectionUtils.isEmpty(coverLayers)) { results.addAll(coverLayers); } log.info("Auto-generation completed. Generated {} records", results.size()); return results; } private List<LfmsAsmlAlSizeSummary> fetchCurrentSizeSummaries(MarkAutoGenerateDTO dto) { // 获取查询参数 Map<String, String> params = markSizeUtils.getMarkSizeParam( dto.getCurrentProject(), dto.getCurrentProjectId(), dto.getCurrentPart(), dto.getTypeName(), dto.getMainVersion() ); // 提取当前层名称 List<String> layerNames = dto.getReferenceLayers().stream() .map(MarkAutoGenerateLayerDTO::getCurrentLayer) .collect(Collectors.toList()); // 构建查询条件 LambdaQueryWrapper<LfmsAsmlAlSizeSummary> query = new LambdaQueryWrapper<>(); query.eq(LfmsAsmlAlSizeSummary::getReticleKey, params.get("rKey")) .eq(LfmsAsmlAlSizeSummary::getSubVersion, dto.getSubVersion()) .eq(LfmsAsmlAlSizeSummary::getSizeType, "mark") .in(LfmsAsmlAlSizeSummary::getLayerName, layerNames); return asmlAlSizeSummaryMapper.selectList(query); } public List<LfmsAsmlAlSizeSummary> markAutoGenerate_old(MarkAutoGenerateDTO markAutoGenerateDTO) { log.info("asml sheet markAutoGenerate 入参:{}", JsonUtil.toJSONString(markAutoGenerateDTO)); List<LfmsAsmlAlSizeSummary> result = new ArrayList<>(); //如果没有选的就没有 if (CollectionUtils.isEmpty(markAutoGenerateDTO.getReferenceLayers())) { return result; } //1.获取本地数据SizeSummaries List<LfmsAsmlAlSizeSummary> currentSizeSummaries = getAsmlAlSizeSummaryList(markAutoGenerateDTO); if (CollectionUtils.isEmpty(currentSizeSummaries)) { log.info("getAsmlAlSizeSummaryList 数据为空"); return result; } //2.获取kpi 数据 result = this.sizeSummaryAutoGenerate(markAutoGenerateDTO, currentSizeSummaries); //3.获取 coverLayer 数据 List<LfmsAsmlAlSizeSummary> coverLayerList = this.coverLayerAutoGenerate(markAutoGenerateDTO, currentSizeSummaries); //总数据 result.addAll(coverLayerList); return result; } /** * 获取本地数据SizeSummaries * * @param markAutoGenerateDTO * @return */ private List<LfmsAsmlAlSizeSummary> getAsmlAlSizeSummaryList(MarkAutoGenerateDTO markAutoGenerateDTO) { //获取lfms系统mark size summary 信息 List<String> currentLayerNameList = markAutoGenerateDTO.getReferenceLayers().stream().map(MarkAutoGenerateLayerDTO::getCurrentLayer).collect(Collectors.toList()); //生成查询参数 rKey projectId Map<String, String> currentMarkSizeParam = markSizeUtils.getMarkSizeParam(markAutoGenerateDTO.getCurrentProject(), markAutoGenerateDTO.getCurrentProjectId(), markAutoGenerateDTO.getCurrentPart(), markAutoGenerateDTO.getTypeName(), markAutoGenerateDTO.getMainVersion()); LambdaQueryWrapper<LfmsAsmlAlSizeSummary> asmlAlSizeSummaryQueryWrapper = new LambdaQueryWrapper<>(); asmlAlSizeSummaryQueryWrapper .eq(LfmsAsmlAlSizeSummary::getReticleKey, currentMarkSizeParam.get("rKey")) .eq(LfmsAsmlAlSizeSummary::getSubVersion, markAutoGenerateDTO.getSubVersion()) .eq(LfmsAsmlAlSizeSummary::getSizeType,"mark") .in(LfmsAsmlAlSizeSummary::getLayerName, currentLayerNameList); return asmlAlSizeSummaryMapper.selectList(asmlAlSizeSummaryQueryWrapper); } private void getMainKpiProjectId(MarkAutoGenerateDTO markAutoGenerateDTO) { } private List<TMainAlignApply> getTMainAlignApplyList(MarkAutoGenerateDTO markAutoGenerateDTO) { //拉取alignment数据 LambdaQueryWrapper<TMainAlignApply> alignQueryWrapper = new LambdaQueryWrapper<>(); String projectIdSql = String.format("PROJECT_ID = " + "(SELECT ID FROM T_MAIN_TAIN_KPI_APPLY WHERE ARCHIVE = 0 AND PROJECT = '%s' AND lOOP_F = '%s' ORDER BY CREATE_TIME FETCH FIRST 1 ROW ONLY)", markAutoGenerateDTO.getProject(), markAutoGenerateDTO.getPart()); List<String> referenceLayerNameList = markAutoGenerateDTO.getReferenceLayers().stream().map(MarkAutoGenerateLayerDTO::getReferenceLayer).collect(Collectors.toList()); /** * todo * 且过滤WQ/MCC” X/Y值如果违反“WQ>1%”“MCC>0.97和If need redesign(Y/N)”为Y * */ //先获取maskVersion alignQueryWrapper .in(TMainAlignApply::getAlignTo, referenceLayerNameList) .apply(projectIdSql) // .ne(TMainAlignApply::getIfNeedRedesign, "Y") // WQ/MCC” X/Y值如果违反“WQ>1% .eq(TMainAlignApply::getMarkType,"ASML_AL") .isNotNull(TMainAlignApply::getMarkSizeMarkType).isNotNull(TMainAlignApply::getMarkSizeCellName) .isNotNull(TMainAlignApply::getMarkSizeSegType).isNotNull(TMainAlignApply::getMarkSizeCd) .isNotNull(TMainAlignApply::getMarkSizePitch).isNotNull(TMainAlignApply::getMarkSizeMirror); return alignApplyMapper.selectList(alignQueryWrapper); } private List<TMainOvlApply> getTMainOvlApplyList(MarkAutoGenerateDTO markAutoGenerateDTO) { String projectIdSql = String.format("PROJECT_ID = " + "(SELECT ID FROM T_MAIN_TAIN_KPI_APPLY WHERE ARCHIVE = 0 AND PROJECT = '%s' AND lOOP_F = '%s' ORDER BY CREATE_TIME FETCH FIRST 1 ROW ONLY)", markAutoGenerateDTO.getProject(), markAutoGenerateDTO.getPart()); List<String> referenceLayerNameList = markAutoGenerateDTO.getReferenceLayers().stream().map(MarkAutoGenerateLayerDTO::getReferenceLayer).collect(Collectors.toList()); //查询KPI系统的ovl数据 LambdaQueryWrapper<TMainOvlApply> ovlQueryWrapper = new LambdaQueryWrapper<>(); ovlQueryWrapper.eq(TMainOvlApply::getArchive, 0). in(TMainOvlApply::getLayerName, referenceLayerNameList) .eq(TMainOvlApply::getMarkType, "OVL") .ne(TMainOvlApply::getIfNeedRedesign, "Y") .apply(projectIdSql); // .isNotNull(TMainOvlApply::getMarkSizeMarkType) // .isNotNull(TMainOvlApply::getMarkSizeSegType).isNotNull(TMainOvlApply::getMarkSizeCd) // .isNotNull(TMainOvlApply::getMarkSizePitch); List<TMainOvlApply> ovlApplies = ovlApplyMapper.selectList(ovlQueryWrapper); return ovlApplies; } private Map<String, List<TMainAlignApply>> tMainAlignApplyConvertToMap(List<TMainAlignApply> mainAlignApplies) { //根据layer name分组,获取组内最新的maskVersion 按理来应该有align to来分组 return mainAlignApplies.stream().collect(Collectors.groupingBy(TMainAlignApply::getAlignTo, Collectors.collectingAndThen(Collectors.toList(), list -> { String newMaskVersion = list.stream().map(TMainAlignApply::getMaskVersion).max(String::compareTo).get(); return list.stream().filter(item -> Objects.equals(item.getMaskVersion(), newMaskVersion)).collect(Collectors.toList()); } ) )); } private Map<String, List<TMainOvlApply>> tMainOvlApplysConvertToMap(List<TMainOvlApply> mainOvlApplys) { if(CollectionUtils.isEmpty(mainOvlApplys)){ return new HashMap<>(); } //根据layer name分组,获取组内最新的maskVersion return mainOvlApplys.stream().collect(Collectors.groupingBy(TMainOvlApply::getLayerName, Collectors.collectingAndThen(Collectors.toList(), list -> { String newMaskVersion = list.stream().map(TMainOvlApply::getMaskVersion).max(String::compareTo).get(); return list.stream().filter(item -> Objects.equals(item.getMaskVersion(), newMaskVersion)).collect(Collectors.toList()); } ) )); } private Map<String, List<LfmsAsmlAlSizeSummary>> sizeSummariesConvertToMap(List<LfmsAsmlAlSizeSummary> currentSizeSummaries) { return currentSizeSummaries.stream().collect(Collectors.groupingBy(LfmsAsmlAlSizeSummary::getLayerName)); } private final static List<String> markTypeList = Arrays.asList("HOLE_SEG", "LS_SEG_L", "LS_SEG_S", "LS_SEG_HOR", "LS_SEG_VER", "CTB_STD", "CTB_HOLE_SEG", "CTB_LS_SEG_L", "CTB_LS_SEG_S", "CTB_LS_SEG_HOR", "CTB_LS_SEG_VER"); private void fillFmsAsmlAlSizeSummary(LfmsAsmlAlSizeSummary lfmsAsmlAlSizeSummary, TMainAlignApply tMainAlignApply, MarkAutoGenerateDTO markAutoGenerateDTO, Map<String, String> usedMap, List<LfmsAsmlAlSizeSummary> resultList) { /** *  如果对于参考的KPI的mark和当前的Mark 的mark type不相等, * 且 SEG type不等于HOLE_SEG / LS_SEG_L / LS_SEG_S / LS_SEG_HOR / LS_SEG_VER / CTB_STD / CTB_HOLE_SEG / CTB_LS_SEG_L / CTB_LS_SEG_S / CTB_LS_SEG_HOR / CTB_LS_SEG_VER,需要highlight,当前mark背景色标红即可。 */ if (!lfmsAsmlAlSizeSummary.getMarkType().equals(tMainAlignApply.getMarkType())) { if (!markTypeList.contains(lfmsAsmlAlSizeSummary.getSegType())) { //需要highlight,当前mark背景色标红即可 } } lfmsAsmlAlSizeSummary.setSegType(tMainAlignApply.getMarkSizeSegType()); lfmsAsmlAlSizeSummary.setCd(tMainAlignApply.getMarkSizeCd()); lfmsAsmlAlSizeSummary.setPitch(tMainAlignApply.getMarkSizePitch()); lfmsAsmlAlSizeSummary.setTone(tMainAlignApply.getMarkSizeTone()); //Mark remark字段默认填写:refer proj+layer+NO.+mark type,同时可以将mark type字段单独存储,因为后续Hightlight规则会匹配当前的mark type和引用的mark type是否一致 lfmsAsmlAlSizeSummary.setAdditionRemark(markAutoGenerateDTO.getProject() + tMainAlignApply.getLayerName() + tMainAlignApply.getOrderNo() + tMainAlignApply.getMarkType()); usedMap.put(lfmsAsmlAlSizeSummary.getMarkType() + lfmsAsmlAlSizeSummary.getMirror(), tMainAlignApply.getCellName()); resultList.add(lfmsAsmlAlSizeSummary); } private void fillFmsAsmlAlSizeSummary(LfmsAsmlAlSizeSummary lfmsAsmlAlSizeSummary, TMainOvlApply tMainOvlApply, MarkAutoGenerateDTO markAutoGenerateDTO, Map<String, String> usedMap, List<LfmsAsmlAlSizeSummary> resultList) { /** *  如果对于参考的KPI的mark和当前的Mark 的mark type不相等, * 且 SEG type不等于HOLE_SEG / LS_SEG_L / LS_SEG_S / LS_SEG_HOR / LS_SEG_VER / CTB_STD / CTB_HOLE_SEG / CTB_LS_SEG_L / CTB_LS_SEG_S / CTB_LS_SEG_HOR / CTB_LS_SEG_VER,需要highlight,当前mark背景色标红即可。 */ if (!lfmsAsmlAlSizeSummary.getMarkType().equals(tMainOvlApply.getMarkType())) { if (!markTypeList.contains(lfmsAsmlAlSizeSummary.getSegType())) { //需要highlight,当前mark背景色标红即可 } } lfmsAsmlAlSizeSummary.setSegType(tMainOvlApply.getMarkSizeSegType()); lfmsAsmlAlSizeSummary.setCd(tMainOvlApply.getMarkSizeCd()); lfmsAsmlAlSizeSummary.setPitch(tMainOvlApply.getMarkSizePitch()); lfmsAsmlAlSizeSummary.setTone(tMainOvlApply.getMarkSizeTone()); //Mark remark字段默认填写:refer proj+layer+NO.+mark type,同时可以将mark type字段单独存储,因为后续Hightlight规则会匹配当前的mark type和引用的mark type是否一致 lfmsAsmlAlSizeSummary.setAdditionRemark(markAutoGenerateDTO.getProject() + tMainOvlApply.getLayerName() + tMainOvlApply.getSequenceNo() + tMainOvlApply.getMarkType()); usedMap.put(lfmsAsmlAlSizeSummary.getMarkType() + lfmsAsmlAlSizeSummary.getMirror(), tMainOvlApply.getCellName()); resultList.add(lfmsAsmlAlSizeSummary); } // 方法:返回两个double型参数中的最大值 public static double maxOfTwoDoubles(double num1, double num2) { return (num1 > num2) ? num1 : num2; } public static double sumJsonXOrY(String jsonStr) { JSONObject jsonObject = JSONObject.parseObject(jsonStr); Double x = jsonObject.getDouble("X"); Double y = jsonObject.getDouble("Y"); return x+y; } public static double maxJsonXOrY(String jsonStr) { JSONObject jsonObject = JSONObject.parseObject(jsonStr); Double x = jsonObject.getDouble("X"); Double y = jsonObject.getDouble("Y"); return maxOfTwoDoubles(x, y); } /** * 拉取kpi数据,填充相应size summary数据的“Seg Type”“CD” “Pitch”“Tone”字段信息 * * @param markAutoGenerateDTO * @param currentSizeSummaries * @return highlight信息 */ private List<LfmsAsmlAlSizeSummary> sizeSummaryAutoGenerate(MarkAutoGenerateDTO markAutoGenerateDTO, List<LfmsAsmlAlSizeSummary> currentSizeSummaries) { List<LfmsAsmlAlSizeSummary> resultList = new ArrayList<>(); //1.获取AlignApply数据 List<TMainAlignApply> mainAlignApplies = getTMainAlignApplyList(markAutoGenerateDTO); if(CollectionUtils.isEmpty(mainAlignApplies)){ return resultList; } //2.将AlignApply 转换map型 key:LayerName,value:list Map<String, List<TMainAlignApply>> alignApplyMap = tMainAlignApplyConvertToMap(mainAlignApplies); //3.获取 sizeSummariesMap Map<String, List<LfmsAsmlAlSizeSummary>> sizeSummarieMap = sizeSummariesConvertToMap(currentSizeSummaries); //4.获取OvlApply数据 List<TMainOvlApply> mainOvlApplys = getTMainOvlApplyList(markAutoGenerateDTO); //5.ovl转换map Map<String, List<TMainOvlApply>> ovlApplyMap = tMainOvlApplysConvertToMap(mainOvlApplys); for (int i = 0; i < markAutoGenerateDTO.getReferenceLayers().size(); i++) { MarkAutoGenerateLayerDTO markAutoGenerateLayer = markAutoGenerateDTO.getReferenceLayers().get(i); //sizeSummary 数据 List<LfmsAsmlAlSizeSummary> sizeSummarylist = sizeSummarieMap.get(markAutoGenerateLayer.getCurrentLayer()); if (CollectionUtils.isEmpty(sizeSummarylist)) { continue; } //Map key: Mark Type + Mirror value:Alignment Mark Cell name Map<String, String> usedMap = new HashMap<>(); for (LfmsAsmlAlSizeSummary lfmsAsmlAlSizeSummary : sizeSummarylist) { //alignApply 数据 List<TMainAlignApply> alignApplyList = alignApplyMap.get(markAutoGenerateLayer.getReferenceLayer()); //优先Alignment mark > mark type > 方向(if mirror) > BSL mark > Backup mark > LM KPI if (!CollectionUtils.isEmpty(alignApplyList)) { //校验是否出现相同的 mark type + mirror if (usedMap.containsKey(lfmsAsmlAlSizeSummary.getMarkType() + lfmsAsmlAlSizeSummary.getMirror())) { String cellName = usedMap.get(lfmsAsmlAlSizeSummary.getMarkType() + lfmsAsmlAlSizeSummary.getMirror()); //将已使用CellName 移除 alignApplyList = alignApplyList.stream().filter(f -> !f.getCellName().equals(cellName)).collect(Collectors.toList()); } //规则1.[优先级规则去得到mark 对应的Seg_type”“CD/PITCH”“Tone”] String markType = lfmsAsmlAlSizeSummary.getMarkType(); List<TMainAlignApply> markTypeAlignApplyList = alignApplyList.stream().filter(f -> f.getMarkType().equals(markType)).collect(Collectors.toList()); //规则1.[mark type] if (!CollectionUtils.isEmpty(markTypeAlignApplyList) && markTypeAlignApplyList.size() == 1) { TMainAlignApply tMainAlignApply = markTypeAlignApplyList.get(0); fillFmsAsmlAlSizeSummary(lfmsAsmlAlSizeSummary, tMainAlignApply, markAutoGenerateDTO, usedMap, resultList); continue; } //规则2.[方向(if mirror)] markTypeAlignApplyList = alignApplyList.stream().filter(f -> !Objects.isNull(f.getMarkSizeMirror()) && f.getMarkSizeMirror().equals("Y")).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(markTypeAlignApplyList) && markTypeAlignApplyList.size() == 1) { TMainAlignApply tMainAlignApply = markTypeAlignApplyList.get(0); //校验当前是否有相同mark type 由于一个layer会有多个相同的mark type+if Mirror信息,获取KPI数据时不可取相同的 fillFmsAsmlAlSizeSummary(lfmsAsmlAlSizeSummary, tMainAlignApply, markAutoGenerateDTO, usedMap, resultList); continue; } //规则3.[BSL mark] markTypeAlignApplyList = alignApplyList.stream().filter(f -> !Objects.isNull(f.getIfBaselineMark()) && f.getIfBaselineMark().equals("Y")).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(markTypeAlignApplyList) && markTypeAlignApplyList.size() == 1) { TMainAlignApply tMainAlignApply = markTypeAlignApplyList.get(0); fillFmsAsmlAlSizeSummary(lfmsAsmlAlSizeSummary, tMainAlignApply, markAutoGenerateDTO, usedMap, resultList); continue; } //规则4.[Backup mark] markTypeAlignApplyList = alignApplyList.stream().filter(f -> !Objects.isNull(f.getIfBackUp()) && f.getIfBackUp().equals("Y")).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(markTypeAlignApplyList) && markTypeAlignApplyList.size() == 1) { TMainAlignApply tMainAlignApply = markTypeAlignApplyList.get(0); fillFmsAsmlAlSizeSummary(lfmsAsmlAlSizeSummary, tMainAlignApply, markAutoGenerateDTO, usedMap, resultList); continue; } //规则5.[LM KPI] 通过对比“ROPI”值, max(X,Y) 越小越好(对于在KPI系统中没有填数值或为NA的,当成KPI最差。) X:5,Y:8 取8 最后min // maxJsonXOrY(p1.getPerformanceRopi()) Optional<TMainAlignApply> optMarkTypeAlignApply = alignApplyList.stream().filter(f->!Objects.isNull(f.getPerformanceRopi())).min((p1, p2) -> Double.compare(maxJsonXOrY(p1.getPerformanceRopi()), maxJsonXOrY(p2.getPerformanceRopi())));; if (optMarkTypeAlignApply.isPresent()) { fillFmsAsmlAlSizeSummary(lfmsAsmlAlSizeSummary, optMarkTypeAlignApply.get(), markAutoGenerateDTO, usedMap, resultList); continue; } } //ovlApply 数据 List<TMainOvlApply> ovlApplyList = ovlApplyMap.get(markAutoGenerateLayer.getReferenceLayer()); //优先级 OVL mark > BSL mark> backup mark > LM KPI数值 if (!CollectionUtils.isEmpty(ovlApplyList)) { //校验是否出现相同的 mark type + mirror if (usedMap.containsKey(lfmsAsmlAlSizeSummary.getMarkType() + lfmsAsmlAlSizeSummary.getMirror())) { String cellName = usedMap.get(lfmsAsmlAlSizeSummary.getMarkType() + lfmsAsmlAlSizeSummary.getMirror()); //将已使用CellName 移除 ovlApplyList = ovlApplyList.stream().filter(f -> !f.getCellName().equals(cellName)).collect(Collectors.toList()); } String markType = lfmsAsmlAlSizeSummary.getMarkType(); List<TMainOvlApply> markTypeOvlApplyList = ovlApplyList.stream().filter(f -> f.getMarkType().equals(markType)).collect(Collectors.toList()); //规则1.[mark type] if (!CollectionUtils.isEmpty(markTypeOvlApplyList) && markTypeOvlApplyList.size() == 1) { TMainOvlApply mainAlignApply = markTypeOvlApplyList.get(0); //根据id 查询子表 获取到2条数据 然后根据markType 在子表里面比对 符合的就拿 fillFmsAsmlAlSizeSummary(lfmsAsmlAlSizeSummary, mainAlignApply, markAutoGenerateDTO, usedMap, resultList); continue; } //规则2.[BSL mark] markTypeOvlApplyList = ovlApplyList.stream().filter(f -> !Objects.isNull(f.getIfBaselineMark()) && f.getIfBaselineMark().equals("Y")).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(markTypeOvlApplyList) && markTypeOvlApplyList.size() == 1) { TMainOvlApply mainAlignApply = markTypeOvlApplyList.get(0); fillFmsAsmlAlSizeSummary(lfmsAsmlAlSizeSummary, mainAlignApply, markAutoGenerateDTO, usedMap, resultList); continue; } //规则3.[Backup mark] markTypeOvlApplyList = ovlApplyList.stream().filter(f -> !Objects.isNull(f.getIfBackUp()) && f.getIfBackUp().equals("Y")).collect(Collectors.toList()); if (!CollectionUtils.isEmpty(markTypeOvlApplyList) && markTypeOvlApplyList.size() == 1) { TMainOvlApply mainAlignApply = markTypeOvlApplyList.get(0); fillFmsAsmlAlSizeSummary(lfmsAsmlAlSizeSummary, mainAlignApply, markAutoGenerateDTO, usedMap, resultList); continue; } //规则4.[LM KPI] 从系统对比“Qmerit out/in Mean+3Sigma”值, Qmerit out X + Qmerit out Y + Qmerit in X + Qmerit in Y, 加和越小越好。 Optional<TMainOvlApply> optMarkTypeOvlApply = markTypeOvlApplyList.stream().filter(f->!Objects.isNull(f.getQnerutInMs()) && !Objects.isNull(f.getQnerutOutMs()) ).min((p1, p2) -> Double.compare(sumJsonXOrY(p1.getQnerutOutMs()) + sumJsonXOrY(p1.getQnerutInMs()), sumJsonXOrY(p2.getQnerutOutMs()) + sumJsonXOrY(p2.getQnerutInMs()))); if (optMarkTypeOvlApply.isPresent()) { fillFmsAsmlAlSizeSummary(lfmsAsmlAlSizeSummary, optMarkTypeOvlApply.get(), markAutoGenerateDTO, usedMap, resultList); } } } } return resultList; // //查询KPI系统的ovl数据 // LambdaQueryWrapper<TMainOvlApply> ovlQueryWrapper = new LambdaQueryWrapper<>(); // ovlQueryWrapper.eq(TMainOvlApply::getArchive, 0). // in(TMainOvlApply::getLayerName, referenceLayerNameList) // .eq(TMainOvlApply::getIfBaselineMark, 'Y') //----------------------------- 为什么是 Y // .apply(projectIdSql) // .isNotNull(TMainOvlApply::getMarkSizeMarkType) // .isNotNull(TMainOvlApply::getMarkSizeSegType).isNotNull(TMainOvlApply::getMarkSizeCd) // .isNotNull(TMainOvlApply::getMarkSizePitch); // List<TMainOvlApply> ovlApplies = ovlApplyMapper.selectList(ovlQueryWrapper); // //根据layer name分组,获取组内最新的maskVersion // Map<String, List<TMainOvlApply>> mainOvlMap = ovlApplies.stream().collect(Collectors.groupingBy(TMainOvlApply::getLayerName, // Collectors.collectingAndThen(Collectors.toList(), list -> { // String newMaskVersion = list.stream().map(TMainOvlApply::getMaskVersion).max(String::compareTo).get(); // return list.stream().filter(item -> Objects.equals(item.getMaskVersion(), newMaskVersion)).collect(Collectors.toList()); // } // ) // )); // // //按优先级进行匹配(一、优先Alignment mark > mark type > 方向(if mirror) > BSL mark > Backup mark > LM KPI数值) // markAutoGenerateDTO.getReferenceLayers().forEach(referenceLayer -> { // //current Layer的size summary 获取第一个 当前layername 的 数据 本地的 // List<LfmsAsmlAlSizeSummary> sizeSummeryList = currentSizeSummaries.stream().filter(asmlAl -> Objects.equals(asmlAl.getLayerName(), referenceLayer.getCurrentLayer())).collect(Collectors.toList()); // //reference layer 拉取的alignment信息 // List<TMainAlignApply> alignList = mainAlignMap.values().stream().flatMap(Collection::stream) // .filter(kpiAlign -> Objects.equals(kpiAlign.getAlignTo(), referenceLayer.getReferenceLayer())) // .collect(Collectors.toList()); // //reference layer 拉取的ovl信息 // List<TMainOvlApply> ovlList = mainOvlMap.values().stream().flatMap(Collection::stream) // .filter(kpiOvl -> Objects.equals(kpiOvl.getLayerName(), referenceLayer.getReferenceLayer())) // .collect(Collectors.toList()); // // for (int i = 0; i < sizeSummeryList.size(); i++) { // LfmsAsmlAlSizeSummary sizeSummary = sizeSummeryList.get(i); // /*List<TMainAlignApply> sameTypeAlignList = alignList.stream().filter(kpiAlign -> Objects.equals(kpiAlign.getMarkType(), sizeSummary.getMarkType())).map(kpiAlign -> { // return alignList.stream().filter(item -> !Objects.equals(kpiAlign.getMarkSizeSegType(), item.getMarkSizeSegType()) && !Objects.equals(kpiAlign.getMarkSizeCd(), item.getMarkSizeCd()) // && !Objects.equals(kpiAlign.getMarkSizePitch(), item.getMarkSizePitch()) && !Objects.equals(kpiAlign.getMarkSizeMirror(), item.getMarkSizeMirror())).collect(Collectors.toList()); // }) // .flatMap(Collection::stream) // // .filter(kpiAlign -> Objects.equals(kpiAlign.getMarkSizeMarkType(), sizeSummary.getMarkType())) // .collect(Collectors.toList());*/ // TMainAlignApply tMainAlignApply = alignList.stream().filter(kpiAlign -> Objects.equals(kpiAlign.getMarkType(), sizeSummary.getMarkType())).findFirst().orElse(null); // //优先参考与当前layer plan相同的mark type;//优先参考与当前layer plan相同的mark type; // List<TMainAlignApply> sameTypeAlignList = alignList.stream().filter(kpiAlign -> Objects.equals(kpiAlign.getMarkSizeMarkType(), sizeSummary.getMarkType())) // //④ 相同type的AL mark size不能重复(Seg type/CD/Pitch/mirror都相同则算重复), 若重复需要继续参考其他mark; // .filter(kpiAlign -> tMainAlignApply == null || !(Objects.equals(kpiAlign.getMarkType(), sizeSummary.getMarkType()) && // Objects.equals(kpiAlign.getMarkSizeSegType(), kpiAlign.getMarkSizeSegType()) && Objects.equals(kpiAlign.getMarkSizeCd(), kpiAlign.getMarkSizeCd()) // && Objects.equals(kpiAlign.getMarkSizePitch(), kpiAlign.getMarkSizePitch()) && Objects.equals(kpiAlign.getMarkSizeMirror(), kpiAlign.getMarkSizeMirror()))) // .collect(Collectors.toList()); // List<TMainOvlApply> sameTypeOvlList = ovlList.stream().filter(kpiOvl -> Objects.equals(kpiOvl.getMarkSizeMarkType(), sizeSummary.getMarkType())) // //④ 相同type的AL mark size不能重复(Seg type/CD/Pitch/mirror都相同则算重复), 若重复需要继续参考其他mark; // .filter(kpiOvl -> tMainAlignApply == null || !(Objects.equals(kpiOvl.getMarkType(), sizeSummary.getMarkType()) && // Objects.equals(kpiOvl.getMarkSizeSegType(), kpiOvl.getMarkSizeSegType()) && Objects.equals(kpiOvl.getMarkSizeCd(), kpiOvl.getMarkSizeCd()) // && Objects.equals(kpiOvl.getMarkSizePitch(), kpiOvl.getMarkSizePitch()))) // .collect(Collectors.toList()); // // // //定义一个匹配的kpi数据对象 // TMainAlignApply alignApply; // //不同type // /* collect1、collect2表示不同type AL mark情况下过滤掉不符合“SEG TYPE”后的alignment集合、ovl集合 */ // if (CollectionUtils.isEmpty(sameTypeAlignList)) { // List<TMainAlignApply> collect1 = alignList.stream().filter(kpiAlign -> Objects.equals(kpiAlign.getMarkSizeSummary(), sizeSummary.getMarkType())) // .filter(kpiAlign -> { // String segType = kpiAlign.getMarkSizeSegType(); // //② 当不同type AL mark “SEG TYPE”为"STD_Shrink"“SP_*”"_MCD/_Mpitch"时不能被reference,跳过 // return !"STD_Shrink".equals(segType) && !segType.startsWith("SP_") && !segType.endsWith("_MCD") && !segType.endsWith("_Mpitch"); // }).collect(Collectors.toList()); // // if (CollectionUtils.isEmpty(collect1)) { // //alignment查不到,就查询ovl // TMainOvlApply ovlApply; // if (CollectionUtils.isEmpty(sameTypeOvlList)) { // List<TMainOvlApply> collect2 = ovlList.stream().filter(kpiAlign -> Objects.equals(kpiAlign.getMarkSizeSummary(), sizeSummary.getMarkType())) // .filter(kpiAlign -> { // String segType = kpiAlign.getMarkSizeSegType(); // //② 当不同type AL mark “SEG TYPE”为"STD_Shrink"“SP_*”"_MCD/_Mpitch"时不能被reference,跳过 // return !"STD_Shrink".equals(segType) && !segType.startsWith("SP_") && !segType.endsWith("_MCD") && !segType.endsWith("_Mpitch"); // }).collect(Collectors.toList()); // if (CollectionUtils.isEmpty(collect2)) { // continue; // } // ovlApply = ovlBSLMark(collect2); // } else if (sameTypeOvlList.size() == 1) { // ovlApply = sameTypeOvlList.get(0); // } else { // ovlApply = ovlBSLMark(sameTypeOvlList); // } // // sizeSummary.setSegType(ovlApply.getMarkSizeSegType()); // sizeSummary.setCd(ovlApply.getMarkSizeCd()); // sizeSummary.setPitch(ovlApply.getMarkSizePitch()); // sizeSummary.setTone(ovlApply.getMarkSizeTone()); // sizeSummary.setAdditionRemark("'layer':" + ovlApply.getLayerName() + ",'mark':" + ovlApply.getCurrentMarkSize()); // updateSizeSummaries.add(sizeSummary); // //⑤ 若Reference AL mark 在LM KPI中“If need redesign(Y/N)”为Y需要highlight; // if (Objects.equals("Y", ovlApply.getIfNeedRedesign())) { // result.add(String.format("%s:LM KPI system Mark Auto need re-design", sizeSummary.getLayerName())); // } // //标记已经引用的mark(相同markType不能引用重复的mark) // ovlList.stream().filter(item -> Objects.equals(item.getId(), ovlApply.getId())).findFirst().ifPresent(item -> item.setMarkType(sizeSummary.getMarkType())); // continue; // } // alignApply = alignMirror(collect1, sizeSummary); // } // //只有一个相同的markType // else if (sameTypeAlignList.size() == 1) { // alignApply = sameTypeAlignList.get(0); // } // //有多个相同type,继续按规则匹配 // else { // alignApply = alignMirror(sameTypeAlignList, sizeSummary); // } // // sizeSummary.setSegType(alignApply.getMarkSizeSegType()); // sizeSummary.setCd(alignApply.getMarkSizeCd()); // sizeSummary.setPitch(alignApply.getMarkSizePitch()); // sizeSummary.setTone(alignApply.getMarkSizeTone()); // sizeSummary.setAdditionRemark("'layer':" + alignApply.getLayerName() + ",'mark':" + alignApply.getMarkSize()); // updateSizeSummaries.add(sizeSummary); // //⑤ 若Reference AL mark 在LM KPI中“If need redesign(Y/N)”为Y需要highlight; // if (Objects.equals("Y", alignApply.getIfNeedRedesign())) { // result.add(String.format("%s:LM KPI system Mark Auto need re-design", sizeSummary.getLayerName())); // } // //标记已经引用的mark(相同markType不能引用重复的mark) // alignList.stream().filter(item -> Objects.equals(item.getId(), alignApply.getId())).findFirst().ifPresent(item -> item.setMarkType(sizeSummary.getMarkType())); // } // }); // // if (!CollectionUtils.isEmpty(updateSizeSummaries)) { // asmlAlSizeSummaryMapper.updateBatch(updateSizeSummaries); // } // return result; } /** * 查询出所选的referenceLayer的sizeSummary,过滤出coverLayer,将coverLayer信息新增给对应的currentLayer * coverLayer定义:LFMS_ASML_AL_SIZE_SUMMARY 表SIZE_TYPE=‘cover’,FEATURE1 = ‘Special’ * * @return highlight信息 */ private List<LfmsAsmlAlSizeSummary> coverLayerAutoGenerate(MarkAutoGenerateDTO markAutoGenerateDTO, List<LfmsAsmlAlSizeSummary> currentSizeSummaries) { List<LfmsAsmlAlSizeSummary> coverLayerList = new ArrayList<>(); List<String> referenceLayerNameList = markAutoGenerateDTO.getReferenceLayers().stream().map(MarkAutoGenerateLayerDTO::getReferenceLayer).collect(Collectors.toList()); //生成cover layer String projectId = markSizeUtils.getProjectId(markAutoGenerateDTO.getProjectId()); Map<String, String> currentMarkSizeParam = markSizeUtils.getMarkSizeParam(markAutoGenerateDTO.getCurrentProject(), markAutoGenerateDTO.getCurrentProjectId(), markAutoGenerateDTO.getCurrentPart(), markAutoGenerateDTO.getTypeName(), markAutoGenerateDTO.getMainVersion()); //查询LfmsDesignRecord获取最新mainVersion和subVersion,然后拉取LFMS系统的sizeSummary信息(coverLayer) LambdaQueryWrapper<LfmsDesignRecord> designRecordQueryWrapper = new LambdaQueryWrapper<>(); designRecordQueryWrapper.eq(LfmsDesignRecord::getProjAbbr, markAutoGenerateDTO.getProject()) .eq(LfmsDesignRecord::getPart, markAutoGenerateDTO.getPart()) .eq(LfmsDesignRecord::getProjId, projectId) .eq(LfmsDesignRecord::getProjType, markAutoGenerateDTO.getTypeName()) .eq(LfmsDesignRecord::getDesignTable, "RETICLE") .orderByDesc(LfmsDesignRecord::getMainVersion); //查询目标数据 design List<LfmsDesignRecord> designRecords = designRecordMapper.selectList(designRecordQueryWrapper); String mainVersion = designRecords.get(0).getMainVersion(); String subversion = designRecords.stream().filter(designRecord -> Objects.equals(mainVersion, designRecord.getMainVersion())).map(LfmsDesignRecord::getSubVersion).max(String::compareTo).get(); String rKey = String.join("@", markAutoGenerateDTO.getProject(), markAutoGenerateDTO.getPart(), mainVersion, projectId, markAutoGenerateDTO.getTypeName()); LambdaQueryWrapper<LfmsAsmlAlSizeSummary> asmlAlSizeSummaryQueryWrapper = new LambdaQueryWrapper<>(); asmlAlSizeSummaryQueryWrapper.eq(LfmsAsmlAlSizeSummary::getReticleKey, rKey).eq(LfmsAsmlAlSizeSummary::getSubVersion, subversion) .eq(LfmsAsmlAlSizeSummary::getSizeType, "cover").eq(LfmsAsmlAlSizeSummary::getFeature1, "Special") .in(LfmsAsmlAlSizeSummary::getLayerName, referenceLayerNameList); List<LfmsAsmlAlSizeSummary> asmlAlSizeSummaries = asmlAlSizeSummaryMapper.selectList(asmlAlSizeSummaryQueryWrapper); if (CollectionUtils.isEmpty(asmlAlSizeSummaries)) { return coverLayerList;//todo 需要根据规则highlight提醒 } //匹配到sizeSummary信息,然后新增到数据库,其中四个字段使用当前系统的数据:reticleKey、markCountKey、layerName、subVersion for (MarkAutoGenerateLayerDTO referenceLayer : markAutoGenerateDTO.getReferenceLayers()) { boolean match = currentSizeSummaries.stream().anyMatch(sizeSummary -> Objects.equals(sizeSummary.getLayerName(), referenceLayer.getCurrentLayer()) && Objects.equals(sizeSummary.getSizeType(), "cover")); if (match) continue; asmlAlSizeSummaries.stream().filter(sizeSummary -> Objects.equals(sizeSummary.getLayerName(), referenceLayer.getReferenceLayer())) .forEach(sizeSummary -> { LfmsAsmlAlSizeSummary addSizeSummary = new LfmsAsmlAlSizeSummary(); BeanUtils.copyProperties(sizeSummary, addSizeSummary); addSizeSummary.setLayerName(referenceLayer.getCurrentLayer()); addSizeSummary.setReticleKey(currentMarkSizeParam.get("rKey")); addSizeSummary.setMarkCountKey(String.join("@", markAutoGenerateDTO.getCurrentProjectId(), markAutoGenerateDTO.getMarkCountVersion())); addSizeSummary.setSubVersion(markAutoGenerateDTO.getSubVersion()); addSizeSummary.setNo(new BigDecimal(1)); coverLayerList.add(addSizeSummary); }); } return coverLayerList; // this.saveBatch(coverLayerList); // return "";//todo 需要根据规则highlight提醒 } /** * 判断页面上的If tape out or not = Y的数据中哪些是Dummy Block,GDS NO 去Reticel table 里查找If Dummy block 是Y,自动创建#_normal * <p> * 如何判断If tape out or not = Y? * 查询LFMS_ASML_AL_CELL_VALUE表里面的if_tape_out值 "IF_TAPE_OUT": "N" if len(df_dummy_value) == 0 else df_dummy_value["IF_TAPE_OUT"].iat[0], * <p> * 如何判断Dummy Block? * 1、查询LFMS_DESIGN_RECORD,找到对应的小版本号或者最新的小版本号subversion * 2、然后根据subversion匹配LFMS_RETICLE里相应的的数据,找到DUMMY_LAYER==Y的数据,即为Dummy block * * @param markAutoGenerateDTO */ @Override public void dummyBlockAutoGenerate(MarkAutoGenerateDTO markAutoGenerateDTO) { Map<String, String> markSizeParam = markSizeUtils.getMarkSizeParam(markAutoGenerateDTO.getCurrentProject(), markAutoGenerateDTO.getCurrentProjectId(), markAutoGenerateDTO.getCurrentPart(), markAutoGenerateDTO.getTypeName(), markAutoGenerateDTO.getMainVersion()); //取subversion,根据subversion查询出LfmsReticle的DUMMY_LAYER信息 String subversion = markAutoGenerateDTO.getSubVersion(); LambdaQueryWrapper<LfmsDesignRecord> designRecordQueryWrapper = new LambdaQueryWrapper<>(); designRecordQueryWrapper.eq(LfmsDesignRecord::getProjAbbr, markAutoGenerateDTO.getCurrentProject()).eq(LfmsDesignRecord::getPart, markAutoGenerateDTO.getCurrentPart()) .eq(LfmsDesignRecord::getProjId, markSizeParam.get("projectId")).eq(LfmsDesignRecord::getProjType, markAutoGenerateDTO.getTypeName()) .eq(LfmsDesignRecord::getMainVersion, markAutoGenerateDTO.getMainVersion()).eq(LfmsDesignRecord::getDesignTable, "RETICLE") .select(LfmsDesignRecord::getSubVersion) .orderByDesc(LfmsDesignRecord::getSubVersion); List<LfmsDesignRecord> designRecords = designRecordMapper.selectList(designRecordQueryWrapper); boolean existSubversion = designRecords.stream().anyMatch(designRecord -> Objects.equals(designRecord.getSubVersion(), markAutoGenerateDTO.getSubVersion())); if (!existSubversion) { String reg = "^[1-9][0-9]{7}(_[0-9]{1,2})?$";//原python代码,经了解部分老数据的版本不规范,后期都是采用日期当做版本号,如:“20240621”,不存在此问题 subversion = designRecords.stream().filter(designRecord -> designRecord.getSubVersion().matches(reg)).map(LfmsDesignRecord::getSubVersion).findFirst().get(); } LambdaQueryWrapper<LfmsReticle> reticleQueryWrapper = new LambdaQueryWrapper<>(); reticleQueryWrapper.eq(LfmsReticle::getSubVersion, subversion).eq(LfmsReticle::getDummyLayer, "Y").like(LfmsReticle::getIdx, markSizeParam.get("rKey")); List<LfmsReticle> lfmsReticles = reticleMapper.selectList(reticleQueryWrapper); if (CollectionUtils.isEmpty(lfmsReticles)) { return; } LambdaQueryWrapper<LfmsAsmlAlCellValue> cellValueQueryWrapper = new LambdaQueryWrapper<>(); cellValueQueryWrapper.eq(LfmsAsmlAlCellValue::getReticleKey, markSizeParam.get("rKey")).eq(LfmsAsmlAlCellValue::getSubVersion, subversion) .eq(LfmsAsmlAlCellValue::getIfTapeOut, "Y").select(LfmsAsmlAlCellValue::getLayerName); List<LfmsAsmlAlCellValue> asmlAlCellValues = asmlAlCellValueMapper.selectList(cellValueQueryWrapper); if (CollectionUtils.isEmpty(asmlAlCellValues)) { return; } //LfmsAsmlAlCellValue里的layerName值示例M2_ARRAY_Dummy List<String> cellValueLayers = asmlAlCellValues.stream().map(LfmsAsmlAlCellValue::getLayerName).collect(Collectors.toList()); List<String> dummyLayerNames = lfmsReticles.stream().filter(reticle -> cellValueLayers.contains(reticle.getLayerName() + "_Dummy")) .map(reticle -> reticle.getLayerName() + "_Dummy").collect(Collectors.toList()); if (CollectionUtils.isEmpty(dummyLayerNames)) { return; } LambdaQueryWrapper<LfmsAsmlAlDummySummary> dummySummaryQueryWrapper = new LambdaQueryWrapper<>(); dummySummaryQueryWrapper.eq(LfmsAsmlAlDummySummary::getReticleKey, markSizeParam.get("rKey")).eq(LfmsAsmlAlDummySummary::getSubVersion, subversion) .in(LfmsAsmlAlDummySummary::getLayerName, dummyLayerNames); //先删除dummySummary信息,再新增 asmlAlDummySummaryMapper.delete(dummySummaryQueryWrapper); String finalSubversion = subversion; List<LfmsAsmlAlDummySummary> addDummySummaries = dummyLayerNames.stream().map(layer -> { LfmsAsmlAlDummySummary dummySummary = new LfmsAsmlAlDummySummary(); dummySummary.setReticleKey(markSizeParam.get("rKey")); dummySummary.setMarkCountKey(markSizeParam.get("mKey")); dummySummary.setLayerName(layer); dummySummary.setNo(new BigDecimal(1)); dummySummary.setType("NORMAL"); dummySummary.setRefreshed("GREEN"); dummySummary.setSubVersion(finalSubversion); dummySummary.setCol(""); return dummySummary; }).collect(Collectors.toList()); addDummySummaries.forEach(dummySummary -> asmlAlDummySummaryMapper.insert(dummySummary)); } /** * 根据align sheet 的markSizeMirror判断 * * @param mainAlignList * @param asmlAl * @return */ private TMainAlignApply alignMirror(List<TMainAlignApply> mainAlignList, LfmsAsmlAlSizeSummary asmlAl) { List<TMainAlignApply> mirrorAlignList = mainAlignList.stream().filter(kpiAlign -> Objects.equals(kpiAlign.getMarkSizeMirror(), asmlAl.getMirror())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(mirrorAlignList)) { return alignBSLMark(mainAlignList); } else if (mirrorAlignList.size() == 1) { return mirrorAlignList.get(0); } else { return alignBSLMark(mirrorAlignList); } } /** * 根据align sheet 的ifBaselineMark判断 * * @param mainAlignList * @return */ private TMainAlignApply alignBSLMark(List<TMainAlignApply> mainAlignList) { List<TMainAlignApply> baseLineList = mainAlignList.stream().filter(kpiAlign -> Objects.equals("Y", kpiAlign.getIfBaselineMark())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(baseLineList)) { return alignBackUpMark(mainAlignList); } else if (baseLineList.size() == 1) { return baseLineList.get(0); } else { return alignBackUpMark(baseLineList); } } /** * 根据align sheet 的ifBackUp判断 * * @param mainAlignList * @return */ private TMainAlignApply alignBackUpMark(List<TMainAlignApply> mainAlignList) { List<TMainAlignApply> backUpList = mainAlignList.stream().filter(kpiAlign -> Objects.equals("Y", kpiAlign.getIfBackUp())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(backUpList)) { //todo 从系统对比“ROPI”值 return mainAlignList.get(0); } else if (backUpList.size() == 1) { return backUpList.get(0); } else { //todo 从系统对比“ROPI”值 return backUpList.get(0); } } /** * 根据ovl sheet 的ifBaselineMark判断 * * @param mainOvlList * @return */ private TMainOvlApply ovlBSLMark(List<TMainOvlApply> mainOvlList) { List<TMainOvlApply> baseLineList = mainOvlList.stream().filter(kpiOvl -> Objects.equals("Y", kpiOvl.getIfBaselineMark())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(baseLineList)) { return ovlBackUpMark(mainOvlList); } else if (baseLineList.size() == 1) { return baseLineList.get(0); } else { return ovlBackUpMark(baseLineList); } } /** * 根据ovlsheet的ifBackUp判断 * * @param mainOvlList * @return */ private TMainOvlApply ovlBackUpMark(List<TMainOvlApply> mainOvlList) { List<TMainOvlApply> backUpList = mainOvlList.stream().filter(kpiOvl -> Objects.equals("Y", kpiOvl.getIfBackUp())).collect(Collectors.toList()); if (CollectionUtils.isEmpty(backUpList)) { //todo 从系统对比“ROPI”值 return mainOvlList.get(0); } else if (backUpList.size() == 1) { return backUpList.get(0); } else { //todo 从系统对比“ROPI”值 return backUpList.get(0); } } /** * 表头生成重构 * 从markcount拉取数据,并按feature2>mark type>feature1>pepper排序 * * @param dto * @return */ @Override public AsmlQueryMarkCountVO fetchSheet(FetchSheetDTO dto) { //查询sizeMapping信息 List<MarkSizeSpec> sizeMappingList = markSizeSpecMapper.selectList(new LambdaQueryWrapper<MarkSizeSpec>() .eq(MarkSizeSpec::getTableType, "ASML_AL Mark Type")); //查询 reticle 的信息, 对应的是表格行信息 //取subversion,根据subversion查询出LfmsReticle String subversion = dto.getSubVersion(); LambdaQueryWrapper<LfmsDesignRecord> designRecordQueryWrapper = new LambdaQueryWrapper<>(); Map<String, String> markSizeParam = markSizeUtils.getMarkSizeParam(dto.getProject(), dto.getProjectId(), dto.getPart(), dto.getProjectType(), dto.getMainVersion()); designRecordQueryWrapper.eq(LfmsDesignRecord::getProjAbbr, dto.getProject()).eq(LfmsDesignRecord::getPart, dto.getPart()) .eq(LfmsDesignRecord::getProjId, markSizeParam.get("projectId")).eq(LfmsDesignRecord::getProjType, dto.getProjectType()) .eq(LfmsDesignRecord::getMainVersion, dto.getMainVersion()).eq(LfmsDesignRecord::getDesignTable, "RETICLE") .select(LfmsDesignRecord::getSubVersion) .orderByDesc(LfmsDesignRecord::getSubVersion); List<LfmsDesignRecord> designRecords = designRecordMapper.selectList(designRecordQueryWrapper); boolean existSubversion = designRecords.stream().anyMatch(designRecord -> Objects.equals(designRecord.getSubVersion(), dto.getSubVersion())); if (!existSubversion) { String reg = "^[1-9][0-9]{7}(_[0-9]{1,2})?$";//原python代码,经了解部分老数据的版本不规范,后期都是采用日期当做版本号,如:“20240621”,不存在此问题 subversion = designRecords.stream().filter(designRecord -> designRecord.getSubVersion().matches(reg)).map(LfmsDesignRecord::getSubVersion).findFirst().get(); } LambdaQueryWrapper<LfmsReticle> reticleQueryWrapper = new LambdaQueryWrapper<>(); reticleQueryWrapper.eq(LfmsReticle::getSubVersion, subversion).eq(LfmsReticle::getDummyLayer, "Y").like(LfmsReticle::getIdx, markSizeParam.get("rKey")); List<LfmsReticle> lfmsReticles = reticleMapper.selectList(reticleQueryWrapper); if (CollectionUtils.isEmpty(lfmsReticles)) { return null; } return null; } }帮忙优化下 markAutoGenerate 这个方法关联得代码
最新发布
11-19
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值