|
@@ -0,0 +1,287 @@
|
|
|
+package com.persagy.dmp.rwd.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import cn.hutool.poi.excel.ExcelUtil;
|
|
|
+import cn.hutool.poi.excel.RowUtil;
|
|
|
+import cn.hutool.poi.excel.WorkbookUtil;
|
|
|
+import cn.hutool.poi.excel.cell.CellUtil;
|
|
|
+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.web.ListResponse;
|
|
|
+import com.persagy.common.web.PagedResponse;
|
|
|
+import com.persagy.dmp.rwd.entity.FuncidDef;
|
|
|
+import com.persagy.dmp.rwd.entity.QFuncidDef;
|
|
|
+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 lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+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 javax.servlet.http.HttpServletRequest;
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.io.IOException;
|
|
|
+import java.text.Collator;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.ConcurrentLinkedQueue;
|
|
|
+
|
|
|
+/***
|
|
|
+ * Description: 对象的上传下载逻辑处理类
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/9/22 9:55
|
|
|
+ * Update By lijie 2021/9/22 9:55
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class BatchHandleObjectServiceImpl extends BaseService implements BatchHandleObjectService {
|
|
|
+ /**中文比较器*/
|
|
|
+ public final static Collator CHINA_COLLATOR = Collator.getInstance(Locale.CHINA);
|
|
|
+ /**功能点逻辑处理类*/
|
|
|
+ private final FuncidDefService funcidDefService;
|
|
|
+ /**类型定义逻辑处理类*/
|
|
|
+ private final ClassDefService classDefService;
|
|
|
+ /**物理世界对象批量导入模板的位置*/
|
|
|
+ private static final String TEMPLATE_FILE_PATH="/template/ObjectInfoTemplate.xlsx";
|
|
|
+ /**建筑功能类型sheet*/
|
|
|
+ private static final String BUILDING_FUNC_TYPE_SHEET_NAME="buildingFuncTypes";
|
|
|
+ /**空间分区sheet*/
|
|
|
+ private static final String SPACE_ZONES_SHEET_NAME="spaceZones";
|
|
|
+ /**空间功能类型sheet*/
|
|
|
+ private static final String SPACE_FUNC_TYPES_SHEET_NAME="roomFuncTypes";
|
|
|
+
|
|
|
+
|
|
|
+ /***
|
|
|
+ * Description: 下载模板接口
|
|
|
+ * @param response : 响应对象
|
|
|
+ * @param groupCode : 集团编码
|
|
|
+ * @return : void
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/9/22 9:54
|
|
|
+ * Update By lijie 2021/9/22 9:54
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public void downloadObjectTemplateFile(HttpServletResponse response,String groupCode) throws IOException {
|
|
|
+ // 下载Excel模板类
|
|
|
+ new DownloadService() {
|
|
|
+ @Override
|
|
|
+ protected void handleWorkbook(Workbook workbook) {
|
|
|
+ // 1.填充对象类数据
|
|
|
+ fillDataToWorkbook(workbook,groupCode);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected String getFilePath() {
|
|
|
+ return TEMPLATE_FILE_PATH;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected HttpServletResponse getHttpServletResponse() {
|
|
|
+ return response;
|
|
|
+ }
|
|
|
+ }.downloadFile();
|
|
|
+ }
|
|
|
+ /***
|
|
|
+ * Description: 填充对象数据
|
|
|
+ * @param workbook : 工作簿
|
|
|
+ * @return : void
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/9/22 10:23
|
|
|
+ * Update By lijie 2021/9/22 10:23
|
|
|
+ */
|
|
|
+ private void fillDataToWorkbook(Workbook workbook,String groupCode) {
|
|
|
+ // 1.填充建筑功能类型
|
|
|
+ fillBuildFuncDataToWorkbook(workbook,groupCode);
|
|
|
+ // 2.设置建筑功能类型的下拉框-交给Excel自己实现
|
|
|
+ // constructBuildFuncComboBox(workbook);
|
|
|
+ // 3.填充楼层编码-因标准字典暂无该信息点,暂时根据已有的枚举值写死
|
|
|
+ // fillFloorIdentitiesDataToWorkbook(workbook,groupCode);
|
|
|
+ // 4.填充空间分区
|
|
|
+ fillSpaceZoneDataToWorkbook(workbook,groupCode);
|
|
|
+ // 5.填充空间功能类型
|
|
|
+ fillSpaceFuncTypesDataToWorkbook(workbook,groupCode);
|
|
|
+ }
|
|
|
+ /***
|
|
|
+ * Description: 填充空间功能类型
|
|
|
+ * @param workbook : 工作簿
|
|
|
+ * @param groupCode : 集团编码
|
|
|
+ * @return : void
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/9/22 19:51
|
|
|
+ * Update By lijie 2021/9/22 19:51
|
|
|
+ */
|
|
|
+ private void fillSpaceFuncTypesDataToWorkbook(Workbook workbook, String groupCode) {
|
|
|
+ // 1.根据集团编码查询空间功能类型
|
|
|
+ Sheet spaceFuncTypesSheet = WorkbookUtil.getOrCreateSheet(workbook, SPACE_FUNC_TYPES_SHEET_NAME);
|
|
|
+ JacksonCriteria criteria = JacksonCriteria.newInstance();
|
|
|
+ criteria.getCriteria().put("classCode","GeneralZone").put("code","roomFuncType");
|
|
|
+ ListResponse<FuncidDefModel> funcidDefModelListResponse = funcidDefService
|
|
|
+ .queryFuncid(groupCode, null, null, null, criteria);
|
|
|
+ if (!funcidDefModelListResponse.success()){
|
|
|
+ throw new BusinessException(ResponseCode.C0320.getCode(),"空间功能类型不存在");
|
|
|
+ }
|
|
|
+ List<FuncidDefModel> data = funcidDefModelListResponse.getData();
|
|
|
+ if (CollUtil.isEmpty(data)){
|
|
|
+ throw new BusinessException(ResponseCode.C0320.getCode(),"空间功能类型不存在");
|
|
|
+ }
|
|
|
+ FuncidDefModel defModel = data.get(0);
|
|
|
+ ArrayNode spaceFuncTypeArr = defModel.getDataSource();
|
|
|
+ if (spaceFuncTypeArr.size()<=0){
|
|
|
+ throw new BusinessException(ResponseCode.C0320.getCode(),"空间功能类型不存在");
|
|
|
+ }
|
|
|
+ // 2.使用队列获取建筑功能类型的名称及code
|
|
|
+ Map<String,String> funcNameMap = analysisTreeDataToNameMap(spaceFuncTypeArr);
|
|
|
+ // 3.将内容写到Excel里
|
|
|
+ writeDataToSheet(funcNameMap,spaceFuncTypesSheet);
|
|
|
+ }
|
|
|
+
|
|
|
+ /***
|
|
|
+ * Description: 填充空间分区数据
|
|
|
+ * @param workbook : 工作簿
|
|
|
+ * @param groupCode : 集团编码
|
|
|
+ * @return : void
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/9/22 19:11
|
|
|
+ * Update By lijie 2021/9/22 19:11
|
|
|
+ */
|
|
|
+ private void fillSpaceZoneDataToWorkbook(Workbook workbook, String groupCode) {
|
|
|
+ // 1.根据集团编码查询空间分区
|
|
|
+ Sheet zonesSheet = WorkbookUtil.getOrCreateSheet(workbook, SPACE_ZONES_SHEET_NAME);
|
|
|
+ JacksonCriteria jacksonCriteria = JacksonCriteria.newInstance();
|
|
|
+ jacksonCriteria.getCriteria().put("objType","space");
|
|
|
+ ListResponse<ClassDefModel> listResponse = classDefService.queryClass(groupCode, null, null, null, true, jacksonCriteria);
|
|
|
+ if (!listResponse.success()){
|
|
|
+ throw new BusinessException(ResponseCode.C0320.getCode(),"空间分区不存在");
|
|
|
+ }
|
|
|
+ List<ClassDefModel> classDefModels = listResponse.getData();
|
|
|
+ if (CollUtil.isEmpty(classDefModels)){
|
|
|
+ throw new BusinessException(ResponseCode.C0320.getCode(),"空间分区不存在");
|
|
|
+ }
|
|
|
+ // 2.根据分区名称进行排序
|
|
|
+ classDefModels.sort((m1,m2)->CHINA_COLLATOR.compare(m1.getName(),m2.getName()));
|
|
|
+ // 3.填充分区名称数据
|
|
|
+ int j=0;
|
|
|
+ for (ClassDefModel classDefModel : classDefModels) {
|
|
|
+ if (classDefModel.getCode().equals(classDefModel.getObjType().name())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(zonesSheet, j), 0), classDefModel.getName(), null);
|
|
|
+ CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(zonesSheet, j), 1), classDefModel.getCode(), null);
|
|
|
+ j++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /***
|
|
|
+ * Description: 构建建筑功能类型的下拉框
|
|
|
+ * @param workbook : 工作簿
|
|
|
+ * @return : void
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/9/22 17:06
|
|
|
+ * Update By lijie 2021/9/22 17:06
|
|
|
+ */
|
|
|
+ private void constructBuildFuncComboBox(Workbook workbook) {}
|
|
|
+
|
|
|
+ /***
|
|
|
+ * Description: 填充建筑功能类型
|
|
|
+ * @param workbook : 工作簿
|
|
|
+ * @return : void
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/9/22 14:29
|
|
|
+ * Update By lijie 2021/9/22 14:29
|
|
|
+ */
|
|
|
+ private void fillBuildFuncDataToWorkbook(Workbook workbook,String groupCode) {
|
|
|
+ Sheet buildingFuncTypeSheet = WorkbookUtil.getOrCreateSheet(workbook, BUILDING_FUNC_TYPE_SHEET_NAME);
|
|
|
+ // 1.查询建筑功能类型数据
|
|
|
+ JacksonCriteria criteria = JacksonCriteria.newInstance();
|
|
|
+ criteria.getCriteria().put("classCode","building").put("code","buildFuncType");
|
|
|
+ ListResponse<FuncidDefModel> funcidDefModelListResponse = funcidDefService
|
|
|
+ .queryFuncid(groupCode, null, null, null, criteria);
|
|
|
+ if (!funcidDefModelListResponse.success()){
|
|
|
+ throw new BusinessException(ResponseCode.C0320.getCode(),"建筑功能类型不存在");
|
|
|
+ }
|
|
|
+ List<FuncidDefModel> data = funcidDefModelListResponse.getData();
|
|
|
+ if (CollUtil.isEmpty(data)){
|
|
|
+ throw new BusinessException(ResponseCode.C0320.getCode(),"建筑功能类型不存在");
|
|
|
+ }
|
|
|
+ FuncidDefModel defModel = data.get(0);
|
|
|
+ ArrayNode buildFuncDataSource = defModel.getDataSource();
|
|
|
+ if (buildFuncDataSource.size()<=0){
|
|
|
+ throw new BusinessException(ResponseCode.C0320.getCode(),"建筑功能类型不存在");
|
|
|
+ }
|
|
|
+ // 2.使用队列获取建筑功能类型的名称及code
|
|
|
+ Map<String,String> funcNameMap = analysisTreeDataToNameMap(buildFuncDataSource);
|
|
|
+ // 3.将内容写到Excel里
|
|
|
+ writeDataToSheet(funcNameMap,buildingFuncTypeSheet);
|
|
|
+ }
|
|
|
+ /***
|
|
|
+ * Description: 写数据到sheet中
|
|
|
+ * @param funcNameMap : 功能名称映射
|
|
|
+ * @param supSheet : 填写的sheet对象
|
|
|
+ * @return : void
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/9/22 19:59
|
|
|
+ * Update By lijie 2021/9/22 19:59
|
|
|
+ */
|
|
|
+ private void writeDataToSheet(Map<String, String> funcNameMap, Sheet supSheet) {
|
|
|
+ Set<Map.Entry<String, String>> entries = funcNameMap.entrySet();
|
|
|
+ List<Map.Entry<String, String>> list = new ArrayList<>(entries);
|
|
|
+ list.sort((e1,e2)->CHINA_COLLATOR.compare(e1.getValue(),e2.getValue()));
|
|
|
+ int i=0;
|
|
|
+ for (Map.Entry<String, String> entry : list) {
|
|
|
+ String key = entry.getKey();
|
|
|
+ String value = entry.getValue();
|
|
|
+ CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(supSheet,i),0),value,null);
|
|
|
+ CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(supSheet,i),1),key,null);
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /***
|
|
|
+ * Description: 获得code与名称的映射
|
|
|
+ * @param arrayNode : 节点数组
|
|
|
+ * @return : void
|
|
|
+ * @author : lijie
|
|
|
+ * @date :2021/9/22 19:57
|
|
|
+ * Update By lijie 2021/9/22 19:57
|
|
|
+ */
|
|
|
+ private Map<String, String> analysisTreeDataToNameMap(ArrayNode arrayNode) {
|
|
|
+ Map<String, List<JsonNode>> map = new HashMap<>();
|
|
|
+ arrayNode.forEach(node->{
|
|
|
+ String parentCode = node.has("parentCode")?node.get("parentCode").asText("0"):"0";
|
|
|
+ List<JsonNode> sonList = map
|
|
|
+ .getOrDefault(parentCode, new ArrayList<>());
|
|
|
+ sonList.add(node);
|
|
|
+ map.put(parentCode,sonList);
|
|
|
+ });
|
|
|
+ Map<String, String> funcNameMap = new HashMap<>();
|
|
|
+ Queue<JsonNode> queue = new ConcurrentLinkedQueue<>(map.getOrDefault("0", new ArrayList<>()));
|
|
|
+ while (!queue.isEmpty()){
|
|
|
+ JsonNode jsonNode = queue.poll();
|
|
|
+ String parentCode = jsonNode.has("parentCode")?jsonNode.get("parentCode").asText("0"):"0";
|
|
|
+ if ("0".equals(parentCode)){
|
|
|
+ funcNameMap.put(jsonNode.get("code").asText(""),jsonNode.get("name").asText(""));
|
|
|
+ queue.addAll(map.getOrDefault(jsonNode.get("code").asText(""),new ArrayList<>()));
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String parentText = funcNameMap.getOrDefault(parentCode, "");
|
|
|
+ if (StrUtil.isBlank(parentText)){
|
|
|
+ funcNameMap.put(jsonNode.get("code").asText(""),jsonNode.get("name").asText(""));
|
|
|
+ queue.addAll(map.getOrDefault(jsonNode.get("code").asText(""),new ArrayList<>()));
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ funcNameMap.put( jsonNode.get("code").asText(""),
|
|
|
+ parentText+StrUtil.DASHED+jsonNode.get("name").asText(""));
|
|
|
+ queue.addAll(map.getOrDefault(jsonNode.get("code").asText(""),new ArrayList<>()));
|
|
|
+ }
|
|
|
+ return funcNameMap;
|
|
|
+ }
|
|
|
+}
|