package com.testor.ddd.safetyControl.application.service.spaceManage.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.testor.biz.sys.org.model.domain.SysOrg;
import com.testor.biz.sys.org.service.SysOrgService;
import com.testor.ddd.safetyControl.application.service.equipmentManage.EquipmentManageService;
import com.testor.ddd.safetyControl.application.service.riskPointManage.RiskPointManageService;
import com.testor.ddd.safetyControl.application.service.riskSourceManage.RiskSourceManageService;
import com.testor.ddd.safetyControl.application.service.spaceManage.SpaceManageService;
import com.testor.ddd.safetyControl.application.service.spaceManage.SpaceTypeManageService;
import com.testor.ddd.safetyControl.domain.space.entity.TSafeSpaceRepo;
import com.testor.ddd.safetyControl.domain.space.entity.TSafeSpaceTypeRepo;
import com.testor.ddd.safetyControl.domain.space.service.SpaceService;
import com.testor.ddd.safetyControl.infrastructure.client.funConfClient.TableNumClient;
import com.testor.ddd.safetyControl.infrastructure.repository.space.entity.TSafeSpaceDO;
import com.testor.ddd.safetyControl.infrastructure.repository.space.entity.TSafeSpaceTypeDO;
import com.testor.ddd.safetyControl.infrastructure.uitls.GenerateCode;
import com.testor.ddd.safetyControl.infrastructure.uitls.SpaceLevelEnum;
import com.testor.ddd.safetyControl.interfaces.model.dto.space.TSafeSpaceDTO;
import com.testor.ddd.safetyControl.interfaces.model.dto.space.TSafeSpaceDTOParam;
import com.testor.ddd.safetyControl.interfaces.model.dto.space.TSafeSpaceTypeDTO;
import com.testor.ddd.safetyControl.interfaces.model.dto.space.TSafeSpaceTypeDTOParam;
import com.testor.ddd.safetyControl.interfaces.model.vo.space.TSafeSpaceVO;
import com.testor.module.duty.util.PoiExcelUtils;
import com.testor.module.notice.model.domain.TreeVO;
import com.testor.module.safe.model.dto.TSafeHazardOrgDTO;
import com.testor.module.safe.model.dto.TSafeHazardOrgParam;
import com.testor.module.safe.service.TSafeHazardOrgService;
import com.testor.module.safeCheck.model.domain.TSafeHazardCheckObject;
import com.testor.module.safeCheck.model.domain.TSafeHazardCheckPlan;
import com.testor.module.safeCheck.service.TSafeHazardCheckPlanService;
import com.tongtech.tfw.backend.common.biz.constants.BizConstants;
import com.tongtech.tfw.backend.common.biz.models.BaseResponse;
import com.tongtech.tfw.backend.common.biz.models.BaseResponseList;
import com.tongtech.tfw.backend.common.constants.enumeration.BaseStatusEnum;
import com.tongtech.tfw.backend.common.context.ContextUtils;
import com.tongtech.tfw.backend.common.exception.BusinessException;
import com.tongtech.tfw.backend.common.models.sys.UserInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class SpaceManageServiceImpl implements SpaceManageService {

    @Resource
    private SysOrgService orgService;

    @Resource
    private SpaceService spaceService;

    @Resource
    private TSafeSpaceRepo tSafeSpaceRepo;

    @Resource
    private TSafeSpaceTypeRepo tSafeSpaceTypeRepo;

    @Resource
    private TableNumClient tableNumClient;

    @Resource
    private GenerateCode generateCode;

    @Resource
    private EquipmentManageService equipmentManageService;

    @Resource
    private SpaceTypeManageService spaceTypeManageService;

    @Resource
    private RiskSourceManageService riskSourceManageService;

    @Resource
    private RiskPointManageService riskPointManageService;
    @Resource
    private TSafeHazardCheckPlanService tSafeHazardCheckPlanService;

    @Resource
    private TSafeHazardOrgService tSafeHazardOrgService;
    /**
     * 编辑空间
     *
     * @param spaceDto
     * @return
     */
    @Transactional
    public BaseResponse editSpace(TSafeSpaceDTO spaceDto){
        BaseResponse baseResponse = new BaseResponse<>();

        UserInfo curUser = ContextUtils.getLoginUser();
        if (StrUtil.isBlank(curUser.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("用户信息错误");
            return baseResponse;
        }
        String curUserOrgId = curUser.getOrgId();
        spaceDto.setOrgId(curUserOrgId);

        Integer level = spaceDto.getLevel();

        String fieldName = null;
        boolean isGenerate = false; // 是否生成了编码
        if(StrUtil.isBlank(spaceDto.getId())) { // 新增 生成编码
            fieldName = generateCode.generateSpaceTableNumFieldName(spaceDto);
            String code = generateCode.generateCodeByFieldName("t_safe_space", fieldName);
            spaceDto.setCode(code);
            isGenerate = true;
        } else { // 编辑 不允许 修改 类型 或是 车间/场所   // 编辑 修改 类型 或是 车间/场所 时 重写生成 编码
            /*TSafeSpaceDTO oldSpaceDTO = spaceService.findById(spaceDto.getId());*/
/*            if((level == 1 && !oldSpaceDTO.getSpaceTypeId().equals(spaceDto.getSpaceTypeId()))
            || (level == 2 && !oldSpaceDTO.getSpaceId().equals(spaceDto.getSpaceId()))) {
//                fieldName = generateCode.generateSpaceTableNumFieldName(spaceDto);
//                String code = generateCode.generateSpaceCodeByFieldName(fieldName);
//                spaceDto.setCode(code);
//                isGenerate = true;

                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("所属的上级不允许修改");
                return baseResponse;
            }*/
        }

        baseResponse = spaceService.editSpace(curUser.getUserId(), curUserOrgId, spaceDto);

        if(isGenerate && BaseStatusEnum.SUCCESS.code() == baseResponse.getCode().intValue()) {
            String code = spaceDto.getCode();
            String [] codeArr = code.split("-");
            String maxNum = codeArr[codeArr.length-1];
            tableNumClient.saveMaxNum("t_safe_space", fieldName, Integer.parseInt(maxNum));
        }
        return baseResponse;
    }


    public BaseResponseList<TSafeSpaceVO> listByPage(TSafeSpaceDTOParam param){

//        if(StrUtil.isBlank(param.getOrgId()) &&
//                (param.getCondOrgIdList() == null || param.getCondOrgIdList().size() == 0)) {
//            UserInfo curUser = ContextUtils.getLoginUser();
//            String curUserOrgId = curUser.getOrgId();
//            param.setOrgId(curUserOrgId);
//        }
        return spaceService.listByPage(param);
    }

    /**
     * 根据编码查询
     * @param code
     * @return
     */
    public List<TSafeSpaceVO> listByCode(String code){
        if(StrUtil.isBlank(code)) {
            return null;
        }
        List<TSafeSpaceVO> baseResponseList= spaceService.listByCode(code);

        return baseResponseList;
    }

    public TSafeSpaceDTO findById(String id){
        return tSafeSpaceRepo.findById(id);
    }

    /**
     *
     * @param type 1-车间场所，2-作业区域
     * @param id
     * @return
     */
    @Transactional
    public BaseResponse deleteById(Integer type, String id){
        BaseResponse baseResponse = new BaseResponse<>();
        if((type == null || type.intValue() != SpaceLevelEnum.workshop.getCode()
            && type.intValue() != SpaceLevelEnum.workarea.getCode())
        || StrUtil.isBlank(id)) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("参数缺失");
            return baseResponse;
        }

        UserInfo curUser = ContextUtils.getLoginUser();
        if (StrUtil.isBlank(curUser.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("用户信息错误");
            return baseResponse;
        }
        String curUserOrgId = curUser.getOrgId();
        TSafeSpaceDTO oldSpaceDto = tSafeSpaceRepo.findById(id);
        if(!curUserOrgId.equals(oldSpaceDto.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UNAUTHORIZED.code());
            baseResponse.setMsg("无权限操作");
            return baseResponse;
        }

        String checkMsg = checkDelete(id);
        if(!StrUtil.isBlank(checkMsg)) {
            baseResponse.setCode(BaseStatusEnum.UNAUTHORIZED.code());
            baseResponse.setMsg(checkMsg);
            return baseResponse;
        }

        deleteRelation(type, id);
        return baseResponse;
    }

    public String checkDelete(String spaceId){
        //  关联巡检计划、任务的判断
        //  此设备当前关联巡检计划，且巡检计划没有到达计划结束时间，
        //  或此巡检计划生成的巡检任务（存在巡检任务生成时间早于巡检计划的计划开始时间，
        //  巡检任务的结束时间晚于巡检计划的计划结束时间）没有完成，
        //  则此设备不得进行删除，进行删除则提示文案”此设备存在未完成的巡检任务或隐患排查工单，
        //  不得进行删除“。
        TSafeHazardCheckObject checkObject = new TSafeHazardCheckObject();
        checkObject.setObjId(spaceId);
        List<TSafeHazardCheckPlan> checkPlanList = tSafeHazardCheckPlanService.findByObjectInfo(checkObject);
        if(checkPlanList != null && checkPlanList.size() > 0) {
            return "此设备存在未完成的巡检任务或隐患排查工单,不得进行删除";
        }
        //  此设备当前关联隐患，
        //  且隐患状态不为“已完成”或“已关闭”，则此设备不得进行删除，
        //  进行删除则提示文案“此设备存在未完成的巡检任务或隐患排查工单，不得进行删除”。
        List<String> notInStatusList = new ArrayList<>();
        notInStatusList.add("4");
        notInStatusList.add("5");
        TSafeHazardOrgParam safeHazardOrgParam = new TSafeHazardOrgParam();
        safeHazardOrgParam.setProcessNotInStatusList(notInStatusList);
        safeHazardOrgParam.setEquipment(spaceId);
        BaseResponse<BaseResponseList<TSafeHazardOrgDTO>> hazardOrgResult = tSafeHazardOrgService.listEntity(safeHazardOrgParam);
        if(hazardOrgResult != null && hazardOrgResult.getData() != null && hazardOrgResult.getData().getTotal() > 0){
            return "此设备存在未完成的巡检任务或隐患排查工单,不得进行删除";
        }
        return null;
    }


    @Transactional
    public boolean deleteBySpaceType(String spaceTypeId) {
        if(StrUtil.isBlank(spaceTypeId)) {
            return true;
        }
        TSafeSpaceDTOParam param = new TSafeSpaceDTOParam();
        param.setStatus(BizConstants.STATUS_ENABLE);
        param.setSpaceTypeId(spaceTypeId);
        List<TSafeSpaceDTO> spaceDTOList = tSafeSpaceRepo.listAllEntity(param);
        if(spaceDTOList == null || spaceDTOList.size() ==0) {
            return true;
        }

        spaceDTOList.parallelStream().forEach(item -> {
            deleteRelation(item.getLevel(), item.getId());
        });
        return true;
    }

    /**
     * 删除 空间场所、作业区域  及 关联影响
     * @param id
     * @return
     */
    public boolean deleteRelation(Integer type, String id){
        if((type.intValue() != SpaceLevelEnum.workshop.getCode()
                && type.intValue() != SpaceLevelEnum.workarea.getCode())
                || StrUtil.isBlank(id)) {
            return false;
        }

        tSafeSpaceRepo.deleteById(id);

        //   1）设备台账—若设备“安装位置-作业区域”字段所选空间为此区域，则自动删除此设备；
        equipmentManageService.deleteBySpaceId(type, id);

       int riskRelationType = 0;
        if(type.intValue() == SpaceLevelEnum.workshop.getCode()) {
            riskRelationType = 3;
        }
        if(type.intValue() == SpaceLevelEnum.workarea.getCode()) {
            riskRelationType = 2;
        }
        //  2）风险点—若危险源的“关联空间”字段所选空间为此作业区域，则删除此风险点；
        riskSourceManageService.deleteBySpaceOrEquipment(riskRelationType, id);
        //3）危险源—若风险点的“关联空间”字段所选空间为此作业区域，则删除此危险源；
        riskPointManageService.deleteBySpaceOrEquipment(riskRelationType, id);

        /** todo 逻辑待续
         *
         *           4）风险地图—“车间/场所级”地图：系统自动在地图上删除表示此作业区域的区域
         *
         */


        return true;
    }

    @Transactional
    public Integer replaceCode(String spaceTypeId, String oldCode, String newCode){
        return tSafeSpaceRepo.replaceCode(spaceTypeId, oldCode, newCode);
    }

    /**
     * 导入车间场所
     * @param file
     * @return
     * @throws IOException
     */
    @Transactional
    public BaseResponse<String> importWorkshop(MultipartFile file) throws IOException {
        BaseResponse<String> baseResponse = new BaseResponse<>();

        UserInfo curUser = ContextUtils.getLoginUser();
        if (StrUtil.isBlank(curUser.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("用户信息错误");
            return baseResponse;
        }
        String curUserOrgId = curUser.getOrgId();
        SysOrg org = orgService.getById(curUserOrgId);
        String curUserOrgCode = org.getOrgCode();

        //判断是否为null
        if (file==null || file.getSize() <= 0) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("上传文件数据错误");
            return baseResponse;
        }
        InputStream inputStream = null;
        Workbook workbook = null;

        StringBuilder sbMsg = new StringBuilder();

        try {
            inputStream = file.getInputStream();
            // 读取Excel⽂件⼯作表
            workbook = PoiExcelUtils.readFile(inputStream, file.getOriginalFilename());
            //取得第⼀个⼯作表
            Sheet sheet = workbook.getSheetAt(0);
            //报表上传的没条数据
            List<Map<Integer, Object>> dataList = PoiExcelUtils.getBody(sheet, 5, 2);
            System.out.println(JSON.toJSONString(dataList));
            if (dataList == null || dataList.size() == 0) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("请填写模板后上传");
                return baseResponse;
            }

         //   List<WorkshopImportEntity> workshopImportList = BeanHelper.listToList(dataList, WorkshopImportEntity.class);
            List<TSafeSpaceDTO> spaceDTOList = new ArrayList<>();
            TSafeSpaceDTO spaceDTO;
            int index =0;
            // key: spaceTypeCode; value: spaceTypeId 。 根据类型code获取类型id
            Map<String, String> spaceTypeMap = new HashMap<>();
            // key: spaceName; value: index 。判断重名
            Map<String, Integer> spaceNameMap = new HashMap<>();
            // key: fieldName; value: num 。根据类型code获取 对应的table_num 的最大值
            Map<String, Integer> tabeNumMap = new HashMap<>();
          //  for (WorkshopImportEntity rowData : workshopImportList) {
            for (Map<Integer, Object> rowData : dataList) {
                index ++;
                // 车间场所名称、类型编码不为空
                if (rowData.get(1) == null || StrUtil.isBlank(rowData.get(1).toString()) ||
                    rowData.get(2) == null || StrUtil.isBlank(rowData.get(2).toString()) ||
                    rowData.get(4) == null  || StrUtil.isBlank(rowData.get(4).toString())) {
                    sbMsg.append("第"+index+"条数据，参数缺失；\n");
                    continue;
                }

                // 判断企业编码与当前用户所属企业编码是否相同
                String orgCode = rowData.get(1).toString();
                String spaceName = rowData.get(2).toString();
                String spaceTypeCode = rowData.get(4).toString();
                if(StrUtil.isBlank(orgCode)) {
                    orgCode = curUserOrgCode;
                }
                if(!curUserOrgCode.equals(orgCode)) {
                    sbMsg.append("第"+index+"条数据，车间场所["+spaceName+"]当前用户无权操作；\n");
                    continue;
                }

                // 检测 相同类型下 是否存在重名的
                String key = spaceTypeCode + "-" + spaceName;
                if(spaceNameMap.get(key) != null) {
                    sbMsg.append("第"+index+"条数据 与 第"+spaceNameMap.get(key)+"条重名，请修改第"+index+"条数据作；\n");
                    continue;
                } else {
                    spaceNameMap.put(key, index);
                }

                // 根据车间场所类型编号获取车间场所类型id
                String spaceTypeId = null;
                Integer curNum = null;
                String fieldName = orgCode+"-"+spaceTypeCode;
                if(spaceTypeMap.get(spaceTypeCode) == null) {
                    TSafeSpaceTypeDTOParam spaceTypeDTOParam = new TSafeSpaceTypeDTOParam();
                  //  spaceTypeDTOParam.setOrgId(orgCode);
                    spaceTypeDTOParam.setStatus(BizConstants.STATUS_ENABLE);
                    spaceTypeDTOParam.setCode(spaceTypeCode);
                    BaseResponseList<TSafeSpaceTypeDTO> spaceTypeDTOList = spaceTypeManageService.listByPage(spaceTypeDTOParam);
                    if(spaceTypeDTOList == null || spaceTypeDTOList.getData() == null || spaceTypeDTOList.getData().size() == 0) {
                        sbMsg.append("第"+index+"条数据，车间场所["+spaceName+"]所属的车间场所类型编码无效；\n");
                        continue;
                    }
                    TSafeSpaceTypeDTO spaceTypeDTO = spaceTypeDTOList.getData().get(0);
                    spaceTypeId = spaceTypeDTO.getId();
                    spaceTypeMap.put(spaceTypeCode, spaceTypeId);

                    // 查询此 类型 下的最大编码数
                    Integer maxNum = tableNumClient.obtainMaxNum("t_safe_space", fieldName);
                    curNum = maxNum == null ?  1 : maxNum+1;

                } else {
                    spaceTypeId = spaceTypeMap.get(spaceTypeCode);
                    curNum = tabeNumMap.get(fieldName)+1;
                }

                tabeNumMap.put(fieldName, curNum);

                String spaceCode = fieldName+"-"+curNum;
                boolean checkResult = spaceService.checkUniqueness(null, spaceTypeId, 1, spaceName, spaceCode);
                if (!checkResult) {
                    sbMsg.append("第"+index+"条数据，车间场所["+spaceName+"]在库中已存在；\n");
                    continue;
                }

                spaceDTO = new TSafeSpaceDTO();
                spaceDTO.setOrgId(curUserOrgId);
                spaceDTO.setName(spaceName);
                spaceDTO.setLevel(SpaceLevelEnum.workshop.getCode());
                spaceDTO.setSpaceTypeId(spaceTypeId);
                spaceDTO.setCode(spaceCode);
                spaceDTOList.add(spaceDTO);
            }

            if(spaceDTOList == null || spaceDTOList.size() == 0) {
                if(sbMsg == null) {
                    return baseResponse;
                } else {
                    baseResponse.setCode(BaseStatusEnum.UNKNOWN.code());
                    baseResponse.setMsg(sbMsg.toString());
                    return baseResponse;
                }
            }

            boolean result = tSafeSpaceRepo.saveBatch(spaceDTOList);
            if(!result){
                throw new BusinessException("导入失败");
            }

            // 保持 table_num 表
            for (Map.Entry<String, Integer> entry : tabeNumMap.entrySet()) {
               // System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
                tableNumClient.saveMaxNum("t_safe_space", entry.getKey(), entry.getValue());
            }

        } catch (Exception e) {
            e.printStackTrace();
            baseResponse.setCode(BaseStatusEnum.UNKNOWN.code());
            baseResponse.setData(e.getMessage());
            return baseResponse;
        }finally {
            if(inputStream != null) {
                inputStream.close();
            }
            if(workbook != null) {
                workbook.close();
            }
        }
        baseResponse.setData(sbMsg == null ? "导入成功" : sbMsg.toString());
        return baseResponse;
    }

    /**
     * 导入作业区域
     * @param file
     * @return
     * @throws IOException
     */
    @Transactional
    public BaseResponse<String> importWorkarea(MultipartFile file) throws IOException {
        BaseResponse<String> baseResponse = new BaseResponse<>();

        UserInfo curUser = ContextUtils.getLoginUser();
        if (StrUtil.isBlank(curUser.getOrgId())) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("用户信息错误");
            return baseResponse;
        }
        String curUserOrgId = curUser.getOrgId();
        SysOrg org = orgService.getById(curUserOrgId);
        String curUserOrgCode = org.getOrgCode();

        //判断是否为null
        if (file==null || file.getSize() <= 0) {
            baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
            baseResponse.setMsg("上传文件数据错误");
            return baseResponse;
        }
        InputStream inputStream = null;
        Workbook workbook = null;

        StringBuilder sbMsg = new StringBuilder();

        try {
            inputStream = file.getInputStream();
            // 读取Excel⽂件⼯作表
            workbook = PoiExcelUtils.readFile(inputStream, file.getOriginalFilename());
            //取得第⼀个⼯作表
            Sheet sheet = workbook.getSheetAt(0);
            //报表上传的没条数据
            List<Map<Integer, Object>> dataList = PoiExcelUtils.getBody(sheet, 5, 2);
            System.out.println(JSON.toJSONString(dataList));
            if (dataList == null || dataList.size() == 0) {
                baseResponse.setCode(BaseStatusEnum.UN_DATA.code());
                baseResponse.setMsg("请填写数据");
                return baseResponse;
            }

            List<TSafeSpaceDTO> spaceDTOList = new ArrayList<>();
            TSafeSpaceDTO spaceDTO;
            int index =0;
            // key: spaceCode; value: spaceId 。 根据类型code获取类型id
            Map<String, String> spaceMap = new HashMap<>();
            // key: spaceName; value: index 。判断重名
            Map<String, Integer> spaceNameMap = new HashMap<>();
            // key: fieldName; value: num 。根据类型code获取 对应的table_num 的最大值
            Map<String, Integer> tabeNumMap = new HashMap<>();
            //  for (WorkshopImportEntity rowData : workshopImportList) {
            for (Map<Integer, Object> rowData : dataList) {
                index ++;
                // 车间场所名称、类型编码不为空
                if (rowData.get(1) == null || StrUtil.isBlank(rowData.get(1).toString()) ||
                        rowData.get(2) == null || StrUtil.isBlank(rowData.get(2).toString()) ||
                        rowData.get(4) == null  || StrUtil.isBlank(rowData.get(4).toString())) {
                    sbMsg.append("第"+index+"条数据，参数缺失；\n");
                    continue;
                }

                // 判断企业编码与当前用户所属企业编码是否相同
                String orgCode = rowData.get(1).toString();
                String spaceName = rowData.get(2).toString();
                String workshopCode = rowData.get(4).toString();
                if(StrUtil.isBlank(orgCode)) {
                    orgCode = curUserOrgCode;
                }
                if(!curUserOrgCode.equals(orgCode)) {
                    sbMsg.append("第"+index+"条数据，作业区域["+spaceName+"]当前用户无权操作；\n");
                    continue;
                }

                // 检测 相同类型下 是否存在重名的
                String key = workshopCode + "-" + spaceName;
                if(spaceNameMap.get(key) != null) {
                    sbMsg.append("第"+index+"条数据 与 第"+spaceNameMap.get(key)+"条重名，请修改第"+index+"条数据作；\n");
                    continue;
                } else {
                    spaceNameMap.put(key, index);
                }

                // 根据车间场所编号获取车间场所id
                String workshopId = null;
                String spaceTypeId = null;
                Integer curNum = null;
                String fieldName = workshopCode;
                if(spaceMap.get(workshopCode) == null) {
                    TSafeSpaceDTOParam spaceDTOParam = new TSafeSpaceDTOParam();
                    spaceDTOParam.setOrgId(curUserOrgId);
                    spaceDTOParam.setStatus(BizConstants.STATUS_ENABLE);
                    spaceDTOParam.setLevel(SpaceLevelEnum.workshop.getCode());
                    spaceDTOParam.setCode(workshopCode);
                    BaseResponseList<TSafeSpaceVO> spaceVOList = listByPage(spaceDTOParam);
                    if(spaceVOList == null || spaceVOList.getData() == null || spaceVOList.getData().size() == 0) {
                        sbMsg.append("第"+index+"条数据，作业区域["+spaceName+"]所属的车间场所编码无效；\n");
                        continue;
                    }
                    TSafeSpaceVO spaceVO = spaceVOList.getData().get(0);
                    workshopId = spaceVO.getId();
                    spaceTypeId = spaceVO.getSpaceTypeId();
                    spaceMap.put(workshopCode, workshopId+"-"+spaceTypeId);

                    // 查询此 类型 下的最大编码数
                    Integer maxNum = tableNumClient.obtainMaxNum("t_safe_space", fieldName);
                    curNum = maxNum == null ?  1 : maxNum+1;

                } else {
                    String idStr = spaceMap.get(workshopCode);
                    workshopId = idStr.split("-")[0];
                    spaceTypeId = idStr.split("-")[1];
                    curNum = tabeNumMap.get(fieldName)+1;
                }

                tabeNumMap.put(fieldName, curNum);

                String spaceCode = fieldName+"-"+curNum;
                boolean checkResult = spaceService.checkUniqueness(null, workshopId, 2, spaceName, spaceCode);
                if (!checkResult) {
                    sbMsg.append("第"+index+"条数据，作业区域["+spaceName+"]在库中已存在；\n");
                    continue;
                }

                spaceDTO = new TSafeSpaceDTO();
                spaceDTO.setOrgId(curUserOrgId);
                spaceDTO.setName(spaceName);
                spaceDTO.setSpaceId(workshopId);
                spaceDTO.setLevel(SpaceLevelEnum.workarea.getCode());
                spaceDTO.setSpaceTypeId(spaceTypeId);
                spaceDTO.setCode(spaceCode);
                spaceDTOList.add(spaceDTO);
            }

            if(spaceDTOList == null || spaceDTOList.size() == 0) {
                if(sbMsg == null) {
                    return baseResponse;
                } else {
                    baseResponse.setCode(BaseStatusEnum.UNKNOWN.code());
                    baseResponse.setMsg(sbMsg.toString());
                    return baseResponse;
                }
            }

            boolean result = tSafeSpaceRepo.saveBatch(spaceDTOList);
            if(!result){
                throw new BusinessException("导入失败");
            }

            // 保持 table_num 表
            for (Map.Entry<String, Integer> entry : tabeNumMap.entrySet()) {
                // System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
                tableNumClient.saveMaxNum("t_safe_space", entry.getKey(), entry.getValue());
            }

        } catch (Exception e) {
            e.printStackTrace();
            baseResponse.setCode(BaseStatusEnum.UNKNOWN.code());
            baseResponse.setData(e.getMessage());
            return baseResponse;
        }finally {
            if(inputStream != null) {
                inputStream.close();
            }
            if(workbook != null) {
                workbook.close();
            }
        }
        baseResponse.setData(sbMsg == null ? "导入成功" : sbMsg.toString());
        return baseResponse;
    }

    @Override
    public List<TSafeSpaceDTO> findBySpaceTypeId(String id) {
        return tSafeSpaceRepo.findBySpaceTypeId(id);
    }

    @Override
    public List<TSafeSpaceDTO> selectList(String orgId) {
        return spaceService.myList(orgId);
    }

    @Override
    public List<TreeVO> getTree(String orgId) {
        if (StringUtils.isBlank(orgId)){
            orgId = ContextUtils.getLoginUser().getOrgId();
        }
        // 获取组织中使用的所有类型ID
        List<String> spaceTypeIdsByOrgId = tSafeSpaceRepo.getSpaceTypeIdsByOrgId(orgId);
        if (spaceTypeIdsByOrgId == null || spaceTypeIdsByOrgId.size() == 0){
            return Collections.emptyList();
        }
        // 使用单个查询获取所有空间场所和作业区域，并按类型ID进行分组
        Map<String, List<TSafeSpaceDO>> spacesByType = tSafeSpaceRepo.findAllSpacesByTypeIdsAndOrgId(spaceTypeIdsByOrgId, orgId)
                .stream()
                .collect(Collectors.groupingBy(TSafeSpaceDO::getSpaceTypeId));

        // 获取所有空间类型
        List<TSafeSpaceTypeDO> spaceTypes = tSafeSpaceTypeRepo.getListByIds(spaceTypeIdsByOrgId);

        // 构建树形结构
        List<TreeVO> treeVOList = spaceTypes.stream()
                .map(tSafeSpaceTypeDO -> {
                    // 创建一个 TreeVO 表示空间类型
                    TreeVO type = new TreeVO(tSafeSpaceTypeDO.getId(), tSafeSpaceTypeDO.getName(), "0");

                    // 获取该类型下的所有空间场所和作业区域
                    List<TSafeSpaceDO> spacesForType = spacesByType.getOrDefault(tSafeSpaceTypeDO.getId(), Collections.emptyList());

                    // 构建该类型下的空间场所列表
                    List<TreeVO> typeChildren = spacesForType.stream()
                            .filter(tSafeSpaceDO -> tSafeSpaceDO.getLevel().equals(1)) // 过滤出空间场所
                            .map(tSafeSpaceDO -> {
                                // 创建一个 TreeVO 表示空间场所
                                TreeVO space = new TreeVO(tSafeSpaceDO.getId(), tSafeSpaceDO.getName(), tSafeSpaceTypeDO.getId());

                                // 获取该空间场所下的所有作业区域
                                List<TSafeSpaceDO> activitiesForSpace = spacesForType.stream()
                                        .filter(activity -> activity.getLevel().equals(2) && activity.getSpaceId().equals(tSafeSpaceDO.getId())) // 过滤出作业区域
                                        .collect(Collectors.toList());

                                // 构建该空间场所下的作业区域列表
                                List<TreeVO> spaceChildren = activitiesForSpace.stream()
                                        .map(activity -> new TreeVO(activity.getId(), activity.getName(), tSafeSpaceDO.getId())) // 创建一个 TreeVO 表示作业区域
                                        .collect(Collectors.toList());

                                // 设置空间场所的子节点
                                space.setChildren(spaceChildren);
                                return space;
                            })
                            .collect(Collectors.toList()); // 收集所有空间场所

                    // 设置空间类型的子节点
                    type.setChildren(typeChildren);
                    return type;
                })
                .collect(Collectors.toList()); // 收集所有空间类型

        return treeVOList; // 返回最终的树形结构列表
    }

    @Override
    public TSafeSpaceDTO findBySpaceName(String id,String orgId) {
        return tSafeSpaceRepo.findBySpaceName(id,orgId);
    }

    @Override
    public List<TSafeSpaceVO> listSafeSpaceAll(TSafeSpaceDTOParam param) {
        return spaceService.listSafeSpaceAll(param);
    }

}
