Преглед на файлове

实现下载模板逻辑

lijie преди 3 години
родител
ревизия
96c539570b

+ 7 - 1
dmp-rwd/src/main/java/com/persagy/dmp/rwd/constants/CommonConstant.java

@@ -10,7 +10,7 @@ public class CommonConstant {
     //public static final String UPLOAD_FLAG = "uploadFlag";
     public static final String UPLOAD_FLAG = "successFlag";
     /**Excel文件的文件后缀*/
-    public static final String EXCEL_SUFFIX = "xlsm";
+    public static final String EXCEL_SUFFIX = "xlsx";
     /**响应头:Access-Control-Expose-Headers*/
     public static final String REPONSE_HEAD_ACCESS_CONTROL_EXPOSE_HEADERS = "Access-Control-Expose-Headers";
     /**响应头:Content-disposition*/
@@ -47,5 +47,11 @@ public class CommonConstant {
     public static final String SUCCESS_FLAG_ONE="1";
     /**成功标记,0-失败*/
     public static final String SUCCESS_FLAG_ZERO="0";
+    /**账号id*/
+    public static final String USER_ID="userId";
+    /**文件名称*/
+    public static final String DTO_FILE="file";
+    /**批量导入物理世界对象错误提示文件名称*/
+    public static final String UPLOAD_PERSON_ERR_FILE_NAME="批量导入物理世界对象错误提示文件.txt";
 
 }

+ 49 - 5
dmp-rwd/src/main/java/com/persagy/dmp/rwd/controller/BatchHandleObjectController.java

@@ -5,23 +5,27 @@ import com.persagy.common.criteria.JacksonCriteria;
 import com.persagy.common.web.PagedResponse;
 import com.persagy.dmp.config.DmpParameterStorage;
 import com.persagy.dmp.rwd.config.RwdConstants;
+import com.persagy.dmp.rwd.constants.CommonConstant;
 import com.persagy.dmp.rwd.handler.BusinessException;
 import com.persagy.dmp.rwd.handler.ResponseCode;
 import com.persagy.dmp.rwd.model.RelationInstanceModel;
 import com.persagy.dmp.rwd.service.BatchHandleObjectService;
+import com.persagy.dmp.rwd.util.FileUtil;
 import lombok.RequiredArgsConstructor;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 
 @RestController
 @RequestMapping("/rwd/instance/object/")
 @RequiredArgsConstructor
+@Slf4j
 public class BatchHandleObjectController {
 
     private final BatchHandleObjectService batchHandleObjectService;
@@ -34,12 +38,52 @@ public class BatchHandleObjectController {
      * Update By lijie 2021/9/22 9:54
      */
     @PostMapping("downloadObjectTemplateFile")
-    public void query(HttpServletResponse response) throws IOException {
+    public void downloadObjectTemplateFile(HttpServletResponse response) throws IOException {
         String groupCode = DmpParameterStorage.getGroupCode();
         if (StrUtil.isBlank(groupCode)) {
             throw new BusinessException(ResponseCode.A0402.getCode(),"缺少集团编码");
         }
         batchHandleObjectService.downloadObjectTemplateFile(response,groupCode);
     }
+    /***
+     * Description: 上传模板接口
+     * @param file : 文件对象
+     * @param request : 请求参数
+     * @param response : 响应参数
+     * return : void
+     * @author : lijie
+     * date :2021/9/24 10:10
+     * Update By lijie 2021/9/24 10:10
+     */
+    @PostMapping("uploadObjectTemplateFile")
+    public void uploadObjectTemplateFile(@RequestParam(CommonConstant.DTO_FILE) MultipartFile file,
+                                          HttpServletRequest request,
+                                          HttpServletResponse response){
+        String groupCode = DmpParameterStorage.getGroupCode();
+        if (StrUtil.isBlank(groupCode)) {
+            throw new BusinessException(ResponseCode.A0402.getCode(),"缺少集团编码");
+        }
+        try {
+            if (file.isEmpty()){
+                throw new BusinessException(ResponseCode.A0400.getCode(),"文件不能为空");
+            }
+            String originalFilename = file.getOriginalFilename();
+            if (StrUtil.isBlank(originalFilename)){
+                throw new BusinessException(ResponseCode.A0400.getCode(),"文件名称不能为空");
+            }
+            if (!originalFilename.endsWith(CommonConstant.EXCEL_SUFFIX)){
+                throw new BusinessException(ResponseCode.A0400.getCode(),"文件后缀名不符合,应该为xlsx");
+            }
+            batchHandleObjectService.uploadObjectTemplateFile(file,request,response);
+        }catch (Exception exr){
+            log.error("上传文件失败",exr);
+            List<String> errorList = new ArrayList<>();
+            errorList.add(exr.getMessage());
+            FileUtil.writeErrorContentToResponse(errorList,response,request,CommonConstant.UPLOAD_PERSON_ERR_FILE_NAME);
+        }
+    }
+
+
+
 
 }

+ 28 - 0
dmp-rwd/src/main/java/com/persagy/dmp/rwd/feign/DicClient.java

@@ -0,0 +1,28 @@
+package com.persagy.dmp.rwd.feign;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.persagy.common.criteria.JacksonCriteria;
+import com.persagy.common.web.MapResponse;
+import com.persagy.common.web.PagedResponse;
+import com.persagy.dmp.rwd.model.GroupModel;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.Map;
+
+/***
+ * Description: 字典服务Client
+ * @author : lijie
+ * @date :2021/9/23 15:03
+ * Update By lijie 2021/9/23 15:03
+ */
+@FeignClient(name = "dmp-dic",path = "/dic/dt/data/",url = "${persagy.dmp.dic.service:}")
+public interface DicClient {
+
+	@PostMapping("query")
+	PagedResponse<JsonNode> query(@RequestParam(name = "userId") String userId,
+								  @RequestParam(name = "groupCode") String groupCode,
+								  @RequestBody JacksonCriteria criteria);
+}

+ 13 - 1
dmp-rwd/src/main/java/com/persagy/dmp/rwd/service/BatchHandleObjectService.java

@@ -1,5 +1,7 @@
 package com.persagy.dmp.rwd.service;
 
+import org.springframework.web.multipart.MultipartFile;
+
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
@@ -21,5 +23,15 @@ public interface BatchHandleObjectService {
      * Update By lijie 2021/9/22 9:54
      */
     void downloadObjectTemplateFile(HttpServletResponse response,String groupCode) throws IOException;
-
+    /***
+     * Description: 上传模板接口
+     * @param file : 文件对象
+     * @param request : 请求参数
+     * @param response : 响应参数
+     * return : void
+     * @author : lijie
+     * date :2021/9/24 10:10
+     * Update By lijie 2021/9/24 10:10
+     */
+    void uploadObjectTemplateFile(MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IOException;
 }

+ 574 - 0
dmp-rwd/src/main/java/com/persagy/dmp/rwd/service/impl/BatchHandleObjectServiceImpl.java

@@ -2,6 +2,7 @@ package com.persagy.dmp.rwd.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.poi.excel.ExcelReader;
 import cn.hutool.poi.excel.ExcelUtil;
 import cn.hutool.poi.excel.RowUtil;
 import cn.hutool.poi.excel.WorkbookUtil;
@@ -10,22 +11,29 @@ import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.persagy.common.criteria.JacksonCriteria;
+import com.persagy.common.json.JacksonMapper;
 import com.persagy.common.web.ListResponse;
 import com.persagy.common.web.PagedResponse;
+import com.persagy.dmp.rwd.constants.CommonConstant;
 import com.persagy.dmp.rwd.entity.FuncidDef;
 import com.persagy.dmp.rwd.entity.QFuncidDef;
+import com.persagy.dmp.rwd.enums.ObjType;
+import com.persagy.dmp.rwd.feign.DicClient;
 import com.persagy.dmp.rwd.handler.BusinessException;
 import com.persagy.dmp.rwd.handler.ResponseCode;
 import com.persagy.dmp.rwd.model.ClassDefModel;
 import com.persagy.dmp.rwd.model.FuncidDefModel;
 import com.persagy.dmp.rwd.repository.FuncidDefRepository;
 import com.persagy.dmp.rwd.service.*;
+import com.persagy.dmp.rwd.util.FileUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.ss.usermodel.Name;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.apache.poi.ss.util.SheetUtil;
 import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -33,6 +41,7 @@ import java.io.IOException;
 import java.text.Collator;
 import java.util.*;
 import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.stream.Collectors;
 
 /***
  * Description: 对象的上传下载逻辑处理类
@@ -50,6 +59,8 @@ public class BatchHandleObjectServiceImpl extends BaseService implements BatchHa
     private final FuncidDefService funcidDefService;
     /**类型定义逻辑处理类*/
     private final ClassDefService classDefService;
+    /**字典服务客户端*/
+    private final DicClient dicClient;
     /**物理世界对象批量导入模板的位置*/
     private static final String TEMPLATE_FILE_PATH="/template/ObjectInfoTemplate.xlsx";
     /**建筑功能类型sheet*/
@@ -58,6 +69,16 @@ public class BatchHandleObjectServiceImpl extends BaseService implements BatchHa
     private static final String SPACE_ZONES_SHEET_NAME="spaceZones";
     /**空间功能类型sheet*/
     private static final String SPACE_FUNC_TYPES_SHEET_NAME="roomFuncTypes";
+    /**专业系统类sheet*/
+    private static final String SYSTEM_OBJECT_CLAZZ_SHEET_NAME="systemObjectClazz";
+    /**专业系统设备类sheet*/
+    private static final String EQUIPMENT_OBJECT_CLAZZ_SHEET_NAME="equipmentObjectClazz";
+    /**对象信息点sheet*/
+    private static final String SYSTEM_OBJECT_INFOS_SHEET_NAME="systemObjectInfos";
+    /**对象信息点sheet*/
+    private static final String EQUIPMENT_OBJECT_INFOS_SHEET_NAME="equipmentObjectInfos";
+    /**对象信息点sheet*/
+    private static final String OBJECT_CLAZZ_SHEET_NAME="objectClazz";
 
 
     /***
@@ -91,6 +112,63 @@ public class BatchHandleObjectServiceImpl extends BaseService implements BatchHa
         }.downloadFile();
     }
     /***
+     * Description: 上传模板接口
+     * @param file : 文件对象
+     * @param request : 请求参数
+     * @param response : 响应参数
+     * return : void
+     * @author : lijie
+     * date :2021/9/24 10:10
+     * Update By lijie 2021/9/24 10:10
+     */
+    @Override
+    public void uploadObjectTemplateFile(MultipartFile file, HttpServletRequest request,
+                                         HttpServletResponse response) throws IOException {
+        ExcelReader commonObjectSheet = ExcelUtil.getReader(file.getInputStream(),0);
+        ExcelReader equipObjectSheet = ExcelUtil.getReader(file.getInputStream(),1);
+        ExcelReader systemObjectSheet = ExcelUtil.getReader(file.getInputStream(),2);
+        ExcelReader systemObjectInfosSheet = ExcelUtil.getReader(file.getInputStream(), SYSTEM_OBJECT_INFOS_SHEET_NAME);
+        ExcelReader equipObjectInfosSheet = ExcelUtil.getReader(file.getInputStream(), EQUIPMENT_OBJECT_INFOS_SHEET_NAME);
+        ExcelReader deptSheet = ExcelUtil.getReader(file.getInputStream(),1);
+        ExcelReader positionSheet = ExcelUtil.getReader(file.getInputStream(),2);
+        ExcelReader domainSheet = ExcelUtil.getReader(file.getInputStream(),3);
+        ExcelReader sexSheet = ExcelUtil.getReader(file.getInputStream(),4);
+        ExcelReader prjectSheet = ExcelUtil.getReader(file.getInputStream(),5);
+//        List<List<Object>> uploadData = firstSheet.read();
+//        List<List<Object>> deptListList = deptSheet.read();
+//        List<List<Object>> positionListList = positionSheet.read();
+//        List<List<Object>> domainListList = domainSheet.read();
+//        List<List<Object>> sexListList = sexSheet.read();
+//        List<List<Object>> prjectListList = prjectSheet.read();
+//        List<String> checkFileErrList = checkFileIsValid(uploadData);
+//        if (CollUtil.isNotEmpty(checkFileErrList)){
+//            FileUtil.writeErrorContentToResponse(checkFileErrList,response,request, WorkConstant.UPLOAD_PERSON_ERR_FILE_NAME);
+//            return;
+//        }
+//        // 1.{部门名称:部门id}映射
+//        Map<String,String> deptMap = createDataMap(deptListList,0,1);
+//        Map<String,String> deptTypeMap = createDataMap(deptListList,1,2);
+//        // 2.{岗位名称:岗位id}映射
+//        Map<String,String> positionMap = createDataMap(positionListList,0,1);
+//        Map<String,String> positionAuthoMap = createDataMap(positionListList,1,2);
+//        // 3.{专业名称:专业id}映射
+//        Map<String,String> domainMap = createDataMap(domainListList,0,1);
+//        // 4.{性别名称:性别id}映射
+//        Map<String,String> sexMap = createDataMap(sexListList,0,1);
+//        // 5.{项目名称:项目id}映射
+//        Map<String,String> projectMap = createDataMap(prjectListList,0,1);
+//        // 4.检验数据合法性
+//        List<String> checkDataErrList = checkDataIsValid(uploadData, deptMap, positionMap, domainMap,sexMap,projectMap,firstSheet);
+//        if (CollUtil.isNotEmpty(checkDataErrList)){
+//            FileUtil.writeErrorContentToResponse(checkDataErrList,response,request, WorkConstant.UPLOAD_PERSON_ERR_FILE_NAME);
+//            return;
+//        }
+//        batchHandleUploadDatas(userId, uploadData,firstSheet, deptMap, positionMap, domainMap,
+//                sexMap,projectMap,deptTypeMap,positionAuthoMap);
+//        response.addHeader(CommonConstant.UPLOAD_FLAG,MagicNumEnum.SUCCESS_FLAG_ONE.getValue());
+    }
+
+    /***
      * Description: 填充对象数据
      * @param workbook : 工作簿
      * @return : void
@@ -109,7 +187,503 @@ public class BatchHandleObjectServiceImpl extends BaseService implements BatchHa
         fillSpaceZoneDataToWorkbook(workbook,groupCode);
         // 5.填充空间功能类型
         fillSpaceFuncTypesDataToWorkbook(workbook,groupCode);
+        // 6.填充专业系统设备类
+        fillObjectClazzDataToWorkbook(workbook,groupCode);
+    }
+    /***
+     * Description: 填充专业系统设备类型
+     * 存两个excel以方便做名称管理器
+     * @param workbook : 工作簿
+     * @param groupCode : 集团编码
+     * @return : void
+     * @author : lijie
+     * @date :2021/9/23 14:10
+     * Update By lijie 2021/9/23 14:10
+     */
+    private void fillObjectClazzDataToWorkbook(Workbook workbook, String groupCode) {
+        // 1.查询专业数据
+        List<JsonNode> domainDatas = queryDomainData(groupCode);
+        // 1.1 获得专业code与专业名称的映射
+        Map<String, String> domainNameMap = getDomainCodeMap(domainDatas);
+        // 1.2 获得专业code集合
+        List<String> domainCodes = new ArrayList<>(domainNameMap.keySet());
+        // 1.3 查询系统设备类数据
+        List<ClassDefModel> defModels = querySystemEquipClassDataByDomainCodes(domainCodes,groupCode);
+        // 1.4 获得系统类的映射,设备类的映射
+        Map<String,Map<String, String>> systemCodeMap = new HashMap<>();
+        Map<String,Map<String, String>> equipmentCodeMap = new HashMap<>();
+        Set<String> classCodeSet = new HashSet<>();
+        analysisSystemEquipmentMap(defModels,systemCodeMap,equipmentCodeMap,domainNameMap,classCodeSet);
+        // 2.查询信息点数据
+        classCodeSet.add(ObjType.system.name());
+        classCodeSet.add(ObjType.equipment.name());
+        List<FuncidDefModel> funcidDefModels = queryDefFuncidByClassCodes(classCodeSet, groupCode);
+        Map<String,List<FuncidDefModel>> systemFuncidMap = new HashMap<>();
+        Map<String,List<FuncidDefModel>> equipFuncidMap = new HashMap<>();
+        analysisSystemEquipFuncidMap(funcidDefModels,systemFuncidMap,equipFuncidMap);
+        // 3.填充excel数据
+        // 3.1 填充系统类及系统类信息点
+        fillSystemObjectClazzDataToWorkbook(workbook,domainNameMap,systemCodeMap,systemFuncidMap);
+        // 3.2 填充设备类及设备类信息点
+        fillEquipObjectClazzDataToWorkbook(workbook,domainNameMap,systemCodeMap,equipmentCodeMap,equipFuncidMap);
+    }
+    /***
+     * Description: 填充设备类信息点及设备类数据
+     * @param workbook : 工作簿
+     * @param domainNameMap : 专业数据
+     * @param systemCodeMap : 系统类数据
+     * @param equipmentCodeMap : 设备类数据
+     * @param equipFuncidMap : 设备类信息点
+     * @return : void
+     * @author : lijie
+     * @date :2021/9/24 0:02
+     * Update By lijie 2021/9/24 0:02
+     */
+    private void fillEquipObjectClazzDataToWorkbook(Workbook workbook, Map<String, String> domainNameMap,
+                                                    Map<String, Map<String, String>> systemCodeMap,
+                                                    Map<String, Map<String, String>> equipmentCodeMap,
+                                                    Map<String, List<FuncidDefModel>> equipFuncidMap) {
+        Sheet equipObjectClazzSheet = WorkbookUtil.getOrCreateSheet(workbook, EQUIPMENT_OBJECT_CLAZZ_SHEET_NAME);
+        Sheet equipObjectInfosSheet = WorkbookUtil.getOrCreateSheet(workbook, EQUIPMENT_OBJECT_INFOS_SHEET_NAME);
+        Sheet objectClazzSheet = WorkbookUtil.getOrCreateSheet(workbook, OBJECT_CLAZZ_SHEET_NAME);
+        // 1.写入专业
+        Set<Map.Entry<String, String>> entries = domainNameMap.entrySet();
+        int i=1;
+        int clazzIndex = 0;
+        for (Map.Entry<String, String> entry : entries) {
+            CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(equipObjectClazzSheet,i),0),entry.getValue()+StrUtil.UNDERLINE,null);
+            CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(equipObjectClazzSheet,0),i),entry.getValue()+StrUtil.UNDERLINE,null);
+            CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(objectClazzSheet,clazzIndex),0),entry.getValue(),null);
+            CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(objectClazzSheet,clazzIndex),1),entry.getKey(),null);
+            i++;
+            clazzIndex++;
+        }
+        // 2.写入系统类
+        int m=1;
+        for (Map.Entry<String, String> entry : entries) {
+            String domainCode = entry.getKey();
+            Map<String, String> systemClazzMap = systemCodeMap.getOrDefault(domainCode, new HashMap<>());
+            List<Map.Entry<String, String>> systemClazzEntries = CollUtil.newArrayList(systemClazzMap.entrySet());
+            systemClazzEntries.sort((e1,e2)->CHINA_COLLATOR.compare(e1.getValue(),e2.getValue()));
+            int n=1;
+            for (Map.Entry<String, String> clazzEntry : systemClazzEntries) {
+                CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(equipObjectClazzSheet,n),m),clazzEntry.getValue()+StrUtil.UNDERLINE,null);
+                CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(objectClazzSheet,clazzIndex),0),entry.getValue(),null);
+                CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(objectClazzSheet,clazzIndex),1),entry.getKey(),null);
+                n++;
+                clazzIndex++;
+            }
+            setSheetRefersToFormula(workbook,2,n,m,EQUIPMENT_OBJECT_CLAZZ_SHEET_NAME,entry.getValue()+StrUtil.UNDERLINE);
+            m++;
+        }
+        // 3.写入设备类
+        for (Map.Entry<String, String> entry : entries) {
+            String domainCode = entry.getKey();
+            Map<String, String> systemClazzMap = systemCodeMap.getOrDefault(domainCode, new HashMap<>());
+            List<Map.Entry<String, String>> systemClazzEntries = CollUtil.newArrayList(systemClazzMap.entrySet());
+            systemClazzEntries.sort((e1,e2)->CHINA_COLLATOR.compare(e1.getValue(),e2.getValue()));
+            for (Map.Entry<String, String> clazzEntry : systemClazzEntries) {
+                // 写入信息点
+                String clazzKey = clazzEntry.getKey();
+                Map<String, String> equipClazzMap = equipmentCodeMap.getOrDefault(clazzKey, new HashMap<>());
+                CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(equipObjectClazzSheet,0),m),clazzEntry.getValue(),null);
+                int n=1;
+                List<Map.Entry<String, String>> equipClazzList = CollUtil.newArrayList(equipClazzMap.entrySet());
+                equipClazzList.sort((c1,c2)->CHINA_COLLATOR.compare(c1.getValue(),c2.getValue()));
+                for (Map.Entry<String, String> equipEntry : equipClazzList) {
+                    String modelName = equipEntry.getValue();
+                    CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(equipObjectClazzSheet,n),m),modelName,null);
+                    CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(objectClazzSheet,clazzIndex),0),entry.getValue(),null);
+                    CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(objectClazzSheet,clazzIndex),1),entry.getKey(),null);
+                    n++;
+                    clazzIndex++;
+                }
+                setSheetRefersToFormula(workbook,2,n,m,EQUIPMENT_OBJECT_CLAZZ_SHEET_NAME,clazzEntry.getValue()+StrUtil.UNDERLINE);
+                m++;
+            }
+        }
+        // 3.写入设备类信息点
+        int infoIndex=0;
+        for (Map.Entry<String, String> entry : entries) {
+            String domainCode = entry.getKey();
+            Map<String, String> systemClazzMap = systemCodeMap.getOrDefault(domainCode, new HashMap<>());
+            List<Map.Entry<String, String>> systemClazzEntries = CollUtil.newArrayList(systemClazzMap.entrySet());
+            systemClazzEntries.sort((e1,e2)->CHINA_COLLATOR.compare(e1.getValue(),e2.getValue()));
+            for (Map.Entry<String, String> clazzEntry : systemClazzEntries) {
+                // 写入信息点
+                String clazzKey = clazzEntry.getKey();
+                Map<String, String> equipClazzMap = equipmentCodeMap.getOrDefault(clazzKey, new HashMap<>());
+                List<Map.Entry<String, String>> equipClazzList = CollUtil.newArrayList(equipClazzMap.entrySet());
+                equipClazzList.sort((c1,c2)->CHINA_COLLATOR.compare(c1.getValue(),c2.getValue()));
+                for (Map.Entry<String, String> equipEntry : equipClazzList) {
+                    String equipClazzKey = equipEntry.getKey();
+                    List<FuncidDefModel> defModels = equipFuncidMap.getOrDefault(equipClazzKey, new ArrayList<>());
+                    defModels.sort((m1,m2)->CHINA_COLLATOR.compare(m1.getName(),m2.getName()));
+                    CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(equipObjectClazzSheet,0),m),equipEntry.getValue(),null);
+                    int n=1;
+                    Set<String> codes = new HashSet<>();
+                    for (FuncidDefModel defModel : defModels) {
+                        if (codes.contains(defModel.getCode())){
+                            continue;
+                        }
+                        codes.add(defModel.getCode());
+                        String modelName = equipEntry.getValue()+StrUtil.UNDERLINE+defModel.getName();
+                        CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(equipObjectClazzSheet,n),m),modelName,null);
+                        CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(equipObjectInfosSheet,infoIndex),0),modelName,null);
+                        CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(equipObjectInfosSheet,infoIndex),1),defModel.getCode(),null);
+                        infoIndex++;
+                        n++;
+                    }
+                    setSheetRefersToFormula(workbook,2,n,m,EQUIPMENT_OBJECT_CLAZZ_SHEET_NAME,equipEntry.getValue());
+                    m++;
+                }
+            }
+        }
+    }
+
+    /***
+     * Description: 填充系统类数据
+     * @param workbook : 工作簿
+     * @param domainNameMap : 专业名称映射
+     * @param systemCodeMap : 系统名称映射
+     * @return : void
+     * @author : lijie
+     * @date :2021/9/23 18:54
+     * Update By lijie 2021/9/23 18:54
+     */
+    private void fillSystemObjectClazzDataToWorkbook(Workbook workbook,
+                                                     Map<String, String> domainNameMap,
+                                                     Map<String, Map<String, String>> systemCodeMap,
+                                                     Map<String,List<FuncidDefModel>> systemFuncidMap) {
+        Sheet systemObjectClazzSheet = WorkbookUtil.getOrCreateSheet(workbook, SYSTEM_OBJECT_CLAZZ_SHEET_NAME);
+        Sheet objectInfosSheet = WorkbookUtil.getOrCreateSheet(workbook, SYSTEM_OBJECT_INFOS_SHEET_NAME);
+        // 1.写入专业
+        Set<Map.Entry<String, String>> entries = domainNameMap.entrySet();
+        int i=1;
+        for (Map.Entry<String, String> entry : entries) {
+            CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(systemObjectClazzSheet,i),0),entry.getValue(),null);
+            CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(systemObjectClazzSheet,0),i),entry.getValue(),null);
+            i++;
+        }
+        // 2.写入系统类
+        int m=1;
+        for (Map.Entry<String, String> entry : entries) {
+            String domainCode = entry.getKey();
+            Map<String, String> systemClazzMap = systemCodeMap.getOrDefault(domainCode, new HashMap<>());
+            List<Map.Entry<String, String>> systemClazzEntries = CollUtil.newArrayList(systemClazzMap.entrySet());
+            systemClazzEntries.sort((e1,e2)->CHINA_COLLATOR.compare(e1.getValue(),e2.getValue()));
+            int n=1;
+            for (Map.Entry<String, String> clazzEntry : systemClazzEntries) {
+                CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(systemObjectClazzSheet,n),m),clazzEntry.getValue(),null);
+                n++;
+            }
+            setSheetRefersToFormula(workbook,2,n,m,SYSTEM_OBJECT_CLAZZ_SHEET_NAME,entry.getValue());
+            m++;
+        }
+        // 3.写入信息点
+        int infoIndex = 0;
+        for (Map.Entry<String, String> entry : entries) {
+            String domainCode = entry.getKey();
+            Map<String, String> systemClazzMap = systemCodeMap.getOrDefault(domainCode, new HashMap<>());
+            List<Map.Entry<String, String>> systemClazzEntries = CollUtil.newArrayList(systemClazzMap.entrySet());
+            systemClazzEntries.sort((e1,e2)->CHINA_COLLATOR.compare(e1.getValue(),e2.getValue()));
+            for (Map.Entry<String, String> clazzEntry : systemClazzEntries) {
+                // 写入信息点
+                String clazzKey = clazzEntry.getKey();
+                List<FuncidDefModel> defModels = systemFuncidMap.getOrDefault(clazzKey, new ArrayList<>());
+                defModels.sort((m1,m2)->CHINA_COLLATOR.compare(m1.getName(),m2.getName()));
+                CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(systemObjectClazzSheet,0),m),clazzEntry.getValue(),null);
+                int n=1;
+                Set<String> codes = new HashSet<>();
+                for (FuncidDefModel defModel : defModels) {
+                    if (codes.contains(defModel.getCode())){
+                        continue;
+                    }
+                    codes.add(defModel.getCode());
+                    String modelName = clazzEntry.getValue()+StrUtil.UNDERLINE+defModel.getName();
+                    CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(systemObjectClazzSheet,n),m),modelName,null);
+                    CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(objectInfosSheet,infoIndex),0),modelName,null);
+                    CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(objectInfosSheet,infoIndex),1),defModel.getCode(),null);
+                    infoIndex++;
+                    n++;
+                }
+                setSheetRefersToFormula(workbook,2,n,m,SYSTEM_OBJECT_CLAZZ_SHEET_NAME,clazzEntry.getValue());
+                m++;
+            }
+        }
+
+    }
+
+    /***
+     * Description: 创建名称
+     * @param workbook : 工作簿
+     * @param startRowId : 便宜量
+     * @param endRowId : 行id
+     * @param colCount : 索引数
+     * @param sheetName : sheet名称
+     * @param manageName : 名称管理器中的名称
+     * @return : void
+     * @author : lijie
+     * @date :2021/4/29 10:23
+     * Update By lijie 2021/4/29 10:23
+     */
+    private void setSheetRefersToFormula(Workbook workbook, int startRowId, int endRowId, int colCount,String sheetName,String manageName) {
+        String range = getRange(startRowId, endRowId, colCount);
+        Name name = workbook.createName();
+        //key不可重复
+        name.setNameName(manageName);
+        String formula = sheetName+"!" + range;
+        name.setRefersToFormula(formula);
+    }
+
+    /**
+     *  计算formula
+     * @param startRowId 偏移量,如果给0,表示从A列开始,1,就是从B列
+     * @param endRowId 第几行
+     * @param colCount 一共多少列
+     * @return 如果给入参 1,1,10. 表示从B1-K1。最终返回 $B$1:$K$1
+     *
+     */
+    public static String getRange(int startRowId, int endRowId, int colCount) {
+        char start = 'A';
+        if (colCount <= 25) {
+//            char end = (char)(start + colCount - 1);
+//            return "$" + start + "$" + rowId + ":$" + end + "$" + rowId;
+            char end = (char)(start + colCount);
+            return "$" + end + "$" + startRowId + ":$" + end + "$" + endRowId;
+        } else {
+            char endPrefix = 'A';
+            char endSuffix = 'A';
+            if ((colCount - 25) / 26 == 0 || colCount == 51) {// 26-51之间,包括边界(仅两次字母表计算)
+                if ((colCount - 25) % 26 == 0) {// 边界值
+                    endSuffix = (char)('A' + 25);
+                } else {
+                    endSuffix = (char)('A' + (colCount - 25) % 26 - 1);
+                }
+            } else {// 51以上
+                if ((colCount - 25) % 26 == 0) {
+                    endSuffix = (char)('A' + 25);
+                    endPrefix = (char)(endPrefix + (colCount - 25) / 26 - 1);
+                } else {
+                    endSuffix = (char)('A' + (colCount - 25) % 26 - 1);
+                    endPrefix = (char)(endPrefix + (colCount - 25) / 26);
+                }
+            }
+            return "$" + endPrefix + endSuffix + "$" + startRowId + ":$" + endPrefix + endSuffix + "$" + endRowId;
+        }
+    }
+
+    /***
+     * Description: 解析系统设备类信息点映射
+     * @param funcidDefModels : 信息点集合
+     * @param systemFuncidMap : 系统类信息点映射
+     * @param equipFuncidMap : 设备类型信息点映射
+     * @return : void
+     * @author : lijie
+     * @date :2021/9/23 18:24
+     * Update By lijie 2021/9/23 18:24
+     */
+    private void analysisSystemEquipFuncidMap(List<FuncidDefModel> funcidDefModels,
+                                              Map<String, List<FuncidDefModel>> systemFuncidMap,
+                                              Map<String, List<FuncidDefModel>> equipFuncidMap) {
+        if (CollUtil.isEmpty(funcidDefModels)){
+            return;
+        }
+        Set<String> filterCodes = CollUtil.newHashSet("localId", "localName", "id", "name");
+        // 1.获得系统类通用信息点(去掉localId,localName,id,name)
+        List<FuncidDefModel> commonSystemModels = funcidDefModels.stream()
+                .filter(model -> ObjType.system.name().equals(model.getClassCode())
+                        && StrUtil.isNotBlank(model.getCode())
+                        && StrUtil.isNotBlank(model.getName())
+                        && !filterCodes.contains(model.getCode()))
+                .collect(Collectors.toList());
+        // 2.获得设备类通用信息点(去掉localId,localName,id,name)
+        List<FuncidDefModel> commonEquipModels = funcidDefModels.stream()
+                .filter(model -> ObjType.equipment.name().equals(model.getClassCode())
+                        && StrUtil.isNotBlank(model.getCode())
+                        && StrUtil.isNotBlank(model.getName())
+                        && !filterCodes.contains(model.getCode()))
+                .collect(Collectors.toList());
+        // 3.解析数据
+        for (FuncidDefModel model : funcidDefModels) {
+            if (ObjType.system.name().equals(model.getClassCode())
+                    || ObjType.equipment.name().equals(model.getClassCode())
+                    || StrUtil.isBlank(model.getCode())
+                    || StrUtil.isBlank(model.getName())
+                    || filterCodes.contains(model.getCode())){
+                continue;
+            }
+            if (model.getClassCode().length()!=4 && model.getClassCode().length()!=6){
+                continue;
+            }
+            // classCode长度为4位的是系统类
+            if (model.getClassCode().length()==4){
+                List<FuncidDefModel> defModelList = systemFuncidMap.getOrDefault(model.getClassCode(), new ArrayList<>());
+                if (CollUtil.isEmpty(defModelList)){
+                    defModelList.addAll(commonSystemModels);
+                }
+                defModelList.add(model);
+                systemFuncidMap.put(model.getClassCode(),defModelList);
+                continue;
+            }
+            // classCode长度为6位的是设备类
+            List<FuncidDefModel> defModelList = equipFuncidMap.getOrDefault(model.getClassCode(), new ArrayList<>());
+            if (CollUtil.isEmpty(defModelList)){
+                defModelList.addAll(commonEquipModels);
+            }
+            defModelList.add(model);
+            equipFuncidMap.put(model.getClassCode(),defModelList);
+        }
+    }
+
+    /***
+     * Description: 根据classCode查询系统和设备的信息点
+     * @param classCodeSet : classCode的集合
+     * @return : void
+     * @author : lijie
+     * @date :2021/9/23 18:14
+     * Update By lijie 2021/9/23 18:14
+     */
+    private List<FuncidDefModel> queryDefFuncidByClassCodes(Set<String> classCodeSet,String groupCode) {
+        JacksonCriteria jacksonCriteria = JacksonCriteria.newInstance();
+        jacksonCriteria.add("classCode").in(new ArrayList<>(classCodeSet));
+        ListResponse<FuncidDefModel> modelListResponse =
+                funcidDefService.queryFuncid(groupCode, null, null, null, jacksonCriteria);
+        if (!modelListResponse.success() || CollUtil.isEmpty(modelListResponse.getData())){
+            return new ArrayList<>();
+        }
+        return modelListResponse.getData();
+    }
+
+    /***
+     * Description: 解析系统设备类数据,得到系统类映射,设备类映射
+     * @param defModels : 系统设备类型数据
+     * @param systemCodeMap : 系统类映射
+     * @param equipmentCodeMap : 设备类型映射
+     * @param domainNameMap : 专业code和专业名称的映射
+     * @param classCodeSet : classCode的集合
+     * @return : void
+     * @author : lijie
+     * @date :2021/9/23 17:34
+     * Update By lijie 2021/9/23 17:34
+     */
+    private void analysisSystemEquipmentMap(List<ClassDefModel> defModels,
+                                            Map<String, Map<String, String>> systemCodeMap,
+                                            Map<String, Map<String, String>> equipmentCodeMap,
+                                            Map<String,String> domainNameMap,
+                                            Set<String> classCodeSet) {
+        // 1.获得系统类映射
+        for (ClassDefModel defModel : defModels) {
+            if (!ObjType.system.equals(defModel.getObjType())){
+                continue;
+            }
+            if (!domainNameMap.containsKey(defModel.getMajorCode())){
+                continue;
+            }
+            classCodeSet.add(defModel.getCode());
+            Map<String, String> systemClassMap = systemCodeMap.getOrDefault(defModel.getMajorCode(), new HashMap<>());
+            systemClassMap.put(defModel.getCode(),domainNameMap.get(defModel.getMajorCode())+StrUtil.UNDERLINE+defModel.getName());
+            systemCodeMap.put(defModel.getMajorCode(),systemClassMap);
+        }
+        // 2.获得设备类映射
+        for (ClassDefModel defModel : defModels) {
+            if (!ObjType.equipment.equals(defModel.getObjType())
+                    || !domainNameMap.containsKey(defModel.getMajorCode())){
+                continue;
+            }
+            Map<String, String> systemClassMap = systemCodeMap.getOrDefault(defModel.getMajorCode(), new HashMap<>());
+            if (!systemClassMap.containsKey(defModel.getSystemCode())){
+                continue;
+            }
+            classCodeSet.add(defModel.getCode());
+            Map<String, String> equipClassMap = equipmentCodeMap.getOrDefault(defModel.getSystemCode(), new HashMap<>());
+            String systemClassName = systemClassMap.get(defModel.getSystemCode());
+            String equipName = systemClassName+StrUtil.UNDERLINE+defModel.getName();
+            equipClassMap.put(defModel.getCode(),equipName);
+            equipmentCodeMap.put(defModel.getSystemCode(),equipClassMap);
+        }
+    }
+
+    /***
+     * Description: 根据专业code集合查询系统设备类数据
+     * @param domainCodes : 专业code集合
+     * @param groupCode : 集团编码
+     * @return : java.util.List<com.persagy.dmp.rwd.model.ClassDefModel>
+     * @author : lijie
+     * @date :2021/9/23 17:29
+     * Update By lijie 2021/9/23 17:29
+     */
+    private List<ClassDefModel> querySystemEquipClassDataByDomainCodes(List<String> domainCodes,String groupCode) {
+        JacksonCriteria jacksonCriteria = JacksonCriteria.newInstance();
+        jacksonCriteria.add("majorCode").in(domainCodes);
+        ListResponse<ClassDefModel> queryClass =
+                classDefService.queryClass(groupCode, null, null, null, true, jacksonCriteria);
+        if (!queryClass.success()){
+            throw new BusinessException(ResponseCode.B0001.getCode(),"查询系统设备类数据失败");
+        }
+        List<ClassDefModel> defModels = queryClass.getData();
+        if (CollUtil.isEmpty(defModels)){
+            throw new BusinessException(ResponseCode.B0001.getCode(),"查询系统设备类数据失败");
+        }
+        // 特殊处理一下带()的名称
+        for (ClassDefModel defModel : defModels) {
+            String name = defModel.getName();
+            if (name.contains("(")){
+                name = name.replace("(","_");
+            }
+            if (name.contains(")")){
+                name = name.replace(")","");
+            }
+            name = StrUtil.trim(name, 0);
+            defModel.setName(name);
+        }
+        return defModels;
+    }
+
+    /***
+     * Description: 获得专业code与专业名称的映射
+     * @param domainDatas : 专业数据
+     * @return : java.util.Map<java.lang.String,java.lang.String>
+     * @author : lijie
+     * @date :2021/9/23 17:14
+     * Update By lijie 2021/9/23 17:14
+     */
+    private Map<String, String> getDomainCodeMap(List<JsonNode> domainDatas) {
+        return domainDatas
+                .stream()
+                .filter(node -> node.has("code")
+                        && StrUtil.isNotBlank(node.get("code").asText())
+                        && node.has("label")
+                        && StrUtil.isNotBlank(node.get("label").asText()))
+                .collect(Collectors
+                        .toMap(node -> node.get("code").asText(),
+                                node -> node.get("label").asText(),
+                                (k1, k2) -> k1));
     }
+
+    /***
+     * Description: 查询专业数据
+     * @param groupCode : 集团编码
+     * @return : java.util.List<com.fasterxml.jackson.databind.JsonNode>
+     * @author : lijie
+     * @date :2021/9/23 15:10
+     * Update By lijie 2021/9/23 15:10
+     */
+    private List<JsonNode> queryDomainData(String groupCode) {
+        // 调用client查询专业数据
+        JacksonCriteria jacksonCriteria = JacksonCriteria.newInstance();
+        jacksonCriteria.getCriteria().put("type","major");
+        PagedResponse<JsonNode> response = dicClient.query("0", groupCode, jacksonCriteria);
+        if (!response.success()){
+            throw new BusinessException(ResponseCode.C0001.getCode(),"查询专业数据出错");
+        }
+        List<JsonNode> data = response.getData();
+        if (CollUtil.isEmpty(data)){
+            return new ArrayList<>();
+        }
+        return data;
+    }
+
     /***
      * Description: 填充空间功能类型
      * @param workbook : 工作簿

BIN
dmp-rwd/src/main/resources/template/ObjectInfoTemplate.xlsx