EdcQueryManagerImpl.java
package com.mycim.server.wip.manager.impl;
import com.fa.sesa.exception.Assert;
import com.fa.sesa.exception.Errors;
import com.fa.sesa.exception.SystemIllegalArgumentException;
import com.fa.sesa.threadlocal.LocalContext;
import com.mycim.framework.utils.lang.StringUtils;
import com.mycim.framework.utils.lang.collections.CollectionUtils;
import com.mycim.framework.utils.lang.collections.MapUtils;
import com.mycim.framework.utils.lang.math.NumberUtils;
import com.mycim.server.base.manager.NamedObjectManager;
import com.mycim.server.ctx.exec.manager.EdcLotContextManager;
import com.mycim.server.edc.manager.DataCollectionRuleManager;
import com.mycim.server.edc.manager.ParameterRuleManager;
import com.mycim.server.edc.manager.ParameterSetManager;
import com.mycim.server.system.manager.ReferenceFileManager;
import com.mycim.server.wip.dao.EdcQueryDAO;
import com.mycim.server.wip.manager.*;
import com.mycim.utils.ChartNamingRule;
import com.mycim.valueobject.MessageIdList;
import com.mycim.valueobject.ObjectList;
import com.mycim.valueobject.bas.NamedObject;
import com.mycim.valueobject.consts.ActionPointList;
import com.mycim.valueobject.consts.EDCConst;
import com.mycim.valueobject.consts.HoldCodeNames;
import com.mycim.valueobject.consts.ReferenceDetailNames;
import com.mycim.valueobject.edcspc.*;
import com.mycim.valueobject.edcspc.responseModel.ParameterRuleDetailResponse;
import com.mycim.valueobject.edcspc.rule.CollectionRule;
import com.mycim.valueobject.edcspc.rule.CollectionRuleFactory;
import com.mycim.valueobject.edcspc.rule.SpecialRule;
import com.mycim.valueobject.ems.Equipment;
import com.mycim.valueobject.prp.EdcLotContextValue;
import com.mycim.valueobject.sys.ReferenceFileDetail;
import com.mycim.valueobject.wip.BatchLotStore;
import com.mycim.valueobject.wip.Lot;
import com.mycim.valueobject.wip.Unit;
import com.mycim.valueobject.wip.dto.ParameterDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
/**
* @author Johnson.Wang
* @version 6.0.0
* @date 2019/9/27
**/
@Service
@Transactional
public class EdcQueryManagerImpl implements EdcQueryManager {
@Autowired
private NamedObjectManager namedObjectManager;
@Autowired
private EdcQueryDAO edcQueryDAO;
@Autowired
private UnitQueryManager unitQueryManager;
@Autowired
private LotQueryManager lotQueryManager;
@Autowired
private EdcLotContextManager edcLotContextManager;
@Autowired
private ParameterSetManager parameterSetManager;
@Autowired
private DataCollectionRuleManager dataCollectionRuleManager;
@Autowired
private ParameterRuleManager parameterRuleManager;
@Autowired
private OcapQueryManager ocapQueryManager;
@Autowired
private DiffBatchQueryManager diffBatchQueryManager;
@Autowired
private ReferenceFileManager referenceFileManager;
@Override
public double getParamValByCondition(long lotRrn, long operationRrn, long productRrn, long processRrn,
long parameterRrn, String puType) {
return edcQueryDAO.getParamValByCondition(lotRrn, operationRrn, productRrn, processRrn, parameterRrn, puType);
}
@Override
public List<ParameterSetVersion> getParameterSetWithMonitorLot(Lot lot, Equipment equipment) {
Long parameterSetRrn = null;
List parameterSetVersions = null;
List<BatchLotStore> list = diffBatchQueryManager.getBatchStoreListByLot(lot.getLotRrn());
if (CollectionUtils.isNotEmpty(list)) {
for (BatchLotStore bonding : list) {
Long toLotRrn = bonding.getLotRrn();
Lot toLot = lotQueryManager.getLot(toLotRrn);
EdcLotContextValue edcLotContextValue = edcLotContextManager
.getEdcLotContextValue(toLot, equipment, ActionPointList.MOVEOUT_KEY);
if (edcLotContextValue != null && edcLotContextValue.getParameterSetRrn() != null) {
if (parameterSetRrn == null) {
parameterSetRrn = edcLotContextValue.getParameterSetRrn();
parameterSetVersions = parameterSetManager
.buildParameterSetInfo(toLot, equipment, ActionPointList.MOVEOUT_KEY);
} else if (parameterSetRrn.longValue() != edcLotContextValue.getParameterSetRrn().longValue()) {
throw new SystemIllegalArgumentException(
Errors.create().content("Batch lots not the same edcplan.").build());
}
}
}
}
return parameterSetVersions;
}
/**
* 获取可用的规则
*
* @param unitList
* @param parameterRrn
* @return
*/
@Override
public CollectionRule getAvailableDataCollectionRule(List<Unit> unitList, Long parameterRrn) {
List<DataCollectionRule> collectionRules = dataCollectionRuleManager.getDataCollectionRules(parameterRrn);
Assert.isFalse(collectionRules.size() == 0,
Errors.create().key(MessageIdList.RULE_MISSING).content("规则不存在!").build());
CollectionRule collectionRule = null;
for (DataCollectionRule dataCollectionRule : collectionRules) {
collectionRule = new CollectionRuleFactory(dataCollectionRule, unitList).getAndCheckAvailableRule();
if (collectionRule != null) {
return collectionRule;
}
}
return null;
}
/**
* 获取可用的规则
*
* @param unitList
* @param parameterRrn
* @return
*/
@Override
public CollectionRule getAvailableDataCollectionRule(Long facilityRrn, Long lotRrn, Map<String, Object> matchMap,
List<Unit> unitList, Long parameterRrn) {
List<DataCollectionRule> collectionRules = getDataCollectionRules(matchMap, parameterRrn);
Long eqptRrn = MapUtils.getLongValue(matchMap, EDCConst.CollectionRuleMatchKey.EQPT_RRN.getMatchKey());
Long productRrn = MapUtils.getLongValue(matchMap, EDCConst.CollectionRuleMatchKey.PRODUCT_RRN.getMatchKey());
String remeasureUnitIds = ocapQueryManager.getRemeasureUnitIds(facilityRrn, lotRrn, parameterRrn);
CollectionRule collectionRule = null;
boolean newRuleFlag = false;
String ruleId = "";
for (DataCollectionRule dataCollectionRule : collectionRules) {
if (StringUtils.isNotEmpty(remeasureUnitIds)) {
dataCollectionRule.setRuleId(EDCConst.CollectionRuleEnum.OCAP.toString());
dataCollectionRule.setCollectionRule(EDCConst.CollectionRuleEnum.OCAP.toString());
dataCollectionRule.setWaferSample(remeasureUnitIds);
newRuleFlag = true;
} else if (StringUtils.equals(EDCConst.CollectionRuleEnum.SEARCHSTEP.toString(),
dataCollectionRule.getCollectionRule())) {
newRuleFlag = true;
} else {
ruleId = dataCollectionRule.getRuleId();
// 只能是1-25的正整数
if (NumberUtils.isParsable(ruleId) && !StringUtils.contains(ruleId, ".")) {
// ruleId 是数字,使用新规则处理(新规则的处理,实际上是将规则重新构建成special模式的数据结构)
int units = NumberUtils.toInt(ruleId);
if (units > 0 && units < 26) {
newRuleFlag = buildDataCollectionRuleToSpecial(eqptRrn, productRrn, parameterRrn,
unitList.size(), units, dataCollectionRule);
}
}
}
if (newRuleFlag) {
collectionRule = new CollectionRuleFactory(dataCollectionRule, unitList).getAndCheckAvailableRule();
if (collectionRule != null) {
return collectionRule;
}
}
}
return null;
}
/**
* 获取规则
*
* @param unitList
* @param parameterSetRrn
* @param parameterSetVersion
* @param parameterRrn
* @return
*/
@Override
public CollectionRule getDataCollectionRule(List<Unit> unitList, Long parameterSetRrn, Integer parameterSetVersion,
Long parameterRrn) {
List<DataCollectionRule> collectionRules = dataCollectionRuleManager
.getDataCollectionRules(parameterSetRrn, parameterSetVersion, parameterRrn);
CollectionRule collectionRule = null;
for (DataCollectionRule dataCollectionRule : collectionRules) {
collectionRule = new CollectionRuleFactory(dataCollectionRule, unitList).getDataCollectionRule();
if (collectionRule != null) {
return collectionRule;
}
}
return null;
}
/**
* 获取当前参数集当前版本当前参数的数据采集规则
*
* @param matchMap
* @param parameterRrn
* @return
*/
@Override
public List<DataCollectionRule> getDataCollectionRules(Map<String, Object> matchMap, Long parameterRrn) {
List<DataCollectionRule> dataCollectionRules = dataCollectionRuleManager.getDataCollectionRules(parameterRrn);
if (dataCollectionRules == null) {
dataCollectionRules = new ArrayList<>();
}
buildId4MatchMap(matchMap);
for (DataCollectionRule dataCollectionRule : dataCollectionRules) {
String collectionRule = dataCollectionRule.getCollectionRule();
if (ParameterRule.ParameterRuleType.SPECIAL.getValue().equals(collectionRule)) {
WaferSelectionMain mainCondition = new WaferSelectionMain();
mainCondition.setEqptId(
MapUtils.getStringCheckNull(matchMap, EDCConst.CollectionRuleMatchKey.EQPT_ID.getMatchKey()));
List<ParameterRuleDetailResponse> details = dataCollectionRuleManager
.getSpecialRuleDetailByRule(dataCollectionRule.getRuleRrn());
dataCollectionRule.setRuleDetail(details);
}
dataCollectionRule.setCollectionRule(ParameterRule.ParameterRuleType.parseCollectionRule(collectionRule));
}
return dataCollectionRules;
}
@Override
public List<Map<String, Object>> getAllDataCollectionPointInfoByDcolRrn(Long dcolRrn) {
List<Map<String, Object>> result = edcQueryDAO.getAllDataCollectionPointInfoByDcolRrn(dcolRrn);
if (CollectionUtils.isEmpty(result)) {
result = Collections.emptyList();
}
return result;
}
@Override
public List<Parameter> getLotEdcInfoList(Lot lot, Equipment equipment) {
List<Parameter> paramList = new ArrayList<Parameter>();
EdcLotContextValue edcLotContextValue = edcLotContextManager
.getEdcLotContextValue(lot, equipment, ActionPointList.MOVEOUT_KEY);
Long parameterSetRrn = edcLotContextValue.getParameterSetRrn();
if (parameterSetRrn == null || parameterSetRrn.longValue() <= 0) {
return null;
}
//1.获取parameter
List<ParameterSetVersion> parameterSetVersions = parameterSetManager
.getActiveParameterSetVersion(parameterSetRrn);
for (ParameterSetVersion parameterSetVersion : parameterSetVersions) {
List<Parameter> parameters = (List<Parameter>) parameterSetVersion.getParameters();
for (Parameter parameter : parameters) {
Map<String, Object> matchMap = new HashMap<String, Object>();
matchMap.put(EDCConst.CollectionRuleMatchKey.FACILITY_RRN.getMatchKey(), lot.getFacilityRrn());
matchMap.put(EDCConst.CollectionRuleMatchKey.EQPT_RRN.getMatchKey(), equipment.getInstanceRrn());
matchMap.put(EDCConst.CollectionRuleMatchKey.PRODUCT_RRN.getMatchKey(), lot.getProductRrn());
matchMap.put(EDCConst.CollectionRuleMatchKey.RECIPE_RRN.getMatchKey(), lot.getRecipeLogicalRrn());
List<Unit> unitsList = unitQueryManager.getUnitList(lot.getLotRrn());
CollectionRule collectionRule = getAvailableDataCollectionRule(lot.getFacilityRrn(), lot.getLotRrn(),
matchMap, unitsList,
parameter.getInstanceRrn());
if (collectionRule != null) {
parameter.setSelectedUnitIds(collectionRule.getSelectedUnitIds());
parameter.setSelectedUnitPositions(collectionRule.getSelectedUnitPositions());
}
paramList.add(parameter);
}
}
return paramList;
}
@Override
public String getChartOwnerHoldCode(List<ParameterDto> parameters) {
String holdCode = HoldCodeNames.PIE_PIE_ENG;
if (CollectionUtils.isEmpty(parameters)) {
return holdCode;
}
String parameterId = parameters.get(0).getParameterId();
String code = ChartNamingRule.getCodeRepresentedAsModule(parameterId);
String owner = referenceFileManager.getRefValue(ReferenceDetailNames.SPC_CHART_OWNER, code);
if (StringUtils.isBlank(owner)) {
return holdCode;
}
NamedObject holdCodeNmdObj = namedObjectManager.getNamedObject("$HOLD_CODE", namedObjectManager.getNamedSpace(
LocalContext.getFacilityRrn(), ObjectList.SUB_TECHNOLOGY), ObjectList.REFERENCE_FILE_KEY);
if (holdCodeNmdObj == null) { //数据库数据安全校验
return holdCode;
}
long holdCodeRrn = holdCodeNmdObj.getInstanceRrn();
if (holdCodeRrn <= 0) {//rrn 合法校验
return holdCode;
}
//通过rrn 找到明细
List<ReferenceFileDetail> referenceFileDetails = referenceFileManager.getRefFileValues(holdCodeRrn);
if (CollectionUtils.isEmpty(referenceFileDetails)) { //detail 合法校验
return holdCode;
}
//按照需求规则拼接
String chartOwnerHoldCode = String.format("%s_%s_ENG", owner, owner);
//找出按照规则设置的 hold code 信息
ReferenceFileDetail referenceFileDetail = referenceFileDetails.stream()
.filter((e) -> StringUtils.equalsIgnoreCase(
e.getKey1Value(),
chartOwnerHoldCode))
.findFirst().orElse(null);
if (referenceFileDetail == null) {//没有设置 hold code
return holdCode;
}
holdCode = chartOwnerHoldCode;
return holdCode;
}
/**
* 匹配新规则,返回抽片位置数组
*/
public String[] getNewRuleSelectedWafer(Long eqptRrn, Long productRrn, Long parameterRrn, int units, int waferQty) {
String eqptId = namedObjectManager.getInstanceId(eqptRrn);
String prodId = namedObjectManager.getInstanceId(productRrn);
String paramId = namedObjectManager.getInstanceId(parameterRrn);
// param的匹配有点特殊,因为chart的导入创建的parameter id中会在第二位自动添加一个M,
// 手动在MES中添加的不会有M
// 所以匹配的时候两种情况都考虑
String relation = ChartNamingRule.getChartRuleRelationByParameterId(paramId);
List<NewParameterRule> ruleList = parameterRuleManager.getNewRulesByMatch(eqptId, prodId, relation, units);
NewParameterRule rule = new NewParameterRule();
if (CollectionUtils.isNotEmpty(ruleList)) {
if (ruleList.size() > 0) {
// 产品是否已优先匹配
boolean productMatchFlag = false;
// 设备是否已优先匹配
boolean eqptMatchFlag = false;
int prodMaxLen = 0;
for (NewParameterRule r : ruleList) {
if (r.getProductId().length() > prodMaxLen && StringUtils.equals(eqptId, r.getEqptId()) &&
!StringUtils.equals("*", r.getProductId())) {
rule = r;
break;
}
if (r.getProductId().length() > prodMaxLen && !StringUtils.equals("*", r.getProductId())) {
prodMaxLen = r.getProductId().length();
rule = r;
productMatchFlag = true;
}
if (StringUtils.equals(eqptId, r.getEqptId())) {
if (!productMatchFlag) {
rule = r;
eqptMatchFlag = true;
}
}
if (!productMatchFlag && !eqptMatchFlag) {
rule = r;
}
}
String selectedWafers = rule.getActuallyChooseWafers(waferQty);
if (StringUtils.isNotBlank(selectedWafers)) {
return StringUtils.split(selectedWafers, ",");
}
}
}
return new String[0];
}
private void buildId4MatchMap(Map<String, Object> matchMap) {
Long eqptRrn = MapUtils.getLongValue(matchMap, EDCConst.CollectionRuleMatchKey.EQPT_RRN.getMatchKey());
Long productRrn = MapUtils.getLongValue(matchMap, EDCConst.CollectionRuleMatchKey.PRODUCT_RRN.getMatchKey());
Long recipeRrn = MapUtils.getLongValue(matchMap, EDCConst.CollectionRuleMatchKey.RECIPE_RRN.getMatchKey());
matchMap.put(EDCConst.CollectionRuleMatchKey.EQPT_ID.getMatchKey(), namedObjectManager.getInstanceId(eqptRrn));
matchMap.put(EDCConst.CollectionRuleMatchKey.PRODUCT_ID.getMatchKey(),
namedObjectManager.getInstanceId(productRrn));
matchMap.put(EDCConst.CollectionRuleMatchKey.RECIPE_ID.getMatchKey(),
namedObjectManager.getInstanceId(recipeRrn));
}
/**
* 匹配新规则,将新规则数据结构重构为SPECIAL模式
*
* @param eqptRrn 机台
* @param productRrn 批次product
* @param parameterRrn chart
* @param waferQty 批次上的晶圆数
* @param units 要采集的片数
* @param dataCollectionRule 参数,参数规则集合 信息
* @return true 匹配上新规则,false 没有匹配上新规则
*/
private boolean buildDataCollectionRuleToSpecial(long eqptRrn, long productRrn, long parameterRrn, int waferQty,
int units, DataCollectionRule dataCollectionRule) {
String[] selectedWafers = getNewRuleSelectedWafer(eqptRrn, productRrn, parameterRrn, units, waferQty);
if (selectedWafers != null && selectedWafers.length > 0) {
List<ParameterRuleDetailResponse> ruleDetailList = buildNewRuleToSpecialRuleDetail(
dataCollectionRule.getRuleRrn(), waferQty, selectedWafers, units);
dataCollectionRule.setRuleDetail(ruleDetailList);
// 不论之前是什么模式,匹配上后,都重置为SPECIAL模式
dataCollectionRule.setCollectionRule(ParameterRule.ParameterRuleType.SPECIAL.toString());
dataCollectionRule.setCollectionRuleSequence(1);
String waferSample = StringUtils.EMPTY;
for (int i = 0; i < selectedWafers.length; i++) {
int waferIndex = Integer.parseInt(selectedWafers[i]);
waferSample += waferIndex + ",";
}
waferSample = StringUtils.removeLastChar(waferSample, ",");
dataCollectionRule.setWaferSampleByNewParamRule(waferSample);
return true;
}
return false;
}
private List<ParameterRuleDetailResponse> buildNewRuleToSpecialRuleDetail(long ruleRrn, int rangeEnd,
String[] selectedWafer, int units) {
ParameterRuleDetailResponse detail = new ParameterRuleDetailResponse();
detail.setDetailSeq(1);
detail.setQtyRangeEnd(rangeEnd);
detail.setQtyRangeStart(1);
detail.setRuleRrn(ruleRrn);
String specialSelectedWafer = StringUtils.EMPTY;
for (int i = 0; i < selectedWafer.length; i++) {
int waferIndex = Integer.parseInt(selectedWafer[i]);
if (waferIndex == 1) {
specialSelectedWafer += SpecialRule.TOP_KEY + ",";
} else {
specialSelectedWafer += SpecialRule.TOP_KEY + "+" + (waferIndex - 1) + ",";
}
}
specialSelectedWafer = StringUtils.removeLastChar(specialSelectedWafer, ",");
detail.setSelectedWafer(specialSelectedWafer);
detail.setWaferNum(units);
List<ParameterRuleDetailResponse> list = new ArrayList<ParameterRuleDetailResponse>();
list.add(detail);
return list;
}
}