Browse Source

初步实现SOP批量上传的功能

lijie 4 năm trước cách đây
mục cha
commit
6a7da2159c

+ 19 - 0
fm-sop/src/main/java/com/persagy/fm/sop/aop/GlobalExceptionHandler.java

@@ -4,6 +4,8 @@ import com.persagy.common.aop.GlobalBussinessExceptionHandler;
 import com.persagy.common.enums.ResponseCode;
 import com.persagy.common.exception.BusinessException;
 import com.persagy.common.utils.ResponseResult;
+import com.persagy.fm.common.utils.FileUtil;
+import com.persagy.fm.sop.constant.SopQueryConst;
 import com.persagy.fm.sop.utils.OldResponseResultUtil;
 import feign.FeignException;
 import lombok.extern.slf4j.Slf4j;
@@ -14,9 +16,14 @@ import org.springframework.web.bind.MethodArgumentNotValidException;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.ResponseStatus;
 import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
 import org.springframework.web.servlet.NoHandlerFoundException;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.validation.ValidationException;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * 全局异常拦截器
@@ -88,6 +95,18 @@ public class GlobalExceptionHandler extends GlobalBussinessExceptionHandler {
     @ExceptionHandler({Exception.class})
     public ResponseResult handleException(Exception e) {
         log.error(e.getMessage(), e);
+        // 针对请求地址为上传标准模板的特殊处理
+        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        if (null!=servletRequestAttributes){
+            HttpServletRequest request = servletRequestAttributes.getRequest();
+            String requestUri = request.getRequestURI();
+            if (SopQueryConst.IMPORT_SOP_REQUEST_URI.equals(requestUri)){
+                List<String> errorList = new ArrayList<>();
+                errorList.add(e.getMessage());
+                FileUtil.writeErrorContentToResponse(errorList,servletRequestAttributes.getResponse(),request, SopQueryConst.UPLOAD_SOP_ERR_FILE_NAME);
+                return null;
+            }
+        }
         return OldResponseResultUtil.errorResult(ResponseCode.Z9999.getCode(), ResponseCode.Z9999.getDesc());
     }
 }

+ 10 - 0
fm-sop/src/main/java/com/persagy/fm/sop/constant/SopQueryConst.java

@@ -28,6 +28,10 @@ public class SopQueryConst {
     public static final String FIT_OBJ_IDS="fit_obj_ids";
     /**项目id*/
     public static final String PROJECT_ID="project_id";
+    /**项目id的驼峰写法*/
+    public static final String PROJECT_ID_HUMP="projectId";
+    /**文件写法*/
+    public static final String DTO_FILE="file";
     /**设备模型id*/
     public static final String EQUIP_MODEL_ID="equip_model_id";
     /**设备模型名称*/
@@ -48,4 +52,10 @@ public class SopQueryConst {
     public static final String VERSION_EXPLAIN="version_explain";
     /**version_count*/
     public static final String VERSION_COUNT="version_count";
+    /**批量导入SOP错误提示文件名称*/
+    public static final String UPLOAD_SOP_ERR_FILE_NAME="批量导入SOP错误提示文件.txt";
+    /**上传标准文件的请求URI*/
+    public static final String IMPORT_SOP_REQUEST_URI = "/restInputSopService/uploadSop";
+    /**有表头的标准导入excel内容*/
+    public static final Integer EXCEL_HEAD_INDEX = 2;
 }

+ 49 - 4
fm-sop/src/main/java/com/persagy/fm/sop/controller/BatchHandleSopController.java

@@ -1,25 +1,32 @@
 package com.persagy.fm.sop.controller;
 
 import com.persagy.common.exception.BusinessException;
+import com.persagy.fm.common.constant.CommonConstant;
 import com.persagy.fm.common.model.vo.BaseVo;
+import com.persagy.fm.common.utils.FileUtil;
+import com.persagy.fm.sop.aop.BusinessAssert;
+import com.persagy.fm.sop.constant.SopCommonConst;
+import com.persagy.fm.sop.constant.SopQueryConst;
 import com.persagy.fm.sop.model.vo.SaveSopVo;
 import com.persagy.fm.sop.service.IBatchHandleSopService;
 import com.persagy.fm.sop.utils.OldResponseResult;
 import com.persagy.fm.sop.utils.OldResponseResultUtil;
 import com.persagy.fm.sop.validator.Insert;
+import com.persagy.log.core.annotation.IgnoreLog;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
-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 org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.util.ArrayList;
+import java.util.List;
 
 /***
  * Description: 批量导入下载SOP的controler类
@@ -46,9 +53,47 @@ public class BatchHandleSopController {
      */
     @ApiOperation("下载导入模板")
     @PostMapping("downloadSopTemplate")
+    @CrossOrigin
     public void addPublishedSop(@RequestBody @Validated BaseVo baseVo, HttpServletResponse httpServletResponse) throws Exception {
         batchHandleSopService.downloadSopTemplate(baseVo,httpServletResponse);
     }
+    /***
+     * Description: 批量导入SOP
+     * @param projectId : 项目id
+     * @param file : 上传的文件流
+     * @param response : 响应体对象
+     * @param request : 请求体对象
+     * @return : void
+     * @author : lijie
+     * @date :2021/4/30 12:08
+     * Update By lijie 2021/4/30 12:08
+     */
+    @ApiOperation("下载导入模板")
+    @PostMapping("uploadSop")
+    @CrossOrigin
+    @IgnoreLog
+    public void uploadSop(@RequestParam(value = SopQueryConst.PROJECT_ID_HUMP,required = false) String projectId,
+                          @RequestParam(SopQueryConst.DTO_FILE) MultipartFile file,
+                          HttpServletRequest request,
+                          HttpServletResponse response){
+        try {
+            if (file.isEmpty()){
+                BusinessAssert.isNotEmpty(file.getName(),SopQueryConst.DTO_FILE);
+            }
+            String originalFilename = file.getOriginalFilename();
+            if (StringUtils.isNotBlank(originalFilename)
+                    && !originalFilename.endsWith(CommonConstant.EXCEL_SUFFIX)){
+                BusinessAssert.notMatch(CommonConstant.EXCEL_SUFFIX);
+            }
+            batchHandleSopService.uploadSop(projectId,file,request,response);
+        }catch (Exception exr){
+            log.error("上传文件失败",exr);
+            List<String> errorList = new ArrayList<>();
+            errorList.add(exr.getMessage());
+            FileUtil.writeErrorContentToResponse(errorList,response,request,SopQueryConst.UPLOAD_SOP_ERR_FILE_NAME);
+        }
+
+    }
 
 
 }

+ 8 - 0
fm-sop/src/main/java/com/persagy/fm/sop/enums/ObjTypeEnum.java

@@ -10,8 +10,14 @@ public enum ObjTypeEnum {
     BUILD("build","建筑"),
     /**建筑*/
     BUILDING("building","建筑"),
+    /**建筑功能类型*/
+    BUILD_FUNC_TYPE("build_func_type","建筑功能类型"),
     /**楼层*/
     FLOOR("floor","楼层"),
+    /**楼层类型*/
+    FLOOR_TYPE("floor_type","楼层类型"),
+    /**竖井类型*/
+    SHAFT_TYPE("shaft_type","竖井类型"),
     /**空间*/
     SPACE("space","空间"),
     /**系统*/
@@ -22,6 +28,8 @@ public enum ObjTypeEnum {
     EQUIP("equip","设备"),
     /**设备类*/
     EQUIP_CLASS("equip_class","设备类"),
+    /**设备类*/
+    SPACE_CLASS("space_class","空间类型"),
     /**系统类*/
     SYSTEM_CLASS("system_class","系统类");
 

+ 74 - 0
fm-sop/src/main/java/com/persagy/fm/sop/enums/SopColumnEnum.java

@@ -0,0 +1,74 @@
+package com.persagy.fm.sop.enums;
+
+
+/***
+ * Description: 导入SOP文件表头
+ * @author : lijie
+ * @date :2021/3/4 10:58
+ * Update By lijie 2021/3/4 10:58
+ */
+public enum SopColumnEnum {
+
+	/**标准操作知识名称*/
+	SOP_NAME(0,"标准操作知识名称"),
+	/**对象分类*/
+	OBJ_CLASSIFY(1,"对象分类"),
+	/**对象选择*/
+	OBJ_CHOICE(2,"对象选择"),
+	/**对象编码*/
+	OBJ_CODE(3,"对象编码"),
+	/**空间范围*/
+	SPACE_SCOPE(4,"空间范围"),
+	/**空间编码*/
+	SPACE_CODE(5,"空间编码"),
+	/**在到达每个对象位置时拍照*/
+	PHOTOGRAPH(6,"在到达每个对象位置时拍照"),
+	/**在到达每个对象位置时扫码*/
+	SCAN(7,"在到达每个对象位置时扫码"),
+	/**工作时长(天)*/
+	WORK_TIME_DAY(8,"工作时长(天)"),
+	/**工作时长(小时)*/
+	WORK_TIME_HOUR(9,"工作时长(小时)"),
+	/**工作时长(分)*/
+	WORK_TIME_MIN(10,"工作时长(分)"),
+	/**强制确认操作前提*/
+	PRE_CONFORM(11,"强制确认操作前提"),
+	/**注意事项*/
+	NOTICE(12,"注意事项"),
+	/**标准作业操作内容*/
+	JOB_DESCRIPTION(13,"标准作业操作内容"),
+	/**是否反馈异常*/
+	WRONG_FLAG(14,"是否反馈异常"),
+	/**添加信息点*/
+	INFO_NAME(15,"添加信息点"),
+	/**标准下限*/
+	DOWN_LIMIT(16,"标准下限"),
+	/**添加信息点*/
+	UPPER_LIMIT(17,"标准上限");
+
+	/**在上传标准文件中的列索引号*/
+	private Integer index;
+
+	/**
+	 * 描述
+	 */
+	private String name;
+
+	public Integer getIndex() {
+		return index;
+	}
+
+	public String getName() {
+		return this.name;
+	}
+
+	SopColumnEnum(Integer index, String name) {
+		this.name = name;
+		this.index = index;
+	}
+
+	@Override
+	public String toString() {
+		return this.index+"_"+this.name;
+	}
+}

+ 50 - 0
fm-sop/src/main/java/com/persagy/fm/sop/enums/SopErrorEnum.java

@@ -0,0 +1,50 @@
+package com.persagy.fm.sop.enums;
+
+
+/***
+ * Description: 导入标准错误提示码
+ * @author : lijie
+ * @date :2021/3/4 10:58
+ * Update By lijie 2021/3/4 10:58
+ */
+public enum SopErrorEnum {
+
+	/**
+	 *内容错误
+	 */
+	CONTENT_ERROR("内容错误"),
+	/**
+	 *标准名称重复
+	 */
+	SOP_NAME_REPEAT_ERROR("标准操作知识名称已存在"),
+	/**
+	 *不能为空
+	 */
+	CONTENT_BLANK_ERROR("不能为空"),
+	/**
+	 *存在非法数字
+	 */
+	NUMBER_ERROR("存在非法数字"),
+	/**
+	 *非模板文件,请上传正确的模板文件
+	 */
+	FILE_ERROR("非模板文件,请上传正确的模板文件");
+
+	/**
+	 * 描述
+	 */
+	private String desc;
+
+	public String getDesc() {
+		return this.desc;
+	}
+
+	SopErrorEnum(String desc) {
+		this.desc = desc;
+	}
+
+	@Override
+	public String toString() {
+		return this.desc;
+	}
+}

+ 14 - 0
fm-sop/src/main/java/com/persagy/fm/sop/service/IBatchHandleSopService.java

@@ -1,7 +1,9 @@
 package com.persagy.fm.sop.service;
 
 import com.persagy.fm.common.model.vo.BaseVo;
+import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 
@@ -22,4 +24,16 @@ public interface IBatchHandleSopService {
      * Update By lijie 2021/4/28 10:53
      */
     void downloadSopTemplate(BaseVo baseVo, HttpServletResponse response) throws IOException;
+    /***
+     * Description: 批量上传SOP
+     * @param projectId : 项目id
+     * @param file : 文件流
+     * @param request : 请求体对象
+     * @param response : 响应体对象
+     * @return : void
+     * @author : lijie
+     * @date :2021/4/30 12:15
+     * Update By lijie 2021/4/30 12:15
+     */
+    void uploadSop(String projectId, MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IOException;
 }

+ 9 - 0
fm-sop/src/main/java/com/persagy/fm/sop/service/IProjectSopService.java

@@ -464,4 +464,13 @@ public interface IProjectSopService {
      * Update By lijie 2021/4/21 16:59
      */
     String queryRecommendSop(JSONObject jsonObject) throws Exception;
+    /***
+     * Description: 批量添加SOP方法
+     * @param saveSopVos : 请求参数
+     * @return : void
+     * @author : lijie
+     * @date :2021/4/1 16:30
+     * Update By lijie 2021/4/1 16:30
+     */
+    void batchAddPublishedSop(List<SaveSopVo> saveSopVos);
 }

+ 409 - 25
fm-sop/src/main/java/com/persagy/fm/sop/service/impl/BatchHandleSopServiceImpl.java

@@ -1,11 +1,13 @@
 package com.persagy.fm.sop.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.text.CharSequenceUtil;
+import cn.hutool.core.util.EnumUtil;
+import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.StrUtil;
-import cn.hutool.poi.excel.ExcelUtil;
-import cn.hutool.poi.excel.ExcelWriter;
-import cn.hutool.poi.excel.RowUtil;
-import cn.hutool.poi.excel.StyleSet;
+import cn.hutool.poi.excel.*;
+import cn.hutool.poi.excel.cell.CellHandler;
 import cn.hutool.poi.excel.cell.CellUtil;
 import cn.hutool.poi.excel.cell.FormulaCellValue;
 import com.alibaba.excel.util.SheetUtils;
@@ -18,17 +20,24 @@ import com.persagy.fm.common.constant.enums.ResultEnum;
 import com.persagy.fm.common.model.vo.BaseVo;
 import com.persagy.fm.common.model.vo.GeneralDictVo;
 import com.persagy.fm.common.service.DownloadService;
+import com.persagy.fm.common.utils.FileUtil;
 import com.persagy.fm.sop.client.SaasClient;
 import com.persagy.fm.sop.constant.SopCommonConst;
-import com.persagy.fm.sop.enums.ClassTypeEnum;
-import com.persagy.fm.sop.enums.ObjTypeEnum;
-import com.persagy.fm.sop.enums.SheetNameEnum;
-import com.persagy.fm.sop.model.dto.InfoPointsBean;
-import com.persagy.fm.sop.model.dto.ObjBean;
+import com.persagy.fm.sop.constant.SopQueryConst;
+import com.persagy.fm.sop.entity.CustomInfoPoint;
+import com.persagy.fm.sop.entity.Sop;
+import com.persagy.fm.sop.enums.*;
+import com.persagy.fm.sop.model.dto.*;
+import com.persagy.fm.sop.model.vo.SaveSopVo;
 import com.persagy.fm.sop.service.IBatchHandleSopService;
+import com.persagy.fm.sop.service.IProjectSopService;
+import com.persagy.fm.sop.service.ISopService;
 import com.persagy.fm.sop.service.ObjService;
+import com.persagy.fm.sop.validator.ProjectInsert;
+import com.persagy.fm.sop.validator.ProjectUpdate;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.CellAddress;
 import org.apache.poi.ss.util.CellRangeAddress;
@@ -37,17 +46,23 @@ import org.apache.poi.ss.util.SheetUtil;
 import org.apache.poi.xssf.usermodel.*;
 import org.apache.poi.xssf.usermodel.helpers.XSSFFormulaUtils;
 import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import javax.validation.constraints.NotEmpty;
 import java.io.IOException;
 import java.util.*;
+import java.util.stream.Collectors;
 
 @Service
 @RequiredArgsConstructor
 @Slf4j
 public class BatchHandleSopServiceImpl implements IBatchHandleSopService {
-
+    private final ISopService sopService;
     private final SaasClient saasClient;
+    private final IProjectSopService projectSopService;
 
     /**SOP批量导入模板的位置*/
     private static final String TEMPLATE_FILE_PATH="/template/SOP导入模板.xlsx";
@@ -94,6 +109,373 @@ public class BatchHandleSopServiceImpl implements IBatchHandleSopService {
         }.downloadFile();
     }
     /***
+     * Description: 批量上传SOP
+     * @param projectId : 项目id
+     * @param file : 文件流
+     * @param request : 请求体对象
+     * @param response : 响应体对象
+     * @return : void
+     * @author : lijie
+     * @date :2021/4/30 12:15
+     * Update By lijie 2021/4/30 12:15
+     */
+    @Override
+    public void uploadSop(String projectId, MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IOException {
+        if (StrUtil.isBlank(projectId)){
+            projectId = SopCommonConst.GROUP_SOP_ID;
+        }
+        ExcelReader firstSheet = ExcelUtil.getReader(file.getInputStream(),0);
+        ExcelReader classDataSheet = ExcelUtil.getReader(file.getInputStream(),1);
+        ExcelReader codeDataSheet = ExcelUtil.getReader(file.getInputStream(),2);
+        ExcelReader infoDataSheet = ExcelUtil.getReader(file.getInputStream(),3);
+        List<List<Object>> uploadData = firstSheet.read();
+        List<List<Object>> classListList = classDataSheet.read();
+        List<List<Object>> codeListList = codeDataSheet.read();
+        List<List<Object>> infoListList = infoDataSheet.read();
+        List<String> checkFileErrList = checkFileIsValid(uploadData);
+        if (CollUtil.isNotEmpty(checkFileErrList)){
+            FileUtil.writeErrorContentToResponse(checkFileErrList,response,request,SopQueryConst.UPLOAD_SOP_ERR_FILE_NAME);
+            return;
+        }
+        // 1.大类名称集合
+        Set<String> classNameSet = new HashSet<>();
+        for (int i = 0; i < classListList.size(); i++) {
+            List<Object> objects = classListList.get(i);
+            classNameSet.add(CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(objects.get(0))));
+        }
+        // 2.分类映射
+        Map<String,String> codeMap = new HashMap<>();
+        Map<String,String> objTypeMap = new HashMap<>();
+        for (List<Object> objects : codeListList) {
+            String objName = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(objects.get(0)));
+            String objCode = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(objects.get(1)));
+            String objType = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(objects.get(2)));
+            codeMap.putIfAbsent(objName,objCode);
+            objTypeMap.putIfAbsent(objName,objType);
+        }
+        // 3.信息点映射
+        Map<String,InfoPointsBean> infoMap = new HashMap<>();
+        for (List<Object> objects : infoListList) {
+            String objName = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(objects.get(0)));
+            String objCode = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(objects.get(1)));
+            if (StrUtil.isBlank(objCode) || !objCode.startsWith("{")){
+                objCode = "{}";
+            }
+            infoMap.putIfAbsent(objName,JSONObject.parseObject(objCode,InfoPointsBean.class));
+        }
+        // 4.检验数据合法性
+        List<String> checkDataErrList = checkDataIsValid(uploadData, classNameSet, codeMap, infoMap,firstSheet);
+        if (CollUtil.isNotEmpty(checkDataErrList)){
+            FileUtil.writeErrorContentToResponse(checkDataErrList,response,request,SopQueryConst.UPLOAD_SOP_ERR_FILE_NAME);
+            return;
+        }
+        List<SaveSopVo> saveSopVos = generateSaveSopVo(uploadData,codeMap,infoMap,firstSheet,projectId,objTypeMap);
+        projectSopService.batchAddPublishedSop(saveSopVos);
+    }
+    /***
+     * Description: 生成需要保存的对象
+     * @param uploadData : 上传的数据
+     * @param codeMap : code映射
+     * @param infoMap : 信息点映射
+     * @param firstSheet : sheet对象
+     * @param objTypeMap
+     * @return : java.util.List<com.persagy.fm.sop.model.vo.SaveSopVo>
+     * @author : lijie
+     * @date :2021/4/30 17:04
+     * Update By lijie 2021/4/30 17:04
+     */
+    private List<SaveSopVo> generateSaveSopVo(List<List<Object>> uploadData, Map<String, String> codeMap,
+                                              Map<String, InfoPointsBean> infoMap, ExcelReader firstSheet, String projectId, Map<String, String> objTypeMap) {
+        int size = uploadData.size();
+        Map<String,SaveSopVo> resultMap = new HashMap<>();
+        Map<String,Set<String>> objNameMap = new HashMap<>();
+        Map<String,Set<String>> confirmResultMap = new HashMap<>();
+        for (int i = 2; i < size; i++) {
+            // 1.SOP的名称
+            String sopName = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(0,i))));
+            SaveSopVo saveSopVo = resultMap.getOrDefault(sopName, new SaveSopVo());
+            saveSopVo.setSopName(sopName);
+            saveSopVo.setProjectId(projectId);
+            List<FitObjsBean> fitObjs = saveSopVo.getFitObjs();
+            if (CollUtil.isEmpty(fitObjs)){
+                fitObjs = new ArrayList<>();
+                saveSopVo.setFitObjs(fitObjs);
+            }
+            List<SopStepsBean> steps = saveSopVo.getSteps();
+            SopStepsBean sopStepsBean;
+            if (CollUtil.isEmpty(steps)){
+                steps = new ArrayList<>();
+                sopStepsBean = SopStepsBean.builder().fromSop(false).build();
+                steps.add(sopStepsBean);
+                saveSopVo.setSteps(steps);
+            }else {
+                sopStepsBean=steps.get(0);
+            }
+            Set<String> objNameSet = objNameMap.getOrDefault(sopName, new HashSet<>());
+            // 3.对象名称
+            String objName = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(2,i))));
+            if (!objNameSet.contains(objName)){
+                objNameSet.add(objName);
+                objNameMap.putIfAbsent(sopName,objNameSet);
+                fitObjs.add(FitObjsBean.builder()
+                        .objId(codeMap.getOrDefault(objName,"").substring(1))
+                        .objName(objName.substring(objName.lastIndexOf(SopCommonConst.UNDER_LINE)))
+                        .objCode(codeMap.getOrDefault(objName,"").substring(1))
+                        .objType(objTypeMap.getOrDefault(objName,""))
+                        .objSource(ObjOwnerEnum.CONTENT_OBJ.getType()).build());
+                List<StepContentBean> stepContents = sopStepsBean.getStepContent();
+                StepContentBean stepContentBean;
+                if (CollUtil.isEmpty(stepContents)){
+                    stepContents = new ArrayList<>();
+                    stepContentBean = StepContentBean.builder().fromSop(false).build();
+                    stepContents.add(stepContentBean);
+                }else {
+                    stepContentBean = stepContents.get(0);
+                }
+                List<ContentObjsBean> contentObjs = stepContentBean.getContentObjs();
+                if (CollUtil.isEmpty(contentObjs)){
+                    contentObjs = new ArrayList<>();
+                }
+                contentObjs.add(ContentObjsBean.builder()
+                        .objId(codeMap.getOrDefault(objName,"").substring(1))
+                        .objName(objName.substring(objName.lastIndexOf(SopCommonConst.UNDER_LINE)+1))
+                        .objCode(codeMap.getOrDefault(objName,"").substring(1))
+                        .objType(objTypeMap.getOrDefault(objName,""))
+                        .build());
+                stepContentBean.setContentObjs(contentObjs);
+                sopStepsBean.setStepContent(stepContents);
+            }
+            List<StepContentBean> stepContents = sopStepsBean.getStepContent();
+            StepContentBean stepContentBean;
+            if (CollUtil.isEmpty(stepContents)){
+                stepContents = new ArrayList<>();
+                stepContentBean = StepContentBean.builder().build();
+                stepContents.add(stepContentBean);
+                sopStepsBean.setStepContent(stepContents);
+            }else {
+                stepContentBean = stepContents.get(0);
+            }
+            String photo = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(6, i))));
+            if (null == stepContentBean.getIsPhoto()){
+                if (StrUtil.isBlank(photo) || "否".equals(photo)){
+                    stepContentBean.setIsPhoto(false);
+                }else {
+                    stepContentBean.setIsPhoto(true);
+                }
+            }
+            String scan = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(7, i))));
+            if (null == stepContentBean.getIsScan()){
+                if (StrUtil.isBlank(scan) || "否".equals(scan)){
+                    stepContentBean.setIsScan(false);
+                }else {
+                    stepContentBean.setIsScan(true);
+                }
+            }
+            // 处理时间
+            if (null==stepContentBean.getTimeLimit()){
+                Integer destMin = null;
+                String day = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(8, i))));
+                if (StrUtil.isNotBlank(day)){
+                    destMin = Integer.parseInt(day)*24*60;
+                }
+                String hour = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(9, i))));
+                if (StrUtil.isNotBlank(hour)){
+                    destMin = destMin + Integer.parseInt(hour)*60;
+                }
+                String min = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(10, i))));
+                if (StrUtil.isNotBlank(min)){
+                    destMin = destMin + Integer.parseInt(min);
+                }
+                if (null!=destMin){
+                    stepContentBean.setTimeLimit(destMin);
+                }
+            }
+            String preConform = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(11, i))));
+            if (StrUtil.isBlank(stepContentBean.getPreConform()) && StrUtil.isNotBlank(preConform)){
+                stepContentBean.setPreConform(preConform);
+            }
+            String notice = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(12, i))));
+            if (StrUtil.isBlank(stepContentBean.getNotice()) && StrUtil.isNotBlank(notice)){
+                stepContentBean.setPreConform(notice);
+            }
+            String confirmResultContent = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(13, i))));
+            Set<String> confirmResultContents = confirmResultMap.getOrDefault(sopName,new HashSet<>());
+            if (!confirmResultContents.contains(confirmResultContent)){
+                confirmResultContents.add(confirmResultContent);
+                confirmResultMap.putIfAbsent(sopName,confirmResultContents);
+                List<ConfirmResultBean> confirmResults = stepContentBean.getConfirmResult();
+                if (CollUtil.isEmpty(confirmResults)){
+                    confirmResults = new ArrayList<>();
+                }
+                List<CustomInfoPointsBean> customInfoPoints = new ArrayList<>();
+                String custom = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(14, i))));
+                if (StrUtil.isNotBlank(custom) && "是".equals(custom)){
+                    CustomInfoPointsBean customInfoPoint = new CustomInfoPointsBean();
+                    customInfoPoint.setItems(Arrays.asList("正常","异常"));
+                    customInfoPoint.setWrongs(Collections.singletonList("异常"));
+                    customInfoPoint.setType("2");
+                    customInfoPoint.setName("异常情况");
+                    customInfoPoints.add(customInfoPoint);
+                }
+                List<InfoPointsBean> infoPointsBeans = new ArrayList<>();
+                String infoPointStr = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(15, i))));
+                String downStr = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(16, i))));
+                String upStr = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(17, i))));
+                if (StrUtil.isNotBlank(infoPointStr)){
+                    InfoPointsBean infoPointsBean = infoMap.get(objName+SopCommonConst.UNDER_LINE+infoPointStr);
+                    if (null!=infoPointsBean){
+                        List<WrongRangesBean> wrongRanges = infoPointsBean.getWrongRanges();
+                        if (CollUtil.isEmpty(wrongRanges)){
+                            wrongRanges = new ArrayList<>();
+                        }
+                        if (StrUtil.isNotBlank(downStr)){
+                            wrongRanges.add(WrongRangesBean.builder().type("lt").values(downStr).build());
+                        }
+                        if (StrUtil.isNotBlank(upStr)){
+                            wrongRanges.add(WrongRangesBean.builder().type("gt").values(upStr).build());
+                        }
+                        infoPointsBean.setWrongRanges(wrongRanges);
+                    }
+                    infoPointsBeans.add(infoPointsBean);
+                }
+                confirmResults.add(ConfirmResultBean.builder()
+                        .description(confirmResultContent)
+                        .infoPoints(infoPointsBeans)
+                        .customs(customInfoPoints)
+                        .build());
+                stepContentBean.setConfirmResult(confirmResults);
+            }
+            resultMap.putIfAbsent(sopName,saveSopVo);
+        }
+        return CollUtil.newArrayList(resultMap.values());
+    }
+
+    /***
+     * Description: 校验数据是否正确
+     * @param uploadData : 上传的SOP数据
+     * @param classNameSet : 分类名称集合
+     * @param codeMap : 对象类映射
+     * @param infoMap : 信息点映射
+     * @param firstSheet
+     * @return : java.util.List<java.lang.String>
+     * @author : lijie
+     * @date :2021/4/30 15:05
+     * Update By lijie 2021/4/30 15:05
+     */
+    private List<String> checkDataIsValid(List<List<Object>> uploadData, Set<String> classNameSet,
+                                          Map<String, String> codeMap, Map<String, InfoPointsBean> infoMap, ExcelReader firstSheet) {
+        List<Sop> sops = sopService.list();
+        Set<String> sopNameSet = sops.stream().map(Sop::getSopName).collect(Collectors.toSet());
+        Set<String> codeNameSet = codeMap.keySet();
+        Set<String> codeSet = CollUtil.newHashSet(codeMap.values());
+        Set<String> infoNameSet = infoMap.keySet();
+        List<String> errorList = new ArrayList<>();
+        for (int i = 2; i < uploadData.size(); i++) {
+            List<Object> objects = uploadData.get(i);
+            String realCol="第"+(i+1)+"行,";
+            // 1.SOP的名称
+            String sopName = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(0,i))));
+            if (StrUtil.isBlank(sopName)){
+                errorList.add(realCol+SopColumnEnum.SOP_NAME.getName()+SopErrorEnum.CONTENT_BLANK_ERROR);
+            }
+            if (StrUtil.isNotBlank(sopName) && sopNameSet.contains(sopName)){
+                errorList.add(realCol+SopColumnEnum.SOP_NAME.getName()+SopErrorEnum.SOP_NAME_REPEAT_ERROR);
+            }
+            // 2.对象分类
+            String className = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(1,i))));
+            if (StrUtil.isBlank(className)){
+                errorList.add(realCol+SopColumnEnum.OBJ_CLASSIFY.getName()+SopErrorEnum.CONTENT_BLANK_ERROR);
+            }
+            if (StrUtil.isNotBlank(className) && !classNameSet.contains(className)){
+                errorList.add(realCol+SopColumnEnum.OBJ_CLASSIFY.getName()+SopErrorEnum.CONTENT_ERROR);
+            }
+            // 3.对象选择
+            String objName = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(2,i))));
+            if (StrUtil.isBlank(objName)){
+                errorList.add(realCol+SopColumnEnum.OBJ_CHOICE.getName()+SopErrorEnum.CONTENT_BLANK_ERROR);
+            }
+            if (StrUtil.isNotBlank(objName) && !codeNameSet.contains(objName)){
+                errorList.add(realCol+SopColumnEnum.OBJ_CHOICE.getName()+SopErrorEnum.CONTENT_ERROR);
+            }
+            // 4.对象编码
+            String objCode = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(3,i))));
+            if (StrUtil.isBlank(objCode)){
+                errorList.add(realCol+SopColumnEnum.OBJ_CODE.getName()+SopErrorEnum.CONTENT_BLANK_ERROR);
+            }
+            if (StrUtil.isNotBlank(objCode) && !codeSet.contains(objCode)){
+                errorList.add(realCol+SopColumnEnum.OBJ_CODE.getName()+SopErrorEnum.CONTENT_ERROR);
+            }
+            // 5.工作时长(天)
+            String dayStr = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(8,i))));
+            if (StrUtil.isNotBlank(dayStr) && !NumberUtil.isNumber(dayStr)){
+                errorList.add(realCol+SopColumnEnum.WORK_TIME_DAY+SopErrorEnum.NUMBER_ERROR);
+            }
+            // 6.工作时长(时)
+            String hourStr = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(9,i))));
+            if (StrUtil.isNotBlank(hourStr) && !NumberUtil.isNumber(hourStr)){
+                errorList.add(realCol+SopColumnEnum.WORK_TIME_HOUR+SopErrorEnum.NUMBER_ERROR);
+            }
+            // 7.工作时长(分)
+            String minStr = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(10,i))));
+            if (StrUtil.isNotBlank(minStr) && !NumberUtil.isNumber(minStr)){
+                errorList.add(realCol+SopColumnEnum.WORK_TIME_MIN+SopErrorEnum.NUMBER_ERROR);
+            }
+            // 8.标准作业操作内容
+            String describe = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(13,i))));
+            if (StrUtil.isBlank(describe)){
+                errorList.add(realCol+SopColumnEnum.JOB_DESCRIPTION.getName()+SopErrorEnum.CONTENT_BLANK_ERROR);
+            }
+            // 9.添加信息点
+            String infoCode = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(CellUtil.getCellValue(firstSheet.getOrCreateCell(15,i))));
+            if (StrUtil.isNotBlank(infoCode) && !infoNameSet.contains(objName+SopCommonConst.UNDER_LINE+infoCode)){
+                errorList.add(realCol+SopErrorEnum.CONTENT_ERROR);
+            }
+        }
+        return errorList;
+    }
+
+    /***
+     * Description: 校验文件的正确性
+     * @param lists : 数据列表
+     * @return : java.util.List<java.lang.String>
+     * @author : lijie
+     * @date :2021/3/15 11:51
+     * Update By lijie 2021/3/15 11:51
+     */
+    private List<String> checkFileIsValid(List<List<Object>> lists) {
+        List<String> errorList = new ArrayList<>();
+        if (lists.size() < SopQueryConst.EXCEL_HEAD_INDEX){
+            errorList.add(SopErrorEnum.FILE_ERROR.getDesc());
+            return errorList;
+        }
+        List<Object> rows = lists.get(1);
+        if (CollUtil.isEmpty(rows)){
+            errorList.add(SopErrorEnum.FILE_ERROR.getDesc());
+            return errorList;
+        }
+        List<SopColumnEnum> list = CollUtil.list(false, EnumUtil.getEnumMap(SopColumnEnum.class).values());
+        Map<Integer, String> sopColumnMap = list.stream()
+                .collect(Collectors.toMap(SopColumnEnum::getIndex, SopColumnEnum::getName, (k1, k2) -> k1));
+        if (rows.size()<sopColumnMap.size()){
+            errorList.add(SopErrorEnum.FILE_ERROR.getDesc());
+            return errorList;
+        }
+        for (int i=0;i<sopColumnMap.size();i++){
+            String columnName = sopColumnMap.get(i);
+            if (StringUtils.isBlank(columnName)){
+                errorList.add(SopErrorEnum.FILE_ERROR.getDesc());
+                return errorList;
+            }
+            String realName = CharSequenceUtil.trimToEmpty(StrUtil.utf8Str(rows.get(i)));
+            if (StrUtil.isBlank(realName) || !realName.contains(columnName)){
+                errorList.add(SopErrorEnum.FILE_ERROR.getDesc());
+                return errorList;
+            }
+        }
+        return errorList;
+    }
+
+    /***
      * Description: 填充对象类数据
      * @param workbook : 工作簿
      * @return : void
@@ -251,7 +633,7 @@ public class BatchHandleSopServiceImpl implements IBatchHandleSopService {
             if (StrUtil.isBlank(firstBean.getObjId()) || StrUtil.isBlank(firstBean.getObjName())){
                 continue;
             }
-            setCellValue(firstBean.getObjName(),firstBean.getObjId(),5,listSheet,lookSheet,index);
+            setCellValue(firstBean.getObjName(),firstBean.getObjId(),5,listSheet,lookSheet,index,ObjTypeEnum.SHAFT_TYPE.getType());
             setInfoValue(workbook,lookSheet,infoCodeMap,firstBean.getObjId(),firstBean.getObjName(),infoSheet,ObjTypeEnum.SHAFT.getType());
             index++;
         }
@@ -284,7 +666,7 @@ public class BatchHandleSopServiceImpl implements IBatchHandleSopService {
             if (StrUtil.isBlank(firstBean.getObjId()) || StrUtil.isBlank(firstBean.getObjName())){
                 continue;
             }
-            setCellValue(firstBean.getObjName(),firstBean.getObjId(),4,listSheet,lookSheet,index);
+            setCellValue(firstBean.getObjName(),firstBean.getObjId(),4,listSheet,lookSheet,index,ObjTypeEnum.FLOOR_TYPE.getType());
             setInfoValue(workbook,lookSheet,infoCodeMap,firstBean.getObjId(),firstBean.getObjName(),infoSheet,ObjTypeEnum.FLOOR.getType());
             index++;
         }
@@ -318,7 +700,7 @@ public class BatchHandleSopServiceImpl implements IBatchHandleSopService {
             if (StrUtil.isBlank(firstBean.getObjId()) || StrUtil.isBlank(firstBean.getObjName())){
                 continue;
             }
-            setCellValue(firstBean.getObjName(),firstBean.getObjId(),3,listSheet,lookSheet,index);
+            setCellValue(firstBean.getObjName(),firstBean.getObjId(),3,listSheet,lookSheet,index,ObjTypeEnum.BUILD_FUNC_TYPE.getType());
             setInfoValue(workbook,lookSheet,infoCodeMap,firstBean.getObjId(),firstBean.getObjName(),infoSheet,ObjTypeEnum.BUILDING.getType());
             index++;
             List<ObjBean> secondBeans = firstBean.getContent();
@@ -329,7 +711,7 @@ public class BatchHandleSopServiceImpl implements IBatchHandleSopService {
                 if (StrUtil.isBlank(firstBean.getObjId()) || StrUtil.isBlank(firstBean.getObjName())){
                     continue;
                 }
-                setCellValue(firstBean.getObjName()+SopCommonConst.UNDER_LINE+secondBean.getObjName(),secondBean.getObjId(),3,listSheet,lookSheet,index);
+                setCellValue(firstBean.getObjName()+SopCommonConst.UNDER_LINE+secondBean.getObjName(),secondBean.getObjId(),3,listSheet,lookSheet,index,ObjTypeEnum.BUILD_FUNC_TYPE.getType());
                 setInfoValue(workbook,lookSheet,infoCodeMap,secondBean.getObjId(),firstBean.getObjName()+SopCommonConst.UNDER_LINE+secondBean.getObjName(),infoSheet,ObjTypeEnum.BUILDING.getType());
                 index++;
                 List<ObjBean> thirdBeans = secondBean.getContent();
@@ -340,7 +722,7 @@ public class BatchHandleSopServiceImpl implements IBatchHandleSopService {
                     if (StrUtil.isBlank(firstBean.getObjId()) || StrUtil.isBlank(firstBean.getObjName())){
                         continue;
                     }
-                    setCellValue(firstBean.getObjName()+SopCommonConst.UNDER_LINE+secondBean.getObjName()+SopCommonConst.UNDER_LINE+thirdBean.getObjName(),thirdBean.getObjId(),3,listSheet,lookSheet,index);
+                    setCellValue(firstBean.getObjName()+SopCommonConst.UNDER_LINE+secondBean.getObjName()+SopCommonConst.UNDER_LINE+thirdBean.getObjName(),thirdBean.getObjId(),3,listSheet,lookSheet,index,ObjTypeEnum.BUILD_FUNC_TYPE.getType());
                     setInfoValue(workbook,lookSheet,infoCodeMap,thirdBean.getObjId(),firstBean.getObjName()+SopCommonConst.UNDER_LINE+secondBean.getObjName()+SopCommonConst.UNDER_LINE+thirdBean.getObjName(),infoSheet,ObjTypeEnum.BUILDING.getType());
                     index++;
                 }
@@ -375,7 +757,7 @@ public class BatchHandleSopServiceImpl implements IBatchHandleSopService {
             if (StrUtil.isBlank(objBean.getObjId()) || StrUtil.isBlank(objBean.getObjName())){
                 continue;
             }
-            setCellValue(objBean.getObjName(),objBean.getObjId(),2,listSheet,lookSheet,index);
+            setCellValue(objBean.getObjName(),objBean.getObjId(),2,listSheet,lookSheet,index,ObjTypeEnum.SPACE_CLASS.getType());
             setInfoValue(workbook, lookSheet,infoCodeMap,objBean.getObjId(),objBean.getObjName(),infoSheet, ObjTypeEnum.SPACE.getType());
             index++;
         }
@@ -425,7 +807,7 @@ public class BatchHandleSopServiceImpl implements IBatchHandleSopService {
                     if (StrUtil.isNotBlank(domainBean.getObjName())){
                         equipName = domainBean.getObjName()+SopCommonConst.UNDER_LINE+equipName;
                     }
-                    setCellValue(equipName,equipBean.getObjId(),1,listSheet,lookSheet,index);
+                    setCellValue(equipName,equipBean.getObjId(),1,listSheet,lookSheet,index,ObjTypeEnum.EQUIP_CLASS.getType());
                     setInfoValue(workbook, lookSheet,infoCodeMap,equipBean.getObjId(),equipName,infoSheet,equipBean.getObjId());
                     index++;
                 }
@@ -469,13 +851,15 @@ public class BatchHandleSopServiceImpl implements IBatchHandleSopService {
      * Update By lijie 2021/4/28 20:52
      */
     private void setCellValue(String objName, String objId, Integer index, Sheet listSheet,
-                              Sheet lookSheet,Integer listCellIndex) {
+                              Sheet lookSheet,Integer listCellIndex,String objType) {
         CellUtil.setCellValue(CellUtil
                 .getOrCreateCell(RowUtil.getOrCreateRow(listSheet,index),listCellIndex), objName,null);
         CellUtil.setCellValue(CellUtil
                 .getOrCreateCell(RowUtil.getOrCreateRow(lookSheet,LOOK_INDEX.get()),0), objName,null);
         CellUtil.setCellValue(CellUtil
                 .getOrCreateCell(RowUtil.getOrCreateRow(lookSheet,LOOK_INDEX.get()),1), "_"+objId,null);
+        CellUtil.setCellValue(CellUtil
+                .getOrCreateCell(RowUtil.getOrCreateRow(lookSheet,LOOK_INDEX.get()),2), objType,null);
         LOOK_INDEX.set(LOOK_INDEX.get()+1);
     }
 
@@ -508,7 +892,7 @@ public class BatchHandleSopServiceImpl implements IBatchHandleSopService {
                     continue;
                 }
                 String objName = StrUtil.isBlank(objBean.getObjName()) ?subObjBean.getObjName():objBean.getObjName()+ SopCommonConst.UNDER_LINE +subObjBean.getObjName();
-                setCellValue(objName,subObjBean.getObjId(),0,listSheet,lookSheet,index);
+                setCellValue(objName,subObjBean.getObjId(),0,listSheet,lookSheet,index,ObjTypeEnum.SYSTEM_CLASS.getType());
                 setInfoValue(workbook,lookSheet,infoCodeMap,subObjBean.getObjId(),objName,infoSheet,subObjBean.getObjId());
                 index++;
             }
@@ -531,12 +915,12 @@ public class BatchHandleSopServiceImpl implements IBatchHandleSopService {
         List<InfoPointsBean> infoPointsBeans = infoCodeMap.getOrDefault(objType, new ArrayList<>());
         for (int i = 0; i < infoPointsBeans.size(); i++) {
             InfoPointsBean infoPointsBean = infoPointsBeans.get(i);
-            CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(lookSheet, LOOK_INDEX.get()-1),i+2),infoPointsBean.getName(),null);
+            CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(lookSheet, LOOK_INDEX.get()-1),i+3),infoPointsBean.getName(),null);
             CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(infoSheet, INFO_INDEX.get()),0),objName+SopCommonConst.UNDER_LINE+infoPointsBean.getName(),null);
             CellUtil.setCellValue(CellUtil.getOrCreateCell(RowUtil.getOrCreateRow(infoSheet, INFO_INDEX.get()),1),JSONObject.toJSONString(infoPointsBean),null);
             INFO_INDEX.set(INFO_INDEX.get()+1);
         }
-        setSheetRefersToFormula(workbook,2,LOOK_INDEX.get(),infoPointsBeans.size()+1, SheetNameEnum.CODE_DATA.getType(),"_"+objId);
+        setSheetRefersToFormula(workbook,3,LOOK_INDEX.get(),infoPointsBeans.size()+1, SheetNameEnum.CODE_DATA.getType(),"_"+objId);
     }
 
     /**
@@ -551,10 +935,10 @@ public class BatchHandleSopServiceImpl implements IBatchHandleSopService {
         char start = (char)(colFlag + offset);
         if (colCount <= 25) {
             char end;
-            if (colCount<2){
+            if ((colCount - offset)<0){
                 end = (char)(start + colCount - 1);
             }else {
-                end = (char)(start + colCount - 2);
+                end = (char)(start + colCount - offset);
             }
             return "$" + start + "$" + rowId + ":$" + end + "$" + rowId;
         } else {
@@ -572,10 +956,10 @@ public class BatchHandleSopServiceImpl implements IBatchHandleSopService {
                     endSuffix = (char)(colFlag + 25);
                     endPrefix = (char)(endPrefix + (colCount - 25) / 26 - 1);
                 } else {
-                    if ((colCount - 25) % 26 < 2){
+                    if (((colCount - 25) % 26 - offset)<0){
                         endSuffix = (char)(colFlag + (colCount - 25) % 26 - 1);
                     }else {
-                        endSuffix = (char)(colFlag + (colCount - 25) % 26 - 2);
+                        endSuffix = (char)(colFlag + (colCount - 25) % 26 - offset);
                     }
                     endPrefix = (char)(endPrefix + (colCount - 25) / 26);
                 }

+ 2 - 1
fm-sop/src/main/java/com/persagy/fm/sop/service/impl/ProjectSopServiceImpl.java

@@ -4395,7 +4395,8 @@ public class ProjectSopServiceImpl implements IProjectSopService {
      * @date :2021/4/1 16:30
      * Update By lijie 2021/4/1 16:30
      */
-    private void batchAddPublishedSop(List<SaveSopVo> saveSopVos) {
+    @Override
+    public void batchAddPublishedSop(List<SaveSopVo> saveSopVos) {
         if (CollUtil.isEmpty(saveSopVos)) {
             return;
         }

+ 4 - 0
fm-sop/src/main/resources/bootstrap.yml

@@ -36,6 +36,10 @@ spring:
             initial-size: 1
             max-wait: 60000
             min-idle: 5
+  servlet:
+    multipart:
+      max-request-size: 200MB
+      max-file-size: 200MB
 mybatis-plus:
   # mapper-locations: classpath*:/mapper/*Mapper.xml
   typeAliasesPackage: com.persagy.fm.sop.entity

BIN
fm-sop/src/main/resources/template/SOP导入模板.xlsx