package com.yeejoin.equipmanage.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.dto.OrgMenuDto;
import com.yeejoin.amos.boot.biz.common.excel.ExcelUtil;
import com.yeejoin.amos.boot.biz.common.utils.SnowFlakeGenerateIdWorker;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.component.feign.utils.FeignUtil;
import com.yeejoin.amos.feign.morphic.Morphic;
import com.yeejoin.amos.feign.morphic.model.ResourceDTO;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.DictionarieValueModel;
import com.yeejoin.equipmanage.common.dto.BuildingImportDto;
import com.yeejoin.equipmanage.common.dto.OrgUsrDto;
import com.yeejoin.equipmanage.common.entity.*;
import com.yeejoin.equipmanage.common.entity.dto.BuildIsRiskDTO;
import com.yeejoin.equipmanage.common.entity.dto.BuildSearchDTO;
import com.yeejoin.equipmanage.common.entity.vo.*;
import com.yeejoin.equipmanage.common.enums.GroupCodeEnum;
import com.yeejoin.equipmanage.common.enums.GroupTypeEnum;
import com.yeejoin.equipmanage.common.enums.IndustryEnum;
import com.yeejoin.equipmanage.common.enums.IsIotEnum;
import com.yeejoin.equipmanage.common.utils.CommonResponseUtil;
import com.yeejoin.equipmanage.common.utils.EnumsUtils;
import com.yeejoin.equipmanage.common.utils.StringUtil;
import com.yeejoin.equipmanage.common.vo.AlarmDataVO;
import com.yeejoin.equipmanage.common.vo.BuildingTreeAndEquipVO;
import com.yeejoin.equipmanage.common.vo.BuildingTreeVo;
import com.yeejoin.equipmanage.context.SpringContextHolder;
import com.yeejoin.equipmanage.event.SyncRiskEvent;
import com.yeejoin.equipmanage.fegin.JcsFeign;
import com.yeejoin.equipmanage.mapper.*;
import com.yeejoin.equipmanage.operation.GroupTypeOperator;
import com.yeejoin.equipmanage.operation.PageOperation;
import com.yeejoin.equipmanage.operation.SyncRiskOperator;
import com.yeejoin.equipmanage.operation.factory.PageOperatorFactory;
import com.yeejoin.equipmanage.remote.RemoteSecurityService;
import com.yeejoin.equipmanage.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;
import org.typroject.tyboot.core.foundation.exception.BaseException;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author ZeHua Li
 * @date 2020/11/12 15:48
 * @since v2.0
 */
@Slf4j
@Service
public class BuildingServiceImpl extends ServiceImpl<BuildingMapper, Building> implements IBuilldService {

    @Autowired
    ISystemDicService systemDicService;

    @Autowired
    private IFormGroupService iFormGroupService;

    @Autowired
    IWarehouseService iWarehouseService;

    @Autowired
    private IEqSourceFileService iEqSourceFileService;

    @Autowired
    private RemoteSecurityService remoteSecurityService;

    @Autowired
    private FireFightingSystemServiceImpl fireFightingSystemService;

    @Autowired
    private IFormInstanceService iFormInstanceService;

    @Autowired
    private FormInstanceMapper formInstanceMapper;
    @Autowired
    private JcsFeign jcsFeign;
    @Autowired
    FireFightingSystemMapper fireFightingSystemMapper;

    @Autowired
    IWarehouseStructureService iWarehouseStructureService;

    @Autowired
    EquipmentSpecificMapper equipmentSpecificMapper;

    @Autowired
    StockDetailMapper stockDetailMapper;
    @Autowired
    ISourceSceneService sourceSceneService;

    @Autowired
    IVideoService iVideoService;

    @Value("${morphic.projectSeq}")
    private Long projectSeq;

    @Value("${mqtt.scene.host}")
    private String sceneUrl;

    @Value("${equip.point.equipmentdata.topic}")
    private String wsTopic;

    @Value("${systemctl.dict.allow-operation}")
    private String allowOperation;

    @Value("${systemctl.dict.build-type}")
    private String buildType;

    @Value("${systemctl.dict.build-use-type}")
    private String buildUseType;

    @Value("${systemctl.dict.building-structure-type}")
    private String buildingStructureType;

    @Value("${systemctl.sync.switch}")
    private Boolean syncSwitch;

    @Value("${auth-key-fire-building:fire_building_info}")
    private String authKey;

    @Value("${auth-key-fire-build-video:fire_build_video_info}")
    private String buildVideoAuthKey;

    @Autowired
    private JCSRemoteService jcsRemoteService;
    @Value("${window.vedioFormat}")
    private String vedioFormat;

    @Autowired
    private SourceSceneMapper sourceSceneMapper;

    @Autowired
    VideoMapper videoMapper;

    @Autowired
    EquipmentSpecificRelationMapper equipmentSpecificRelationMapper;

    @Autowired
    private ISyncDataService syncDataService;

    @Autowired
    @Lazy
    private IVideoService videoService;

    @Value("${building.detail}")
    private String address;

    @Value("${building.floor.detail}")
    private String apiUrl;

    @Value("${firefightingsystem.equip.alarms.url}")
    private String ffsEquipAlarmsUrl;

    final String ALL_BUILDING = "allBuilding";

    final static String[] list = {"92031900", "92011000", "92010700"};

    /**
     * @param groupCode
     * @Description 根据groupCode查询allowOperation对应的操作菜单
     * @Return List<DictionarieValueModel>
     * @Date 2020/12/18 10:13
     */
    @Override
    public List<DictionarieValueModel> rightClickMenu(String groupCode) {
        FeignClientResult<List<DictionarieValueModel>> dictValues = Systemctl.dictionarieClient.dictValues(allowOperation);
        Optional.ofNullable(dictValues).orElseThrow(() -> new BadRequest("查询字段数据为空"));
        log.info("字典数据：{}", dictValues.getResult().toString());
        FormGroup formGroup = iFormGroupService.allowOperationByGroupCode(groupCode);
        String[] array = formGroup.getAllowOperation().split(",");
        List<DictionarieValueModel> values = dictValues.getResult();
        List<DictionarieValueModel> models = new ArrayList<>();
        Arrays.stream(array).forEach(item -> {
            models.addAll(values.stream()
                    .filter(o -> o.getDictDataKey().equals(item))
                    .collect(Collectors.toList()));
        });
        return models;
    }

    @Override
    public Map<String, String> createMorphic(Map<String, String> model) {
        ResourceDTO resourceDTO = new ResourceDTO();
        resourceDTO.setSubjectId(projectSeq);
        resourceDTO.setSubjectid(projectSeq);
        resourceDTO.setName(model.get("name"));
        // 为首次 添加的画布添加mqtt 相关数据
        String content = "{\"layout\":\"\",\"boardConfig\":{\"modeType\":\"custom\",\"orientation\":\"lengthways\",\"autoRefresh\":true,\"name\":\"1\",\"showMode\":\"actual\",\"paperSize\":\"1280X900\"},\"boardStyle\":{\"backgroundImage\":\"\"},\"dataConfig\":{}}";
        Map parse = (Map) JSON.parse(content);
        Map<String, Object> dataConfig = new HashMap<>();
        dataConfig.put("msgType", "mqtt");
        dataConfig.put("wsUrl", sceneUrl);
        dataConfig.put("wsTopic", wsTopic);
        parse.put("dataConfig", dataConfig);
        content = JSONObject.toJSONString(parse);
        resourceDTO.setContent(content);
        ResourceDTO morphic = Morphic.morphicSubjectClient.create(resourceDTO).getResult();
        model.put("sceneId", String.valueOf(morphic.getId()));
//        model.put("id", String.valueOf(System.currentTimeMillis()));
//        model.put("projectId", String.valueOf(projectSeq));
//        model.put("creatorId", userId);
//        this.baseMapper.insetSourceScene(model);
        return model;
    }

    @Override
    @Transactional
    public ResourceDTO updateMorphic(ResourceDTO resourceDTO) {
        try {
            resourceDTO.setSubjectId(projectSeq);
            resourceDTO.setSubjectid(projectSeq);
            String content = resourceDTO.getContent();
            Map parse = (Map) JSON.parse(content);
            Map<String, Object> dataConfig = new HashMap<>();
            dataConfig.put("msgType", "mqtt");
            dataConfig.put("wsUrl", sceneUrl);
            dataConfig.put("wsTopic", wsTopic);
            parse.put("dataConfig", dataConfig);
            content = JSONObject.toJSONString(parse);
            resourceDTO.setContent(content);
            FeignUtil.remoteCall(() -> Morphic.morphicSubjectClient.update(resourceDTO));
            //获取画布id
            Long sceneId = resourceDTO.getId();
            SourceScene sourceScene = sourceSceneMapper.selectOne(new QueryWrapper<SourceScene>().eq("scene_id", sceneId));
            if (sourceScene == null) {
                String userId = remoteSecurityService.getAgencyUser().getUserId();
                Map<String, Object> model = new HashMap<>();
                model.put("sceneId", sceneId);
                model.put("id", String.valueOf(System.currentTimeMillis()));
                model.put("projectId", String.valueOf(projectSeq));
                model.put("creatorId", userId);
                model.put("sourceType", "building");
                model.put("instanceId", resourceDTO.getCode());
                model.put("name", resourceDTO.getName());
                this.baseMapper.insetSourceScene(model);
            }
            //获取画布下 绑定的装备点
            List<Map> children = (List<Map>) parse.get("children");
            String pointInScene = "";
            String videoInScene = "";
            if (!CollectionUtils.isEmpty(children)) {
                for (Map<String, String> map : children) {
                    String key = map.get("key");
                    if (!"".equals(key) && "equipment".equals(key)) {
                        pointInScene = "".equals(pointInScene) ? map.get("sequenceNbr") : pointInScene + "," + map.get("sequenceNbr");
                    }
                    if (!"".equals(key) && "video".equals(key)) {
                        videoInScene = "".equals(videoInScene) ? map.get("sequenceNbr") : videoInScene + "," + map.get("sequenceNbr");
                    }
                }
            }
            this.baseMapper.setSceneId(sceneId, pointInScene, videoInScene);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BadRequest("保存画布失败");
        }
        return resourceDTO;
    }

    @Override
    public Boolean isDeleteCanvas(Long id) {
        SourceScene sourceScene = sourceSceneMapper.selectOne(new QueryWrapper<SourceScene>().eq("scene_id", id));
        if (sourceScene != null) {
            return true;
        } else {
            FeignUtil.remoteCall(() -> Morphic.morphicSubjectClient.delete(id));
            return false;
        }
    }

    @Override
    public List<SourceScene> getScenesList(Long id, String groupType) {
        List<SourceScene> list;
        try {
            if (groupType.equals("room")) {
                // 获取房间绑定关系，如为建筑，返回建筑id，否则返回null
                Long buildingId = this.baseMapper.isBuildingRoom(id);
                if (buildingId != null) {
                    id = buildingId;
                    groupType = "building";
                }
            }
            list = this.baseMapper.getScenesList(id, groupType);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BadRequest("查询失败");
        }
        return list;
    }

    @Override
    public Object saveForm(String groupCode, String companyCode, Map<String, Object> map, String caseId) {
        final String instanceId = "instanceId";
        //1.保存表单数据
        //前端的address中携带了经纬度,后台切割保存
        if (map.containsKey("address") && map.get("address") != null){
            String address = map.get("address").toString();
            String[] addressData = address.split("@address@");
            if (addressData.length > 1) {
                map.put("address",addressData[0]);
                JSONObject langLatObj = JSON.parseObject(addressData[1]);
                if (StringUtils.isNotEmpty(langLatObj.getString("longitude"))) {
                    map.put("longitude",langLatObj.getString("longitude"));
                }
                if (StringUtils.isNotEmpty(langLatObj.getString("latitude"))) {
                    map.put("latitude",langLatObj.getString("latitude"));
                }
            }

//            if (address.contains("@")){
//                String[] addresses = address.split("@");
//                map.put("address",addresses[0]);
//                map.put("longitude",addresses[0]);
//                map.put("latitude",addresses[0]);
//            }
        }

        Map<String, Object> formKeyMap = iFormInstanceService.createByMap(groupCode, companyCode, map, caseId);
        if (StringUtil.isNotEmpty(caseId)) {
            return CommonResponseUtil.success(formKeyMap);
        }
        if (formKeyMap.get(instanceId) != null) {
            //2.保存图片
            this.saveFiles(Long.parseLong(formKeyMap.get("instanceId").toString()), map);
            synWarehouse(formKeyMap);
            // 新增储罐类型，保存不需要风险
            if (!"storageTank".equals(groupCode)) {
                // 发布风险区域同步操作事件
                map.put("instanceId", formKeyMap.get("instanceId"));
                map.put("code", formKeyMap.get("code"));
                map.put("name", formKeyMap.get("name"));
                map.put("companyCode", companyCode);
                SpringContextHolder.publishEvent(new SyncRiskEvent(this, map, SyncRiskOperator.ADD.getType()));
            }
        }
        return formKeyMap;
    }

    private void synWarehouse(Map<String, Object> formKeyMap) {
        String parentId = (String) formKeyMap.get("parentId");
        String stuctureName = formInstanceMapper.getStuctureName(parentId);
        if (StringUtils.isEmpty(stuctureName)){
            formKeyMap.put("address",formKeyMap.get("name"));
        }else {
            formKeyMap.put("address", stuctureName + "-" + formKeyMap.get("name"));
        }
        formInstanceMapper.saveStucture(formKeyMap);

    }

    @Override
    @Transactional(rollbackFor = {Exception.class, BaseException.class})
    public Object updateForm(Long instanceId, String orgCode, Map<String, Object> map, String groupCode) {
        if (StringUtil.isNotEmpty(groupCode)) {
            map.keySet().forEach(x -> {
                formInstanceMapper.updateFormFieldValue(instanceId, x, String.valueOf(map.get(x)));
            });
            return CommonResponseUtil.success();
        }
        Long id = formInstanceMapper.getStructureParentId(String.valueOf(instanceId));
        //1.保存图片
        this.saveFiles(instanceId, map);
        //2.修改仓库对应数据
        String beforFullName = formInstanceMapper.getStuctureName(String.valueOf(instanceId));
        String stuName = formInstanceMapper.getStuName(String.valueOf(instanceId));
        String name = (String) map.get("name");
        String parentId = (String) map.get("parentId");
        String fullName = name;
        String code = (String) map.get("code");
        String parentName = formInstanceMapper.getStuctureName(parentId);
        String bizOrgCode = map.get("bizOrgCode").toString();
        String bizOrgName = map.get("bizOrgName").toString();
        if (!"0".equals(parentId)) {
            fullName = parentName + '-' + name;
        }
        formInstanceMapper.updateStr(instanceId, name, fullName, parentId, code,bizOrgCode,bizOrgName);
        /*若还有子级节点，一起修改*/
        List<Map<String, Object>> result = formInstanceMapper.getParentId(instanceId);
        if (result.size()>0 && result != null){
            result.forEach(e->
            {
               /*    Long  subInstanceId =Long.parseLong(e.get("id").toString());
            	  // Long  subInstanceId =Long.parseLong(e.get("instance_id").toString());
            	  formInstanceMapper.updateFormInstanceByInstanceAndFieldName("bizOrgCode", bizOrgCode, subInstanceId);
                  formInstanceMapper.updateFormInstanceByInstanceAndFieldName("bizOrgName", bizOrgName, subInstanceId);*/
                long id1 = Long.parseLong(e.get("id").toString());
                formInstanceMapper.updateStr(id1 ,e.get("name").toString(),e.get("full_name").toString(),e.get("parent_id").toString(),e.get("code").toString(),bizOrgCode,bizOrgName);
                List<Map<String, Object>> resultSon = formInstanceMapper.getParentId(id1);
                if (resultSon.size()>0&& resultSon != null){
                    resultSon.forEach(r->{
                   /* 	// Long  subInstanceId1 =Long.parseLong(r.get("instance_id").toString());
                        Long  subInstanceId1 =Long.parseLong(e.get("id").toString());

                        formInstanceMapper.updateFormInstanceByInstanceAndFieldName("bizOrgCode", bizOrgCode, subInstanceId1);
                         formInstanceMapper.updateFormInstanceByInstanceAndFieldName("bizOrgName", bizOrgName, subInstanceId1);*/
                        long id2 = Long.parseLong(r.get("id").toString());
                        formInstanceMapper.updateStr(id2 ,r.get("name").toString(),r.get("full_name").toString(),r.get("parent_id").toString(),r.get("code").toString(),bizOrgCode,bizOrgName);
                        List<Map<String, Object>> resultSons = formInstanceMapper.getParentId(id2);
                        if (resultSons.size()>0 && !ValidationUtil.isEmpty(resultSons)){
                            resultSons.forEach(z->{
                      /*     	// Long  subInstanceId2 =Long.parseLong(z.get("instance_id").toString());
                                Long  subInstanceId2 =Long.parseLong(z.get("id").toString());
                          	  formInstanceMapper.updateFormInstanceByInstanceAndFieldName("bizOrgCode", bizOrgCode, subInstanceId2);
                                formInstanceMapper.updateFormInstanceByInstanceAndFieldName("bizOrgName", bizOrgName, subInstanceId2);*/
                                    long id3 = Long.parseLong(z.get("id").toString());
                                    formInstanceMapper.updateStr(id3 ,z.get("name").toString(),z.get("full_name").toString(),z.get("parent_id").toString(),z.get("code").toString(),bizOrgCode,bizOrgName);
                                });
                        }
                    });
                }
            });
        }
        //3.修改仓库对应子数据
        fullName = "0".equals(parentId) ? name + "-" : "-" + name;
        name = beforFullName + "-";
        if (!"0".equals(parentId)) {
            name = "-" + stuName;
        }
        formInstanceMapper.updateStrFullName(instanceId, name, fullName);
        //4.保存表单数据
        if (map.get("isRisk").equals("false")) {
            map.remove("riskPointId");
        }
        Map<String, Object> formKeyMap = iFormInstanceService.updateInstance(instanceId, orgCode, map);
        // 同步统计表数据
        if (!Long.valueOf(parentId).equals(id)) {
            List<SourceScene> bySourceId = sourceSceneService.findBySourceId(instanceId);
            if (bySourceId != null && bySourceId.size() > 0) {
                String equipIds = bySourceId.get(0).getPointInScene();
                List<String> equipIdList = new ArrayList<>();
                if (StringUtil.isNotEmpty(equipIds)) {
                    if (-1 != equipIds.indexOf(",")) {
                        equipIdList = Arrays.asList(equipIds.split(","));
                    } else {
                        equipIdList.add(equipIds);
                    }
                }
            }
        }
		/* 解决bug 5103中修改节点信息之后没有同步修改动态表单的问题 ------by chenhao 2022-03-22 --开始 */
    //    formInstanceMapper.updateFormInstanceByInstanceAndFieldName("bizOrgCode", bizOrgCode, instanceId);
     //   formInstanceMapper.updateFormInstanceByInstanceAndFieldName("bizOrgName", bizOrgName, instanceId);
        /* 解决bug 5103中修改节点信息之后没有同步修改动态表单的问题 ------by chenhao 2022-03-22  -- 结束 */
        // 发布风险区域同步操作事件
        map.put("instanceId", formKeyMap.get("instanceId"));
        map.put("code", formKeyMap.get("code"));
        map.put("name", formKeyMap.get("name"));
        map.put("companyCode", orgCode);
        SpringContextHolder.publishEvent(new SyncRiskEvent(this, map, SyncRiskOperator.UPDATE.getType()));
        return formKeyMap;
    }

    public List<BuildingTreeVo> getBuildingTreeNew(String bizOrgCode) {
        List<BuildingTreeVo> allListVo = getBuildingTreeVos(true, bizOrgCode);
        return allListVo.stream().filter(s -> "-1".equals(s.getParentId())).map(s -> {
            BuildingTreeVo t = new BuildingTreeVo();
            Bean.copyExistPropertis(s, t);
            t.setChildren(this.getChildren(t.getInstanceId(), allListVo));
            t.setDetailPaneApi(address);
            t.setApiUrl(apiUrl);
            return t;
        }).collect(Collectors.toList());
    }

    @Override
    public List<BuildingTreeVo> getBuildingTree(String bizOrgCode) {
        List<BuildingTreeVo> allListVo = getBuildingTreeVos(true, bizOrgCode);
        return allListVo.stream().filter(s -> "-1".equals(s.getParentId())).map(s -> {
            BuildingTreeVo t = new BuildingTreeVo();
            Bean.copyExistPropertis(s, t);
            t.setChildren(this.getChildren(t.getInstanceId(), allListVo));
            t.setDetailPaneApi(address);
            t.setApiUrl(apiUrl);
            return t;
        }).collect(Collectors.toList());
    }

    public List<BuildingTreeVo> getBuildingTree() {
        List<BuildingTreeVo> allListVo = getBuildingTreeVos(true, null);
        return allListVo.stream().filter(s -> "-1".equals(s.getParentId())).map(s -> {
            BuildingTreeVo t = new BuildingTreeVo();
            Bean.copyExistPropertis(s, t);
            t.setChildren(this.getChildren(t.getInstanceId(), allListVo));
            t.setDetailPaneApi(address);
            t.setApiUrl(apiUrl);
            return t;
        }).collect(Collectors.toList());
    }

    @Override
    public List<BuildingTreeVo> getBuildingTreeByBizOrgCode(String bizOrgCode) {
        List<BuildingTreeVo> allListVo = getBuildingTreeVosByBizOrgCode(true, bizOrgCode);
        return allListVo.stream().filter(s -> "-1".equals(s.getParentId())).map(s -> {
            BuildingTreeVo t = new BuildingTreeVo();
            Bean.copyExistPropertis(s, t);
            t.setChildren(this.getChildren(t.getInstanceId(), allListVo));
            t.setDetailPaneApi(address);
            t.setApiUrl(apiUrl);
            return t;
        }).collect(Collectors.toList());
    }

    private List<BuildingTreeVo> getBuildingTreeVosByBizOrgCode(Boolean isContainRootNode, String bizOrgCode) {
        FormGroup formGroup = iFormGroupService.getByUniqueKey(GroupCodeEnum.ALL_BUILDING.getGroupCode());
        List<Map<String, Object>> allList = iFormInstanceService.getSpecialChildrenListByBizOrgCode(null, bizOrgCode);
        List<BuildingTreeVo> allListVo = buildBuildingData(formGroup, allList, isContainRootNode);
        Map<Long, String> absolutePositionMap = getBuildingAbsolutePosition(allListVo);
        allListVo.forEach(s -> s.setAbsolutePosition(absolutePositionMap.get(s.getId())));
        return allListVo;
    }

    @Override
    public List<Map<String, Object>> getBuildingDetaiList() {
        return iFormInstanceService.getSpecialChildrenList(null, null);
    }

    private List<BuildingTreeVo> getBuildingTreeVos(Boolean isContainRootNode, String bizOrgCode) {
        FormGroup formGroup = iFormGroupService.getByUniqueKey(GroupCodeEnum.ALL_BUILDING.getGroupCode());
        List<Map<String, Object>> allList = iFormInstanceService.getSpecialChildrenList(null, bizOrgCode);
        List<BuildingTreeVo> allListVo = buildBuildingData(formGroup, allList, isContainRootNode);
        Map<Long, String> absolutePositionMap = getBuildingAbsolutePosition(allListVo);
        allListVo.forEach(s -> s.setAbsolutePosition(absolutePositionMap.get(s.getId())));
        return allListVo;
    }



    @Override
    public List<BuildingTreeVo> getBuildingTierTree(Integer tier) {
        if (tier != null) {
            List<BuildingTreeVo> list = getBuildingTreeVos(true, null);
            if (!CollectionUtils.isEmpty(list)) {
                if (tier == 1) {
                    List<BuildingTreeVo> collect = list.stream().filter(x -> "-1".equals(x.getParentId()) || "building".equalsIgnoreCase(x.getGroupType())).collect(Collectors.toList());
                    final List<BuildingTreeVo> collect1 = collect.stream().filter(s -> "-1".equals(s.getParentId())).collect(Collectors.toList());
                    final List<BuildingTreeVo> collect2 = list.stream().filter(s -> "-1".equals(s.getParentId())).collect(Collectors.toList());
                    return collect.stream().filter(s -> "-1".equals(s.getParentId())).map(s -> {
                        BuildingTreeVo t = new BuildingTreeVo();
                        Bean.copyExistPropertis(s, t);
                        t.setChildren(this.getChildren(t.getInstanceId(), collect));
                        t.setDetailPaneApi(address);
                        t.setApiUrl(apiUrl);
                        return t;
                    }).collect(Collectors.toList());
                } else if (tier == 2) {
                    List<BuildingTreeVo> collect = list.stream().filter(x -> !"room".equalsIgnoreCase(x.getGroupType())).collect(Collectors.toList());
                    return list.stream().filter(s -> "-1".equals(s.getParentId())).map(s -> {
                        BuildingTreeVo t = new BuildingTreeVo();
                        Bean.copyExistPropertis(s, t);
                        t.setChildren(this.getChildren(t.getInstanceId(), collect));
                        t.setDetailPaneApi(address);
                        t.setApiUrl(apiUrl);
                        return t;
                    }).collect(Collectors.toList());
                } else {
                    return getBuildingTree();
                }
            }
            return Lists.newArrayList();
        } else {
            return getBuildingTree();
        }
    }

    private List<BuildingTreeVo> buildBuildingData(FormGroup
                                                           formGroup, List<Map<String, Object>> allList, Boolean isContainRootNode) {
        List<BuildingTreeVo> allListVo = Bean.listMap2ListBean(allList, BuildingTreeVo.class);
        if (isContainRootNode) {
            BuildingTreeVo treeNode = new BuildingTreeVo();
            treeNode.setDetailPaneApi(address);
            treeNode.setApiUrl(apiUrl);
            treeNode.setName(formGroup.getGroupName());
            treeNode.setInstanceId(formGroup.getId());
            treeNode.setInstanceName(formGroup.getGroupName());
            treeNode.setParentId("-1");
            treeNode.setGroupType(formGroup.getGroupType());
            treeNode.setGroupCode(formGroup.getGroupCode());
            allListVo.add(treeNode);
        }
        return allListVo;
    }

    private List<BuildingTreeVo> getChildren(Long parentId, List<BuildingTreeVo> allListVo) {
        List<BuildingTreeVo> children = new ArrayList<>();
        allListVo.stream().filter(a -> !ObjectUtils.isEmpty(a.getParentId()) && a.getParentId().equals(String.valueOf(parentId))).forEach(s -> {
            s.setChildren(this.getChildren(s.getInstanceId(), allListVo));
            s.setDetailPaneApi(address);
            s.setApiUrl(apiUrl);
            s.setDetailListPaneApi(ffsEquipAlarmsUrl);
            children.add(s);
        });
        return children;
    }

    private List<BuildingTreeVo> getChildrenNew(Long parentId, List<BuildingTreeVo> allListVo, List<ImportantEquipmentVO> listEqu) {
        List<BuildingTreeVo> children = new ArrayList<>();
        allListVo.stream().filter(a -> !ObjectUtils.isEmpty(a.getParentId()) && a.getParentId().equals(String.valueOf(parentId))).forEach(s -> {
            s.setChildren(this.getChildrenNew(s.getInstanceId(), allListVo, listEqu));
            s.setType("building");
            children.add(s);
            for (ImportantEquipmentVO v :listEqu
                 ) {
                if(v.getRiskSource().equals(s.getInstanceId().toString())) {
                    BuildingTreeVo buildTree = new BuildingTreeVo();
                    buildTree.setId(v.getId());
                    buildTree.setName(v.getName());
                    buildTree.setParentId(s.getParentId());
                    buildTree.setType("equipment");
                    children.add(buildTree);
                }
            }
        });
        return children;
    }

    @Override
    public List<PointTreeVo> getBuildTree(String bizOrgCode,String instanceId) {
        List<PointTreeVo> responses = this.baseMapper.getBuildList(bizOrgCode,instanceId);
        // id为null 避免查询时按系统点位图逻辑查询
        return fireFightingSystemService.transferListToPointTree(responses, null,instanceId);
    }

    @Override
    public List<PointTreeVo> getEquipTree(String bizOrgCode, String instanceId, String displayName) {
        //根据关键字筛选建筑树
        List<PointTreeVo> responses = this.baseMapper.getBuildAll(displayName);
        if(ValidationUtil.isEmpty(bizOrgCode) && ValidationUtil.isEmpty(instanceId)  && ValidationUtil.isEmpty(displayName) ){
            return getTree(responses);
        } else {
            //组装 建筑和装备树
            List<PointTreeVo> pointTreeVos = fireFightingSystemService.transferListToPointTreeNew(responses, null, instanceId, displayName);
            if(!ValidationUtil.isEmpty(pointTreeVos)){
                return pointTreeVos ;
            }
            //如果筛选的关键字没有装备 返回建筑树
            return getTree(responses);
        }
    }

    //组装接口
    public List<PointTreeVo> getTree( List<PointTreeVo> responses) {
        List<PointTreeVo> pointDataNum = fireFightingSystemMapper.getPointDataNum(null);
        if (pointDataNum.size() > 0 && pointDataNum.size() == responses.size()) {
            responses.addAll(pointDataNum);
        }else {
            List<String> ids = Lists.newArrayList();
            responses.forEach(r->ids.add(r.getSequenceNbr().toString()));
            List<PointTreeVo> collect = pointDataNum.stream().filter(e -> ids.toString().contains(e.getParentId().toString())).collect(Collectors.toList());
            responses.addAll(collect);
        }
        Map<Long, PointTreeVo> map = new HashMap<>(responses.size());
        responses.forEach(e -> map.put(e.getSequenceNbr(), e));
        Set<? extends Map.Entry<Long, ? extends PointTreeVo>> entries = map.entrySet();
        List<PointTreeVo> treeList = new ArrayList<>();
        entries.forEach(entry -> {
            PointTreeVo value = entry.getValue();
            if (value != null) {
                PointTreeVo treeDto = map.get(value.getParentId());
                if (treeDto != null) {
                    List<PointTreeVo> children = treeDto.getChildren();
                    if (children == null) {
                        children = new ArrayList<>();
                        treeDto.setChildren(children);
                    }
                    children.add(value);
                } else {
                    treeList.add(value);
                }
            }
        });
        return treeList;
    }

    @Override
    public List<PointTreeVo> getBuildTreeNew(String bizOrgCode,String instanceId) {
        List<PointTreeVo> responses = this.baseMapper.getBuildListNew(bizOrgCode,instanceId);
        // id为null 避免查询时按系统点位图逻辑查询
        return fireFightingSystemService.transferListToPointTree(responses, null,instanceId);
    }

    @Override
    public List<PointTreeVo> getBuildTreeNot(String bizOrgCode) {
        List<PointTreeVo> responses = this.baseMapper.getBuildList(bizOrgCode,null);
        List<PointTreeVo> treeList = new ArrayList<>();

        for (PointTreeVo tree : responses) {
            if (tree.getParentId() == null || tree.getParentId() == -1) {
                treeList.add(tree);
            }
            for (PointTreeVo treeNode : responses) {
                if (tree.getSequenceNbr().equals(treeNode.getParentId())) {
                    if (tree.getChildren() == null) {
                        tree.setChildren(new ArrayList<>());
                    }
                    tree.getChildren().add(treeNode);
                }
            }
        }


        return treeList;
    }

    @Override
    public List<PointTreeVo> get3dBuildTree() {
        List<PointTreeVo> responses = this.baseMapper.getBuildList(null,null);
        return fireFightingSystemService.transferListTo3dPointTree(responses);
    }

    @Override
    public Map<String, Object> buildingDetail(Long instanceId) {
        return iFormInstanceService.queryForMap(instanceId);
    }

    @Override
    @Transactional
    public Boolean deleteBuilding(Long instanceId) {
        List<FormInstance> lists = formInstanceMapper.selectList(new QueryWrapper<FormInstance>().eq("instance_id", instanceId));
        if (0 < lists.size()) {
            String groupCode = lists.get(0).getGroupCode();
            if (!ValidationUtil.isEmpty(Arrays.stream(list).filter(x -> x.equals(groupCode)).collect(Collectors.toList()))) {
                formInstanceMapper.delete(new QueryWrapper<FormInstance>().eq("group_code", groupCode).eq("instance_id", instanceId));
                return true;
            }
        }

        List<StockDetail> list = stockDetailMapper.selectList(new QueryWrapper<StockDetail>().eq("warehouse_structure_id", instanceId));
        if (list != null && list.size() > 0) {
            throw new BadRequest("该建筑存在入库装备，无法直接删除");
        }
        stockDetailMapper.clearWareHouse(instanceId);
        Boolean flag = iFormInstanceService.deleteInstanceById(instanceId);
        if (flag && syncSwitch) {
            //数据同步
            syncDataService.syncDeletedBuilding(Arrays.asList(instanceId));
            syncDataService.syncDeletedFloor(Arrays.asList(instanceId));
            syncDataService.syncDeletedRoom(Arrays.asList(instanceId));
        }
        List<SourceScene> bySourceId = sourceSceneService.findBySourceId(instanceId);
        if (bySourceId != null && bySourceId.size() > 0) {
            Long id = bySourceId.get(0).getId();
            Long sceneId = bySourceId.get(0).getSceneId();
            sourceSceneService.removeById(id);
            FeignUtil.remoteCall(() -> Morphic.morphicSubjectClient.delete(sceneId));
        }
        Map<String, Object> map = new HashMap<>(16);
        map.put("instanceId", instanceId);
        SpringContextHolder.publishEvent(new SyncRiskEvent(this, map, SyncRiskOperator.DELETE.getType()));
        return flag;
    }

    @Override
    public Map<String, Object> getAllPermission() {
        return iFormGroupService.getAllOperation();
    }

    @Override
    public int pageBuildingVideoCount(BuildingVideoListVO dto) {
        return videoService.pageBuildingVideoCount(dto);
    }

    @Override
    public List<BuildingVideoVO> pageBuildingVideoList(Page page, BuildingVideoListVO dto) {
        List<BuildingVideoVO> pages = videoService.pageBuildingVideoList(page, dto);
        pages.forEach(x -> {
            if (StringUtil.isNotEmpty(x.getLocation()) && StringUtil.isNotEmpty(x.getAddress())) {
                x.setLocation(x.getLocation() + '-' + x.getAddress());
            } else {
                if (!StringUtil.isNotEmpty(x.getLocation())) {
                    x.setLocation(x.getAddress());
                }
            }
            x.setVedioFormat(x.getVideoType());
            x.setUrl(videoService.getVideoUrl(x.getName(), x.getPresetPosition(), x.getUrl(), x.getCode()));
        });
        return pages;
    }


    @Override
    public Map<String, Object> getEveryCount(Long id, String groupType, String bizOrgCode) {
        Map<String, Object> map = new HashMap<>();
        if ("".equals(groupType) || "allBuilding".equals(groupType)) {
            Long roomCount = this.baseMapper.getCountByTypeCode("room", bizOrgCode);
            Long floorCount = this.baseMapper.getCountByTypeCode("floor", bizOrgCode);
            Long equipCount = this.baseMapper.getEquipCount(bizOrgCode);
            map.put("floorCount", floorCount);
            map.put("roomCount", roomCount);
            map.put("equipCount", equipCount);
            return map;
        }
        if ("allfloor".equals(groupType)) {
            List<FormInstance> allfloorCount = this.baseMapper.getAllfloorCount(id);
            map.put("res", allfloorCount);
            return map;
        }
        Long equipCount = this.baseMapper.getEquipmentCount(id, groupType);
        map.put("equipCount", equipCount);
        if ("room".equals(groupType)) {
            return map;
        }
        if ("floor".equals(groupType)) {
            Long roomCount = this.baseMapper.getFloorOrRoomCount(id, groupType);
            map.put("roomCount", roomCount);
        }
        if ("building".equals(groupType)) {
            Long floorCount = this.baseMapper.getFloorOrRoomCount(id, groupType);
            Long roomCount = this.baseMapper.getRoomCount(id);
            map.put("floorCount", floorCount);
            map.put("roomCount", roomCount);
        }
        return map;
    }

    /**
     * 保存图片
     * sourceId 数据拥有者
     *
     * @param map 集合
     */
    @Transactional(rollbackFor = {Exception.class, BaseException.class})
    public void saveFiles(Long sourceId, Map<String, Object> map) {
        List<SourceFile> sourceFiles = new ArrayList<>();
        String fileKey = "files";
        if (map.get(fileKey) != null) {
            sourceFiles = JSONObject.parseArray(JSONObject.toJSON(map.get(fileKey)).toString(), SourceFile.class);
            iEqSourceFileService.saveSourceFile(sourceId, sourceFiles);
        }
    }

    /**
     * @param dto 查询参数
     * @Description 分页查询
     * @Return Page
     * @Date 2020/12/19 11:47
     */
    @Override
    public Page buildingList(Page page, BuildSearchDTO dto) {
        Optional.ofNullable(dto.getInstanceId()).orElseThrow(() -> new BadRequest("instanceId参数不能为空"));
        Optional.ofNullable(dto.getGroupType()).orElseThrow(() -> new BadRequest("groupType参数不能为空"));
        // 根据不同的groupType 查询分页
        PageOperation targetOperation = PageOperatorFactory
                .getOperation(dto.getGroupType())
                .orElseThrow(() -> new BadRequest("Invalid Operator"));
        return targetOperation.apply(page, dto);
    }

    /**
     * @param dto 查询参数
     * @Description 建筑楼层分页查询
     * @Return Page
     * @Date 2020/12/19 11:47
     */
    @Override
    public Page floorPage(Page page, BuildSearchDTO dto) {
        Page pageData = iFormInstanceService.roomPage(page, dto);
        pageData.getRecords().parallelStream().forEach(item -> {
            Map<String, Object> map = (Map<String, Object>) item;
            Long eqTotalNum = equipmentTotal(Long.valueOf(String.valueOf(map.get("instanceId").toString())), GroupTypeEnum.ROOM.getType());
            this.files(map);
            this.sourceBuild(map);
            map.put("equipmentTotal", eqTotalNum);
        });
        return pageData;
    }

    /**
     * @param page
     * @param dto
     * @Description 房间
     * @Return Page
     * @Date 2020/12/22 13:55
     */
    @Override
    public Page roomPage(Page page, BuildSearchDTO dto) {
        Page pageData = iFormInstanceService.roomPage(page, dto);
        pageData.getRecords().parallelStream().forEach(item -> {
            Map<String, Object> map = (Map<String, Object>) item;
            Long eqTotalNum = equipmentTotal(Long.valueOf(String.valueOf(map.get("instanceId").toString())), GroupTypeEnum.ROOM.getType());
            this.files(map);
            this.sourceBuild(map);
            map.put("equipmentTotal", eqTotalNum);
        });
        return pageData;
    }

    /**
     * @param instanceId
     * @Description 构建设备，房间，建筑所属
     * @Description 构建设备，房间，建筑所属
     * @Return int
     * @Date 2020/12/21 13:55
     */
    @Override
    public Long equipmentTotal(Long instanceId, String groupType) {
        Map<String, Object> map = getEveryCount(instanceId, groupType, null);
        return Long.parseLong(String.valueOf(map.get("equipCount")));
    }

    public Map<String, Object> getAllOperation() {
        return iFormGroupService.getAllOperation();
    }

    /**
     * @param map
     * @Description 所属楼层
     * @Date 2020/12/22 11:29
     */
    @Override
    public void sourceBuild(Map<String, Object> map) {
        Optional<GroupTypeOperator> m = EnumsUtils.getEnumObject(GroupTypeOperator.class,
                e -> e.getType().equals(String.valueOf(map.get("groupType"))));
        calculate(map, m.get());
    }

    public void calculate(Map<String, Object> map, GroupTypeOperator operator) {
        operator.apply(map);
    }

    /**
     * @param coll
     * @Description 统计房间数
     * @Date 2020/12/22 15:33
     */
    @Override
    public void roomNum(List<Map<String, Object>> coll, Map<String, Object> map) {
        //建筑底下的房间
        int roomNum = coll.parallelStream().filter(o -> o.get("groupType").equals(GroupTypeEnum.ROOM.getType())).collect(Collectors.toList()).size();
        //建筑底下楼层底下的房间
        List<Long> floorInstanceId = new ArrayList<>();
        coll.parallelStream().forEach(c -> {
            floorInstanceId.add(Long.parseLong(c.get("instanceId").toString()));
        });
        if (!CollectionUtils.isEmpty(floorInstanceId)) {
            List<Map<String, Object>> rooms = iFormInstanceService.queryFloorRoom(floorInstanceId);
            int floorRoomNum = rooms.parallelStream().filter(o -> o.get("groupType").equals(GroupTypeEnum.ROOM.getType())).collect(Collectors.toList()).size();
            map.put("roomNum", roomNum + floorRoomNum);
        } else {
            map.put("roomNum", roomNum);
        }
    }

    /**
     * @param map
     * @Description 文件
     * @Return
     * @Exception
     * @Date 2020/12/22 19:39
     */
    @Override
    public void files(Map<String, Object> map) {
        List<SourceFile> sourceFiles = iEqSourceFileService.findBySourceId(Long.parseLong(String.valueOf(map.get("instanceId"))));
        map.put("files", sourceFiles);
    }

    @Override
    public List<BuildingTreeVo> getBuildingVideoTree() {
        FormGroup formGroup = iFormGroupService.getByUniqueKey(GroupCodeEnum.ALL_BUILDING.getGroupCode());
        List<Map<String, Object>> allList = iFormInstanceService.getBuildVideoListCount(null);
        List<BuildingTreeVo> allListVo = buildColaBuildingData(formGroup, allList);
        // tree 统计处理
        return allListVo.stream().filter(s -> "-1".equals(s.getParentId())).map(s -> {
            BuildingTreeVo t = new BuildingTreeVo();
            Bean.copyExistPropertis(s, t);
            Map<String, Object> childrenTotal = this.getChildrenTotal(t.getInstanceId(), allListVo);
            t.setChildren((List<BuildingTreeVo>) childrenTotal.get("list"));
            t.setTotal((Long) childrenTotal.get("total"));
            t.setDetailPaneApi(address);
            return t;
        }).collect(Collectors.toList());
    }

    private List<BuildingTreeVo> buildColaBuildingData(FormGroup formGroup, List<Map<String, Object>> allList) {
        List<BuildingTreeVo> allListVo = Bean.listMap2ListBean(allList, BuildingTreeVo.class);
        BuildingTreeVo treeNode = new BuildingTreeVo();
        treeNode.setDetailPaneApi(address);
        treeNode.setInstanceId(formGroup.getId());
        treeNode.setInstanceName(formGroup.getGroupName());
        treeNode.setParentId("-1");
        treeNode.setGroupType(formGroup.getGroupType());
        treeNode.setGroupCode(formGroup.getGroupCode());
        allListVo.add(treeNode);
        return allListVo;
    }

    /**
     * 子集统计求和
     *
     * @param parentId  父级id
     * @param allListVo 所属有数据
     * @return
     */
    private Map<String, Object> getChildrenTotal(Long parentId, List<BuildingTreeVo> allListVo) {
        if (parentId == null || (allListVo == null && allListVo.size() == 0)) {
            return null;
        }
        Map<String, Object> map = new HashMap<>();
        List<BuildingTreeVo> children = new ArrayList<>();
        BigDecimal total = BigDecimal.ZERO;
        List<BuildingTreeVo> childrenFilter = new ArrayList<>();
        for (BuildingTreeVo buildingTreeVo : allListVo) {
            if (buildingTreeVo.getParentId().equals(String.valueOf(parentId))) {
                childrenFilter.add(buildingTreeVo);
            }
        }
        if (childrenFilter.size() > 0) {
            total = BigDecimal.ZERO;
            for (BuildingTreeVo s : childrenFilter) {
                Map<String, Object> childrenTotal = this.getChildrenTotal(s.getInstanceId(), allListVo);
                List<BuildingTreeVo> childrens = (List<BuildingTreeVo>) childrenTotal.get("list");
                s.setChildren(childrens);
                if (childrens.size() > 0) {
                    s.setTotal(new BigDecimal(s.getTotal().toString()).add(new BigDecimal(childrenTotal.get("total").toString())).longValue());
                }
                children.add(s);
                total = total.add(new BigDecimal(s.getTotal().toString()));
            }
        }
        map.put("list", children);
        map.put("total", total.longValue());
        return map;
    }

    @Override
    public Page<BuildingVideoVO> buildingVideoList(Page page, BuildingVideoListVO dto) {
        Page<BuildingVideoVO> pages = videoService.pageBuildingVideo(page, dto);
        pages.getRecords().forEach(x -> {
            if (StringUtil.isNotEmpty(x.getLocation()) && StringUtil.isNotEmpty(x.getAddress())) {
                x.setLocation(x.getLocation() + '-' + x.getAddress());
            } else {
                if (!StringUtil.isNotEmpty(x.getLocation())) {
                    x.setLocation(x.getAddress());
                }
            }
            x.setVedioFormat(x.getVideoType());
            x.setUrl(videoService.getVideoUrl(x.getName(), x.getPresetPosition(), x.getUrl(), x.getCode()));
        });
        return pages;
    }

    @Override
    public List<BuildingListVO> getFireEquipByVideoId(Long videoId) {
        return videoService.getFireEquipByVideoId(videoId);
    }

    @Override
    public List<BuildingListVO> getPowerEquipByVideoId(Long videoId) {
        return videoService.getPowerEquipByVideoId(videoId);
    }

    @Override
    public List<BuildIsRiskDTO> getChildrenNotIsRiskList(String instanceId) {
        return formInstanceMapper.getChildrenNotIsRiskList(instanceId);
    }

    @Override
    public void unbindRelation(Long instanceId) {
        iFormInstanceService.unbindRegionRelation(instanceId);
    }

    @Override
    public List<BuildingTreeVo> getBuildingVideoColaTree() {
        FormGroup formGroup = iFormGroupService.getByUniqueKey(GroupCodeEnum.ALL_BUILDING.getGroupCode());
        BuildingVideoListVO dto = new BuildingVideoListVO();
        dto.setMonitorCodes(videoService.getSecurityCodeList());
        List<Map<String, Object>> allList = iFormInstanceService.getColaBuildVideoListCount(dto);
        List<BuildingTreeVo> allListVo = buildBuildingColaData(formGroup, allList);
        // tree 统计处理
        return allListVo.stream().filter(s -> "-1".equals(s.getParentId())).map(s -> {
            BuildingTreeVo t = new BuildingTreeVo();
            Bean.copyExistPropertis(s, t);
            Map<String, Object> childrenTotal = this.getColaChildrenTotal(t.getInstanceId(), allListVo);
            t.setChildren((List<BuildingTreeVo>) childrenTotal.get("list"));
            t.setTotal((Long) childrenTotal.get("total"));
            t.setDetailPaneApi(address);
            return t;
        }).collect(Collectors.toList());
    }

    private List<BuildingTreeVo> buildBuildingColaData(FormGroup formGroup, List<Map<String, Object>> allList) {
        List<BuildingTreeVo> allListVo = Bean.listMap2ListBean(allList, BuildingTreeVo.class);
        BuildingTreeVo treeNode = new BuildingTreeVo();
        treeNode.setDetailPaneApi(address);
        treeNode.setInstanceId(formGroup.getId());
        treeNode.setInstanceName(formGroup.getGroupName());
        treeNode.setParentId("-1");
        treeNode.setGroupType(formGroup.getGroupType());
        treeNode.setGroupCode(formGroup.getGroupCode());
        allListVo.add(treeNode);
        return allListVo;
    }

    /**
     * 安防消防建筑树子集统计求和
     *
     * @param parentId  父级id
     * @param allListVo 所属有数据
     * @return
     */
    private Map<String, Object> getColaChildrenTotal(Long parentId, List<BuildingTreeVo> allListVo) {
        if (parentId == null || (allListVo == null && allListVo.size() == 0)) {
            return null;
        }
        Map<String, Object> map = new HashMap<>();
        List<BuildingTreeVo> children = new ArrayList<>();
        BigDecimal total = BigDecimal.ZERO;
        List<BuildingTreeVo> childrenFilter = new ArrayList<>();
        for (BuildingTreeVo buildingTreeVo : allListVo) {
            if (buildingTreeVo.getParentId().equals(String.valueOf(parentId))) {
                childrenFilter.add(buildingTreeVo);
            }
        }
        if (childrenFilter.size() > 0) {
            total = BigDecimal.ZERO;
            for (BuildingTreeVo s : childrenFilter) {
                Map<String, Object> childrenTotal = this.getChildrenTotal(s.getInstanceId(), allListVo);
                List<BuildingTreeVo> childrens = (List<BuildingTreeVo>) childrenTotal.get("list");
                s.setChildren(childrens);
                if (childrens.size() > 0) {
                    s.setTotal(new BigDecimal(s.getTotal().toString()).add(new BigDecimal(childrenTotal.get("total").toString())).longValue());
                }
                children.add(s);
                total = total.add(new BigDecimal(s.getTotal().toString()));
            }
        }
        map.put("list", children);
        map.put("total", total.longValue());
        return map;
    }

    @Override
    public Page<BuildingVideoVO> buildingColaVideoList(Page page, BuildingVideoListVO dto) {
        return videoService.pageColaBuildingVideo(page, dto);
    }

    @Override
    public List<BuildingListVO> getFireEquipment(Long id) {
        QueryWrapper<EquipmentSpecificRelation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("equipment_specific_id", id);
        queryWrapper.eq("type", IndustryEnum.EQUIP.getCode());
        List<EquipmentSpecificRelation> lists = equipmentSpecificRelationMapper.selectList(queryWrapper);
        List<BuildingListVO> result = new ArrayList<>();
        if (0 < lists.size()) {
            lists.forEach(x -> {
                BuildingListVO buildingListVO = new BuildingListVO();
                buildingListVO = videoMapper.getSecurityOrFireEquipment(x.getRelationEquipmentSpecificId());
                result.add(buildingListVO);
            });
        }
        return result;
    }

    @Override
    public List<BuildingListVO> getSecurityEquipment(Long id) {
        QueryWrapper<EquipmentSpecificRelation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("equipment_specific_id", id);
        queryWrapper.eq("type", IndustryEnum.SECURITY.getCode());
        List<EquipmentSpecificRelation> lists = equipmentSpecificRelationMapper.selectList(queryWrapper);
        List<BuildingListVO> result = new ArrayList<>();
        if (0 < lists.size()) {
            lists.forEach(x -> {
                BuildingListVO buildingListVO = new BuildingListVO();
                buildingListVO = videoMapper.getSecurityOrFireEquipment(x.getRelationEquipmentSpecificId());
                result.add(buildingListVO);
            });
        }
        return result;
    }

    @Override
    public List<BuildingTreeVo> gettreeAndEquip(String bizOrgCode) {
        List<ImportantEquipmentVO> equipment = equipmentSpecificMapper.getEquipment();
        List<BuildingTreeVo> allListVo = getBuildingTreeVos(true, bizOrgCode);
        allListVo.stream().filter(s -> "-1".equals(s.getParentId())).map(s -> {
            BuildingTreeVo t = new BuildingTreeVo();
            Bean.copyExistPropertis(s, t);
            t.setChildren(this.getChildrenNew(t.getInstanceId(), allListVo, equipment));
            t.setType("building");
            return t;
        }).collect(Collectors.toList());

        return allListVo;
    }

    @Override
    public Map<String, Object> getBuildDetaliByFloorId(String instanceId) {
        List<DictionarieValueModel> build_type = Systemctl.dictionarieClient.dictValues(buildType).getResult();
        Map<String, String> buildType = build_type.stream().collect(Collectors.toMap(DictionarieValueModel::getDictDataKey, DictionarieValueModel::getDictDataValue));

        List<DictionarieValueModel> build_use_type = Systemctl.dictionarieClient.dictValues(buildUseType).getResult();
        Map<String, String> buildUseType = build_use_type.stream().collect(Collectors.toMap(DictionarieValueModel::getDictDataKey, DictionarieValueModel::getDictDataValue));

        List<DictionarieValueModel> building_structure_type = Systemctl.dictionarieClient.dictValues(buildingStructureType).getResult();
        Map<String, String> buildingStructureType = building_structure_type.stream().collect(Collectors.toMap(DictionarieValueModel::getDictDataKey, DictionarieValueModel::getDictDataValue));

        List<FireFightingSystemEntity> system = fireFightingSystemService.list();
        Map<Long, String> systems = system.stream().collect(Collectors.toMap(FireFightingSystemEntity::getId, FireFightingSystemEntity::getName));

        Map<String, String> idAndType = formInstanceMapper.getIdAndType(instanceId);
        String id = idAndType.get("id");
        String type = idAndType.get("type");
        String addr = idAndType.get("address");
        Map<String, Object> map = iFormInstanceService.queryForMap(Long.valueOf(id));

        String userId = String.valueOf(map.get("dutyUser"));
        String dutyUser = "";
        if (userId != null && !"".equals(userId)) {
            dutyUser = remoteSecurityService.getUserById(userId).getRealName();
        }

        Map<String, Object> res = new LinkedHashMap<>();
        List<AlarmDataVO> list = new ArrayList<>();
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
        try {
            if ("building".equals(type)) {
                list.add(new AlarmDataVO("建构筑名称", String.valueOf(map.get("name")), true));
                list.add(new AlarmDataVO("责任人", dutyUser, false));
                list.add(new AlarmDataVO("责任人电话", String.valueOf(map.get("dutyUserPhone")), false));
                list.add(new AlarmDataVO("建（构）筑类别", buildType.get(map.get("buildType")), false));
                list.add(new AlarmDataVO("使用性质", buildUseType.get(map.get("buildUseType")), false));
                list.add(new AlarmDataVO("结构类型", buildingStructureType.get(map.get("structureType")), false));
            }
            if ("pool".equals(type)) {
                list.add(new AlarmDataVO("消防水池名称", String.valueOf(map.get("name")), true));
                list.add(new AlarmDataVO("责任人", dutyUser, false));
                list.add(new AlarmDataVO("维保单位", String.valueOf(map.get("maintenanceUnit")), false));
                list.add(new AlarmDataVO("储水量（m³）", String.valueOf(map.get("waterStorage")), false));
                list.add(new AlarmDataVO("容量（m³）", String.valueOf(map.get("volume")), false));
                list.add(new AlarmDataVO("建造日期", sd.format(sd.parse(String.valueOf(map.get("buildDate")))), false));
            }
            if ("fireFoamRoom".equals(type)) {
                list.add(new AlarmDataVO("消防泡沫间名称", String.valueOf(map.get("name")), true));
                list.add(new AlarmDataVO("责任人", dutyUser, false));
                list.add(new AlarmDataVO("面积（㎡）", String.valueOf(map.get("area")), false));
                list.add(new AlarmDataVO("维保单位", String.valueOf(map.get("maintenanceUnit")), false));
                list.add(new AlarmDataVO("保护对象", String.valueOf(map.get("protectedObjects")), false));
                list.add(new AlarmDataVO("泡沫灭火剂名称", String.valueOf(map.get("foamExtinguishingAgentName")), false));
            }
            if ("rainRoom".equals(type)) {
                list.add(new AlarmDataVO("雨淋阀间名称", String.valueOf(map.get("name")), true));
                list.add(new AlarmDataVO("面积（㎡）", String.valueOf(map.get("area")), false));
                list.add(new AlarmDataVO("所属系统", systems.get(Long.valueOf(String.valueOf(map.get("system")))), false));
                list.add(new AlarmDataVO("责任人", dutyUser, false));
            }
            if ("fireRoom".equals(type)) {
                list.add(new AlarmDataVO("消防小室名称", String.valueOf(map.get("name")), true));
                list.add(new AlarmDataVO("责任人", dutyUser, false));
                list.add(new AlarmDataVO("建造日期", sd.format(sd.parse(String.valueOf(map.get("buildDate")))), false));
                list.add(new AlarmDataVO("面积（㎡）", String.valueOf(map.get("area")), false));
                list.add(new AlarmDataVO("所属系统", systems.get(Long.valueOf(String.valueOf(map.get("system")))), false));
            }
            if ("fireControlRoom".equals(type)) {
                list.add(new AlarmDataVO("消控室名称", String.valueOf(map.get("name")), true));
                list.add(new AlarmDataVO("投用日期", sd.format(sd.parse(String.valueOf(map.get("useDate")))), false));
                list.add(new AlarmDataVO("责任人", dutyUser, false));
                list.add(new AlarmDataVO("维保单位", String.valueOf(map.get("maintenanceUnit")), false));
                list.add(new AlarmDataVO("每班人数", String.valueOf(map.get("personNum")), false));
                list.add(new AlarmDataVO("消防控制室操作人员持证数", String.valueOf(map.get("certificatesPersonNum")), false));
            }
        } catch (Exception e) {
            throw new BadRequest(e.toString());
        }
        list.add(new AlarmDataVO("详细地址", addr, false));
        res.put("items", list);
        res.put("title", "建筑简介");
        //TODO 组态使用接口，组态特殊接口形式修改-20210826
        Map<String, Object> state = new HashMap<>();
        Map<String, Object> detail = new HashMap<>();
        state.put("instanceId", id);
        state.put("groupCode", type);
        state.put("groupType", "building");
        state.put("parentId", "0");
        state.put("parentType", "building");
        detail.putAll(state);
        state.put("detail", detail);
        res.put("state", state);
        return res;
    }

    @Override
    public Map<Long, String> getBuildingAbsolutePosition() {
        FormGroup formGroup = iFormGroupService.getByUniqueKey(GroupCodeEnum.ALL_BUILDING.getGroupCode());
        List<Map<String, Object>> allList = iFormInstanceService.getSpecialChildrenList(null, null);
        List<BuildingTreeVo> allListVo = buildBuildingData(formGroup, allList, true);
        return getBuildingAbsolutePosition(allListVo);
    }

    @Override
    public Map<String, Long> getBuildingCodeKey() {
        Map<String, Long> resMap = new HashMap<>();
        List<Map<String, Object>> allList = iFormInstanceService.getSpecialChildrenList(null, null);
        if (!allList.isEmpty()) {
            allList.forEach(map -> resMap.put(String.valueOf(map.get("code")), Long.valueOf(String.valueOf(map.get("id")))));
        }
        return resMap;
    }

    private Map<Long, String> getBuildingAbsolutePosition(List<BuildingTreeVo> all) {
        Map<Long, String> res = new HashMap<>();
        if (!all.isEmpty()) {
            Map<Object, BuildingTreeVo> map = Bean.listToMap(all, "id", BuildingTreeVo.class);
            for (BuildingTreeVo build : all) {
                if (build == null || build.getId() == null) {
                    continue;
                }
                StringBuilder builder = new StringBuilder();
                Stack<String> stack = new Stack<String>();
                stitchName(map, stack, build);
                while (true) {
                    builder.append(stack.pop());
                    if (stack.isEmpty()) {
                        break;
                    } else {
                        builder.append("·");
                    }
                }
                res.put(build.getId(), builder.toString());
            }
        }
        return res;
    }

    private void stitchName(Map<Object, BuildingTreeVo> map, Stack<String> stack, BuildingTreeVo building) {
        stack.push(building.getName());
        if (building.getParentId() == null || !map.containsKey(Long.valueOf(building.getParentId()))) {
            return;
        }
        stitchName(map, stack, map.get(Long.valueOf(building.getParentId())));
    }

    @Override
    public Map<String, String> getStorageTankCodeByBelongUnitId(String belongUnitId, String groupCode) {
        Map<String, String> map = new HashMap<>();
        map.put("code", belongUnitId);
        List<Map<String, Object>> list = iFormInstanceService.queryForMapList(groupCode, map);
        if (list.size() > 0) {
            map.clear();
            int count = iFormInstanceService.count((new QueryWrapper<FormInstance>().eq("field_value", stroageTankCode(belongUnitId, list.size() + 1)).eq("field_name", "code")));
            if(count > 0) {
                String code = list.get(0).get("code").toString();
                String subEnd = code.substring(code.length() - 6, code.length() -1);
                String subStart = code.substring(0, code.length() -6);
                map.put("storageTankCode", subStart + (Integer.parseInt(subEnd) + 1 ));
            } else {
                map.put("storageTankCode", stroageTankCode(belongUnitId, list.size() + 1));
            }
        } else {
            map.clear();
            map.put("storageTankCode", belongUnitId + "0001");
        }
        return map;
    }

    // 生成四位流水号
    private String stroageTankCode(String belongUnitId, int num) {
        if (num < 10) {
            return belongUnitId + "000" + num;
        }

        if (num < 100 && num > 9) {
            return belongUnitId + "00" + num;
        }

        if (num < 1000 && num > 99) {
            return belongUnitId + "0" + num;
        }

        if (num < 10000 && num > 999) {
            return belongUnitId + num;
        }
        throw new BadRequest("无流水号可生成");
    }

    // 需求958 导出模板需要列表获取建筑 by kongfm 2021-09-15
    @Override
    public List<LinkedHashMap<String, Object>> getAllBuilding() {
        return formInstanceMapper.getAllBuilding();
    }

    @Override
    public Map<String, String> getBuildingToLongitudeAndLatitude(String instanceId) {
        // TODO Auto-generated method stub
        return formInstanceMapper.getBuildingToLongitudeAndLatitude(instanceId);
    }

    @Override
    public List<BuildingTreeVo> getCompanyBuildingTree(String authKey, String type) {
        //1.组装数据
        List<BuildingTreeVo> companyBuildingList = buildBuildingAndCompanyListVos(authKey, type,"building");
        //2.list to tree
        List<BuildingTreeVo> buildingTreeVos = companyBuildingList.stream().filter(a -> companyBuildingList.stream().noneMatch(c -> c.getId().toString().equals(a.getParentId()))).peek(b -> b.setChildren(getCompanyBuildingChildrenTree(b.getId().toString(), companyBuildingList))).collect(Collectors.toList());
        // 任务 7481
        if(buildingTreeVos.size() == 1 && buildingTreeVos.get(0).getChildren().size() > 0) {
            List<BuildingTreeVo> buildingTreeVosNew = buildingTreeVos.get(0).getChildren().stream().sorted(new Comparator<BuildingTreeVo>() {
                @Override
                public int compare(BuildingTreeVo o1, BuildingTreeVo o2) {
                    if(o1.getGroupType().equals(o2.getGroupType())) {
                        return 0;
                    }
                    if(o1.getGroupType().equals("building")  ) {
                        return -1;
                    }
                    if(o2.getGroupType().equals("building") ) {
                        return 1;
                    }
                    return 0;
                }
            }).collect(Collectors.toList());
            buildingTreeVos.get(0).setChildren(buildingTreeVosNew);
        }
        return buildingTreeVos;
    }

    @Override
    public List<BuildingTreeVo> selectCompanyTree(String authKey) {
        if (StringUtils.isEmpty(authKey)) {
            authKey = this.buildVideoAuthKey;
        }
        Map<String, Long> countMap = iVideoService.getVideoCountMap();
        // 1.获取公司list
        List<OrgUsrDto> orgUsrLists = jcsRemoteService.getlistCompanyTree("COMPANY");
        if (orgUsrLists.isEmpty()) {
            return new ArrayList<>();
        }
        // 2.数据结构转换
        List<BuildingTreeVo> companyList = orgUsrLists.stream().map(orgUsrDto -> {
            BuildingTreeVo vo = new BuildingTreeVo();
            vo.setGroupType("allBuilding");
            vo.setGroupCode("allBuilding");
            vo.setInstanceName(orgUsrDto.getBizOrgName());
            vo.setBizOrgCode(orgUsrDto.getBizOrgCode());
            vo.setInstanceId(orgUsrDto.getSequenceNbr());
            vo.setParentId(orgUsrDto.getParentId());
            vo.setName(orgUsrDto.getBizOrgName());
            vo.setId(orgUsrDto.getSequenceNbr());
            vo.setBizOrgName(orgUsrDto.getBizOrgName());
            vo.setTotal(countMap.get(orgUsrDto.getBizOrgCode()) == null ? 0L : countMap.get(orgUsrDto.getBizOrgCode()));
            return vo;
        }).collect(Collectors.toList());
        return companyList.stream().filter(a -> companyList.stream().noneMatch(c -> c.getId().toString().equals(a.getParentId())))
                .peek(b -> {
                    b.setChildren(getCompanyBuildingChildrenTree(b.getId().toString(), companyList));
                    b.setTotal(b.getChildren().stream().filter(c -> c.getTotal() != null).mapToLong(BuildingTreeVo::getTotal).sum() + b.getTotal());
                }).collect(Collectors.toList());

    }


    private List<BuildingTreeVo> buildBuildingAndCompanyListVos(String authKey, String type, String ment) {
        if (StringUtils.isEmpty(authKey)) {
            authKey = this.authKey;
        }
        List<BuildingTreeVo> buildingTreeVos = getBuildingTreeVos(false, null);
        // 1.获取公司list
        List<OrgUsrDto> orgUsrLists = jcsRemoteService.getCompanyDeptListWithAuth(authKey, "COMPANY", type);
        if(orgUsrLists.isEmpty()){
            return new ArrayList<>();
        }
        // 2.数据结构转换
        List<BuildingTreeVo> companyList = orgUsrLists.stream().map(orgUsrDto -> {
            BuildingTreeVo vo = new BuildingTreeVo();
            vo.setGroupType("allBuilding");
            vo.setGroupCode("allBuilding");
            vo.setInstanceName(orgUsrDto.getBizOrgName());
            vo.setBizOrgCode(orgUsrDto.getBizOrgCode());
            vo.setInstanceId(orgUsrDto.getSequenceNbr());
            vo.setParentId(orgUsrDto.getParentId());
            vo.setName(orgUsrDto.getBizOrgName());
            vo.setId(orgUsrDto.getSequenceNbr());
            vo.setBizOrgName(orgUsrDto.getBizOrgName());
            //此处为公共接口 未区分导致消防建筑页面树统计错误
            if(ment.equals("video")){
                vo.setTotal(!StringUtils.isEmpty(orgUsrDto.getBizOrgCode()) ? formInstanceMapper.queryVideoCountByBizOrgCode(orgUsrDto.getBizOrgCode()) : 0L);
            }else {
                vo.setTotal(buildingTreeVos.stream().filter(b -> !ObjectUtils.isEmpty(b.getBizOrgCode()) && b.getBizOrgCode().contains(ObjectUtils.isEmpty(vo.getBizOrgCode())?"":vo.getBizOrgCode()) && "building".equals(b.getGroupType())).count());
            }
            return vo;
        }).collect(Collectors.toList());
        // 3.将建筑的bizOrgCode转换为parentId连接树 ,拼接数据准备
        Map<String, Long> comMap = orgUsrLists.stream().collect(Collectors.toMap(OrgUsrDto::getBizOrgCode, OrgUsrDto::getSequenceNbr));
        //增加了一层对树的过滤，过滤掉指定公司外的其他建筑。
     List<BuildingTreeVo> collect = buildingTreeVos.stream().filter(build ->companyList.stream().map(m -> {
         String bizOrgCode = m.getBizOrgCode();
         return bizOrgCode;
     }).collect(Collectors.toList()).contains(build.getBizOrgCode())).collect(Collectors.toList());

        collect.forEach(b -> {
            b.setParentId("0".equals(b.getParentId()) ? String.valueOf(comMap.get(b.getBizOrgCode())) : b.getParentId());
            b.setDetailPaneApi(address);
            b.setApiUrl(apiUrl);
        });
        // 4.组装树
        companyList.addAll(collect);
        return companyList;
    }

    @Override
    public List<BuildingTreeVo> getBuildingVideoTreeNew() {
        //1.组装数据
        List<BuildingTreeVo> companyBuildingList = buildBuildingAndCompanyListVos(buildVideoAuthKey, null,"video");


        List<Map<String, Long>> countList = iFormInstanceService.getBuildVideoCount();
        Map<Long, Long> countMap = countList.stream().collect(Collectors.toMap(p -> p.get("buildId"), p -> p.get("total")));


        companyBuildingList.forEach(c -> {
            // 建筑类型数据，填充本级及子级包含的摄像头数量
            if (!ALL_BUILDING.equals(c.getGroupType())) {
                c.setTotal(countMap.get(c.getInstanceId()) == null ? 0L : countMap.get(c.getInstanceId()));
            } else {
                // 方法 复用，覆盖掉不需要的数据
//                c.setTotal(0L);
            }
        });
        //2.list to tree
        return companyBuildingList.stream()
                .filter(a -> companyBuildingList.stream().noneMatch(c -> c.getId().toString().equals(a.getParentId())))
                .peek(b -> {
                    b.setChildren(getCompanyBuildingChildrenWithCount(b.getId().toString(), companyBuildingList));
                    if (!ALL_BUILDING.equals(b.getGroupType())) {
                        b.setTotal(b.getChildren().stream().filter(c -> c.getTotal() != null).mapToLong(BuildingTreeVo::getTotal).sum());
                    }
                }).collect(Collectors.toList());
    }

    private List<BuildingTreeVo> getCompanyBuildingChildrenWithCount(String parentId, List<BuildingTreeVo> companyBuildingList) {
        return companyBuildingList.stream().filter(a -> parentId.equals(a.getParentId())).peek(a -> {
            a.setChildren(getCompanyBuildingChildrenWithCount(a.getId().toString(), companyBuildingList));
            //单位类型节点才需要设置摄像头总数，建筑的下摄像头总数已经在sql计算出来
            if (ALL_BUILDING.equals(a.getGroupType())) {
                a.setTotal(a.getChildren().stream().filter(c -> c.getTotal() != null).mapToLong(BuildingTreeVo::getTotal).sum());
            }
        }).collect(Collectors.toList());
    }

    @Override
    public List<EquiplistSpecificBySystemVO> getPointInFloor(Long floorId) {
        //0.查询画布信息，todo 建筑可标记点类型为装备、摄像头
      //  List<SourceScene> sourceScenes = sourceSceneService.findBySourceId(floorId);
        //查询所有画布
        List<SourceScene> sourceScenes = sourceSceneService.findByType("building");


//        SourceScene sourceScene = sourceScenes.size() > 0 ? sourceScenes.get(0) : new SourceScene();
////        //0.1已标记装备点
////        String equipPointInScene = sourceScene.getPointInScene() != null ? sourceScene.getPointInScene() : "";
////        //0.2已标记视频点
////        String videoPointInScene = sourceScene.getVideoInScene() != null ? sourceScene.getVideoInScene() : "";

        //1.查询楼层下的所有装备list
        List<EquiplistSpecificBySystemVO> equipmentSpecifics = equipmentSpecificMapper.getListByWarehouseStructureId(floorId, IsIotEnum.isIot.getStatus());

        equipmentSpecifics.forEach(e -> {
            //已经标记则为已绑定



            if(sourceScenes!=null&&sourceScenes.size()>0){
                Boolean isBound=false;
                for (SourceScene sourceScene : sourceScenes) {
                    String equipPointInScene = sourceScene.getPointInScene() != null ? sourceScene.getPointInScene() : "";
                    isBound= equipPointInScene.contains(e.getId().toString());
                    if(isBound){
                       break;
                    }
                }
                e.setIsBound(isBound);
            }


            e.setType("装备点");
        });
        List<EquiplistSpecificBySystemVO> bySystemVOS = new ArrayList<>(equipmentSpecifics);
        //2.查询楼层下的所有视频list
        List<Video> videos = videoMapper.selectListBySourceId(floorId);
        //3.数据加工
        videos.forEach(v -> {
            EquiplistSpecificBySystemVO vo = new EquiplistSpecificBySystemVO();
            vo.setId(v.getId());
            vo.setCode(v.getCode());
            vo.setCategoryName(v.getType());
            vo.setEquipmentName(v.getName());
            vo.setType("视频点");
            //已经标记则为已绑定
            if(sourceScenes!=null&&sourceScenes.size()>0){
                Boolean isBound=false;
                for (SourceScene sourceScene : sourceScenes) {
                    String videoPointInScene = sourceScene.getVideoInScene() != null ? sourceScene.getVideoInScene() : "";
                    isBound= videoPointInScene.contains(v.getId().toString());
                    if(isBound){
                        break;
                    }
                }
                vo.setIsBound(isBound);
            }

            bySystemVOS.add(vo);
        });
        return bySystemVOS;
    }


    @Override
    public List<BuildingTreeVo> getBuildingTreeInOrgCode(String bizOrgCode) {

        //如果传递的为部门bizOrgCode 取其上级单位下的建筑
//        ResponseModel<OrgUsrDto> companyByBizOrgCodeList = jcsFeign.getCompanyByBizOrgCodeList(bizOrgCode);
//        String resultCode = companyByBizOrgCodeList.getResult().getBizOrgCode();
        List<BuildingTreeVo> buildingTreeVos = this.getBuildingTreeVos(true, null);
        List<BuildingTreeVo> orgBuildingTreeVos = buildingTreeVos.stream().filter(b-> b.getBizOrgCode() != null && b.getBizOrgCode().contains(bizOrgCode)).collect(Collectors.toList());
        return buildingTreeVos.stream().filter(b -> "-1".equals(b.getParentId())).peek(b -> {
            b.setId(0L);
            b.setChildren(this.getCompanyBuildingChildrenTree(b.getId().toString(), orgBuildingTreeVos));
        }).collect(Collectors.toList());
    }

    public List<BuildingTreeVo> getBuildingTreeInMyOrgCode(String bizOrgCode) {

        //如果传递的为部门bizOrgCode 取其上级单位下的建筑
         ResponseModel<OrgUsrDto> companyByBizOrgCodeList = jcsFeign.getCompanyByBizOrgCodeList(bizOrgCode);
          String companyCode = companyByBizOrgCodeList.getResult().getBizOrgCode();
        List<BuildingTreeVo> buildingTreeVos = this.getBuildingTreeVos(true, companyCode);
        List<BuildingTreeVo> orgBuildingTreeVos = buildingTreeVos.stream().filter(b-> b.getBizOrgCode() != null && b.getBizOrgCode().startsWith(companyCode)).collect(Collectors.toList());


           List<BuildingTreeVo> collect = buildingTreeVos.stream().filter(b -> "-1".equals(b.getParentId())).peek(b -> {
            b.setId(0L);
            b.setChildren(this.getCompanyBuildingChildrenTree(b.getId().toString(), orgBuildingTreeVos));
        }).collect(Collectors.toList());
        return collect.get(0).getChildren();
    }

    public List<BuildingTreeVo> getBuildingTreeInMyOrgCodeList(String bizOrgCode) {
        //如果传递的为部门bizOrgCode 取其上级单位下的建筑
        ResponseModel<OrgUsrDto> companyByBizOrgCodeList = jcsFeign.getCompanyByBizOrgCodeList(bizOrgCode);
        String companyCode = companyByBizOrgCodeList.getResult().getBizOrgCode();
        List<BuildingTreeVo> buildingTreeVos = this.getBuildingTreeVos(true, companyCode);
        List<BuildingTreeVo> orgBuildingTreeVos = buildingTreeVos.stream().filter(b-> b.getBizOrgCode() != null && b.getBizOrgCode().startsWith(companyCode)).collect(Collectors.toList());
        return orgBuildingTreeVos;
    }

    @Override
    public List<OrgMenuDto> companyTreeByUserAndType() {
        return jcsRemoteService.getCompanyDeptTreeWithAuth(authKey, "COMPANY");
    }

    private List<BuildingTreeVo> getCompanyBuildingChildrenTree(String parentId, List<BuildingTreeVo> all) {
        return all.stream().filter(a -> parentId.equals(a.getParentId())).peek(a -> {
            a.setChildren(getCompanyBuildingChildrenTree(a.getId().toString(), all));
        }).collect(Collectors.toList());
    }

    @Override
    public List<BuildingTreeVo> treeByName(String bizOrgCode, String name) {
        List<BuildingTreeVo> allListVo = getBuildingTreeVosByName(true, bizOrgCode, name);
        return allListVo.stream().filter(s -> "-1".equals(s.getParentId())).map(s -> {
            BuildingTreeVo t = new BuildingTreeVo();
            Bean.copyExistPropertis(s, t);
            t.setChildren(this.getChildren(t.getInstanceId(), allListVo));
            t.setDetailPaneApi(address);
            t.setApiUrl(apiUrl);
            return t;
        }).collect(Collectors.toList());
    }

    private List<BuildingTreeVo> getBuildingTreeVosByName(Boolean isContainRootNode, String bizOrgCode, String name) {
        FormGroup formGroup = iFormGroupService.getByUniqueKey(GroupCodeEnum.ALL_BUILDING.getGroupCode());
        List<Map<String, Object>> allList = iFormInstanceService.getSpecialChildrenListByName(null, bizOrgCode, name);
        List<BuildingTreeVo> allListVo = buildBuildingData(formGroup, allList, isContainRootNode);
        Map<Long, String> absolutePositionMap = getBuildingAbsolutePosition(allListVo);
        allListVo.forEach(s -> s.setAbsolutePosition(absolutePositionMap.get(s.getId())));
        return allListVo;
    }

    @Override
    @Transactional
    public void importBuilding(MultipartFile file, ReginParams reginParams) {
        // 机构信息
        String companyCode = null;
        String orgCode = null;
        String companyName = null;
        String dutyUser = null;

        //代码执行前 需清空数据库原有数据 涉及 wl_warehouse、wl_warehouse_structure、wl_form_instance。
        formInstanceMapper.delete(null);
        iWarehouseStructureService.getBaseMapper().delete(null);
        iWarehouseService.getBaseMapper().delete(null);

        if (!ObjectUtils.isEmpty(reginParams) && !ObjectUtils.isEmpty(reginParams.getPersonIdentity())) {
            if (!ObjectUtils.isEmpty(reginParams.getPersonIdentity().getBizOrgCode())) {
                companyCode = reginParams.getPersonIdentity().getBizOrgCode();
                companyName = reginParams.getPersonIdentity().getCompanyName();
            }
            if (!ObjectUtils.isEmpty(reginParams.getCompany()) && !ObjectUtils.isEmpty(reginParams.getCompany().getOrgCode())) {
                orgCode = reginParams.getCompany().getOrgCode();
            }
        }
        if (!ObjectUtils.isEmpty(reginParams.getUserModel()) || !ObjectUtils.isEmpty(reginParams.getUserModel().getSequenceNbr())) {
            dutyUser = String.valueOf(reginParams.getUserModel().getSequenceNbr());
        }
        try {
            ExcelReader reader = EasyExcel.read(file.getInputStream()).build();
            List<BuildingImportDto> importList = ExcelUtil.readExcel(reader, BuildingImportDto.class, 0);
            if (!ObjectUtils.isEmpty(importList)) {
                // 获取所有建筑信息
                List<BuildingImportDto> buildList = importList.stream().filter(item -> item.getDataType().equals("建筑@building")).collect(Collectors.toList());
                // 建筑信息入库
                importBuildMessage(buildList, orgCode, companyName, companyCode, dutyUser);
                // 获取所有楼层信息
                List<BuildingImportDto> floorList = importList.stream().filter(item -> item.getDataType().equals("楼层@floor")).collect(Collectors.toList());
                // 楼层信息入库
                importFloorMessage(floorList, orgCode, companyName, companyCode, dutyUser);
                // 获取房间信息
                List<BuildingImportDto> roomList = importList.stream().filter(item -> item.getDataType().equals("房间@room")).collect(Collectors.toList());
                // 房间信息入库
                importRoomMessage(roomList, orgCode, companyName, companyCode, dutyUser);
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }

    }

    private void importBuildMessage(List<BuildingImportDto> collect, String orgCode, String bizOrgName, String bizOrgCode, String dutyUser) {
        // 处理建筑数据、入库 并在wl_warehouse插入跟数据
        //避免id重复且sourceId与id保持一致 通过雪花算法生成
        SnowFlakeGenerateIdWorker snowFlakeGenerateIdWorker =
                new SnowFlakeGenerateIdWorker(0L, 0L);
        long id = snowFlakeGenerateIdWorker.nextId();
        Warehouse warehouse = new Warehouse();
        warehouse.setName(orgCode);
        warehouse.setCompanyName(bizOrgName);
        warehouse.setSourceCode("10000");
        warehouse.setId(id);
        warehouse.setSourceId(id);
        iWarehouseService.getBaseMapper().insert(warehouse);

        collect.forEach(item -> {
            HashMap<String, Object> buildingData = new HashMap<>();
            // 建筑默认父级id 为顶级id
            buildingData.put("parentId", 0);
            // 建筑类型
            String groupCode = null;
            if (!ObjectUtils.isEmpty(item.getBuildingType())) {
                if (item.getBuildingType().contains("@")) {
                    String[] certificates = item.getBuildingType().split("@");
                    groupCode = certificates[1];
                }
            }
            // 建筑类别
            String buildType = null;
            if (!ObjectUtils.isEmpty(item.getBuildingCategory())) {
                if (item.getBuildingType().contains("@")) {
                    String[] certificates = item.getBuildingCategory().split("@");
                    buildType = certificates[1];
                    buildingData.put("buildType", buildType);
                }
            }
            // 建造日期
            if (!ObjectUtils.isEmpty(item.getBuildDate())) {
                buildingData.put("buildDate", item.getBuildDate());
            }

            // 公共字段处理
            publicData(item, buildingData, bizOrgCode, bizOrgName, dutyUser);
            // 保存建筑信息
            saveForm(groupCode, orgCode, buildingData, null);
        });
    }


    private void importFloorMessage(List<BuildingImportDto> collect, String orgCode, String bizOrgName, String bizOrgCode, String dutyUser) {
        // 处理楼层数据、入库
        collect.forEach(item -> {
            HashMap<String, Object> buildingData = new HashMap<>();
            // 楼层所在建筑父级id
            if (!ObjectUtils.isEmpty(item.getInWhichBuild())) {
                String parentBuildId = formInstanceMapper.selectParentBuildId(item.getInWhichBuild());
                buildingData.put("inwhichBuild", parentBuildId);
                buildingData.put("parentId", parentBuildId);
            }
            // 数据类型
            String groupCode = null;
            if (!ObjectUtils.isEmpty(item.getBuildingType())) {
                if (item.getBuildingType().contains("@")) {
                    String[] certificates = item.getBuildingType().split("@");
                    groupCode = certificates[1];
                }
            }
            // 公共字段处理
            publicData(item, buildingData, bizOrgCode, bizOrgName, dutyUser);
            // 保存楼层信息
            saveForm(groupCode, orgCode, buildingData, null);
        });
    }


    private void importRoomMessage(List<BuildingImportDto> collect, String orgCode, String bizOrgName, String bizOrgCode, String dutyUser) {
        // 处理房间数据、入库
        collect.forEach(item -> {
            HashMap<String, Object> buildingData = new HashMap<>();
            // 房间所在建筑父级id
            if (!ObjectUtils.isEmpty(item.getInWhichBuild())) {
                String parentBuildId = formInstanceMapper.selectParentBuildId(item.getInWhichBuild());
                buildingData.put("inwhichBuild", parentBuildId);
                buildingData.put("parentId", parentBuildId);
            }
            // 数据类型
            String groupCode = null;
            if (!ObjectUtils.isEmpty(item.getBuildingType())) {
                if (item.getBuildingType().contains("@")) {
                    String[] certificates = item.getBuildingType().split("@");
                    groupCode = certificates[1];
                }
            }
            // 操作人员持证数
            if (!ObjectUtils.isEmpty(item.getLicensesNumber())) {
                buildingData.put("certificatesPersonNum", item.getLicensesNumber());
            }
            // 安装位置
            if (!ObjectUtils.isEmpty(item.getLocationDescription())) {
                buildingData.put("installLoc", item.getLocationDescription());
            }
            // 维保单位
            if (!ObjectUtils.isEmpty(item.getMaintenanceCompany())) {
                buildingData.put("maintenanceUnit", item.getMaintenanceCompany());
            }
            // 每班人数
            if (!ObjectUtils.isEmpty(item.getPersonNumber())) {
                buildingData.put("personNum", item.getPersonNumber());
            }
            // 火灾预案
            if (!ObjectUtils.isEmpty(item.getFirePlan())) {
                buildingData.put("hasFirePlan", item.getFirePlan().equals("有") ? "true" : "false");
            }

            // 每班人数
            if (!ObjectUtils.isEmpty(item.getPutDate())) {
                buildingData.put("useDate", item.getPutDate());
            }
            // 每班人数
            if (!ObjectUtils.isEmpty(item.getProtectedObjects())) {
                buildingData.put("protectedObjects", item.getProtectedObjects());
            }
            // 公共字段处理
            publicData(item, buildingData, bizOrgCode, bizOrgName, dutyUser);
            // 保存楼层信息
            saveForm(groupCode, orgCode, buildingData, null);
        });
    }

    private void publicData(BuildingImportDto item, HashMap<String, Object> buildingData, String bizOrgCode, String bizOrgName, String dutyUser) {
        // 编码
        if (!ObjectUtils.isEmpty(item.getCode())) {
            buildingData.put("code", item.getCode());
        }
        // 责任人
        if (!ObjectUtils.isEmpty(dutyUser)) {
            buildingData.put("dutyUser", dutyUser);
        }
        // 房间名称
        if (!ObjectUtils.isEmpty(item.getBuildName())) {
            buildingData.put("name", item.getBuildName());
        }
        // 房间地址
        if (!ObjectUtils.isEmpty(item.getBuildingAddress())) {
            buildingData.put("address", item.getBuildingAddress());
        }
        // 添加同步风险区域操作  默认false
        if (!ObjectUtils.isEmpty(item.getBuildName())) {
            buildingData.put("isRisk", "false");
        }
        // 机构编码
        if (!ObjectUtils.isEmpty(bizOrgCode)) {
            buildingData.put("bizOrgCode", bizOrgCode);
        }
        // 机构名称
        if (!ObjectUtils.isEmpty(bizOrgName)) {
            buildingData.put("bizOrgName", bizOrgName);
        }
    }
}
