# SorterQueryManagerImpl.java

    package com.mycim.server.sorter.manager.imp;

    import com.fa.sesa.threadlocal.LocalContext;
    import com.mycim.framework.jdbc.Page;
    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.framework.utils.msg.JsonUtils;
    import com.mycim.server.base.manager.NamedObjectManager;
    import com.mycim.server.base.manager.RelationManager;
    import com.mycim.server.carrier.manager.CarrierManager;
    import com.mycim.server.security.manager.RoleManager;
    import com.mycim.server.sorter.dao.SorterQueryDAO;
    import com.mycim.server.sorter.manager.SorterQueryManager;
    import com.mycim.server.spec.manager.ProcessSpecItemManager;
    import com.mycim.server.system.manager.ReferenceFileManager;
    import com.mycim.server.wip.manager.*;
    import com.mycim.valueobject.bas.Relation;
    import com.mycim.valueobject.consts.LinkTypeList;
    import com.mycim.valueobject.consts.SorterEnum;
    import com.mycim.valueobject.runcard.util.RunCardUtils;
    import com.mycim.valueobject.sorter.*;
    import com.mycim.valueobject.wip.Lot;
    import com.mycim.valueobject.wip.LotRunCardStore;
    import com.mycim.valueobject.wip.SRCLotSpecialStep;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;

    import java.util.*;
    import java.util.stream.Collectors;

    /**
     * @Author: yibing.liu
     * @Date: 2021/7/16 10:51
     */
    @Service
    public class SorterQueryManagerImpl implements SorterQueryManager {

        @Autowired
        SorterQueryDAO sorterDAO;

        @Autowired
        NamedObjectManager namedObjectManager;

        @Autowired
        LotManager lotManager;

        @Autowired
        LotQueryManager lotQueryManager;

        @Autowired
        UnitQueryManager unitQueryManager;

        @Autowired
        CarrierManager carrierManager;

        @Autowired
        JobManager jobManager;

        @Autowired
        ReferenceFileManager referenceFileManager;

        @Autowired
        ProcessSpecItemManager processSpecItemManager;

        @Autowired
        SorterQueryDAO sorterQueryDAO;

        @Autowired
        RoleManager roleManager;

        @Autowired
        RelationManager relationManager;

        @Autowired
        RunCardQueryManager runCardQueryManager;

        @Override
        public Page querySorterList(Page page, SorterBean sorterBean) {
            boolean hasPromission = false;
            List<Relation>  userRole = relationManager.getRelationsUseFromRrn(LocalContext.getUserRrn(), LinkTypeList.USER_ROLE_KEY);
            List<Relation>  userGroupRole = relationManager.getRelationsUseFromRrn(LocalContext.getUserRrn(), LinkTypeList.USER_USERGROUP_KEY);
            if(roleManager.isAdminRole(LocalContext.getFacilityRrn(), LocalContext.getUserRrn())){
                hasPromission = true;
            }else{
                //by user role
                if (CollectionUtils.isNotEmpty(userRole)&&!hasPromission) {
                    List<Long> roles =  userRole.stream().map(Relation::getToRrn).collect(Collectors.toList());
                    Map button =  CollectionUtils.isEmpty(roles)? MapUtils.EMPTY_MAP:roleManager.getButtonInfoWithRoles(roles,"BTN_VIEW_INLINE_SORTER");
                    if(MapUtils.isNotEmpty(button)){
                        hasPromission = true;
                    }
                }
                //by user group role
                if(CollectionUtils.isNotEmpty(userGroupRole)&&!hasPromission){
                    List<Relation>  gourpRoles = null;
                    for (Relation userGroup : userGroupRole){
                        gourpRoles = relationManager.getRelationsUseFromRrn(userGroup.getToRrn(), LinkTypeList.USERGROUP_ROLE_KEY);
                        List<Long> roleRrns = gourpRoles.stream().map(Relation::getToRrn).collect(Collectors.toList());
                        Map button =  CollectionUtils.isEmpty(roleRrns)? MapUtils.EMPTY_MAP:roleManager.getButtonInfoWithRoles(roleRrns,"BTN_VIEW_INLINE_SORTER");
                        if(MapUtils.isNotEmpty(button)){
                            hasPromission = true;
                            break;
                        }
                    };
                }
            }
            if(hasPromission){
                return sorterDAO.queryAllSorterList(page,sorterBean);
            }

            return sorterDAO.querySorterList(page, sorterBean);
        }

        @Override
        public List<SortJobBean> querySortJobByCarrierRrn(long sourceCarrierRrn, long targetCarrierRrn) {
            List<SortJobBean> sortJobBeanList = new ArrayList<>();
            //源晶舟和目标晶舟可确认唯一SortJob
            if (sourceCarrierRrn > 0 && targetCarrierRrn > 0) {
                SorterBean sorterBean = new SorterBean();
                sorterBean.setSourceCarrierRrn(sourceCarrierRrn);
                sorterBean.setTargetCarrierRrn(targetCarrierRrn);
                SortJobBean sjb = sorterDAO.getSortJob(sorterBean);
                sortJobBeanList.add(sjb);
                return sortJobBeanList;
            }
            //单独查询目标晶舟，存在多个SortJob的情况，例如：Merge
            if (targetCarrierRrn > 0) {
                sortJobBeanList = sorterDAO.getSortJobByCarrierRrn(targetCarrierRrn);
            }
            return sortJobBeanList;
        }

        @Override
        public SortJobBean querySortJobByCarrierRrn(long carrierRrn) {
            SortJobBean sortJobBean = new SortJobBean();

            long mainJobRrn = sorterDAO.querySorterJobRrnByCarrierRrn(carrierRrn, new StatusBean());
            if (mainJobRrn > 0) {
                sortJobBean = dealSorterData(mainJobRrn);
            }
            return sortJobBean;
        }

        @Override
        public SortJobBean querySortJobBySourceCarrierRrn(long sourceCarrierRrn) {
            SortJobBean sortJobBean = new SortJobBean();

            long mainJobRrn = sorterDAO.querySorterJobRrnBySourceCarrierRrn(sourceCarrierRrn);
            if (mainJobRrn > 0) {
                sortJobBean = dealSorterData(mainJobRrn);
            }
            return sortJobBean;
        }

        @Override
        public SorterBean getSorterByCarrier(String carrierId) {
            return sorterDAO.getSorterByCarrier(carrierId);
        }

        @Override
        public List<SorterBean> getSorterList(SorterBean sorterBean) {
            return sorterDAO.getSorterList(sorterBean);
        }

        @Override
        public SortJobBean getSortJob(SorterBean sortBean) {
            return sorterDAO.getSortJob(sortBean);
        }

        @Override
        public SortJobBean getSortJob(SortJobBean sortJobBean) {
            return sorterDAO.getSortJob(sortJobBean);
        }

        @Override
        public String[] getChildLotIdListByLotId(String lotId) {
            String[] childLotIdArr;
            List<String> childLotIds = sorterDAO.getChildLotIdListByLotId(lotId);
            if (CollectionUtils.isNotEmpty(childLotIds)) {
                String maxChildLotId = SorterEnum.getListFirst(childLotIds);
                int maxChildLotNum =
                        NumberUtils.toInt(StringUtils.substring(maxChildLotId, maxChildLotId.indexOf(".") + 1)) + 1;
                childLotIdArr = new String[maxChildLotNum];
                for (String str : childLotIds) {
                    childLotIdArr[NumberUtils.toInt(StringUtils.substring(str, str.indexOf(".") + 1)) - 1] = str;
                }
            } else {
                childLotIdArr = new String[0];
            }
            return childLotIdArr;
        }

        @Override
        public List<String> getChildLotInSortTask(long lotRrn, Long carrierRrn) {
            return sorterDAO.getSourceLotIdByTargetCarrier(carrierRrn, SorterEnum.JobType.MERGE.getJobType());
        }

        @Override
        public List<SorterBean> querySorterByCarrier(long sourceCarrierRrn, long targetCarrierRrn) {
            return sorterDAO.querySorterByCarriers(sourceCarrierRrn, targetCarrierRrn);
        }

        @Override
        public List<SorterBean> getSoterListByCarrier(Long sourceCarrierRrn) {
            return sorterDAO.getSoterListByCarrier(sourceCarrierRrn);
        }

        @Override
        public List<SorterBean> getSoterListByCarrier(Long sourceCarrierRrn, Long targetCarrierRrn) {
            return sorterDAO.getSoterListByCarrier(sourceCarrierRrn, targetCarrierRrn);
        }

        @Override
        public List<SorterBean> getJobTypeOrStatusList(String type, String language) {
            return sorterDAO.getJobTypeOrStatusList(type, language);
        }

        @Override
        public SortJobBean getSortJobByJobRrnAndStatus(Long jobRrn, Long subJobRrn, StatusBean status) {
            return sorterDAO.getSortJobByStatus(jobRrn, subJobRrn, status);
        }

        @Override
        public SorterDetailBean querySorterByLotRrn(Long lotRrn) {
            return sorterDAO.getSorterByLotRrn(lotRrn);
        }

        @Override
        public SortJobBean getSortJobByCarrier(Long sourceCarrierRrn, Long targetCarrierRrn, Long targetCarrierRrn2) {
            SortJobBean sjb = new SortJobBean();
            if (targetCarrierRrn <= 0) {//只需根据SourceCarrierRRN去查询
                sjb = querySortJobByCarrierRrn(sourceCarrierRrn);
            } else {
                if (!sjb.isEmpty()) {
                    sjb = querySortJobBySourceAndTargetCarrierRrn(sourceCarrierRrn, targetCarrierRrn);
                }
                if (!sjb.isEmpty() && targetCarrierRrn2 != null && targetCarrierRrn2 > 0) {
                    sjb = querySortJobByCarrierRrn(targetCarrierRrn2);
                }
            }
            return sjb;
        }

        @Override
        public List<SorterBean> getAllSortJobBySourceCarrierRrn(long carrierRrn) {
            return sorterDAO.getAllSortJobBySourceCarrierRrn(carrierRrn, new StatusBean());
        }

        @Override
        public List<SortJobBean> getSortJobListByCarrier(long carrierRrn) {
            List<SortJobBean> sortJobList = new ArrayList<>();

            List<String> mainJobRrnList = sorterDAO.querySorterJobRrnListByCarrierRrn(carrierRrn);
            if (CollectionUtils.isNotEmpty(mainJobRrnList)) {
                for (String mainJobStr : mainJobRrnList) {
                    SortJobBean sortJobBean = getSortJob(new SortJobBean(NumberUtils.toLong(mainJobStr, 0L)));
                    List<SorterBean> sorterBeans = sortJobBean.getSorterBeans();
                    SorterBean sb1 = SorterEnum.getListFirst(sorterBeans);
                    sortJobBean.setSourceCarrierId(sb1.getSourceCarrierId());
                    sortJobBean.setTargetCarrierId(sb1.getTargetCarrierId());
                    if (sorterBeans.size() > 1) {
                        sortJobBean.setTargetCarrierId2(sorterBeans.get(1).getTargetCarrierId());
                    }
                    sortJobBean.setJobType(sb1.getJobType());
                    sortJobBean.setStatus(sb1.getStatus());
                    sortJobList.add(sortJobBean);
                }
            }
            return sortJobList;
        }

        @Override
        public <T> T parseToJsonT(List<?> unitList, FilterParam filterParam) {
            if (unitList == null || filterParam == null) {
                return null;
            }
            Map[] unitMapArr = new Map[filterParam.getSlotCount()];
            List<FilterParam.Column> strStrList = filterParam.getColumnArrayList();
            for (Map unit : (List<Map<String, Object>>) unitList) {
                int seq = MapUtils.getIntValue(unit, filterParam.getIntegerColumn());
                if (seq <= 0)
                    continue;
                Map<String, Object> unitMap = new HashMap<>();
                unitMap.put(filterParam.getSeqColumn(), seq);
                for (FilterParam.Column c : strStrList) {
                    unitMap.put(c.getMatchColumn(), unit.get(c.getActualColumn()));
                }
                if (filterParam.isFilter()) {
                    unitMap.put(filterParam.getKeyColumn(), filterParam.canMark(unit, filterParam.getMark()));
                }
                unitMapArr[seq - 1] = unitMap;
            }

            if (filterParam.isFillBlank()) {
                for (int i = 0; i < filterParam.getSlotCount(); i++) {
                    if (unitMapArr[i] == null) {
                        Map<String, Object> unitMap = new HashMap<>();
                        unitMap.put(filterParam.getSeqColumn(), i + 1);
                        for (FilterParam.Column c : strStrList) {
                            unitMap.put(c.getMatchColumn(), StringUtils.EMPTY);
                        }
                        unitMapArr[i] = unitMap;
                    }
                }
            }

            List list = Arrays.stream(unitMapArr).filter(Objects::nonNull).collect(Collectors.toList());
            if (String.class.isAssignableFrom(filterParam.getOutType())) {
                return (T) JsonUtils.toString(list);
            } else if (List.class.isAssignableFrom(filterParam.getOutType())) {
                return (T) list;
            } else {
                return null;
            }
        }

        private SortJobBean querySortJobBySourceAndTargetCarrierRrn(long sourceCarrierRrn, long targetCarrierRrn) {
            SortJobBean sortJobBean = new SortJobBean();
            //目前的业务存储能够通过sourceCarrierRrn和targetCarrierRrn确定一个唯一的SorterJob
            long mainJobRrn = sorterDAO.querySorterJobRrnBySourceAndTargetCarrierRrn(sourceCarrierRrn, targetCarrierRrn);
            if (mainJobRrn > 0) {
                sortJobBean = dealSorterData(mainJobRrn);
            }
            return sortJobBean;
        }

        private SortJobBean dealSorterData(long mainJobRrn) {
            SortJobBean sortJobBean = getSortJob(new SortJobBean(mainJobRrn));
            List<SorterBean> sorterBeans = sortJobBean.getSorterBeans();
            SorterBean sb1 = SorterEnum.getListFirst(sorterBeans);
            sortJobBean.setSourceCarrierId(sb1.getSourceCarrierId());
            sortJobBean.setTargetCarrierId(sb1.getTargetCarrierId());
            if (sorterBeans.size() > 1) {
                sortJobBean.setTargetCarrierId2(sorterBeans.get(1).getTargetCarrierId());
            }
            sortJobBean.setJobType(sb1.getJobType());
            sortJobBean.setStatus(sb1.getStatus());
            sortJobBean.setSorterBeans(sorterBeans);
            return sortJobBean;
        }

        @Override
        public String getFlipTypeByLot(Lot lot) {
            String flipType = StringUtils.EMPTY;
            if (RunCardUtils.checkLotIdIsRunCardLot(lot.getLotId())) {
                LotRunCardStore lotStore = runCardQueryManager.getSplitRunCardLotStore(lot.getLotRrn());
                Long lotSpecialStepRrn = lotStore.getLotSpecialStepRrn();
                SRCLotSpecialStep lotSpecialStep = runCardQueryManager
                        .getLotSplitRunCardSpecialStep(lotSpecialStepRrn, lotStore.getStepSequence());
                flipType = lotSpecialStep.getFlipType();
            } else {
                flipType = processSpecItemManager.getFlipType(lot.getProcessRrn(), lot.getProcessVersion(), lot.getRouteRrn(),
                                                              lot.getOperationRrn());
            }
            return flipType;
        }

        @Override
        public List<SorterCarrierMap> getSorterCarrierMapList(Long subJobRrn) {
            return sorterQueryDAO.getSorterCarrierMapList(subJobRrn);
        }

    }