package com.persagy.proxy.dictionary.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.persagy.dmp.basic.model.QueryCriteria;
import com.persagy.dmp.delivery.entity.ObjectInfoCollect;
import com.persagy.proxy.adm.constant.AdmDictConstant;
import com.persagy.proxy.adm.constant.AdmDictCategoryEnum;
import com.persagy.proxy.adm.request.AdmCreateRequest;
import com.persagy.proxy.adm.request.AdmDictQueryCriteria;
import com.persagy.proxy.adm.request.AdmQueryCriteria;
import com.persagy.proxy.adm.request.AdmResponse;
import com.persagy.proxy.dictionary.model.*;
import com.persagy.proxy.dictionary.service.IAdmDictService;
import com.persagy.proxy.common.entity.InstanceUrlParam;
import com.persagy.proxy.object.model.*;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * @ClassName AdmDictServiceImpl
 * @Description: 字典查询
 * @Author linhuili
 * @Date 2021/8/31 18:21
 * @Version V1.0
 **/
@Slf4j
@Service
@EqualsAndHashCode(callSuper=true)
public class AdmDictServiceImpl<T> extends AbstractAdmDictBaseServiceImpl<T> implements IAdmDictService<T> {

    /**
     * 字典类型查询:所有设备类型、部件类型、系统类型、专业类型
     * 查询类型：输入设备类型：equipment，输入部件类型：component,输入系统类型：system,输入专业类型：major,业务空间类型 space ,资产 property,
     *         专业和系统：majorSystem（树）,设备和部件equipmentAndComponent,设备类型要以及对应的部件equipmentComponent(树)，
     *         专业下的设备类型 majorEquipment （树），专业下的系统，系统下的设备majorSystemEquip （树）,systemEquip 系统下的设备类（树）
     * @param request
     * @return
     * @throws Exception
     */
    @Override
    public AdmResponse queryCategory(InstanceUrlParam context , AdmDict request, Class<T> clazz) {
        String type = request.getType();
        QueryCriteria criteria = new QueryCriteria();
        ObjectNode node = JsonNodeFactory.instance.objectNode();
        if(AdmDictCategoryEnum.MAJOR.getValue().equals(type)){
            //查询专业分类
            node.put("type",AdmDictCategoryEnum.MAJOR.getValue());
            criteria.setCriteria(node);
            return doQueryDictData(context, criteria, clazz);
        }

        List<String> baseCategory = getDictBaseCategory();
        if(baseCategory.contains(type)){
            //查询设备类型：equipment，部件类型：component,输入系统类型：system,输入专业类型：major,业务空间类型 space ,资产 property
            node.put("objType",type);
            criteria.setCriteria(node);
            return doQueryObjectType(context, criteria, clazz);
        }

        if(AdmDictCategoryEnum.EQUIPMENT_AND_COMPONENT.getValue().equals(type)){
            //查询设备类型：equipment，部件类型：component,输入系统类型：system,输入专业类型：major,业务空间类型 space ,资产 property
            ArrayNode arrayNode = node.putObject("objType").putArray("$in");
            arrayNode.add(AdmDictCategoryEnum.COMPONENT.getValue());
            arrayNode.add(AdmDictCategoryEnum.EQUIPMENT.getValue());
            criteria.setCriteria(node);
            return doQueryObjectType(context, criteria, clazz);
        }
        List<String> dictTreeCategory = getDictTreeCategory();
        if(dictTreeCategory.contains(type)){
            //查询树形结构：专业和系统：majorSystem（树）,设备类型要以及对应的部件equipmentComponent(树)，专业下的设备类型 majorEquipment（树），
            //专业下的系统，系统下的设备majorSystemEquip （树）,systemEquip 系统下的设备类（树）
            return queryDictObjectTypeTree(context ,type,clazz);
        }
        return null;
    }


    /**
     * 查询字典树
     * @param context
     * @param type
     * @param clazz
     */
    private AdmResponse queryDictObjectTypeTree(InstanceUrlParam context ,String type, Class<T> clazz){
        //查询所有的专业
        List<AdmObjectType> allMajor = getAllMajor(context, clazz);

        //查询所有的类型
        AdmResponse admResponse = doQueryObjectType(context, new QueryCriteria(), clazz);
        List<AdmObjectType> objectTypes = (List<AdmObjectType>) admResponse.getContent();
        Map<String, List<AdmObjectType>> objectTypeMap = objectTypes.stream().filter(k-> StringUtils.isNotEmpty(k.getObjType()))
                .collect(Collectors.groupingBy(AdmObjectType::getObjType));
        //获取专业-设备类关系
        List<AdmObjectType> equipments = objectTypeMap.get(AdmDictCategoryEnum.EQUIPMENT.getValue());
        Map<String,List<AdmObjectType>> majorEquipMap = equipments.stream().filter(k->StringUtils.isNotEmpty(k.getMajorCode()))
                .collect(Collectors.groupingBy(item -> item.getMajorCode()));

        //获取专业-系统类关系
        List<AdmObjectType> systems = objectTypeMap.get(AdmDictCategoryEnum.SYSTEM.getValue());
        Map<String, List<AdmObjectType>> majorSystemMap = systems.stream().filter(k->StringUtils.isNotEmpty(k.getMajorCode())).collect(Collectors.groupingBy(item -> item.getMajorCode()));

        //获取系统-设备类关系
        Map<String, List<AdmObjectType>> systemEquipMap = equipments.stream().filter(k->StringUtils.isNotEmpty(k.getSystemCode())).collect(Collectors.groupingBy(item -> item.getSystemCode()));

        //获取设备类-部件关系
        List<AdmObjectType> components = objectTypeMap.get(AdmDictCategoryEnum.COMPONENT.getValue());
        Map<String, List<AdmObjectType>> equipComponentMap = components.stream().filter(k->StringUtils.isNotEmpty(k.getEquipmentCode())).collect(Collectors.groupingBy(item -> item.getEquipmentCode()));

        List<AdmObjectType> content = new ArrayList<>();
        if(AdmDictCategoryEnum.MAJOR_SYSTEM.getValue().equals(type)){
            //查询专业下的系统
            content = buildDictTree(allMajor,majorSystemMap,null);
        }
        if(AdmDictCategoryEnum.SYSTEM_EQUIP.getValue().equals(type)){
            //查询系统下的设备类
            content = buildDictTree(systems,systemEquipMap,null);
        }
        if(AdmDictCategoryEnum.MAJOR_SYSTEM_EQUIP.getValue().equals(type)){
            //专业下的系统，系统下的设备
            content = buildDictTree(allMajor,majorSystemMap,systemEquipMap);
        }
        if(AdmDictCategoryEnum.MAJOR_EQUIPMENT.getValue().equals(type)){
            //查询专业下的设备类
            content = buildDictTree(allMajor,majorEquipMap,null);
        }
        if(AdmDictCategoryEnum.EQUIPMENT_COMPONENT.getValue().equals(type)){
            //查询设备类下的部件
            content = buildDictTree(equipments,equipComponentMap,null);
        }
        // 设置返回值
        AdmResponse response = AdmResponse.success(content);
        response.setTotal(Long.valueOf(content.size()));
        return response;
    }

    /**
     * 构建专业-系统-设备类树形结构
     * @param allMajor
     * @param majorSystemMap
     * @param systemEquipMap
     * @return
     */
    private ArrayList<AdmObjectType> buildDictTree(List<AdmObjectType> allMajor,Map<String, List<AdmObjectType>> majorSystemMap,Map<String, List<AdmObjectType>> systemEquipMap){
        ArrayList<AdmObjectType> result = new ArrayList<>();
        if(CollUtil.isEmpty(allMajor)){
            return result;
        }
        //构建专业-系统-设备类树形结构
        for (AdmObjectType major : allMajor) {
            //设置专业
            if(CollUtil.isNotEmpty(majorSystemMap)){
                if("system".equals(major) || "equipment".equals(major)){
                    continue;
                }
                //专业下的系统
                List<AdmObjectType> systemCodes = majorSystemMap.get(major.getCode());
                if(CollUtil.isEmpty(systemCodes)){
                    major.setChildren(new ArrayList<>());
                }else{
                    major.setChildren(systemCodes);
                }
                
                //系统下的设备类
                if(CollUtil.isNotEmpty(systemEquipMap) && CollUtil.isNotEmpty(systemCodes)){
                    for (AdmObjectType systemType : systemCodes) {
                        if("system".equals(systemType) || "equipment".equals(systemType)){
                            continue;
                        }
                        List<AdmObjectType> systems = systemEquipMap.get(systemType.getCode());
                        if(CollUtil.isEmpty(systems)){
                            systemType.setChildren(new ArrayList<>());
                        }else {
                            systemType.setChildren(systemEquipMap.get(systemType.getCode()));
                        }
                    }
                }
            }
            result.add(major);
        }
        return result;
    }

    /**
     * 获取所有的专业
     * @param context
     * @param clazz
     * @return
     */
    private List<AdmObjectType> getAllMajor(InstanceUrlParam context, Class<T> clazz){
        //查询专业分类
        QueryCriteria criteria = new QueryCriteria();
        ObjectNode node = JsonNodeFactory.instance.objectNode();
        node.put("type",AdmDictCategoryEnum.MAJOR.getValue());
        criteria.setCriteria(node);
        AdmResponse admResponse = doQueryDictData(context, criteria, clazz);
        List<AdmObjectType> content = (List<AdmObjectType>) admResponse.getContent();
        return content;
    }

    /**
     * 基础数据类型
     * @return
     */
    private List<String> getDictBaseCategory(){
        List<String> category = new ArrayList<>();
        category.add(AdmDictCategoryEnum.EQUIPMENT.getValue());
        category.add(AdmDictCategoryEnum.COMPONENT.getValue());
        category.add(AdmDictCategoryEnum.SYSTEM.getValue());
        category.add(AdmDictCategoryEnum.SPACE.getValue());
        category.add(AdmDictCategoryEnum.PROPRTY.getValue());
        return category;
    }

    /**
     * 查询字典树形结构
     * @return
     */
    private List<String> getDictTreeCategory(){
        List<String> category = new ArrayList<>();
        category.add(AdmDictCategoryEnum.MAJOR_SYSTEM.getValue());
        category.add(AdmDictCategoryEnum.MAJOR_EQUIPMENT.getValue());
        category.add(AdmDictCategoryEnum.MAJOR_SYSTEM_EQUIP.getValue());
        category.add(AdmDictCategoryEnum.EQUIPMENT_COMPONENT.getValue());
        category.add(AdmDictCategoryEnum.SYSTEM_EQUIP.getValue());
        return category;
    }

    /**
     * 重置项目下的信息点
     * @param context
     * @param clazz
     * @return
     * @throws Exception
     */
    @Override
    public AdmResponse resetDic(InstanceUrlParam context, AdmDictQueryCriteria request, String fieldName, Class<T> clazz) throws Exception {

        //查询项目下点所有信息点
        AdmResponse admResponse = doQueryObjectInfo(context, request, fieldName, clazz);
        List<AdmObjectInfo> content = (List<AdmObjectInfo>) admResponse.getContent();
        if(CollUtil.isEmpty(content)){
            AdmResponse response = AdmResponse.success(new ArrayList<>());
            response.setTotal(Long.valueOf(0));
            return response;
        }
        //因BDTP根据项目查询信息点时返回的包含集团+通用信息点，需手动过滤除项目级的信息点
        String projectId = context.getProjectId();

        Iterator<AdmObjectInfo> infoIterator = content.iterator();
        while (infoIterator.hasNext()){
            String admProjectId = infoIterator.next().getProjectId();
            if(StringUtils.isEmpty(admProjectId) || !projectId.equals(admProjectId)){
                infoIterator.remove();
            }
        }
        //删除信息点
        doDeleteObjectInfo(context,(List<T>)content);
        // 设置返回值
        AdmResponse response = AdmResponse.success(content);
        response.setTotal(Long.valueOf(content.size()));
        return response;
    }

    /**
     * 设置-项目定制化字典
     * @param context
     * @param request
     * @param clazz
     * @return
     * @throws Exception
     */
    @Override
    public AdmResponse settingDicProject(InstanceUrlParam context, AdmCreateRequest<AdmDefFuncIdGather> request, Class<T> clazz) throws Exception {
        List<AdmDefFuncIdGather> content = request.getContent();
        if(CollUtil.isEmpty(content)){
            return AdmResponse.success(content);
        }
        //参数转换为中台参数
        List<T> list = new ArrayList<>();
        for (AdmDefFuncIdGather funcIdGather : content) {
            ObjectInfoCollect infoCollect = new ObjectInfoCollect();

            if(StringUtils.isNotEmpty(funcIdGather.getType()) && "common".equals(funcIdGather.getType())){
                infoCollect.setGroupCode("0");
                infoCollect.setProjectId("0");
            }else{
                infoCollect.setGroupCode(context.getGroupCode());
                infoCollect.setProjectId(context.getProjectId());
            }
            infoCollect.setDefineInfoId(funcIdGather.getId());
            infoCollect.setClassCode(funcIdGather.getClassCode());
            infoCollect.setCode(funcIdGather.getCode());
            //infoCollect.setVisiable(funcIdGather.getVisible());
            infoCollect.setKeyWord(funcIdGather.getKeyWord());
            list.add((T) infoCollect);
        }
        //设置采集信息点
        doSetObjectInfoCollect(context, clazz, list);
        return AdmResponse.success(content);
    }

    /**
     * 查询所有字典信息 M 和 L 类型,包括自定义信息点
     * @param context
     * @param dictTypeList
     * @return
     */
    @Override
    public AdmResponse queryMorlDict(InstanceUrlParam context, List<String> dictTypeList) {

        List<AdmObjectInfo> result = new ArrayList<>();
        for (String type : dictTypeList) {
            List<String> classCodes = new ArrayList<>();
            String name = null;
            //项目
            if(AdmDictCategoryEnum.PROJECT.getValue().equals(type)){
                name = AdmDictCategoryEnum.PROJECT.getDesc();
                classCodes.add(AdmDictCategoryEnum.PROJECT.getValue());
            }
            //建筑
            if(AdmDictCategoryEnum.BUILDING.getValue().equals(type)){
                name = AdmDictCategoryEnum.BUILDING.getDesc();
                classCodes.add(AdmDictCategoryEnum.BUILDING.getValue());
            }
            //楼层
            if(AdmDictCategoryEnum.FLOOR.getValue().equals(type)){
                name = AdmDictCategoryEnum.FLOOR.getDesc();
                classCodes.add(AdmDictCategoryEnum.FLOOR.getValue());
            }
            //设备
            if(AdmDictCategoryEnum.EQUIPMENT.getValue().equals(type)){
                name = AdmDictCategoryEnum.EQUIPMENT.getDesc();
                classCodes.addAll(queryDefClassType(context, AdmDictCategoryEnum.EQUIPMENT.getValue()));
            }
            //部件
            if(AdmDictCategoryEnum.COMPONENT.getValue().equals(type)){
                name = AdmDictCategoryEnum.COMPONENT.getDesc();
                classCodes.addAll(queryDefClassType(context, AdmDictCategoryEnum.COMPONENT.getValue()));
            }
            //系统
            if(AdmDictCategoryEnum.SYSTEM.getValue().equals(type)){
                name = AdmDictCategoryEnum.SYSTEM.getDesc();
                classCodes.addAll(queryDefClassType(context, AdmDictCategoryEnum.SYSTEM.getValue()));
            }
            //空间
            if(AdmDictCategoryEnum.SPACE.getValue().equals(type)){
                name = AdmDictCategoryEnum.SPACE.getDesc();
                classCodes.addAll(queryDefClassType(context, AdmDictCategoryEnum.SPACE.getValue()));
            }
            //查询类型下的信息点
            statisticObjectInfo(context,type, name, classCodes,result);
        }
        AdmResponse response = AdmResponse.success(result);
        response.setTotal(Long.valueOf(result.size()));
        return response;
    }


    /**
     * 查询信息点
     * @param context
     * @param request
     * @param fieldName
     * @param clazz
     * @return
     */
    @Override
    public AdmResponse query(InstanceUrlParam context, AdmDictQueryCriteria request, String fieldName, Class<T> clazz) {
        //转换排序字段
        revertSortField(request);
        //查询类型下的所有信息点信息
        AdmResponse admResponse = doQueryObjectInfo(context, request, AdmDictConstant.CLASS_CODE, clazz);
        List<AdmObjectInfo> admObjectInfos = (List<AdmObjectInfo>) admResponse.getContent();
        admObjectInfos = sortFuncidForEdit(admObjectInfos);
        //查询平台级信息点采集信息
        List<ObjectInfoCollect> commonObjectInfoCollect = queryObjectInfoCollect(context, "common", request.getType(), clazz);
        Map<String, ObjectInfoCollect> commonObjectInfoCollectMap = new HashMap<>();
        for(int i = 0,j = CollUtil.size(commonObjectInfoCollect);i < j;i++) {
            ObjectInfoCollect collect = commonObjectInfoCollect.get(i);
            if(StrUtil.isBlank(collect.getDefineInfoId())) {
                continue;
            }
            commonObjectInfoCollectMap.put(collect.getDefineInfoId(),collect);
        }
        //查询项目级信息点采集信息
        List<ObjectInfoCollect> projectObjectInfoCollect = queryObjectInfoCollect(context, "project", request.getType(), clazz);
        Map<String, ObjectInfoCollect> projectObjectInfoCollectMap  = new HashMap<>();
        for(int i = 0,j = CollUtil.size(projectObjectInfoCollect);i < j;i++) {
            ObjectInfoCollect collect = projectObjectInfoCollect.get(i);
            if(StrUtil.isBlank(collect.getDefineInfoId())) {
                continue;
            }
            projectObjectInfoCollectMap.put(collect.getDefineInfoId(),collect);
        }
        String dictType = request.getDictType();

        //采集值配置查询
        if(StringUtils.isNotEmpty(dictType)){
            //查询平台级、项目级信息点采集信息
            if("common".equals(dictType)){
                setObjectInfoVisiable(admObjectInfos,commonObjectInfoCollectMap,dictType);
            }
            if("project".equals(dictType)){
                setObjectInfoVisiable(admObjectInfos,projectObjectInfoCollectMap,dictType);
            }
            admResponse.setContent(admObjectInfos);
            return admResponse;
        }

        //只查看采集值 todo
        if(CollUtil.isNotEmpty(projectObjectInfoCollectMap)){
            setOnlyQueryObjectInfoVisiable(admObjectInfos,projectObjectInfoCollectMap,dictType);
        }else{
            setOnlyQueryObjectInfoVisiable(admObjectInfos,commonObjectInfoCollectMap,dictType);
        }
        admResponse.setContent(admObjectInfos);
        return admResponse;
    }

    /**
     * 转换排序字段
     * @param request
     */
    private void revertSortField(AdmDictQueryCriteria request){
     request.setOrders("showOrder asc, name desc");
    }

    /**
     * 设置信息点是否可见
     * @param admObjectInfos
     * @param objectInfoCollectMap
     */
    private void setObjectInfoVisiable(List<AdmObjectInfo> admObjectInfos,Map<String, ObjectInfoCollect> objectInfoCollectMap,String dictType){
        if(CollUtil.isEmpty(admObjectInfos)){
            return;
        }
        for (AdmObjectInfo admObjectInfo : admObjectInfos) {
            Boolean visiable = null;
            String id = admObjectInfo.getId();
            if(CollUtil.isNotEmpty(objectInfoCollectMap)){
                ObjectInfoCollect collect = objectInfoCollectMap.get(id);
                if(collect != null){
                    //visiable = collect.getVisiable();
                    admObjectInfo.setKeyWord(collect.getKeyWord());
                }
            }
            if(visiable == null){
                if("common".equals(dictType)){
                    if("localId".equals(admObjectInfo.getCode()) || "localName".equals(admObjectInfo.getCode())){
                        visiable = true;
                    }
                }
                if(visiable == null){
                    visiable =false;
                }
            }
            admObjectInfo.setVisible(visiable);
            admObjectInfo.setEditable(true);
            admObjectInfo.setUnDisabled(true);
            if(admObjectInfo.getKeyWord() == null){
                admObjectInfo.setKeyWord(false);
            }
        }
    }


    /**
     * 设置台账管理中只查看采集值的信息点是否可见
     * @param admObjectInfos
     * @param objectInfoCollectMap
     */
    private void setOnlyQueryObjectInfoVisiable(List<AdmObjectInfo> admObjectInfos,Map<String, ObjectInfoCollect> objectInfoCollectMap,String dictType){
        if(CollUtil.isEmpty(admObjectInfos)){
            return;
        }
        for (AdmObjectInfo admObjectInfo : admObjectInfos) {
            Boolean visiable = null;
            String id = admObjectInfo.getId();
            //设置信息点是否可见
            if(CollUtil.isNotEmpty(objectInfoCollectMap)){
                ObjectInfoCollect collect = objectInfoCollectMap.get(id);
                if(collect!=null){
                    //visiable = collect.getVisiable();
                    admObjectInfo.setKeyWord(collect.getKeyWord());
                }
            }
            if(visiable == null && ("localId".equals(admObjectInfo.getCode()) || "localName".equals(admObjectInfo.getCode()))){
                visiable = true;
            }
            if(visiable == null){
                visiable = false;
            }
            //信息点是否可编辑设置默认值
            if(admObjectInfo.getEditable() == null){
                List<String> unEditableList = checkoutDefInfoUnEditable();
                if(unEditableList.contains(admObjectInfo.getCode())){
                    admObjectInfo.setEditable(false);
                }else {
                    admObjectInfo.setEditable(true);
                }
            }
            //是否禁止操作设置默认值
            if(admObjectInfo.getUnDisabled() == null){
                List<String> unDisableList = checkoutDefInfoUnDisable();
                if(unDisableList.contains(admObjectInfo.getCode())){
                    admObjectInfo.setUnDisabled(false);
                }else {
                    admObjectInfo.setUnDisabled(true);
                }
            }
            if(admObjectInfo.getKeyWord() == null){
                admObjectInfo.setKeyWord(false);
            }
            admObjectInfo.setVisible(visiable);
        }
    }


    /**
     * 校验信息点是否可编辑
     * @return
     */
    public List<String> checkoutDefInfoUnEditable(){
        List<String> list = new ArrayList<>();
        list.add("id");
        list.add("name");
        list.add("qRCodePic");
        list.add("defaultQRCode");
        list.add("bimId");
        list.add("bimFamilyName");
        list.add("bimFamilySymbol");
        list.add("floorId");
        list.add("buildingId");
        list.add("state");
        return list;
    }

    /**
     * 校验信息点是否禁止使用
     * @return
     */
    public List<String> checkoutDefInfoUnDisable(){
        List<String> list = new ArrayList<>();
        list.add("id");
        list.add("name");
        list.add("localId");
        list.add("localName");
        list.add("qRCodePic");
        list.add("defaultQRCode");
        list.add("bimId");
        list.add("bimFamilyName");
        list.add("bimFamilySymbol");
        list.add("floorId");
        list.add("buildingId");
        list.add("state");
        return list;
    }
    /**
     * 查询信息点采集信息
     * @param context
     * @param dictType
     * @param classCode
     * @param clazz
     * @return
     */
    private List<ObjectInfoCollect> queryObjectInfoCollect(InstanceUrlParam context, String dictType,String classCode, Class<T> clazz){
        AdmQueryCriteria criteria = new AdmQueryCriteria();
        if("common".equals(dictType)){
            criteria.setFilters("groupCode = '0' and projectId = '0'");
        }else{
            criteria.setFilters("groupCode = '"+context.getGroupCode()+"' and projectId = '"+context.getProjectId()+"'");
        }
        criteria.setName(classCode);
        AdmResponse admResponse = doQueryObjectInfoCollect(context, criteria, "classCode", clazz);
        return (List<ObjectInfoCollect>) admResponse.getContent();
    }

    private List<AdmObjectInfo> sortFuncidForEdit(List<AdmObjectInfo> list) {
        List<AdmObjectInfo> resultOrders = new ArrayList<>();
        List<AdmObjectInfo> defaultOrders = new ArrayList<>();
        for (AdmObjectInfo admObjectInfo : list) {
            if(admObjectInfo.getSort()!=null){
                resultOrders.add(admObjectInfo);
            }else{
                defaultOrders.add(admObjectInfo);
            }
        }
        if(CollUtil.isNotEmpty(defaultOrders)){
            resultOrders.addAll(defaultOrders);
        }
        return resultOrders;
    }

    /**
     * 统计类型下的非静态信息点
     * @param context
     * @param code
     * @param name
     * @param result
     */
    private void statisticObjectInfo(InstanceUrlParam context,String code,String name,List<String> classCode,List<AdmObjectInfo> result){
        //根据类型查询信息点
        AdmQueryCriteria criteria = new AdmQueryCriteria();
        StringBuilder stringBuilder = new StringBuilder();
        classCode.stream().forEach(item -> {
            stringBuilder.append("'").append(item).append("'").append(",");
        });
        String filters = StrUtil.sub(stringBuilder.toString(),0, -1);
        criteria.setFilters("classCode in ["+filters+"]");
        AdmResponse response = doQueryObjectInfo(context, criteria, AdmDictConstant.CLASS_CODE, (Class<T>) AdmObjectInfo.class);
        List<AdmObjectInfo> content = (List<AdmObjectInfo>) response.getContent();
        if(CollUtil.isEmpty(content)){
            return ;
        }
        //过滤不需要的信息点
        Iterator<AdmObjectInfo> iterator = content.iterator();
        while (iterator.hasNext()){
            AdmObjectInfo objectInfo = iterator.next();
            if(StringUtils.isNotEmpty(objectInfo.getCategory()) && "STATIC".equals(objectInfo.getCategory())){
                iterator.remove();
            }
        }
        //返回结果拼装
        AdmObjectInfo admObjectInfo = new AdmObjectInfo();
        admObjectInfo.setCode(code);
        admObjectInfo.setName(name);
        admObjectInfo.setContent(content);
        result.add(admObjectInfo);
    }


    /**
     * 查询对象类型
     * @param context
     * @param code
     * @return
     */
    private List<String> queryDefClassType(InstanceUrlParam context,String code){
        QueryCriteria criteria = new QueryCriteria();
        ObjectNode node = JsonNodeFactory.instance.objectNode();
        node.put("parentCode",code);
        criteria.setCriteria(node);

        AdmResponse response = doQueryObjectType(context, criteria, (Class<T>) AdmObjectType.class);
        List<AdmObjectType> content = (List<AdmObjectType>) response.getContent();
        if(CollUtil.isEmpty(content)){
            return new ArrayList<>();
        }
        return content.stream().map(AdmObjectType::getCode).collect(Collectors.toList());
    }


    /**
     * 信息点转换为中台格式
     * @param content
     * @param dmpObjectInfos
     */
    private void objectInfosTransforDmp(List<AdmObjectInfo> content,List<AdmObjectInfo> dmpObjectInfos,String projectId){
        if(CollUtil.isEmpty(content)){
            return;
        }
        for (AdmObjectInfo admObjectInfo : content) {
            admObjectInfo.setProjectId(projectId);
            if(admObjectInfo.getMultiple() != null){
                admObjectInfo.setIsMultiple(admObjectInfo.getMultiple());
            }
            if(admObjectInfo.getIsRegion() != null){
                admObjectInfo.setIsRegion(admObjectInfo.getRegion());
            }
            if(StringUtils.isNotEmpty(admObjectInfo.getFirstName())){
                admObjectInfo.setFirstTag(admObjectInfo.getFirstName());
            }
            if(StringUtils.isNotEmpty(admObjectInfo.getSecondName())){
                admObjectInfo.setSecondTag(admObjectInfo.getSecondName());
            }
            admObjectInfo.setType(null);
            dmpObjectInfos.add(admObjectInfo);
            //处理子级
            List<AdmObjectInfo> sencondContent = admObjectInfo.getContent();
            if(CollUtil.isNotEmpty(sencondContent)){
                objectInfosTransforDmp(sencondContent,dmpObjectInfos,projectId);
            }
        }
    }

    /**
     * 查询已交付信息点
     * @param request
     * @return
     */
    @Override
    public Map<String, AdmObjectInfo> queryDictDeliveredInfos(InstanceUrlParam context, AdmDictDeliverieInfosRequest request, Class<T> clazz) {
        String classCode = request.getClassCode();
        String objType = request.getObjType();
        //根据类型查询信息点
        List<AdmObjectInfo> admObjectInfos = queryObjectInfoByType(context, objType, classCode, clazz);
        if(CollUtil.isEmpty(admObjectInfos)){
            log.info("此类型下无信息点:{}{}"+objType +","+classCode);
            return new HashMap<>();
        }
        return admObjectInfos.stream().collect(Collectors.toMap(AdmObjectInfo::getCode, Function.identity(),(v1,v2) -> v2));
    }

    /**
     * 组装通用对象查询条件
     * @param request
     * @return
     */
    @Override
    public AdmQueryCriteria commbineObjectQueryCriteria(AdmDictDeliverieInfosRequest request){
        //增加过滤条件
        StringBuilder filters = new StringBuilder();
        if(StringUtils.isNotEmpty(request.getBuildingId())){
            if("isNull".equals(request.getBuildingId())){
                filters.append("buildingId isNull;");
            }else {
                filters.append("buildingId = '"+ request.getBuildingId() +"';");
            }
        }
        if(StringUtils.isNotEmpty(request.getFloorId())){
            if("isNull".equals(request.getFloorId())){
                filters.append("floorId isNull;");
            }else{
                filters.append("floorId = '"+ request.getFloorId() +"';");
            }
        }
        if(StringUtils.isNotEmpty(request.getClassCode())){
            filters.append("classCode = '"+ request.getClassCode() +"';");
        }
        if(StringUtils.isNotEmpty(request.getObjType())){
            filters.append("objType = '"+ request.getObjType() +"';");
        }
        AdmQueryCriteria equipQueryCriteria = new AdmQueryCriteria();
        equipQueryCriteria.setFilters(filters.toString());
        return equipQueryCriteria;
    }

    /**
     * 初始化待交付的信息点
     * @param admObjectInfoMap
     * @param deliveredInfos
     * @param deliveredCodes
     */
    @Override
    public void initDeliveredInfos(Map<String, AdmObjectInfo> admObjectInfoMap,List<AdmObjectInfo> deliveredInfos,List<String> deliveredCodes){
        deliveredCodes.add("id");
        deliveredCodes.add("name");
        deliveredCodes.add("localId");
        deliveredCodes.add("localName");
        //初始化待交付的信息点，id，name，localId，localName 默认展示
        for (String code : deliveredCodes) {
            AdmObjectInfo admObjectInfo = admObjectInfoMap.get(code);
            if(admObjectInfo != null){
                deliveredInfos.add(admObjectInfo);
            }
        }
    }

    /**
     * 根据类型查询信息点（包含信息点是否可见，是否可编辑，是否为采集信息点）
     * @param context
     * @param objType
     * @param classCode
     * @param clazz
     * @return
     */
    private List<AdmObjectInfo> queryObjectInfoByType(InstanceUrlParam context,String objType,String classCode,Class<T> clazz){
       /* AdmQueryCriteria queryCriteria = new AdmQueryCriteria();
        String filters ="classCode = '"+classCode+"'";
        queryCriteria.setFilters(filters);
        AdmResponse admResponse = doQueryObjectInfo(context, queryCriteria, AdmDictConstant.CLASS_CODE, clazz);*/
        AdmDictQueryCriteria request = new AdmDictQueryCriteria();
        request.setName(classCode);
        AdmResponse admResponse = query(context, request, AdmDictConstant.CLASS_CODE, clazz);
        return (List<AdmObjectInfo>) admResponse.getContent();
    }

}
