Эх сурвалжийг харах

Merge remote-tracking branch 'origin/master'

liuyc 2 жил өмнө
parent
commit
51c687bf6c
33 өөрчлөгдсөн 1961 нэмэгдсэн , 1504 устгасан
  1. 6 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/BatchTaskVO.java
  2. 49 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/Coords.java
  3. 14 2
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormData.java
  4. 5 0
      blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/FormulaClient.java
  5. 64 7
      blade-service/blade-business/src/main/java/org/springblade/business/controller/ContractLogController.java
  6. 18 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/DatumPointController.java
  7. 4 0
      blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java
  8. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ContractLogMapper.java
  9. 4 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/ContractLogMapper.xml
  10. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/IContractLogService.java
  11. 5 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ContractLogServiceImpl.java
  12. 46 4
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/DatumPointService.java
  13. 6 60
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ImageClassificationFileServiceImpl.java
  14. 1 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  15. 150 39
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  16. 0 3
      blade-service/blade-business/src/main/java/org/springblade/business/utils/FunctionMain.java
  17. 76 0
      blade-service/blade-business/src/main/java/org/springblade/business/utils/YearTreeUtils.java
  18. 169 457
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  19. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormulaController.java
  20. 20 67
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TableFileController.java
  21. 310 304
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java
  22. 35 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/feign/FormulaClientImpl.java
  23. 13 6
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/CompositeDataAccess.java
  24. 2 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/TableElementConverter.java
  25. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TableFileMapper.java
  26. 3 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TableFileMapper.xml
  27. 9 4
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/IExcelTabService.java
  28. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/ITableFileService.java
  29. 2 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/ITextdictInfoService.java
  30. 930 546
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  31. 5 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TableFileServiceImpl.java
  32. 5 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java
  33. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsParamServiceImpl.java

+ 6 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/BatchTaskVO.java

@@ -18,4 +18,10 @@ public class BatchTaskVO {
     @ApiModelProperty("审批意见")
     private String comment;
 
+    @ApiModelProperty("填报类型")
+    private String approvalType;
+
+    @ApiModelProperty("业务数据")
+    private String formDataId;
+
 }

+ 49 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/Coords.java

@@ -0,0 +1,49 @@
+package org.springblade.manager.dto;
+
+import lombok.Data;
+import org.springblade.core.tool.utils.Func;
+
+import java.util.List;
+
+/**
+ * @author yangyj
+ * @Date 2022/9/9 11:08
+ * @description TODO
+ */
+@Data
+public class Coords {
+    /**开始单元格xy
+     * */
+    private Integer x;
+    private Integer y;
+    /**结束单元格xy
+     * */
+    private Integer x2;
+    private Integer y2;
+    /**无效坐标x*/
+    private List<Integer> ex;
+    /**无效坐标y*/
+    private List<Integer> ey;
+    /**读写方向*/
+    private Boolean horizontal=true;
+    public Coords(String x, String y, String x2, String y2) {
+        this.x = Integer.parseInt(x);
+        this.y = Integer.parseInt(y);
+        this.x2 = Integer.parseInt(x2);
+        this.y2 = Integer.parseInt(y2);
+    }
+
+    public Coords(String x, String y) {
+        this.x = Integer.parseInt(x);
+        this.y = Integer.parseInt(y);
+        this.x2 = this.x;
+        this.y2 = this.y;
+    }
+    public Coords(){
+
+    }
+    public Boolean hasMerge(){
+        return Func.isNotEmpty(ex)||Func.isNotEmpty(ey);
+    }
+
+}

+ 14 - 2
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/dto/FormData.java

@@ -1,12 +1,18 @@
 package org.springblade.manager.dto;
 
+
+
 import lombok.Data;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.core.tool.utils.StringPool;
 import org.springblade.manager.entity.Formula;
 
+
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * @author yangyj
@@ -65,21 +71,27 @@ public class FormData {
     private Integer update=0;
     /**是否完成执行*/
     private Boolean finished=false;
+    public  List<Coords> coordsList= new ArrayList<>();
     public static final String CODE_REG="[^:]+:[^:]+";
 
+
     public FormData() {
     }
-    public FormData(String code, List<ElementData> values, Formula formula) {
+    public FormData(String code, List<ElementData> values, Formula formula,String coords) {
         this.code = code;
         this.values = values;
         this.formula = formula;
+        if(Func.isNotBlank(coords)){
+            this.coordsList = Stream.of(coords).flatMap(e-> Arrays.stream(e.split(";"))).map(e->{String[] xy=e.split("_");return new Coords(xy[1],xy[0]);}).collect(Collectors.toList());
+        }
     }
 
-    public FormData(String code, Integer step, List<ElementData> values, Formula formula) {
+    public FormData(String code, Integer step, List<ElementData> values, Formula formula,String coords) {
         this.code = code;
         this.step = step;
         this.values = values;
         this.formula = formula;
+        this.coordsList = Stream.of(coords).flatMap(e-> Arrays.stream(e.split(";"))).map(e->{String[] xy=e.split("_");return new Coords(xy[1],xy[0]);}).collect(Collectors.toList());
     }
 
     public String getKey(){

+ 5 - 0
blade-service-api/blade-manager-api/src/main/java/org/springblade/manager/feign/FormulaClient.java

@@ -3,7 +3,9 @@ package org.springblade.manager.feign;
 import org.springblade.manager.dto.FormData;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 
+import java.io.FileNotFoundException;
 import java.util.List;
 
 import static org.springblade.core.launch.constant.AppConstant.APPLICATION_NAME_PREFIX;
@@ -20,4 +22,7 @@ public interface FormulaClient {
     @PostMapping(API_PREFIX+"execute")
     void formulaExecute();
 
+    @PostMapping(API_PREFIX+"d-point")
+    String dPoint(@RequestParam Long pkId, @RequestParam String key) throws FileNotFoundException;
+
 }

+ 64 - 7
blade-service/blade-business/src/main/java/org/springblade/business/controller/ContractLogController.java

@@ -21,6 +21,7 @@ import org.springblade.business.feign.OperationLogClient;
 import org.springblade.business.feign.TaskClient;
 import org.springblade.business.service.IContractLogWbsService;
 import org.springblade.business.utils.FileUtils;
+import org.springblade.business.utils.YearTreeUtils;
 import org.springblade.business.vo.*;
 import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.SnowFlakeUtil;
@@ -41,10 +42,7 @@ import org.springframework.web.bind.annotation.*;
 import org.springblade.business.service.IContractLogService;
 import org.springblade.core.boot.ctrl.BladeController;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -77,6 +75,62 @@ public class ContractLogController extends BladeController {
 
 	private final ProjectClient projectClient;
 
+	/**
+	 * 获取填报记录
+	 */
+	@GetMapping("/queryLogList")
+	@ApiOperationSupport(order = 19)
+	@ApiOperation(value = "获取填报记录")
+	@ApiImplicitParams({
+			@ApiImplicitParam(name = "contractId", value = "合同段ID"),
+			@ApiImplicitParam(name = "nodePrimaryKeyId", value = "左侧填报日志节点primaryKeyId"),
+			@ApiImplicitParam(name = "time", value = "所选的时间,格式为yyyy-MM-dd")
+	})
+	public R<List<ContractLog>> queryLogByContractIdAndNodePrimaryKeyId(@RequestParam String contractId, @RequestParam String nodePrimaryKeyId, @RequestParam String time){
+		return R.data(this.contractLogService.list(Wrappers.<ContractLog>lambdaQuery().eq(ContractLog::getContractId, contractId).eq(ContractLog::getWbsNodeId, nodePrimaryKeyId).like(ContractLog::getRecordTime, time)));
+	}
+
+	/**
+	 * 获取当前合同段下本日志节点的填报资料日期树
+	 */
+	@GetMapping("/queryReportLogTimeTree")
+	@ApiOperationSupport(order = 18)
+	@ApiOperation(value = "获取当前合同段下本日志节点的填报资料日期树")
+	@ApiImplicitParams({
+			@ApiImplicitParam(name = "contractId", value = "合同段ID"),
+			@ApiImplicitParam(name = "nodePrimaryKeyId", value = "左侧填报的日志节点primaryKeyId")
+	})
+	public R<List<TreeVo>> queryReportLogTimeTree(@RequestParam String contractId, @RequestParam String nodePrimaryKeyId){
+		//获取填报时间
+		List<String> recordTimeList = this.contractLogService.queryReportLogTimeTree(contractId, nodePrimaryKeyId);
+		//转成结构树
+		return R.data(YearTreeUtils.yearMonthDayTree(recordTimeList));
+	}
+
+	/**
+	 * 删除日志
+	 */
+	@PostMapping("/removeByIds")
+	@ApiOperationSupport(order = 12)
+	@ApiOperation(value = "删除日志")
+	@ApiImplicitParam(name = "ids", value = "删除的数据ID", required = true)
+	public R<Boolean> removeByIds(@RequestBody JSONObject json){
+		if(json.containsKey("ids")){
+			Object ids = json.get("ids");
+			List<Long> idList;
+			if(ids instanceof List){
+				//如果是集合,按集合处理
+				idList = JSONArray.parseArray(JSONObject.toJSONString(ids), Long.class);
+			} else {
+				//否则均按字符串处理
+				idList = Func.toLongList(ids.toString());
+			}
+
+			return R.status(this.contractLogService.deleteLogic(idList));
+		}
+		return R.data(300, false, "未找到具体数据");
+	}
+
 	/**
 	 * 单个废除(填报页)
 	 */
@@ -90,7 +144,10 @@ public class ContractLogController extends BladeController {
 	})
 	public R<Boolean> oneAbolish(@RequestParam String nodePrimaryKeyId, @RequestParam String recordTime, @RequestParam String contractId){
 		//查询数据
-		ContractLog log = this.contractLogService.getOne(Wrappers.<ContractLog>lambdaQuery().eq(ContractLog::getWbsNodeId, nodePrimaryKeyId).eq(ContractLog::getRecordTime, recordTime).eq(ContractLog::getContractId, contractId));
+		ContractLog log = this.contractLogService.getOne(Wrappers.<ContractLog>lambdaQuery().eq(ContractLog::getWbsNodeId, nodePrimaryKeyId)
+				.eq(ContractLog::getCreateUser, AuthUtil.getUserId())
+				.eq(ContractLog::getRecordTime, recordTime)
+				.eq(ContractLog::getContractId, contractId));
 		if(log != null){
 			//调用批量废除接口
 			return this.batchAbolish(log.getId().toString());
@@ -266,7 +323,7 @@ public class ContractLogController extends BladeController {
 	@ApiOperation(value = "批量废除")
 	public R<Boolean> batchAbolish(@RequestParam String ids){
 		//获取所有相关任务记录
-		List<Task> taskList =  this.taskClient.queryTaskListByFormDataId(ids);
+		List<Task> taskList = this.taskClient.queryTaskListByFormDataId(ids);
 		if(taskList != null && taskList.size() > 0){
 			//执行废除
 			for(Task task : taskList){
@@ -422,5 +479,5 @@ public class ContractLogController extends BladeController {
 	public R<List<WbsTreeContractTreeVOS>> queryCurrentContractLogList(@RequestParam String contractId){
 		return R.data(this.wbsTreeContractClient.queryCurrentContractLogList(contractId));
 	}
-	
+
 }

+ 18 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/DatumPointController.java

@@ -4,7 +4,11 @@ import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
 import lombok.AllArgsConstructor;
 import org.apache.poi.hssf.usermodel.HSSFRow;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
@@ -23,6 +27,7 @@ import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintWriter;
@@ -104,6 +109,19 @@ public class DatumPointController {
         return R.data(vo);
     }
 
+    @ResponseBody
+    @GetMapping("/site")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation("测站点信息获取")
+    @ApiImplicitParams(value = {
+            @ApiImplicitParam(name = "contractId", value = "合同段id", required = true),
+            @ApiImplicitParam(name = "pkId", value = "表id", required = true),
+            @ApiImplicitParam(name = "key", value = "元素key", required = true)
+    })
+    public R<Object> site(Long contractId ,Long pkId,String key) throws FileNotFoundException {
+        return this.service.site(contractId,pkId,key);
+    }
+
 
     @PostMapping("/import")
     public R importXy(@RequestParam("file") MultipartFile file, Integer type , Long contractId, Long projectId) throws Exception {

+ 4 - 0
blade-service/blade-business/src/main/java/org/springblade/business/controller/TaskController.java

@@ -232,12 +232,16 @@ public class TaskController extends BladeController {
 		if(StringUtils.isNotEmpty(taskIds)){
 			String[] taskIdArray = taskIds.split(",");
 			String[] parallelProcessInstanceIdArray = parallelProcessInstanceIds.split(",");
+			String[] approvalType = batchTaskVO.getApprovalType().split(",");
+			String[] formDataId = batchTaskVO.getFormDataId().split(",");
 			for(int i = 0, l = taskIdArray.length; i < l; i ++){
 				TaskApprovalVO approvalVO = new TaskApprovalVO();
 				approvalVO.setTaskId(taskIdArray[i]);
 				approvalVO.setParallelProcessInstanceId(parallelProcessInstanceIdArray[i]);
 				approvalVO.setFlag(batchTaskVO.getFlag());
 				approvalVO.setComment(batchTaskVO.getComment());
+				approvalVO.setApprovalType(Integer.parseInt(approvalType[i]));
+				approvalVO.setFormDataId(formDataId[i]);
 
 				//批量审批
 				this.taskService.completeApprovalTask(approvalVO);

+ 2 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/ContractLogMapper.java

@@ -31,6 +31,8 @@ import java.util.List;
  */
 public interface ContractLogMapper extends BaseMapper<ContractLog> {
 
+	List<String> queryReportLogTimeTree(@Param("contractId") String contractId, @Param("nodePrimaryKeyId") String nodePrimaryKeyId);
+
 	List<String> getSubmitLogDateList(@Param("contractId") String contractId, @Param("primaryKeyId") String primaryKeyId, @Param("year") String year);
 
 	List<ContractLog> queryFillUser(@Param("vo") ContractLogVO vo);

+ 4 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/ContractLogMapper.xml

@@ -57,6 +57,10 @@
         <result column="operation" property="operation"/>
     </resultMap>
 
+    <select id="queryReportLogTimeTree" resultType="java.lang.String">
+      select record_time from u_contract_log where contract_id = #{contractId} and wbs_node_id = #{nodePrimaryKeyId} and is_deleted = 0 group by record_time order by record_time DESC
+    </select>
+
     <select id="getSubmitLogDateList" resultType="java.lang.String">
         select record_time from u_contract_log where is_deleted = 0 and wbs_node_id = #{primaryKeyId} and contract_id = #{contractId} and record_time like concat('%',#{year},'%') group by record_time order by record_time DESC
     </select>

+ 2 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/IContractLogService.java

@@ -32,6 +32,8 @@ import java.util.List;
  */
 public interface IContractLogService extends BaseService<ContractLog> {
 
+	List<String> queryReportLogTimeTree(String contractId, String nodePrimaryKeyId);
+
 	List<FileUserVO> queryFillUser(ContractLogVO logVO);
 
 	List<String> getSubmitLogDateList(String contractId, String primaryKeyId, String year);

+ 5 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ContractLogServiceImpl.java

@@ -43,6 +43,11 @@ import java.util.List;
 @Service
 public class ContractLogServiceImpl extends BaseServiceImpl<ContractLogMapper, ContractLog> implements IContractLogService {
 
+	@Override
+	public List<String> queryReportLogTimeTree(String contractId, String nodePrimaryKeyId) {
+		return this.baseMapper.queryReportLogTimeTree(contractId, nodePrimaryKeyId);
+	}
+
 	@Override
 	public List<String> getSubmitLogDateList(String contractId, String primaryKeyId, String year) {
 		return this.baseMapper.getSubmitLogDateList(contractId, primaryKeyId, year);

+ 46 - 4
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/DatumPointService.java

@@ -1,18 +1,22 @@
 package org.springblade.business.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
+import lombok.AllArgsConstructor;
 import org.apache.poi.ss.usermodel.*;
 import org.springblade.business.entity.DatumPoint;
 import org.springblade.business.mapper.DatumPointMapper;
 import org.springblade.business.utils.ExcelUtil;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.core.tool.api.R;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.StringPool;
 import org.springblade.core.tool.utils.StringUtil;
+import org.springblade.manager.feign.FormulaClient;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.io.InputStream;
+import java.io.FileNotFoundException;
 import java.util.*;
 
 /**
@@ -21,10 +25,48 @@ import java.util.*;
  * @description TODO
  */
 @Service
+@AllArgsConstructor
 public class DatumPointService extends BaseServiceImpl<DatumPointMapper, DatumPoint> {
+     private  final FormulaClient formulaClient;
+    public R<Object> site(Long contractId,Long pkId,String key) throws FileNotFoundException {
+          Map<String,Object> result = new HashMap<>();
+          if(Func.isNotEmpty(contractId)&&Func.isNotEmpty(pkId)&&Func.isNotEmpty(key)) {
+              /*获取定位配置信息,取第一个
+               * {站点名称:{key_x:xxx,key_y:xxx,key_h:xxx}}
+               * */
+              key = key.replaceAll("__[\\d_]+", "");
+              String keys = this.formulaClient.dPoint(pkId, key);
+              if (Func.isNotBlank(keys)) {
+                  String[] ka = keys.split(StringPool.COMMA);
+                  LambdaQueryWrapper<DatumPoint> wrapper;
+                  if (ka.length == 1) {
+                      wrapper = Wrappers.<DatumPoint>lambdaQuery().eq(DatumPoint::getContractId, contractId).eq(DatumPoint::getType, 0);
+                  } else {
+                      wrapper = Wrappers.<DatumPoint>lambdaQuery().eq(DatumPoint::getContractId, contractId).eq(DatumPoint::getType, 1);
+                  }
+                  List<DatumPoint> data = this.list(wrapper);
+                  String finalKey = key;
+                  if (Func.isNotEmpty(data)) {
+                      if (ka.length == 1) {
+                          data.forEach(e -> {
+                              Map<String, Object> map = new HashMap<>();
+                              map.put(finalKey +"__"+ka[0], e.getH());
+                              result.put(e.getName(), map);
+                          });
+                      } else {
+                          data.forEach(e -> {
+                              Map<String, Object> map = new HashMap<>();
+                              map.put(finalKey+"__"+ka[0], e.getX());
+                              map.put(finalKey+"__"+ka[1], e.getY());
+                              result.put(e.getName(), map);
+                          });
+                      }
 
-
-
+                  }
+              }
+          }
+          return  R.data(result);
+    }
 
     public R importData(MultipartFile file, Long contractId, Long projectId, Integer dataType) throws Exception {
         List<String> level=new ArrayList<>();

+ 6 - 60
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/ImageClassificationFileServiceImpl.java

@@ -21,6 +21,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.alibaba.nacos.common.utils.DateFormatUtils;
 import org.apache.commons.lang.StringUtils;
 import org.springblade.business.entity.ImageClassificationFile;
+import org.springblade.business.utils.YearTreeUtils;
 import org.springblade.business.vo.ImageClassificationFileVO;
 import org.springblade.business.mapper.ImageClassificationFileMapper;
 import org.springblade.business.service.IImageClassificationFileService;
@@ -55,66 +56,11 @@ public class ImageClassificationFileServiceImpl extends BaseServiceImpl<ImageCla
 	public List<TreeVo> getYearDateTree(String classifyId, String projectId, String contractId) {
 		//获取时间
 		List<Date> shootingTimes = this.baseMapper.selectShootingTimeByClassifyAndProjectId(classifyId, projectId, contractId);
-
-		//最终集合
-		List<TreeVo> result = new ArrayList<>();
-		//年
-		Map<String,List<String>> yearMap = new HashMap<>();
-		for(Date date : shootingTimes){
-			//转换为字符串后拆分获取年月日
-			String dateStr = DateFormatUtils.format(date, "yyyy-MM-dd");
-			String[] dateArray = dateStr.split("-");
-			List<String> monthList;
-			if(yearMap.containsKey(dateArray[0] + "年")){
-				//存在,获取集合
-				monthList = yearMap.get(dateArray[0] + "年");
-			} else {
-				//不存在,创建
-				monthList = new ArrayList<>();
-			}
-			monthList.add(dateArray[1] + "-" + dateArray[2]);
-			yearMap.put(dateArray[0] + "年", monthList);
-		}
-
-		//循环年
-		for(Map.Entry<String,List<String>> yearMaps : yearMap.entrySet()){
-			String year = yearMaps.getKey().replace("年", "");
-			List<String> monthList = yearMaps.getValue();
-
-			//月集合
-			List<TreeVo> monthResult = new ArrayList<>();
-
-			//月
-			TreeVo monthMap = new TreeVo();
-
-			//循环月份
-			String month = monthList.get(0).split("-")[0];
-			int index = 0;
-			for(String monthDay : monthList){
-				//拆分
-				String[] monthDays = monthDay.split("-");
-
-				if(!month.equals(monthDays[0])){
-					month = monthDays[0];
-					monthResult.add(monthMap);
-					monthMap = new TreeVo();
-				}
-				monthMap.setName(month + "月");
-				monthMap.setHierarchy(year + "-" + month);
-				monthMap.getTreeList().add(new TreeVo(monthDays[1] + "日", new ArrayList<>(), year + "-" + month + "-" + monthDays[1]));
-				index ++;
-				if(index == monthList.size()){
-					monthResult.add(monthMap);
-				}
-			}
-			//年
-			TreeVo yearResult = new TreeVo(year, monthResult, year);
-			result.add(yearResult);
-		}
-		//时间倒序
-		result.sort(Comparator.comparing(TreeVo::getName).reversed());
-
-		return result;
+		//转换时间
+		List<String> yearMonthDayList = new ArrayList<>();
+		shootingTimes.forEach(date -> yearMonthDayList.add(DateFormatUtils.format(date, "yyyy-MM-dd")));
+		//转成结构树
+		return YearTreeUtils.yearMonthDayTree(yearMonthDayList);
 	}
 
 	@Override

+ 1 - 1
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java

@@ -465,7 +465,7 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
 							this.integrationMethod(vor, linkTasks);
 						}
 						//设置上报批次
-						vor.setReportNumber(String.valueOf(tasks.get(0).getBatch()));
+//						vor.setReportNumber(String.valueOf(tasks.get(0).getBatch()));
 					}
 				}
 			});

+ 150 - 39
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -1,5 +1,6 @@
 package org.springblade.business.service.impl;
 
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -78,6 +79,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 
     private final ContractClient contractClient;
 
+    private final Integer FOREACH_MAX = 10;
+
     @Override
     public List<TaskParallel> queryApprovalUser(String formDataIds) {
         //返回结果
@@ -104,6 +107,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
       */
      @Override
      public TaskApprovalVO queryBusinessDataTask(TaskApprovalVO taskApprovalVO) {
+         int foreachNumber = 0;
          do {
              //判断锁是否存在
              if(!DistributedRedisLock.getLockStatus(taskApprovalVO.getFormDataId())){
@@ -126,13 +130,21 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                  }
              } else {
                 try{
-                    //如果存在锁,则等待解锁
-                    TimeUnit.MILLISECONDS.sleep(5);
+                    if(foreachNumber < FOREACH_MAX){
+                        //如果存在锁,则等待解锁
+                        TimeUnit.MILLISECONDS.sleep(5);
+                        foreachNumber ++;
+                    } else {
+                        break;
+                    }
                 }catch (Exception e){
                     e.printStackTrace();
                 }
              }
          } while (true);
+         //能走到这说明找不到文件或者超过锁定次数,解锁并返回
+         DistributedRedisLock.release(taskApprovalVO.getFormDataId());
+         return taskApprovalVO;
      }
 
      @Override
@@ -409,49 +421,113 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
             //修改对应的业务数据状态为已废除
             this.updateBusinessDataByFormDataId(this.getOne(Wrappers.<Task>lambdaQuery().eq(Task::getProcessInstanceId, masterProcessInstanceId)), 3, null);
 
-            //查询合同段及项目名称
-            ProjectInfo projectInfo = this.projectClient.queryProjectList(Func.toStrList(masterTask.getProjectId())).get(0);
-            String projectName = StringUtils.isNotEmpty(projectInfo.getProjectAlias()) ? projectInfo.getProjectAlias() : projectInfo.getProjectName();
-            ContractInfo contractInfo = this.contractClient.getContractById(Long.parseLong(masterTask.getContractId()));
-            String contractName = contractInfo.getContractName();
-
-            try{
-                //设置废除通知信息
-                List<MessageWarningVO> messageWarningList = new ArrayList<>();
-                List<TaskParallel> linkTaskList = this.taskParallelService.list(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getProcessInstanceId, masterProcessInstanceId));
-                for(TaskParallel parallel : linkTaskList){
-                    if(!currentLink.getId().equals(parallel.getId())){
-                        messageWarningList.add(new MessageWarningVO(
-                                Long.parseLong(masterTask.getProjectId()),
-                                Long.parseLong(masterTask.getContractId()),
-                                3,
-                                "【" + projectName + "-" + contractName + "】的用户【" + AuthUtil.getNickName() + "】废除了【" + masterTask.getTaskName() + "】,废除原因为【" + comment + "】,请及时查看",
-                                Long.parseLong(parallel.getTaskUser()),
-                                0
-                        ));
-                    }
-                }
+            //任务废除通知
+            this.abolishMessage(masterTask, currentLink, comment);
 
-                //通知上报人
-                messageWarningList.add(new MessageWarningVO(
-                        Long.parseLong(masterTask.getProjectId()),
-                        Long.parseLong(masterTask.getContractId()),
-                        3,
-                        "【" + projectName + "-" + contractName + "】的用户【" + AuthUtil.getNickName() + "】废除了【" + masterTask.getTaskName() + "】,废除原因为【" + comment + "】,请及时查看",
-                        masterTask.getCreateUser(),
-                        0
-                ));
-
-                //生成废除通知
-                this.messageWarningService.savePushUserMessageWarning(messageWarningList);
-            }catch (Exception e){
-                e.printStackTrace();
-            }
         }
 
         return true;
     }
 
+    /**
+     * 任务废除通知
+     */
+    private void abolishMessage(Task masterTask, TaskParallel currentLink, String comment){
+        //查询合同段及项目名称
+        ProjectInfo projectInfo = this.projectClient.queryProjectList(Func.toStrList(masterTask.getProjectId())).get(0);
+        String projectName = StringUtils.isNotEmpty(projectInfo.getProjectAlias()) ? projectInfo.getProjectAlias() : projectInfo.getProjectName();
+        ContractInfo contractInfo = this.contractClient.getContractById(Long.parseLong(masterTask.getContractId()));
+        String contractName = contractInfo.getContractName();
+
+        try{
+            //记录已经通知的人
+            List<Long> userIds = new ArrayList<>();
+
+            //设置废除通知信息
+            List<MessageWarningVO> messageWarningList = new ArrayList<>();
+            List<TaskParallel> linkTaskList = this.taskParallelService.list(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getProcessInstanceId, masterTask.getProcessInstanceId()));
+            for(TaskParallel parallel : linkTaskList){
+                if(!currentLink.getId().equals(parallel.getId()) && !userIds.contains(Long.parseLong(parallel.getTaskUser()))){
+                    messageWarningList.add(new MessageWarningVO(
+                            Long.parseLong(masterTask.getProjectId()),
+                            Long.parseLong(masterTask.getContractId()),
+                            3,
+                            "【" + projectName + "-" + contractName + "】的用户【" + AuthUtil.getNickName() + "】废除了【" + masterTask.getTaskName() + "】,废除原因为【" + comment + "】,请及时查看",
+                            Long.parseLong(parallel.getTaskUser()),
+                            0
+                    ));
+                    //记录添加人
+                    userIds.add(Long.parseLong(parallel.getTaskUser()));
+                }
+            }
+
+            //通知上报人
+            messageWarningList.add(new MessageWarningVO(
+                    Long.parseLong(masterTask.getProjectId()),
+                    Long.parseLong(masterTask.getContractId()),
+                    3,
+                    "【" + projectName + "-" + contractName + "】的用户【" + AuthUtil.getNickName() + "】废除了【" + masterTask.getTaskName() + "】,废除原因为【" + comment + "】,请及时查看",
+                    masterTask.getCreateUser(),
+                    0
+            ));
+            userIds.add(masterTask.getCreateUser());
+
+            //查询业务数据
+            JSONObject businessJson = this.queryTaskBusinessObject(masterTask.getFormDataId());
+            //通知填报人
+            if(businessJson.containsKey("isQuery") || businessJson.containsKey("isLog") || businessJson.containsKey("isArchive")){
+                //获取集合
+                List<JSONObject> result = JSONArray.parseArray(JSONObject.toJSONString(businessJson.get("result")), JSONObject.class);
+                for(JSONObject json : result){
+                    if(businessJson.containsKey("isQuery")){
+                        //填报资料,获取参与的填报人
+                        String fileUserIdAndName = json.getString("fileUserIdAndName");
+                        if(StringUtils.isNotEmpty(fileUserIdAndName)){
+                            String[] fileUserIdAndNames = fileUserIdAndName.split(",");
+                            for(String str : fileUserIdAndNames){
+                                String[] strs = str.split("-");
+                                //可能上报人就是填报人,防止重复推送
+                                if(!userIds.contains(Long.parseLong(strs[0]))){
+                                    //通知上报人
+                                    messageWarningList.add(new MessageWarningVO(
+                                            Long.parseLong(masterTask.getProjectId()),
+                                            Long.parseLong(masterTask.getContractId()),
+                                            3,
+                                            "【" + projectName + "-" + contractName + "】的用户【" + AuthUtil.getNickName() + "】废除了【" + masterTask.getTaskName() + "】,废除原因为【" + comment + "】,请及时查看",
+                                            Long.parseLong(strs[0]),
+                                            0
+                                    ));
+                                    userIds.add(Long.parseLong(strs[0]));
+                                }
+                            }
+                        }
+
+                    } else if(businessJson.containsKey("isLog") || businessJson.containsKey("isArchive")){
+                        //获取填写人
+                        String fillUser = json.getString("createUser");
+                        if(StringUtils.isNotEmpty(fillUser) && !userIds.contains(Long.parseLong(fillUser))){
+                            //通知上报人
+                            messageWarningList.add(new MessageWarningVO(
+                                    Long.parseLong(masterTask.getProjectId()),
+                                    Long.parseLong(masterTask.getContractId()),
+                                    3,
+                                    "【" + projectName + "-" + contractName + "】的用户【" + AuthUtil.getNickName() + "】废除了【" + json.getString("fileName") + "】,废除原因为【" + comment + "】,请及时查看",
+                                    Long.parseLong(fillUser),
+                                    0
+                            ));
+                            userIds.add(Long.parseLong(fillUser));
+                        }
+                    }
+                }
+            }
+
+            //生成废除通知
+            this.messageWarningService.savePushUserMessageWarning(messageWarningList);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
     @Override
     public Boolean startApproval(TaskVO vo) {
         //获取业务表
@@ -536,6 +612,41 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         return true;
     }
 
+    /**
+     * 获取业务数据
+     */
+    private JSONObject queryTaskBusinessObject(String formDataId){
+        JSONObject json = new JSONObject();
+        List<JSONObject> jsonResult;
+        //先检查是否是资料填报
+        List<InformationQuery> querys = this.informationQueryService.list(Wrappers.<InformationQuery>lambdaQuery().in(InformationQuery::getId, Func.toStrList(formDataId)));
+        if(querys != null && querys.size() > 0){
+            jsonResult = JSONArray.parseArray(JSONObject.toJSONString(querys), JSONObject.class);
+            //设置标记
+            json.put("isQuery", "true");
+            json.put("result", jsonResult);
+        } else {
+            //再检查是否是日志
+            List<ContractLog> logs = this.contractLogService.list(Wrappers.<ContractLog>lambdaQuery().in(ContractLog::getId, Func.toStrList(formDataId)));
+            if(logs != null && logs.size() > 0){
+                jsonResult = JSONArray.parseArray(JSONObject.toJSONString(logs), JSONObject.class);
+                //设置标记
+                json.put("isLog", "true");
+                json.put("result", jsonResult);
+            } else {
+                //工程文件
+                List<ArchiveFile> archiveList = this.archiveFileService.list(Wrappers.<ArchiveFile>lambdaQuery().eq(ArchiveFile::getId, Func.toStrList(formDataId)));
+                if(archiveList != null && archiveList.size() > 0){
+                    jsonResult = JSONArray.parseArray(JSONObject.toJSONString(archiveList), JSONObject.class);
+                    //设置标记
+                    json.put("isArchive", "true");
+                    json.put("result", jsonResult);
+                }
+            }
+        }
+        return json;
+    }
+
     /**
      * 修改业务数据状态
      */

+ 0 - 3
blade-service/blade-business/src/main/java/org/springblade/business/utils/FunctionMain.java

@@ -118,9 +118,6 @@ public class FunctionMain {
         }
     }
 
-    /*public static void main(String[] args) {
-        getToken();
-    }*/
     public static void createTable(Class<?> clazz,String remark) {
                String tableName=clazz.getAnnotation(TableName.class).value();
                StringBuilder sql = new StringBuilder( "DROP TABLE IF EXISTS `"+tableName+"`;\n");

+ 76 - 0
blade-service/blade-business/src/main/java/org/springblade/business/utils/YearTreeUtils.java

@@ -0,0 +1,76 @@
+package org.springblade.business.utils;
+
+import org.springblade.business.vo.TreeVo;
+
+import java.util.*;
+
+public class YearTreeUtils {
+
+    public static List<TreeVo> yearMonthDayTree(List<String> yearMonthDayList){
+
+        //最终集合
+        List<TreeVo> result = new ArrayList<>();
+        if(yearMonthDayList == null || yearMonthDayList.size() <= 0){
+            return result;
+        }
+
+        //年
+        Map<String,List<String>> yearMap = new HashMap<>();
+        for(String dateStr : yearMonthDayList){
+            //拆分获取年月日
+            String[] dateArray = dateStr.split("-");
+
+            List<String> monthList;
+            if(yearMap.containsKey(dateArray[0] + "年")){
+                //存在,获取集合
+                monthList = yearMap.get(dateArray[0] + "年");
+            } else {
+                //不存在,创建
+                monthList = new ArrayList<>();
+            }
+            monthList.add(dateArray[1] + "-" + dateArray[2]);
+            yearMap.put(dateArray[0] + "年", monthList);
+        }
+
+        //循环年
+        for(Map.Entry<String,List<String>> yearMaps : yearMap.entrySet()){
+            String year = yearMaps.getKey().replace("年", "");
+            List<String> monthList = yearMaps.getValue();
+
+            //月集合
+            List<TreeVo> monthResult = new ArrayList<>();
+
+            //月
+            TreeVo monthMap = new TreeVo();
+
+            //循环月份
+            String month = monthList.get(0).split("-")[0];
+            int index = 0;
+            for(String monthDay : monthList){
+                //拆分
+                String[] monthDays = monthDay.split("-");
+
+                if(!month.equals(monthDays[0])){
+                    month = monthDays[0];
+                    monthResult.add(monthMap);
+                    monthMap = new TreeVo();
+                }
+                monthMap.setName(month + "月");
+                monthMap.setHierarchy(year + "-" + month);
+                monthMap.getTreeList().add(new TreeVo(monthDays[1] + "日", new ArrayList<>(), year + "-" + month + "-" + monthDays[1]));
+                index ++;
+                if(index == monthList.size()){
+                    monthResult.add(monthMap);
+                }
+            }
+            //年
+            TreeVo yearResult = new TreeVo(year, monthResult, year);
+            result.add(yearResult);
+        }
+        //时间倒序
+        result.sort(Comparator.comparing(TreeVo::getName).reversed());
+
+        return result;
+    }
+
+}

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 169 - 457
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java


+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FormulaController.java

@@ -264,7 +264,7 @@ public class FormulaController {
         if(obs!=null){
             list= Arrays.stream(obs).map(e->new ElementData(0,0,e)).collect(Collectors.toList());
         }
-        return new FormData(code, list,f);
+        return new FormData(code, list,f,"");
     }
 
 

+ 20 - 67
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TableFileController.java

@@ -24,8 +24,10 @@ import lombok.AllArgsConstructor;
 
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
+import org.springblade.manager.entity.ExcelTab;
 import org.springblade.manager.entity.TableFile;
 import org.springblade.manager.entity.WbsTreeContract;
+import org.springblade.manager.service.IExcelTabService;
 import org.springblade.manager.service.IWbsTreeContractService;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.RequestParam;
@@ -50,92 +52,43 @@ public class TableFileController extends BladeController {
 	private final ITableFileService tableFileService;
 
 	private final IWbsTreeContractService wbsTreeContractService;
-/*
-	*//**
-	 * 详情
-	 *//*
-	@GetMapping("/detail")
-	@ApiOperationSupport(order = 1)
-	@ApiOperation(value = "详情", notes = "传入tableFile")
-	public R<TableFile> detail(TableFile tableFile) {
-		TableFile detail = tableFileService.getOne(Condition.getQueryWrapper(tableFile));
-		return R.data(detail);
-	}
-
-	*//**
-	 * 分页 表单附件信息
-	 *//*
-	@GetMapping("/list")
-	@ApiOperationSupport(order = 2)
-	@ApiOperation(value = "分页", notes = "传入tableFile")
-	public R<IPage<TableFile>> list(TableFile tableFile, Query query) {
-		IPage<TableFile> pages = tableFileService.page(Condition.getPage(query), Condition.getQueryWrapper(tableFile));
-		return R.data(pages);
-	}
-
-	*//**
-	 * 自定义分页 表单附件信息
-	 *//*
-	@GetMapping("/page")
-	@ApiOperationSupport(order = 3)
-	@ApiOperation(value = "分页", notes = "传入tableFile")
-	public R<IPage<TableFileVO>> page(TableFileVO tableFile, Query query) {
-		IPage<TableFileVO> pages = tableFileService.selectTableFilePage(Condition.getPage(query), tableFile);
-		return R.data(pages);
-	}
-
-	*//**
-	 * 新增 表单附件信息
-	 *//*
-	@PostMapping("/save")
-	@ApiOperationSupport(order = 4)
-	@ApiOperation(value = "新增", notes = "传入tableFile")
-	public R save(@Valid @RequestBody TableFile tableFile) {
-		return R.status(tableFileService.save(tableFile));
-	}
-
-	*//**
-	 * 修改 表单附件信息
-	 *//*
-	@PostMapping("/update")
-	@ApiOperationSupport(order = 5)
-	@ApiOperation(value = "修改", notes = "传入tableFile")
-	public R update(@Valid @RequestBody TableFile tableFile) {
-		return R.status(tableFileService.updateById(tableFile));
-	}
-
-	*//**
-	 * 新增或修改 表单附件信息
-	 *//*
-	@PostMapping("/submit")
-	@ApiOperationSupport(order = 6)
-	@ApiOperation(value = "新增或修改", notes = "传入tableFile")
-	public R submit(@Valid @RequestBody TableFile tableFile) {
-		return R.status(tableFileService.saveOrUpdate(tableFile));
-	}
 
-	*/
+	// excel 基本信息表
+	private final IExcelTabService excelTabService;
 	/**
 	 * 删除 表单附件信息
 	 */
 	@PostMapping("/remove")
 	@ApiOperationSupport(order = 1)
 	@ApiOperation(value = "逻辑删除", notes = "传入ids")
-	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) throws Exception {
 		// 查出基本信息
 		TableFile tableFile = tableFileService.getById(ids);
 
 		// 删除数据
-		tableFileService.removeByIds(Func.toLongList(ids));
+		tableFileService.delDataById(ids);
 
 		List<TableFileVO> fileVOList = tableFileService.selectTableFileList(Long.parseLong(tableFile.getTabId()));
-
+		// 该文本无附件
 		if(fileVOList==null || fileVOList.size()<=0){
 			UpdateWrapper<WbsTreeContract> updateWrapper = new UpdateWrapper<>();
 			updateWrapper.in("p_key_id",tableFile.getTabId());
 			updateWrapper.set("tab_file_type",1);
 			wbsTreeContractService.update(updateWrapper);
 		}
+		Long pkeyId = Long.parseLong(tableFile.getTabId()+"");
+		excelTabService.getBussPdfInfo(pkeyId);
+
+		WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
+				.eq(WbsTreeContract::getPKeyId, pkeyId));
+
+		WbsTreeContract wbsTreeContractP = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
+				.eq(WbsTreeContract::getContractId, wbsTreeContract.getContractId())
+				.eq(WbsTreeContract::getProjectId, wbsTreeContract.getProjectId())
+				.eq(WbsTreeContract::getId, wbsTreeContract.getParentId())
+		);
+
+		excelTabService.getBussPdfs(wbsTreeContractP.getPKeyId()+"",wbsTreeContract.getTableOwner(),wbsTreeContract.getContractId(),wbsTreeContract.getProjectId());
 		return R.status(true);
 	}
 

+ 310 - 304
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/TextdictInfoController.java

@@ -24,6 +24,7 @@ import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import lombok.AllArgsConstructor;
+
 import javax.validation.Valid;
 
 import org.jsoup.Jsoup;
@@ -71,317 +72,322 @@ import java.util.Map;
 @Api(value = "参数信息表", tags = "参数信息表接口")
 public class TextdictInfoController extends BladeController {
 
-	private final ITextdictInfoService textdictInfoService;
-	private final WbsTreePrivateMapper wbsTreePrivateMapper;
-
-	private final JdbcTemplate jdbcTemplate;
-
-	/**
-	 * 详情
-	 */
-	@GetMapping("/detail")
-	@ApiOperationSupport(order = 1)
-	@ApiOperation(value = "详情", notes = "传入textdictInfo")
-	public R<TextdictInfo> detail(TextdictInfo textdictInfo) {
-		TextdictInfo detail = textdictInfoService.getOne(Condition.getQueryWrapper(textdictInfo));
-		return R.data(detail);
-	}
-
-	/**
-	 * 分页 参数信息表
-	 */
-	@GetMapping("/list")
-	@ApiOperationSupport(order = 2)
-	@ApiOperation(value = "分页", notes = "传入textdictInfo")
-	public R<IPage<TextdictInfo>> list(TextdictInfo textdictInfo, Query query) {
-		IPage<TextdictInfo> pages = textdictInfoService.page(Condition.getPage(query), Condition.getQueryWrapper(textdictInfo));
-		return R.data(pages);
-	}
-
-	/**
-	 * 自定义分页 参数信息表
-	 */
-	@GetMapping("/page")
-	@ApiOperationSupport(order = 3)
-	@ApiOperation(value = "分页", notes = "传入textdictInfo")
-	public R<IPage<TextdictInfoVO>> page(TextdictInfoVO textdictInfo, Query query) {
-		IPage<TextdictInfoVO> pages = textdictInfoService.selectTextdictInfoPage(Condition.getPage(query), textdictInfo);
-		return R.data(pages);
-	}
-
-	/**
-	 * 新增 参数信息表
-	 */
-	@PostMapping("/save")
-	@ApiOperationSupport(order = 4)
-	@ApiOperation(value = "新增", notes = "传入textdictInfo")
-	public R save(@Valid @RequestBody TextdictInfo textdictInfo) {
-		return R.status(textdictInfoService.save(textdictInfo));
-	}
-
-	/**
-	 * 修改 参数信息表
-	 */
-	@PostMapping("/update")
-	@ApiOperationSupport(order = 5)
-	@ApiOperation(value = "修改", notes = "传入textdictInfo")
-	public R update(@Valid @RequestBody TextdictInfo textdictInfo) {
-		return R.status(textdictInfoService.updateById(textdictInfo));
+    private final ITextdictInfoService textdictInfoService;
+    private final WbsTreePrivateMapper wbsTreePrivateMapper;
+
+    private final JdbcTemplate jdbcTemplate;
+
+    /**
+     * 详情
+     */
+    @GetMapping("/detail")
+    @ApiOperationSupport(order = 1)
+    @ApiOperation(value = "详情", notes = "传入textdictInfo")
+    public R<TextdictInfo> detail(TextdictInfo textdictInfo) {
+        TextdictInfo detail = textdictInfoService.getOne(Condition.getQueryWrapper(textdictInfo));
+        return R.data(detail);
+    }
+
+    /**
+     * 分页 参数信息表
+     */
+    @GetMapping("/list")
+    @ApiOperationSupport(order = 2)
+    @ApiOperation(value = "分页", notes = "传入textdictInfo")
+    public R<IPage<TextdictInfo>> list(TextdictInfo textdictInfo, Query query) {
+        IPage<TextdictInfo> pages = textdictInfoService.page(Condition.getPage(query), Condition.getQueryWrapper(textdictInfo));
+        return R.data(pages);
+    }
+
+    /**
+     * 自定义分页 参数信息表
+     */
+    @GetMapping("/page")
+    @ApiOperationSupport(order = 3)
+    @ApiOperation(value = "分页", notes = "传入textdictInfo")
+    public R<IPage<TextdictInfoVO>> page(TextdictInfoVO textdictInfo, Query query) {
+        IPage<TextdictInfoVO> pages = textdictInfoService.selectTextdictInfoPage(Condition.getPage(query), textdictInfo);
+        return R.data(pages);
+    }
+
+    /**
+     * 新增 参数信息表
+     */
+    @PostMapping("/save")
+    @ApiOperationSupport(order = 4)
+    @ApiOperation(value = "新增", notes = "传入textdictInfo")
+    public R save(@Valid @RequestBody TextdictInfo textdictInfo) {
+        return R.status(textdictInfoService.save(textdictInfo));
+    }
+
+    /**
+     * 修改 参数信息表
+     */
+    @PostMapping("/update")
+    @ApiOperationSupport(order = 5)
+    @ApiOperation(value = "修改", notes = "传入textdictInfo")
+    public R update(@Valid @RequestBody TextdictInfo textdictInfo) {
+        return R.status(textdictInfoService.updateById(textdictInfo));
+    }
+
+    /**
+     * 新增或修改 参数信息表
+     */
+    @PostMapping("/submit")
+    @ApiOperationSupport(order = 6)
+    @ApiOperation(value = "新增或修改", notes = "传入textdictInfo")
+    public R submit(@Valid @RequestBody TextdictInfo textdictInfo) {
+        return R.status(textdictInfoService.saveOrUpdate(textdictInfo));
+    }
+
+
+    /**
+     * 删除 参数信息表
+     */
+	@PostMapping("/remove")
+	@ApiOperationSupport(order = 7)
+	@ApiOperation(value = "逻辑删除", notes = "传入ids")
+	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String id) {
+        textdictInfoService.deleDataInfoById(id);
+		return R.success("成功");
 	}
 
-	/**
-	 * 新增或修改 参数信息表
-	 */
-	@PostMapping("/submit")
-	@ApiOperationSupport(order = 6)
-	@ApiOperation(value = "新增或修改", notes = "传入textdictInfo")
-	public R submit(@Valid @RequestBody TextdictInfo textdictInfo) {
-		return R.status(textdictInfoService.saveOrUpdate(textdictInfo));
-	}
 
-	
-	/**
-	 * 删除 参数信息表
-	 */
-//	@PostMapping("/remove")
-//	@ApiOperationSupport(order = 7)
-//	@ApiOperation(value = "逻辑删除", notes = "传入ids")
-//	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
-//		return R.status(textdictInfoService.deleteLogic(Func.toLongList(ids)));
-//	}
-
-
-	/**
-	 * 保存字段信息
-	 */
-	@PostMapping("/saveTextInfo")
-	@ApiOperationSupport(order = 6)
-	@ApiOperation(value = "新增或修改", notes = "传入textdictInfo")
-	public R saveTextInfo(@Valid @RequestBody TextdictDataInfoVO textdictInfo) throws FileNotFoundException, InterruptedException {
-
-		// 获取 节点信息
-		WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(textdictInfo.getTableId());
-
-		// 读取html页面信息
-		File file1 = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
-		String htmlString =  IoUtil.readToString(new FileInputStream(file1));
-		// 样式集合
-		Document doc = Jsoup.parse(htmlString);
-
-		//解析
-		Element table = doc.select("table").first();
-		Elements trs = table.select("tr");
-		Element element = trs.get(textdictInfo.getTrIndex()).select("td").get(textdictInfo.getTdIndex());
-
-		String trindex = element.children().get(0).attr("trindex");
-		String tdindex = element.children().get(0).attr("tdindex");
-		String x1 = element.children().get(0).attr("x1");
-		String x2 = element.children().get(0).attr("x2");
-		String y1 = element.children().get(0).attr("y1");
-		String y2 = element.children().get(0).attr("y2");
-		String placeholder = element.children().get(0).attr("placeholder").replaceAll("[^(\u4E00-\u9FA5_)]", "");
-		String keyname = element.children().get(0).attr("keyname");
-		String weighing = element.children().get(0).attr("weighing");
-
-		String parm = trindex+","+tdindex+","+x1+","+x2+","+y1+","+y2+",$event";
-		String oncklickText ="'"+ placeholder +"',"+trindex+","+tdindex;
-
-		String vmode = "formData."+keyname;
-		if(textdictInfo.getTextId().equals("input")){ // 单选框
-			element.empty().append("<el-input type='text' v-model="+vmode+" placeholder="+placeholder+" keyname="+keyname+" weighing="+weighing+"  @contextmenu.prevent.native='RightClick("+parm+")' trIndex="+trindex+" tdIndex="+tdindex+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+" style='width:100%;height:100%' > </el-input>");
-			element.children().get(0).attr("@focus","getInformation("+oncklickText+")");
-		}else if(textdictInfo.getTextId().equals("textarea")){ // 文本域
-			int rowspan = element.attr("ROWSPAN").equals("") ? 0 : Integer.parseInt(element.attr("ROWSPAN"));
-			//@focus='getInformation("+oncklickText+")'
-			element.empty().append("<el-input :rows="+rowspan*2+"  type='textarea' placeholder="+placeholder+" v-model="+vmode+"    keyname="+keyname+" weighing="+weighing+"  @contextmenu.prevent.native='RightClick("+parm+")' trIndex="+trindex+" tdIndex="+tdindex+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+" style='width:100%;height:100%'  > </el-input>");
-			element.children().get(0).attr("@focus","getInformation("+oncklickText+")");
-		}else if(textdictInfo.getTextId().equals("select")){ // 下拉框
-			String selectText = " <el-select v-model="+vmode+" keyname="+keyname+" weighing="+weighing+" placeholder="+placeholder+" trIndex="+trindex+" tdIndex="+tdindex+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+">"; //v-model="+keyname+"
-			List<TextdictInfo_vo> optionList = textdictInfo.getTextInfo();
-			if(optionList!=null && optionList.size()>=1){
-				for (int i= 0 ; i<optionList.size();i++)
-				selectText +="<el-option  :key='"+i+"' :label='"+optionList.get(i).getDictValue()+"'   :value='"+i+"' > </el-option>";
-			}
-			selectText += "</el-select>";
-			element.empty().append(selectText);
-			element.children().get(0).attr("@focus","getInformation("+oncklickText+")");
-		}else if(textdictInfo.getTextId().equals("radio")){ // 单选按钮
-
-			String radioText = "<template v-model="+vmode+" keyname="+keyname+" weighing="+weighing+" placeholder="+placeholder+" trIndex="+trindex+" tdIndex="+tdindex+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+">";
-			List<TextdictInfo_vo> optionList = textdictInfo.getTextInfo();
-			if(optionList!=null && optionList.size()>=1){
-				for (int i= 0 ; i<optionList.size();i++)
-					radioText +=" <el-radio v-model="+vmode+"  label="+i+">"+optionList.get(i).getDictValue()+"</el-radio>";
-			}
-			radioText += "</template>";
-			element.empty().append(radioText);
-			element.children().get(0).attr("v-on:click","getInformation("+oncklickText+")");
-			element.attr("tabindex","-1");
-		}else if(textdictInfo.getTextId().equals("checkbox")){ // 多选框
-
-			String checkbox = "<template v-model="+vmode+" keyname="+keyname+" weighing="+weighing+" placeholder="+placeholder+" trIndex="+trindex+" tdIndex="+tdindex+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+">";
-			List<TextdictInfo_vo> optionList = textdictInfo.getTextInfo();
-			if(optionList!=null && optionList.size()>=1){
-				for (int i= 0 ; i<optionList.size();i++)
-					checkbox +="<el-checkbox>"+optionList.get(i).getDictValue()+"</el-checkbox>";
-			}
-			checkbox += "</template>";
-			element.empty().append(checkbox);
-			element.children().get(0).attr("@focus","getInformation("+oncklickText+")");
-			element.attr("tabindex","-1");
-		}else if(textdictInfo.getTextId().equals("date")){ // 日期
-
-			element.empty().append("<el-date-picker v-model="+vmode+" type='date' format='YYYY年MM月DD日' placeholder="+placeholder+" keyname="+keyname+" weighing="+weighing+"  @contextmenu.prevent.native='RightClick("+parm+")' trIndex="+trindex+" tdIndex="+tdindex+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+" style='width:100%;height:100%'   placeholder='"+placeholder+"'> </el-date-picker>");
-			element.children().get(0).attr("@focus","getInformation("+oncklickText+")");
-
-		}else if(textdictInfo.getTextId().equals("daterange")){ // 时间段
-			element.empty().append("<el-date-picker  v-model="+vmode+" type='datetimerange' placeholder="+placeholder+"  start-placeholder='开始日期'  end-placeholder='结束日期' format='YYYY年MM月DD日' trIndex="+trindex+" keyname="+keyname+" weighing="+weighing+" tdIndex="+tdindex+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+">");
-			element.children().get(0).attr("@focus","getInformation("+oncklickText+")");
-			element.children().get(0).attr("@change","datePickerChange($event,'"+keyname+"')");
-		}else if(textdictInfo.getTextId().equals("img")){
+    /**
+     * 保存字段信息
+     */
+    @PostMapping("/saveTextInfo")
+    @ApiOperationSupport(order = 9)
+    @ApiOperation(value = "新增或修改", notes = "传入textdictInfo")
+    public R saveTextInfo(@Valid @RequestBody TextdictDataInfoVO textdictInfo) throws FileNotFoundException, InterruptedException {
+
+        // 获取 节点信息
+        WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(textdictInfo.getTableId());
+
+        // 读取html页面信息
+        File file1 = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
+        String htmlString = IoUtil.readToString(new FileInputStream(file1));
+        // 样式集合
+        Document doc = Jsoup.parse(htmlString);
+
+        //解析
+        Element table = doc.select("table").first();
+        Elements trs = table.select("tr");
+        Element element = trs.get(textdictInfo.getTrIndex()).select("td").get(textdictInfo.getTdIndex());
+
+        String trindex = element.children().get(0).attr("trindex");
+        String tdindex = element.children().get(0).attr("tdindex");
+        String x1 = element.children().get(0).attr("x1");
+        String x2 = element.children().get(0).attr("x2");
+        String y1 = element.children().get(0).attr("y1");
+        String y2 = element.children().get(0).attr("y2");
+        String placeholder = element.children().get(0).attr("placeholder").replaceAll("[^(\u4E00-\u9FA5_)]", "");
+        String keyname = element.children().get(0).attr("keyname");
+        String weighing = element.children().get(0).attr("weighing");
+
+        String parm = trindex + "," + tdindex + "," + x1 + "," + x2 + "," + y1 + "," + y2 + ",$event";
+        String oncklickText = "'" + placeholder + "'," + trindex + "," + tdindex;
+
+        String vmode = "formData." + keyname;
+        if (textdictInfo.getTextId().equals("input")) { // 单选框
+            element.empty().append("<el-input type='text' v-model=" + vmode + " placeholder=" + placeholder + " keyname=" + keyname + " weighing=" + weighing + "  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%' > </el-input>");
+            element.children().get(0).attr("@focus", "getInformation(" + oncklickText + ")");
+        } else if (textdictInfo.getTextId().equals("textarea")) { // 文本域
+            int rowspan = element.attr("ROWSPAN").equals("") ? 0 : Integer.parseInt(element.attr("ROWSPAN"));
+            //@focus='getInformation("+oncklickText+")'
+            element.empty().append("<el-input :rows=" + rowspan * 2 + "  type='textarea' placeholder=" + placeholder + " v-model=" + vmode + "    keyname=" + keyname + " weighing=" + weighing + "  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%'  > </el-input>");
+            element.children().get(0).attr("@focus", "getInformation(" + oncklickText + ")");
+        } else if (textdictInfo.getTextId().equals("select")) { // 下拉框
+            String selectText = " <el-select v-model=" + vmode + " keyname=" + keyname + " weighing=" + weighing + " placeholder=" + placeholder + " trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + ">"; //v-model="+keyname+"
+            List<TextdictInfo_vo> optionList = textdictInfo.getTextInfo();
+            if (optionList != null && optionList.size() >= 1) {
+                for (int i = 0; i < optionList.size(); i++)
+                    selectText += "<el-option  :key='" + i + "' :label='" + optionList.get(i).getDictValue() + "'   :value='" + i + "' > </el-option>";
+            }
+            selectText += "</el-select>";
+            element.empty().append(selectText);
+            element.children().get(0).attr("@focus", "getInformation(" + oncklickText + ")");
+        } else if (textdictInfo.getTextId().equals("radio")) { // 单选按钮
+
+            String radioText = "<template v-model=" + vmode + " keyname=" + keyname + " weighing=" + weighing + " placeholder=" + placeholder + " trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + ">";
+            List<TextdictInfo_vo> optionList = textdictInfo.getTextInfo();
+            if (optionList != null && optionList.size() >= 1) {
+                for (int i = 0; i < optionList.size(); i++)
+                    radioText += " <el-radio v-model=" + vmode + "  label=" + i + ">" + optionList.get(i).getDictValue() + "</el-radio>";
+            }
+            radioText += "</template>";
+            element.empty().append(radioText);
+            element.children().get(0).attr("v-on:click", "getInformation(" + oncklickText + ")");
+            element.attr("tabindex", "-1");
+        } else if (textdictInfo.getTextId().equals("checkbox")) { // 多选框
+
+            String checkbox = "<template v-model=" + vmode + " keyname=" + keyname + " weighing=" + weighing + " placeholder=" + placeholder + " trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + ">";
+            List<TextdictInfo_vo> optionList = textdictInfo.getTextInfo();
+            if (optionList != null && optionList.size() >= 1) {
+                for (int i = 0; i < optionList.size(); i++)
+                    checkbox += "<el-checkbox>" + optionList.get(i).getDictValue() + "</el-checkbox>";
+            }
+            checkbox += "</template>";
+            element.empty().append(checkbox);
+            element.children().get(0).attr("@focus", "getInformation(" + oncklickText + ")");
+            element.attr("tabindex", "-1");
+        } else if (textdictInfo.getTextId().equals("date")) { // 日期
+
+            element.empty().append("<el-date-picker v-model=" + vmode + " type='date' format='YYYY年MM月DD日' placeholder=" + placeholder + " keyname=" + keyname + " weighing=" + weighing + "  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%'   placeholder='" + placeholder + "'> </el-date-picker>");
+            element.children().get(0).attr("@focus", "getInformation(" + oncklickText + ")");
+
+        } else if (textdictInfo.getTextId().equals("daterange")) { // 时间段
+            element.empty().append("<el-date-picker  v-model=" + vmode + " type='datetimerange' placeholder=" + placeholder + "  start-placeholder='开始日期'  end-placeholder='结束日期' format='YYYY年MM月DD日' trIndex=" + trindex + " keyname=" + keyname + " weighing=" + weighing + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + ">");
+            element.children().get(0).attr("@focus", "getInformation(" + oncklickText + ")");
+            element.children().get(0).attr("@change", "datePickerChange($event,'" + keyname + "')");
+        } else if (textdictInfo.getTextId().equals("img")) {
 			/*element.empty().append("<el-upload :disabled='formUploadLoading' v-loading='formUploadLoading' element-loading-text='上传中...' :on-progress='uploadprogress' @exceed='formUploadExceed' :on-error='formUploadError' placeholder="+placeholder+" v-model="+vmode+" keyname="+keyname+" weighing="+weighing+"  class='hc-upload-table-form' action='/api/blade-resource/oss/endpoint/put-file' trIndex="+trindex+" tdIndex="+tdindex+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+"  accept='image/png,image/jpg,image/jpeg' :headers='getTokenHeader' :show-file-list='false' > <img v-if='"+vmode+"' :src="+vmode+" class='hc-table-form-img' /> <div class='hc-table-form-icon' v-else> 点此选择文件并上传 </div> <div v-if="+vmode+" class='hc-table-form-del' >" +
 					"        <el-button type='danger'"+ " plain @click.stop=delTableFormFile('"+keyname+"')>删除当前文件</el-button> " +
 					"    </div></el-upload>");*/
 
-			element.empty().append("<HcTableFormUpload :src='"+vmode+"' placeholder="+placeholder+" v-model="+vmode+"  keyName="+keyname+" weighing="+weighing+"  @success='formUploadSuccess' @del='delTableFormFile' trIndex="+trindex+" tdIndex="+tdindex+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+"/>");
-
-			//element.children().get(0);
-			element.attr("@focus","getInformation("+oncklickText+")");
-			element.attr("tabindex","-1");
-		}
-			File writefile = new File(wbsTreePrivate.getHtmlUrl());
-		FileUtil.writeToFile(writefile, doc.html(), Boolean.parseBoolean("UTF-8"));
-		Thread.sleep(300);
-
-		// 清空相关的保存数据
-		String tabName = wbsTreePrivate.getInitTableName();
-		String isExitSql = " select * from information_schema.TABLES where TABLE_NAME='"+tabName+"'";
-		List<Map<String, Object>> tablist = jdbcTemplate.queryForList(isExitSql);
-		if(tablist!=null && tablist.size()>0){
-			String clarSql = "update  "+tabName+" set "+keyname.split("__")[0]+"=null where p_key_id in(SELECT p_key_id FROM m_wbs_tree_contract WHERE id ='"+wbsTreePrivate.getId()+"' and project_id='"+wbsTreePrivate.getProjectId()+"' )";
-			jdbcTemplate.execute(clarSql);
-		}
-		return R.success("操作成功");
-	}
-
-	/**
-	 *保存电签
-	 */
-	@PostMapping("/save_sigInfo")
-	@ApiOperationSupport(order = 7)
-	@ApiOperation(value = "保存电签", notes = "保存电签")
-	public R<String> saveSigInfo(@Valid @RequestBody JSONObject dataInfo) throws IOException {
-
-		JSONArray jsonArray = dataInfo.getJSONArray("dataInfo");
-		Long tableId = jsonArray.getJSONObject(0).getLong("tabId");
-
-		// 删除
-		textdictInfoService.getBaseMapper().delete(Wrappers.<TextdictInfo>query().lambda()
-				.eq(TextdictInfo::getTabId, tableId));
-
-		WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(tableId);
-		// 读取html页面信息
-		File file1 = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
-		String htmlString =  IoUtil.readToString(new FileInputStream(file1));
-		// 样式集合
-		Document doc = Jsoup.parse(htmlString);
-		//解析
-		Element table = doc.select("table").first();
-		Elements trs = table.select("tr");
-
-		List<TextdictInfo> textdictInfos = new ArrayList<>();
-
-		for (int i =0 ; i<jsonArray.size();i++){
-			JSONObject jsonObject = jsonArray.getJSONObject(i);
-			TextdictInfo textdictInfo = new TextdictInfo();
-			String[] trtd = jsonObject.getString("colKey").split("__")[1].split("_");
-			Element element = trs.get(Integer.parseInt(trtd[0])).select("td").get(Integer.parseInt(trtd[1]));
-
-			String id = element.children().get(0).attr("keyname");
-			textdictInfo.setName("电签位置配置");
-			textdictInfo.setType(2);
-			textdictInfo.setColKey(id);
-			textdictInfo.setSigRoleId(jsonObject.getString("sigRoleId"));
-			textdictInfo.setTabId(jsonObject.getString("tabId"));
-			textdictInfo.setColName(jsonObject.getString("colName"));
-			textdictInfo.setSigRoleName(jsonObject.getString("sigRoleName"));
-			textdictInfo.setPyzbx(jsonObject.getDouble("pyzbx"));
-			textdictInfo.setPyzby(jsonObject.getDouble("pyzby"));
-			textdictInfo.setIsDeleted(0);
-			textdictInfoService.saveOrUpdate(textdictInfo);
-			element.attr("dqId",textdictInfo.getId()+"");
-			element.children().get(0).attr("readonly",true);
-		}
-
-		// 写入 excel
-		File writefile = new File(wbsTreePrivate.getHtmlUrl());
-		FileUtil.writeToFile(writefile, doc.html(), Boolean.parseBoolean("UTF-8"));
-		return R.success("操作成功");
-	}
-
-	/**
-	 *保存电签
-	 */
-	@PostMapping("/save_defaulVal")
-	@ApiOperationSupport(order = 7)
-	@ApiOperation(value = "保存默认值", notes = "保存默认值")
-	public R<String> saveDefaulVal(@Valid @RequestBody TextdictBy345VO textdictInfo) throws IOException {
-		WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(textdictInfo.getTableId());
-
-		// 读取html页面信息
-		File file1 = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
-		String htmlString =  IoUtil.readToString(new FileInputStream(file1));
-		// 样式集合
-		Document doc = Jsoup.parse(htmlString);
-		//解析
-		Element table = doc.select("table").first();
-		Elements trs = table.select("tr");
-		Element element = trs.get(textdictInfo.getTrIndex()).select("td").get(textdictInfo.getTdIndex());
-
-		//
-		String placeholder = "";
-		String id = element.children().get(0).attr("keyname");
-		if(element.html().indexOf("el-tooltip")>=0){
-			placeholder = element.children().get(0).children().get(0).attr("placeholder").replaceAll("[^(\u4E00-\u9FA5_)]", "");
-			id = element.children().get(0).children().get(0).attr("keyname");
-		}else{
-			placeholder = element.children().get(0).attr("placeholder").replaceAll("[^(\u4E00-\u9FA5_)]", "");
-			id = element.children().get(0).attr("keyname");
-		}
-
-		TextdictInfo textdictBean = new TextdictInfo();
-		textdictBean.setIsDeleted(0);
-		textdictBean.setTabId(textdictInfo.getTableId()+"");
-
-		textdictBean.setColKey(id);
-		textdictBean.setColName(placeholder);
-		textdictBean.setSigRoleName(textdictInfo.getTextId());
-
-		if(textdictInfo.getType()==4){ //默认值
-			textdictBean.setType(4);
-			textdictBean.setName("编辑默认值");
-		}
-		if(textdictInfo.getType()==5){ // 提示语
-			textdictBean.setType(5);
-			textdictBean.setName("提示信息");
-			String lastHmtl ="";
-			if(element.html().indexOf("el-tooltip")>=0){
-				element.children().attr("content",textdictInfo.getTextId());
-			}else{
-				lastHmtl = " <el-tooltip content='"+textdictInfo.getTextId()+"' placement='top' effect='customized'>"+element.html()+"</el-tooltip>";
-				element.empty().append(lastHmtl);
-			}
-			File writefile = new File(wbsTreePrivate.getHtmlUrl());
-			FileUtil.writeToFile(writefile, doc.html(), Boolean.parseBoolean("UTF-8"));
-		}
-
-		// 删除
-		textdictInfoService.getBaseMapper().delete(Wrappers.<TextdictInfo>query().lambda().eq(TextdictInfo::getTabId, textdictInfo.getTableId())
-				.eq(TextdictInfo::getType,textdictInfo.getType()).eq(TextdictInfo::getColKey,id));
-
-		textdictInfoService.saveOrUpdate(textdictBean);
-		return R.success("操作成功");
-	}
+            element.empty().append("<hc-table-form-upload :src='" + vmode + "' placeholder=" + placeholder + " v-model=" + vmode + "  keyName=" + keyname + " weighing=" + weighing + "  @success='formUploadSuccess' @del='delTableFormFile' trIndex=" + trindex + " tdIndex=" + tdindex + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + "/> ");
+
+            //element.children().get(0);
+            element.attr("@focus", "getInformation(" + oncklickText + ")");
+            element.attr("tabindex", "-1");
+        }
+        File writefile = new File(wbsTreePrivate.getHtmlUrl());
+        FileUtil.writeToFile(writefile, doc.html(), Boolean.parseBoolean("UTF-8"));
+        Thread.sleep(300);
+
+        // 清空相关的保存数据
+        String tabName = wbsTreePrivate.getInitTableName();
+        String isExitSql = " select * from information_schema.TABLES where TABLE_NAME='" + tabName + "'";
+        List<Map<String, Object>> tablist = jdbcTemplate.queryForList(isExitSql);
+        if (tablist != null && tablist.size() > 0) {
+            String clarSql = "update  " + tabName + " set " + keyname.split("__")[0] + "=null where p_key_id in(SELECT p_key_id FROM m_wbs_tree_contract WHERE id ='" + wbsTreePrivate.getId() + "' and project_id='" + wbsTreePrivate.getProjectId() + "' )";
+            jdbcTemplate.execute(clarSql);
+        }
+        return R.success("操作成功");
+    }
+
+    /**
+     * 保存电签
+     */
+    @PostMapping("/save_sigInfo")
+    @ApiOperationSupport(order = 7)
+    @ApiOperation(value = "保存电签", notes = "保存电签")
+    public R<String> saveSigInfo(@Valid @RequestBody JSONObject dataInfo) throws IOException {
+
+        JSONArray jsonArray = dataInfo.getJSONArray("dataInfo");
+        if(jsonArray==null || jsonArray.size()==0){
+            return R.fail("保存列表无任何数据");
+        }
+        Long tableId = jsonArray.getJSONObject(0).getLong("tabId");
+
+        // 删除
+        textdictInfoService.getBaseMapper().delete(Wrappers.<TextdictInfo>query().lambda()
+                .eq(TextdictInfo::getTabId, tableId));
+
+        WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(tableId);
+        // 读取html页面信息
+        File file1 = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
+        String htmlString = IoUtil.readToString(new FileInputStream(file1));
+        // 样式集合
+        Document doc = Jsoup.parse(htmlString);
+        //解析
+        Element table = doc.select("table").first();
+        Elements trs = table.select("tr");
+
+        List<TextdictInfo> textdictInfos = new ArrayList<>();
+
+        for (int i = 0; i < jsonArray.size(); i++) {
+            JSONObject jsonObject = jsonArray.getJSONObject(i);
+            TextdictInfo textdictInfo = new TextdictInfo();
+            String[] trtd = jsonObject.getString("colKey").split("__")[1].split("_");
+            Element element = trs.get(Integer.parseInt(trtd[0])).select("td").get(Integer.parseInt(trtd[1]));
+
+            String id = element.children().get(0).attr("keyname");
+            textdictInfo.setName("电签位置配置");
+            textdictInfo.setType(2);
+            textdictInfo.setColKey(id);
+            textdictInfo.setSigRoleId(jsonObject.getString("sigRoleId"));
+            textdictInfo.setTabId(jsonObject.getString("tabId"));
+            textdictInfo.setColName(jsonObject.getString("colName"));
+            textdictInfo.setSigRoleName(jsonObject.getString("sigRoleName"));
+            textdictInfo.setPyzbx(jsonObject.getDouble("pyzbx"));
+            textdictInfo.setPyzby(jsonObject.getDouble("pyzby"));
+            textdictInfo.setIsDeleted(0);
+            textdictInfoService.saveOrUpdate(textdictInfo);
+            element.removeAttr("dqId");
+            element.attr("dqId", textdictInfo.getId() + "");
+            element.children().get(0).attr("readonly", true);
+        }
+
+        // 写入 excel
+        File writefile = new File(wbsTreePrivate.getHtmlUrl());
+        FileUtil.writeToFile(writefile, doc.html(), Boolean.parseBoolean("UTF-8"));
+        return R.success("操作成功");
+    }
+
+    /**
+     * 保存电签
+     */
+    @PostMapping("/save_defaulVal")
+    @ApiOperationSupport(order = 7)
+    @ApiOperation(value = "保存默认值", notes = "保存默认值")
+    public R<String> saveDefaulVal(@Valid @RequestBody TextdictBy345VO textdictInfo) throws IOException {
+        WbsTreePrivate wbsTreePrivate = wbsTreePrivateMapper.getByPKeyId(textdictInfo.getTableId());
+
+        // 读取html页面信息
+        File file1 = ResourceUtil.getFile(wbsTreePrivate.getHtmlUrl());
+        String htmlString = IoUtil.readToString(new FileInputStream(file1));
+        // 样式集合
+        Document doc = Jsoup.parse(htmlString);
+        //解析
+        Element table = doc.select("table").first();
+        Elements trs = table.select("tr");
+        Element element = trs.get(textdictInfo.getTrIndex()).select("td").get(textdictInfo.getTdIndex());
+
+        //
+        String placeholder = "";
+        String id = element.children().get(0).attr("keyname");
+        if (element.html().indexOf("el-tooltip") >= 0) {
+            placeholder = element.children().get(0).children().get(0).attr("placeholder").replaceAll("[^(\u4E00-\u9FA5_)]", "");
+            id = element.children().get(0).children().get(0).attr("keyname");
+        } else {
+            placeholder = element.children().get(0).attr("placeholder").replaceAll("[^(\u4E00-\u9FA5_)]", "");
+            id = element.children().get(0).attr("keyname");
+        }
+
+        TextdictInfo textdictBean = new TextdictInfo();
+        textdictBean.setIsDeleted(0);
+        textdictBean.setTabId(textdictInfo.getTableId() + "");
+
+        textdictBean.setColKey(id);
+        textdictBean.setColName(placeholder);
+        textdictBean.setSigRoleName(textdictInfo.getTextId());
+
+        if (textdictInfo.getType() == 4) { //默认值
+            textdictBean.setType(4);
+            textdictBean.setName("编辑默认值");
+        }
+        if (textdictInfo.getType() == 5) { // 提示语
+            textdictBean.setType(5);
+            textdictBean.setName("提示信息");
+            String lastHmtl = "";
+            if (element.html().indexOf("el-tooltip") >= 0) {
+                element.children().attr("content", textdictInfo.getTextId());
+            } else {
+                lastHmtl = " <el-tooltip content='" + textdictInfo.getTextId() + "' placement='top' effect='customized'>" + element.html() + "</el-tooltip>";
+                element.empty().append(lastHmtl);
+            }
+            File writefile = new File(wbsTreePrivate.getHtmlUrl());
+            FileUtil.writeToFile(writefile, doc.html(), Boolean.parseBoolean("UTF-8"));
+        }
+
+        // 删除
+        textdictInfoService.getBaseMapper().delete(Wrappers.<TextdictInfo>query().lambda().eq(TextdictInfo::getTabId, textdictInfo.getTableId())
+                .eq(TextdictInfo::getType, textdictInfo.getType()).eq(TextdictInfo::getColKey, id));
+
+        textdictInfoService.saveOrUpdate(textdictBean);
+        return R.success("操作成功");
+    }
 
 /*	public static void main(String[] args) throws FileNotFoundException {
 		File file1 = ResourceUtil.getFile("/Users/hongchuangyanfa/Desktop/privateUrl/1567789917445029888.html");

+ 35 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/feign/FormulaClientImpl.java

@@ -1,15 +1,24 @@
 package org.springblade.manager.feign;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
+import org.springblade.core.tool.utils.BeanUtil;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.core.tool.utils.StringPool;
 import org.springblade.manager.dto.ElementData;
 import org.springblade.manager.dto.FormData;
 import org.springblade.manager.entity.Formula;
+import org.springblade.manager.formula.KeyMapper;
+import org.springblade.manager.service.IExcelTabService;
 import org.springblade.manager.service.IFormulaService;
+import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.io.FileNotFoundException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
@@ -21,6 +30,8 @@ import java.util.stream.Collectors;
 @AllArgsConstructor
 public class FormulaClientImpl implements  FormulaClient{
     private  final IFormulaService service;
+    private final JdbcTemplate jdbcTemplate;
+    private final IExcelTabService excelTabService;
     @Override
     public void formulaExecute() {
         List<FormData> list = new ArrayList<>();
@@ -34,6 +45,29 @@ public class FormulaClientImpl implements  FormulaClient{
         list.add(makeFd("","d","",0,10,7,2,5,5));
         service.execute(list,111111L,22222L);
     }
+
+    @Override
+    public String dPoint(Long pkId, String key)  {
+        StringBuilder sb = new StringBuilder();
+        try {
+            Map<String,String> keysMap = this.excelTabService.getTablbCols(String.valueOf(pkId),null);
+            Map<String, Object> queryForMap = this.jdbcTemplate.queryForMap("SELECT   a.p_key_id as nodeId,b.id as fieldId,b.e_key as field,c.init_table_name as tableName  from m_wbs_tree_contract a LEFT JOIN m_wbs_form_element b on a.id=b.f_id left JOIN m_wbs_tree c on a.id=c.id where b.e_key='"+key+"' and b.is_deleted=0 and a.p_key_id = (" + pkId + ")");
+          if(Func.isNotEmpty(queryForMap)) {
+              KeyMapper keyMapper = BeanUtil.toBean(queryForMap, KeyMapper.class);
+              Formula formula = this.service.getOne(Wrappers.<Formula>lambdaQuery().eq(Formula::getElementId, keyMapper.getFieldId()));
+              if(Func.isNotEmpty(formula)) {
+                  formula.getRelyList().forEach(e -> {
+                      sb.append(keysMap.get(e.split(StringPool.COLON)[1])).append(StringPool.COMMA);
+                  });
+              }
+          }
+        }catch (FileNotFoundException e){
+            e.printStackTrace();
+            sb.append("无法获取定位信息");
+        }
+        return sb.toString();
+    }
+
     public FormData makeFd(String fs,String code,String rely,Object ...obs){
         Formula f= new Formula();
         f.setRely(rely);
@@ -42,6 +76,6 @@ public class FormulaClientImpl implements  FormulaClient{
         if(obs!=null){
             list= Arrays.stream(obs).map(e->new ElementData(0,0,e)).collect(Collectors.toList());
         }
-        return new FormData(code, list,f);
+        return new FormData(code, list,f,"");
     }
 }

+ 13 - 6
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/CompositeDataAccess.java

@@ -17,7 +17,10 @@ import java.util.stream.Collectors;
 public class CompositeDataAccess  {
     private  LinkedHashMap<String, FormData> fds =new LinkedHashMap<>();
     private int maxSize=1;
+    /**当前指针*/
     private int cursor=0;
+    /**下一个数据指针*/
+    private int next=0;
 
     public CompositeDataAccess(LinkedHashMap<String, FormData> fds) {
         if(fds!=null){
@@ -81,10 +84,9 @@ public class CompositeDataAccess  {
             for(Map.Entry<String,FormData> fd:fds.entrySet()){
                 List<ElementData> list = fd.getValue().getValues();
                 if(list.size()<=cursor){
-                    list.addAll(Collections.nCopies(cursor-list.size()+1,null));
+                    list.addAll(Collections.nCopies(cursor-list.size()+1,new ElementData(cursor/fd.getValue().getCoordsList().size(),1,null)));
                 }
-                /*动态增减的时候难以判定是否换页,暂时全部用1代替*/
-                list.add(cursor,data.getOrDefault(fd.getKey(),new ElementData(1,1,"")));
+                list.add(cursor,data.getOrDefault(fd.getKey(),new ElementData(cursor/fd.getValue().getCoordsList().size(),1,null)));
             }
         }
     }
@@ -97,7 +99,7 @@ public class CompositeDataAccess  {
             for(Map.Entry<String,ElementData> d:data.entrySet()){
                 List<ElementData> list = fds.get(d.getKey()).getValues();
                 /*向所有数据末尾追加*/
-                list.addAll(Collections.nCopies(maxSize-list.size(), null));
+                list.addAll(Collections.nCopies(maxSize-list.size(), new ElementData(cursor/fds.get(d.getKey()).getCoordsList().size(),1,null)));
                 list.add(maxSize,d.getValue());
             }
         }
@@ -105,7 +107,11 @@ public class CompositeDataAccess  {
 
 
     public Boolean hasNext(){
-        return (cursor<maxSize-1?++cursor:-1)>0;
+        /*是否存数据,有则设置钩子*/
+        if(next>cursor){
+            cursor=next;
+        }
+        return cursor<maxSize;
     }
     public Boolean isFirst(){
         return cursor==0;
@@ -116,10 +122,11 @@ public class CompositeDataAccess  {
     }
 
     public void close(){
-        this.cursor=this.maxSize-1;
+        this.cursor=this.maxSize;
     }
 
     public LinkedHashMap<String, ElementData> next(){
+        next++;
         return get(cursor);
     }
 

+ 2 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/formula/impl/TableElementConverter.java

@@ -92,7 +92,8 @@ public class TableElementConverter implements ITableElementConverter {
                         index.getAndIncrement();
                     });
                 });
-               this.fds.add(new FormData(codeAndId[0],eds,formulaMap.get(codeAndId[1])));
+                KeyMapper one = kms.get(0);
+               this.fds.add(new FormData(codeAndId[0],eds,formulaMap.get(codeAndId[1]),this.coordinateMap.get(one.getTableName()).get(one.getField())));
             });
         }
     }

+ 2 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TableFileMapper.java

@@ -41,4 +41,6 @@ public interface TableFileMapper extends BaseMapper<TableFile> {
 
 	List<TableFileVO> selectTableFileList(String pkid);
 
+	void delDataById(String id);
+
 }

+ 3 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/mapper/TableFileMapper.xml

@@ -35,4 +35,7 @@
         select *,domain_url as url from m_table_file where is_deleted = 0 and type=2 and tab_id =#{pkid}
     </select>
 
+    <delete id="delDataById" >
+        delete  from m_table_file where id=#{id}
+    </delete>
 </mapper>

+ 9 - 4
blade-service/blade-manager/src/main/java/org/springblade/manager/service/IExcelTabService.java

@@ -19,6 +19,7 @@ package org.springblade.manager.service;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.api.R;
 import org.springblade.manager.bean.TableInfo;
 import org.springblade.manager.entity.ExcelTab;
 import org.springblade.manager.vo.ExceTabTreVO;
@@ -82,10 +83,6 @@ public interface IExcelTabService extends BaseService<ExcelTab> {
 
 	boolean removeBussTabInfoById(String pkeyid);
 
-	/**
-	 *  单个pdf预览
-	 */
-	BladeFile getBussPdfInfo(Long pkeyId);
 
 	/**
 	 *  表格数据封装
@@ -102,5 +99,13 @@ public interface IExcelTabService extends BaseService<ExcelTab> {
 
 	 Map<String,String> getTablbCols(String pkeyid, String colkey) throws FileNotFoundException;
 
+	 // 单个pdf 生成
+	R getBussPdfInfo(Long pkeyId) throws Exception;
+
+	// 多个pdf 合并
+	void getBussPdfs(String nodeId, String classify, String contractId, String projectId) throws Exception;
+
+	// 获取用户端 单个表单接口数据
+	R getBussDataInfo(Long pkeyId);
 
 }

+ 2 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/ITableFileService.java

@@ -43,4 +43,6 @@ public interface ITableFileService extends IService<TableFile> {
 
 	List<TableFileVO> selectTableFileList(long pkid);
 
+	void delDataById(String pkid);
+
 }

+ 2 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/ITextdictInfoService.java

@@ -41,6 +41,8 @@ public interface ITextdictInfoService extends IService<TextdictInfo> {
 	 */
 	IPage<TextdictInfoVO> selectTextdictInfoPage(IPage<TextdictInfoVO> page, TextdictInfoVO textdictInfo);
 
+	void deleDataInfoById(String id);
+
 
 
 }

+ 930 - 546
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -21,11 +21,15 @@ import cn.hutool.log.StaticLog;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.mixsmart.utils.ListUtils;
+import com.spire.xls.CellRange;
+import com.spire.xls.ExcelPicture;
+import com.spire.xls.Workbook;
+import com.spire.xls.Worksheet;
 import lombok.AllArgsConstructor;
-import lombok.Data;
 import org.apache.commons.lang.StringUtils;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
@@ -34,31 +38,40 @@ import org.jsoup.select.Elements;
 import org.springblade.business.feign.ContractLogClient;
 import org.springblade.business.feign.InformationQueryClient;
 import org.springblade.business.vo.SaveContractLogVO;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.secure.utils.AuthUtil;
+import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.node.ForestNodeMerger;
 import org.springblade.core.tool.utils.*;
 import org.springblade.manager.bean.TableInfo;
-import org.springblade.manager.dto.FormData;
 import org.springblade.manager.entity.*;
 import org.springblade.manager.formula.KeyMapper;
 import org.springblade.manager.formula.impl.TableElementConverter;
 import org.springblade.manager.service.*;
+import org.springblade.manager.utils.FileUtils;
 import org.springblade.manager.vo.ExceTabTreVO;
 import org.springblade.manager.vo.ExcelTabVO;
 import org.springblade.manager.mapper.ExcelTabMapper;
 import org.springblade.core.mp.base.BaseServiceImpl;
 import org.springblade.manager.vo.ExcelTabWbsTypeVO;
 import org.springblade.manager.vo.WbsTreeVO;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springblade.system.cache.ParamCache;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.stereotype.Service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.util.*;
+import java.util.List;
 import java.util.stream.Collectors;
 
 /**
@@ -71,549 +84,920 @@ import java.util.stream.Collectors;
 @AllArgsConstructor
 public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTab> implements IExcelTabService {
 
-	//客户端资料查询接口
-	private final InformationQueryClient informationQueryClient;
-	// 元素信息表-
-	private final IWbsTreeContractService wbsTreeContractService;
-	private final IWbsTreeService wbsTreeService;
-	private final IFormulaService formulaService;
-	private final JdbcTemplate jdbcTemplate;
-
-	private final IWbsParamService wbsParamService;
-
-	private final IWbsTreePrivateService wbsTreePrivateService;
-
-	private final ContractLogClient contractLogClient;
-
-	@Override
-	public IPage<ExcelTabVO> selectExcelTabPage(IPage<ExcelTabVO> page, ExcelTabVO excelTab) {
-		return page.setRecords(baseMapper.selectExcelTabPage(page, excelTab));
-	}
-
-	@Override
-	public List<ExceTabTreVO> tabLazyTree(String tenantId, Long modeId,Long parentId) {
-		if (AuthUtil.isAdministrator()) {
-			tenantId = StringPool.EMPTY;
-		}
-		List<ExceTabTreVO> ls = baseMapper.tabLazyTree(tenantId, modeId,parentId+"");
-		return ForestNodeMerger.merge(ls);
-	}
-
-	@Override
-	public List<ExceTabTreVO> tabLazyTreeAll(String tenantId, Long modeId,String name) {
-		if (AuthUtil.isAdministrator()) {
-			tenantId = StringPool.EMPTY;
-		}
-		return ForestNodeMerger.merge(baseMapper.tabLazyTreeAll(tenantId, modeId,name));
-	}
-
-	@Override
-	public List<ExcelTabWbsTypeVO> getWbsTypeList(Integer wbstType) {
-		return baseMapper.getWbsTypeList(wbstType+"");
-	}
-
-	@Override
-	public List<WbsTreeVO> lazyTree(String wbsId, String tenantId, Long parentId) {
-		if (AuthUtil.isAdministrator()) {
-			tenantId = StringPool.EMPTY;
-		}
-		return ForestNodeMerger.merge(baseMapper.lazyTree(wbsId, tenantId, parentId));
-	}
-
-
-	/**
-	 * 私有项目 wbs 树
-	 */
-	@Override
-	public List<WbsTreeVO> lazyTreeByPri(String wbsId, String tenantId, Long parentId) {
-		if (AuthUtil.isAdministrator()) {
-			tenantId = StringPool.EMPTY;
-		}
-		return ForestNodeMerger.merge(baseMapper.lazyTreeByPri(wbsId, tenantId, parentId));
-	}
-
-	@Override
-	public boolean removeBussTabInfoById(String pkeyid) {
-		baseMapper.removeBussTabInfoById(pkeyid);
-		return true;
-	}
-
-	@Override
-	public BladeFile getBussPdfInfo(Long pkeyId) {
-
-
-		return null;
-	}
-
-	private void setFirstData(JSONObject dataInfo2, TableInfo tableInfo){
-		//huangjn 判断是否是首件
-		if(dataInfo2.containsKey("isFirst")){
-			tableInfo.setIsFirst(dataInfo2.getString("isFirst"));
-		}
-		//huangjn 判断是否是首件
-
-		//首件资料绑定的节点
-		if(dataInfo2.containsKey("firstNodeId")){
-			tableInfo.setFirstNodeId(dataInfo2.getString("firstNodeId"));
-		}
-		//首件ID(编辑时有值,新增时为空)
-		if(dataInfo2.containsKey("firstId")){
-			tableInfo.setFirstId(dataInfo2.getString("firstId"));
-		}
-		//源文件
-		if(dataInfo2.containsKey("sourceUrl")){
-			tableInfo.setSourceUrl(dataInfo2.getString("sourceUrl"));
-		}
-		//pdfUrl
-		if(dataInfo2.containsKey("pdfUrl")){
-			tableInfo.setPdfUrl(dataInfo2.getString("pdfUrl"));
-		}
-		//文件名称
-		if(dataInfo2.containsKey("firstFileName")){
-			tableInfo.setFirstFileName(dataInfo2.getString("firstFileName"));
-		}
-	}
-
-	/**
-	 * 设置日志信息
-	 */
-	private void setTheLogData(JSONObject dataInfo2, TableInfo tableInfo){
-		//huangjn 判断是否是日志
-		if(dataInfo2.containsKey("isTheLog")){
-			tableInfo.setIsTheLog(dataInfo2.getString("isTheLog"));
-		}
-		//huangjn 判断是否是日志
-
-		//huangjn 日志ID
-		if(dataInfo2.containsKey("theLogId")){
-			tableInfo.setTheLogId(dataInfo2.getString("theLogId"));
-		}
-		//huangjn 日志ID
-
-		//huangjn 日志勾选的工序
-		if(dataInfo2.containsKey("linkTabIds")){
-			tableInfo.setLinkTabIds(dataInfo2.getJSONArray("linkTabIds"));
-		}
-		//huangjn 日志勾选的工序
-
-		//huangjn 日志所选时间
-		if(dataInfo2.containsKey("recordTime")){
-			tableInfo.setRecordTime(dataInfo2.getString("recordTime"));
-		}
-		//huangjn 日志所选时间
-		//huangjn 每份填报数据的id,目前日志专用
-		if(dataInfo2.containsKey("id")){
-			tableInfo.setBusinessId(dataInfo2.getString("id"));
-		}
-		//huangjn 每份填报数据的id,目前日志专用
-	}
-
-	@Override
-	public List<TableInfo> getTableInfoList(JSONArray dataArray) {
-		if(dataArray!=null&&!dataArray.isEmpty()){
-			List<TableInfo> result = new ArrayList<>();
-			for(int m=0;m<dataArray.size();m++){
-				TableInfo tableInfo = new TableInfo();
-				JSONObject dataInfo2= dataArray.getJSONObject(m);
-				//
-				tableInfo.setContractId(dataInfo2.getString("contractId"));
-				tableInfo.setPkeyId(dataInfo2.getString("pkeyId"));
-				tableInfo.setProjectId(dataInfo2.getString("projectId"));
-				//huangjn 填报的类型,施工或监理
-				tableInfo.setClassify(dataInfo2.getString("classify"));
-				//huangjn 填报的类型,施工或监理
-
-				//设置首件信息
-				this.setFirstData(dataInfo2, tableInfo);
-				//设置日志信息
-				this.setTheLogData(dataInfo2, tableInfo);
-
-				dataInfo2.fluentRemove("contractId")
-						 .fluentRemove("pkeyId")
-						 .fluentRemove("p_key_id")
-				         .fluentRemove("projectId")
-				         .fluentRemove("classify")
-				         .fluentRemove("pickerKey")
-				         .fluentRemove("id")
-						 .fluentRemove("isFirst")
-						 .fluentRemove("firstNodeId")
-						 .fluentRemove("isTheLog")
-						 .fluentRemove("theLogId")
-						 .fluentRemove("linkTabIds")
-						 .fluentRemove("recordTime")
-						 .fluentRemove("businessId")
-						 .fluentRemove("sourceUrl")
-						 .fluentRemove("pdfUrl")
-						 .fluentRemove("firstFileName")
-				         .fluentRemove("");
-				// 计算数据
-				LinkedHashMap<String,List<String>> dataMap =dataInfo2.keySet().stream().filter(e->e.contains("__")).collect(Collectors.groupingBy(e->e.split("__")[0], LinkedHashMap<String,List<String>>::new,Collectors.toList()));
-				LinkedHashMap<String,String> dataMap2 = new LinkedHashMap<>();
-				// 字段组合
-				for(String k:dataMap.keySet()){
-					if(dataMap.get(k).size()>1&& !dataMap.get(k).contains("000Z")){
-						String[] ziduan= dataMap.get(k).toArray(new String[]{});
-						String temp = "";
-						for(int i = 0; i < ziduan.length - 1; i++) {
-							for (int j = 0; j < ziduan.length - i - 1; j++) {
-								Integer tr = Integer.parseInt((ziduan[j].split("__")[1]).split("_")[0]);
-								Integer td = Integer.parseInt(ziduan[j].split("__")[1].split("_")[1]);
-
-								Integer tr_1 = Integer.parseInt(ziduan[j + 1].split("__")[1].split("_")[0]);
-								Integer td_1 = Integer.parseInt(ziduan[j + 1].split("__")[1].split("_")[1]);
-
-								if (tr > tr_1 && td==td_1  ) { //纵向排序
-									temp = ziduan[j];
-									ziduan[j] = ziduan[j + 1];
-									ziduan[j + 1] = temp;
-								}
-							}
-						}
-
-						String lastStr = dataInfo2.getString(ziduan[0])+"_^_"+ziduan[0].split("__")[1];
-						for (int i=1 ;i<ziduan.length;i++){
-							String keyData = dataInfo2.getString(ziduan[i]);
-							if(!keyData.equals("")){
-								lastStr+="☆"+dataInfo2.getString(ziduan[i])+"_^_"+ziduan[i].split("__")[1];
-							}
-
-						}
-						dataMap2.put(k,lastStr);
-					}else{
-						String dataVal = dataInfo2.getString(dataMap.get(k).get(0));
-						dataMap2.put(k, dataVal+"_^_"+dataMap.get(k).get(0).split("__")[1]);
-					}
-				}
-				dataMap2.put("p_key_id",tableInfo.getPkeyId());
-				tableInfo.setDataMap(dataMap2);
-				result.add(tableInfo);
-			}
-			return result;
-		}
-		return null;
-	}
-
-	@Override
-	public void formulaFillData(List<TableInfo> tableInfoList) {
-		if(Func.isNotEmpty(tableInfoList)){
-			StopWatch stopWatch = new StopWatch();
-			String ids =tableInfoList.stream().map(TableInfo::getPkeyId).filter(Func::isNotEmpty).collect(Collectors.joining(","));
-			List<Map<String,Object>> list=this.jdbcTemplate.queryForList("SELECT   a.p_key_id as nodeId,b.id as fieldId,b.e_key as field,c.init_table_name as tableName  from m_wbs_tree_contract a LEFT JOIN m_wbs_form_element b on a.id=b.f_id left JOIN m_wbs_tree c on a.id=c.id where b.is_deleted=0 and a.p_key_id in ("+ids+")");
-			List<KeyMapper> keyMappers = JSON.parseArray(JSONArray.toJSONString(list), KeyMapper.class);
-			if(Func.isNotEmpty(keyMappers)) {
-				Map<String,Map<String,String>> coordinateMap = new HashMap<>(keyMappers.size()*2);
-				keyMappers.forEach(e->{
-					try {
-						if(!coordinateMap.containsKey(e.getTableName())){
-							/*不包含定位信息的情况执行*/
-							coordinateMap.put(e.getTableName(),getTablbCols(e.getNodeId().toString(),null));
-						}
-					} catch (FileNotFoundException fileNotFoundException) {
-						fileNotFoundException.printStackTrace();
-					}
-				});
-				stopWatch.start("公式处理");
-				List<Formula> formulas = this.formulaService.list(Wrappers.<Formula>lambdaQuery().in(Formula::getElementId, keyMappers.stream().map(KeyMapper::getFieldId).distinct().collect(Collectors.toList())));
-				TableElementConverter tec = new TableElementConverter(tableInfoList, keyMappers, formulas,coordinateMap,1111111L);
-				if (tec.isPresent()) {
-					tec.before();
-					this.formulaService.execute(tec);
-					tec.after();
-				}
-				stopWatch.stop();
-				StaticLog.info("{}", stopWatch);
-			}
-		}
-	}
-
-	/**
-	 * 保存日志
-	 */
-	private void saveOrUpdateTheLog(List<TableInfo> tableInfoList){
-		//查询绑定的节点
-		WbsTreePrivate tableNode = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, tableInfoList.get(0).getPkeyId()));
-		WbsTreePrivate parentNode = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getProjectId, tableNode.getProjectId()).eq(WbsTreePrivate::getId, tableNode.getParentId()));
-
-		//填报日期
-		String recordTime = tableInfoList.get(0).getRecordTime();
-		if(StringUtils.isEmpty(recordTime)){
-			//为空,默认今天
-			recordTime = DateUtil.format(new Date(), "yyyy-MM-dd");
-		}
-
-		String businessId = tableInfoList.get(0).getTheLogId();
-		if(StringUtils.isEmpty(businessId)){
-
-			//检查是否存在原本的数据
-			JSONObject logJson = this.contractLogClient.queryContractLogByPrimaryKeyIdAndRecordTime(parentNode.getPKeyId().toString(), recordTime, tableInfoList.get(0).getContractId());
-
-			if(logJson == null){
-				businessId = SnowFlakeUtil.getId().toString();
-			} else {
-				businessId = logJson.getString("dataId");
-				if(StringUtils.isEmpty(businessId)){
-					businessId = SnowFlakeUtil.getId().toString();
-				}
-			}
-		}
-
-		if(StringUtils.isNotEmpty(businessId)){
-			//删除旧数据
-			String delSql = "delete from " + tableNode.getInitTableName() + " where group_id = " + businessId;
-			this.jdbcTemplate.execute(delSql);
-		}
-
-		List<JSONObject> logWbsList = new ArrayList<>();
-
-		for(TableInfo tableInfo : tableInfoList){
-			WbsTreePrivate wbsTreePrivate = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, tableInfo.getPkeyId()));
-			if(wbsTreePrivate == null){
-				continue;
-			}
-			String tabName = wbsTreePrivate.getInitTableName();
-
-			String id = tableInfo.getBusinessId();
-			if(StringUtils.isEmpty(id)){
-				id = SnowFlakeUtil.getId() + "";
-			}
-
-			//拼接SQL
-			StringBuilder sql = new StringBuilder("INSERT INTO " + tabName ),
-						  keySql = new StringBuilder("id, group_id"),
-					      valSql = new StringBuilder("" + id + ", " + businessId);
-			//参数
-			LinkedHashMap<String,String> dataMap2 = tableInfo.getDataMap();
-			for(String key : dataMap2.keySet()){
-				keySql.append(", ").append(key);
-				valSql.append(", '").append(dataMap2.get(key)).append("'");
-			}
-
-			sql.append("(").append(keySql).append(")").append(" values(").append(valSql).append(")");
-
-			//新增数据
-			try{
-				this.jdbcTemplate.execute(sql.toString());
-			}catch (Exception e){
-				e.printStackTrace();
-			}
-
-
-			List<Object> linkTabIds = tableInfo.getLinkTabIds();
-			if(linkTabIds == null || linkTabIds.size() <= 0){
-				//这一步主要为了兼容同工序时只想在第一张勾选的情况
-				linkTabIds = tableInfoList.get(0).getLinkTabIds();
-			}
-			if(linkTabIds != null && linkTabIds.size() > 0){
-				//处理每个表格的关联情况
-				List<JSONObject> jsonLinkTabIds = JSONArray.parseArray(JSONObject.toJSONString(linkTabIds), JSONObject.class);
-				for(JSONObject json : jsonLinkTabIds){
-					json.put("businessId", id);
-				}
-				logWbsList.addAll(jsonLinkTabIds);
-			}
-		}
-
-		//保存日志记录
-		this.contractLogClient.saveContractLog(new SaveContractLogVO(
-				Long.parseLong(businessId),
-				tableInfoList.get(0).getProjectId(),
-				tableInfoList.get(0).getContractId(),
-				parentNode.getPKeyId(),
-				tableNode.getPKeyId(),
-				parentNode.getMajorDataType(),
-				recordTime,
-				logWbsList
-		));
-
-	}
-
-	private void saveOrUpdateFirst(List<TableInfo> tableInfoList){
-		//获取首件绑定的节点
-		String firstNodeId = tableInfoList.get(0).getFirstNodeId();
-		//获取首件关联的施工记录
-		List<JSONObject> linkProcessList = JSONArray.parseArray(JSONObject.toJSONString(tableInfoList.get(0).getLinkProcessList()), JSONObject.class);
-		if(linkProcessList == null){
-			linkProcessList = new ArrayList<>();
-		}
-
-		//获取数据所在数据表名
-		WbsTreeContract table = this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, tableInfoList.get(0).getPkeyId()));
-		if(table == null){
-			return;
-		}
-		String tableName = table.getInitTableName();
-		if(StringUtils.isEmpty(tableName)){
-			return;
-		}
-
-		//获取首件记录ID
-		String firstId = tableInfoList.get(0).getFirstId();
-		if(StringUtils.isNotEmpty(firstId)){
-			//删除掉旧数据
-			this.jdbcTemplate.execute("DELETE FROM " + tableName + " WHERE group_id = " + firstId);
-		} else {
-			firstId = SnowFlakeUtil.getId() + "";
-		}
-
-		//获取上传的文件相关
-		String sourceUrl = tableInfoList.get(0).getSourceUrl(),
-				pdfUrl = tableInfoList.get(0).getPdfUrl(),
-				firstFileName = tableInfoList.get(0).getFirstFileName();
-
-		//新增数据
-		for(TableInfo tableInfo : tableInfoList){
-			//获取字段信息
-			LinkedHashMap<String,String> dataMap2 = tableInfo.getDataMap();
-
-			//拼接SQL
-			StringBuilder sql = new StringBuilder("INSERT INTO " + tableName ),
-					keySql = new StringBuilder("id, group_id"),
-					valSql = new StringBuilder("" + SnowFlakeUtil.getId() + ", " + firstId);
-
-			for(String key : dataMap2.keySet()){
-				keySql.append(", ").append(key);
-				valSql.append(", '").append(dataMap2.get(key)).append("'");
-			}
-
-			sql.append("(").append(keySql).append(")").append(" values(").append(valSql).append(")");
-
-			//新增数据
-			try{
-				this.jdbcTemplate.execute(sql.toString());
-			}catch (Exception e){
-				e.printStackTrace();
-			}
-		}
-
-		try{
-			//新增或修改首件记录
-			this.informationQueryClient.saveOrUpdateInformationQueryData(firstNodeId, tableInfoList.get(0).getPkeyId() + "", firstId, "文件名称", Integer.parseInt(tableInfoList.get(0).getClassify()), 2, "true", sourceUrl, pdfUrl, firstFileName, linkProcessList);
-		}catch (Exception e){
-			e.printStackTrace();
-		}
-
-	}
-
-	@Override
-	public void saveOrUpdateInfo(List<TableInfo> tableInfoList) {
-		if(ListUtils.isNotEmpty(tableInfoList)){
-			if(StringUtils.isNotEmpty(tableInfoList.get(0).getIsFirst())){
-				//首件填报
-				this.saveOrUpdateFirst(tableInfoList);
-
-			} else if(StringUtils.isNotEmpty(tableInfoList.get(0).getIsTheLog())){
-				//日志填报
-				this.saveOrUpdateTheLog(tableInfoList);
-
-			} else {
-				//施工资料填报
-				for(TableInfo tableInfo:tableInfoList){
-					WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
-							.eq(WbsTreeContract::getPKeyId, tableInfo.getPkeyId()));
-					if(wbsTreeContract == null){
-						continue;
-					}
-
-					String tabName = wbsTreeContract.getInitTableName();
-
-					// 判读修改还是 添加
-					String delSql = "delete from "+tabName+" where p_key_id="+tableInfo.getPkeyId();
-					jdbcTemplate.execute(delSql);
-
-					String sqlInfo="";
-					LinkedHashMap<String,String> dataMap2 = tableInfo.getDataMap();
-					sqlInfo = "INSERT INTO "+tabName+" ( ";
-					String keyStr = "id,";
-					String valStr = SnowFlakeUtil.getId() + ",";
-					for (String keys : dataMap2.keySet()){
-						keyStr += keys+",";
-						valStr += "'"+dataMap2.get(keys)+"',";
-					}
-					keyStr=keyStr.substring(0,keyStr.lastIndexOf(","));
-					valStr=valStr.substring(0,valStr.lastIndexOf(","));
-					sqlInfo = sqlInfo + keyStr+") VALUES (" +valStr +")";
-
-				WbsTreeContract wbsTreeContractByP = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
-							.eq(WbsTreeContract::getId, wbsTreeContract.getParentId()).eq(WbsTreeContract::getContractId,tableInfo.getContractId()));
-
-				if (wbsTreeContractByP!=null){
-					//处理文件提名
-					String fileName = this.wbsParamService.createFileTitle(Func.isNotEmpty(wbsTreeContractByP.getOldId())? Long.valueOf(wbsTreeContractByP.getOldId()) :wbsTreeContractByP.getId(), Long.parseLong(wbsTreeContractByP.getContractId()),wbsTreeContractByP);
-					fileName = StringUtils.isNotEmpty(fileName) ? fileName : "缺少文件提名配置";
-
-					//huangjn 保存成功后调用生成资料查询列表数据
-					this.informationQueryClient.saveOrUpdateInformationQueryData(wbsTreeContractByP.getPKeyId()+"", "首件使用字段", "业务ID(主要将来给首件使用)", fileName, Integer.parseInt(tableInfo.getClassify()), 2,"是否是首件(临时,暂时没用到)", "源文件(首件字段)", "pdf文件(首件字段)", "首件上传总结报告名称", new ArrayList<>());
-				}
-
-				UpdateWrapper<WbsTreeContract> updateWrapper = new UpdateWrapper<>();
-				updateWrapper.in("p_key_id",tableInfo.getPkeyId());
-				updateWrapper.set("is_tab_pdf",2);
-				wbsTreeContractService.update(updateWrapper);
-					jdbcTemplate.execute(sqlInfo);
-					// pdf 预览添加
-					//this.getBussPdfInfo(Long.parseLong(tableInfo.getPkeyId()));
-				}
-
-				try{
-					//获取节点
-					WbsTreeContract wbsTreeContract = this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, tableInfoList.get(0).getPkeyId()));
-
-					WbsTreeContract wbsTreeContractByP = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
-							.eq(WbsTreeContract::getId, wbsTreeContract.getParentId()).eq(WbsTreeContract::getContractId, wbsTreeContract.getContractId()));
-					//处理文件提名
-					String fileName = this.wbsParamService.createFileTitle(Func.isNotEmpty(wbsTreeContractByP.getOldId())? Long.valueOf(wbsTreeContractByP.getOldId()) :wbsTreeContractByP.getId(), Long.parseLong(wbsTreeContractByP.getContractId()),wbsTreeContractByP);
-					fileName = StringUtils.isNotEmpty(fileName) ? fileName : "缺少文件提名配置";
-
-					//huangjn 保存成功后调用生成资料查询列表数据
-					this.informationQueryClient.saveOrUpdateInformationQueryData(wbsTreeContractByP.getPKeyId()+"", "首件使用字段", "业务ID(主要将来给首件使用)", fileName, Integer.parseInt(tableInfoList.get(0).getClassify()), 2,"false", "源文件(首件字段)", "pdf文件(首件字段)", "首件上传总结报告名称", new ArrayList<>());
-				}catch (Exception e){
-					e.printStackTrace();
-				}
-			}
-		}
-	}
-
-
-	// 获取用户
-	@Override
-	public Map<String,String>  getTablbCols(String pkeyid, String colkey) throws FileNotFoundException {
-		Map<String,String> dataMap = new HashMap<>();
-		if(StringUtils.isEmpty(pkeyid)){
-			return null;
-		}
-		//获取html
-		WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
-				.eq(WbsTreeContract::getPKeyId,pkeyid));
-        if(Func.isEmpty(wbsTreeContract.getHtmlUrl())){
-        	return  dataMap;
-		}
-		File file1 = ResourceUtil.getFile(wbsTreeContract.getHtmlUrl());
-
-		FileInputStream fileInputStream = new FileInputStream(file1);
-		String htmlString = IoUtil.readToString(fileInputStream);
-		Document doc = Jsoup.parse(htmlString);
-		Element table = doc.select("table").first();
-		Elements trs = table.select("tr");
-
-		for (int i = 0; i <= trs.size() - 1; i++) {
-			Element tr = trs.get(i);
-			Elements tds = tr.select("td");
-			for (int j = 0; j < tds.size(); j++) {
-				Element data = tds.get(j);
-				if(!data.children().isEmpty()){
-				//	String x1 = data.children().get(0).attr("x1");
-				//	String y1 = data.children().get(0).attr("y1");
-					String keyVal = i+"_"+j;
-					String keyname = data.children().get(0).attr("keyname");
-					if(StringUtils.isNotEmpty(keyname)){
-						String[] keys = keyname.split("__");
-						String datakey = keys[0];
-						dataMap.merge(datakey,keyVal,(v1,v2)-> v1+";"+v2);
-					}
-				}
-			}
-		}
-		return dataMap;
-	}
+    //客户端资料查询接口
+    private final InformationQueryClient informationQueryClient;
+    // 元素信息表-
+    private final IWbsTreeContractService wbsTreeContractService;
+    private final IWbsTreeService wbsTreeService;
+    private final IFormulaService formulaService;
+    private final JdbcTemplate jdbcTemplate;
+
+    private final IWbsParamService wbsParamService;
+
+    private final IWbsTreePrivateService wbsTreePrivateService;
+
+    private final ContractLogClient contractLogClient;
+
+    // 表单字典信息表
+    private final ITextdictInfoService textdictInfoService;
+
+    // Oss接口
+    private final NewIOSSClient newIOSSClient;
+    // 表单附件信息
+    private final ITableFileService tableFileService;
+
+    // 合同端信息
+    private final IContractInfoService contractInfoService;
+
+    @Override
+    public IPage<ExcelTabVO> selectExcelTabPage(IPage<ExcelTabVO> page, ExcelTabVO excelTab) {
+        return page.setRecords(baseMapper.selectExcelTabPage(page, excelTab));
+    }
+
+    @Override
+    public List<ExceTabTreVO> tabLazyTree(String tenantId, Long modeId, Long parentId) {
+        if (AuthUtil.isAdministrator()) {
+            tenantId = StringPool.EMPTY;
+        }
+        List<ExceTabTreVO> ls = baseMapper.tabLazyTree(tenantId, modeId, parentId + "");
+        return ForestNodeMerger.merge(ls);
+    }
+
+    @Override
+    public List<ExceTabTreVO> tabLazyTreeAll(String tenantId, Long modeId, String name) {
+        if (AuthUtil.isAdministrator()) {
+            tenantId = StringPool.EMPTY;
+        }
+        return ForestNodeMerger.merge(baseMapper.tabLazyTreeAll(tenantId, modeId, name));
+    }
+
+    @Override
+    public List<ExcelTabWbsTypeVO> getWbsTypeList(Integer wbstType) {
+        return baseMapper.getWbsTypeList(wbstType + "");
+    }
+
+    @Override
+    public List<WbsTreeVO> lazyTree(String wbsId, String tenantId, Long parentId) {
+        if (AuthUtil.isAdministrator()) {
+            tenantId = StringPool.EMPTY;
+        }
+        return ForestNodeMerger.merge(baseMapper.lazyTree(wbsId, tenantId, parentId));
+    }
+
+
+    /**
+     * 私有项目 wbs 树
+     */
+    @Override
+    public List<WbsTreeVO> lazyTreeByPri(String wbsId, String tenantId, Long parentId) {
+        if (AuthUtil.isAdministrator()) {
+            tenantId = StringPool.EMPTY;
+        }
+        return ForestNodeMerger.merge(baseMapper.lazyTreeByPri(wbsId, tenantId, parentId));
+    }
+
+    @Override
+    public boolean removeBussTabInfoById(String pkeyid) {
+        baseMapper.removeBussTabInfoById(pkeyid);
+        return true;
+    }
+
+
+    private void setFirstData(JSONObject dataInfo2, TableInfo tableInfo) {
+        //huangjn 判断是否是首件
+        if (dataInfo2.containsKey("isFirst")) {
+            tableInfo.setIsFirst(dataInfo2.getString("isFirst"));
+        }
+        //huangjn 判断是否是首件
+
+        //首件资料绑定的节点
+        if (dataInfo2.containsKey("firstNodeId")) {
+            tableInfo.setFirstNodeId(dataInfo2.getString("firstNodeId"));
+        }
+        //首件ID(编辑时有值,新增时为空)
+        if (dataInfo2.containsKey("firstId")) {
+            tableInfo.setFirstId(dataInfo2.getString("firstId"));
+        }
+        //源文件
+        if (dataInfo2.containsKey("sourceUrl")) {
+            tableInfo.setSourceUrl(dataInfo2.getString("sourceUrl"));
+        }
+        //pdfUrl
+        if (dataInfo2.containsKey("pdfUrl")) {
+            tableInfo.setPdfUrl(dataInfo2.getString("pdfUrl"));
+        }
+        //文件名称
+        if (dataInfo2.containsKey("firstFileName")) {
+            tableInfo.setFirstFileName(dataInfo2.getString("firstFileName"));
+        }
+    }
+
+    /**
+     * 设置日志信息
+     */
+    private void setTheLogData(JSONObject dataInfo2, TableInfo tableInfo) {
+        //huangjn 判断是否是日志
+        if (dataInfo2.containsKey("isTheLog")) {
+            tableInfo.setIsTheLog(dataInfo2.getString("isTheLog"));
+        }
+        //huangjn 判断是否是日志
+
+        //huangjn 日志ID
+        if (dataInfo2.containsKey("theLogId")) {
+            tableInfo.setTheLogId(dataInfo2.getString("theLogId"));
+        }
+        //huangjn 日志ID
+
+        //huangjn 日志勾选的工序
+        if (dataInfo2.containsKey("linkTabIds")) {
+            tableInfo.setLinkTabIds(dataInfo2.getJSONArray("linkTabIds"));
+        }
+        //huangjn 日志勾选的工序
+
+        //huangjn 日志所选时间
+        if (dataInfo2.containsKey("recordTime")) {
+            tableInfo.setRecordTime(dataInfo2.getString("recordTime"));
+        }
+        //huangjn 日志所选时间
+        //huangjn 每份填报数据的id,目前日志专用
+        if (dataInfo2.containsKey("id")) {
+            tableInfo.setBusinessId(dataInfo2.getString("id"));
+        }
+        //huangjn 每份填报数据的id,目前日志专用
+    }
+
+
+    @Override
+    public List<TableInfo> getTableInfoList(JSONArray dataArray) {
+        if (dataArray != null && !dataArray.isEmpty()) {
+            List<TableInfo> result = new ArrayList<>();
+            for (int m = 0; m < dataArray.size(); m++) {
+                TableInfo tableInfo = new TableInfo();
+                JSONObject dataInfo2 = dataArray.getJSONObject(m);
+                //
+                tableInfo.setContractId(dataInfo2.getString("contractId"));
+                tableInfo.setPkeyId(dataInfo2.getString("pkeyId"));
+                tableInfo.setProjectId(dataInfo2.getString("projectId"));
+                //huangjn 填报的类型,施工或监理
+                tableInfo.setClassify(dataInfo2.getString("classify"));
+                //huangjn 填报的类型,施工或监理
+
+                //设置首件信息
+                this.setFirstData(dataInfo2, tableInfo);
+                //设置日志信息
+                this.setTheLogData(dataInfo2, tableInfo);
+
+                dataInfo2.fluentRemove("contractId")
+                        .fluentRemove("pkeyId")
+                        .fluentRemove("p_key_id")
+                        .fluentRemove("projectId")
+                        .fluentRemove("classify")
+                        .fluentRemove("pickerKey")
+                        .fluentRemove("id")
+                        .fluentRemove("isFirst")
+                        .fluentRemove("firstNodeId")
+                        .fluentRemove("isTheLog")
+                        .fluentRemove("theLogId")
+                        .fluentRemove("linkTabIds")
+                        .fluentRemove("recordTime")
+                        .fluentRemove("businessId")
+                        .fluentRemove("sourceUrl")
+                        .fluentRemove("pdfUrl")
+                        .fluentRemove("firstFileName")
+                        .fluentRemove("");
+                // 计算数据
+                LinkedHashMap<String, List<String>> dataMap = dataInfo2.keySet().stream().filter(e -> e.contains("__")).collect(Collectors.groupingBy(e -> e.split("__")[0], LinkedHashMap<String, List<String>>::new, Collectors.toList()));
+                LinkedHashMap<String, String> dataMap2 = new LinkedHashMap<>();
+                // 字段组合
+                for (String k : dataMap.keySet()) {
+                    if (dataMap.get(k).size() > 1 && !dataMap.get(k).contains("000Z")) {
+                        String[] ziduan = dataMap.get(k).toArray(new String[]{});
+                        String temp = "";
+                        for (int i = 0; i < ziduan.length - 1; i++) {
+                            for (int j = 0; j < ziduan.length - i - 1; j++) {
+                                Integer tr = Integer.parseInt((ziduan[j].split("__")[1]).split("_")[0]);
+                                Integer td = Integer.parseInt(ziduan[j].split("__")[1].split("_")[1]);
+
+                                Integer tr_1 = Integer.parseInt(ziduan[j + 1].split("__")[1].split("_")[0]);
+                                Integer td_1 = Integer.parseInt(ziduan[j + 1].split("__")[1].split("_")[1]);
+
+                                if (tr > tr_1 && td == td_1) { //纵向排序
+                                    temp = ziduan[j];
+                                    ziduan[j] = ziduan[j + 1];
+                                    ziduan[j + 1] = temp;
+                                }
+                            }
+                        }
+
+                        String lastStr = dataInfo2.getString(ziduan[0]) + "_^_" + ziduan[0].split("__")[1];
+                        for (int i = 1; i < ziduan.length; i++) {
+                            String keyData = dataInfo2.getString(ziduan[i]);
+                            if (!keyData.equals("")) {
+                                lastStr += "☆" + dataInfo2.getString(ziduan[i]) + "_^_" + ziduan[i].split("__")[1];
+                            }
+
+                        }
+                        dataMap2.put(k, lastStr);
+                    } else {
+                        String dataVal = dataInfo2.getString(dataMap.get(k).get(0));
+                        dataMap2.put(k, dataVal + "_^_" + dataMap.get(k).get(0).split("__")[1]);
+                    }
+                }
+                dataMap2.put("p_key_id", tableInfo.getPkeyId());
+                tableInfo.setDataMap(dataMap2);
+                result.add(tableInfo);
+            }
+            return result;
+        }
+        return null;
+    }
+
+    @Override
+    public void formulaFillData(List<TableInfo> tableInfoList) {
+        if (Func.isNotEmpty(tableInfoList)) {
+            StopWatch stopWatch = new StopWatch();
+            String ids = tableInfoList.stream().map(TableInfo::getPkeyId).filter(Func::isNotEmpty).collect(Collectors.joining(","));
+            List<Map<String, Object>> list = this.jdbcTemplate.queryForList("SELECT   a.p_key_id as nodeId,b.id as fieldId,b.e_key as field,c.init_table_name as tableName  from m_wbs_tree_contract a LEFT JOIN m_wbs_form_element b on a.id=b.f_id left JOIN m_wbs_tree c on a.id=c.id where b.is_deleted=0 and a.p_key_id in (" + ids + ")");
+            List<KeyMapper> keyMappers = JSON.parseArray(JSONArray.toJSONString(list), KeyMapper.class);
+            if (Func.isNotEmpty(keyMappers)) {
+                Map<String, Map<String, String>> coordinateMap = new HashMap<>(keyMappers.size() * 2);
+                keyMappers.forEach(e -> {
+                    try {
+                        if (!coordinateMap.containsKey(e.getTableName())) {
+                            /*不包含定位信息的情况执行*/
+                            coordinateMap.put(e.getTableName(), getTablbCols(e.getNodeId().toString(), null));
+                        }
+                    } catch (FileNotFoundException fileNotFoundException) {
+                        fileNotFoundException.printStackTrace();
+                    }
+                });
+                stopWatch.start("公式处理");
+                List<Formula> formulas = this.formulaService.list(Wrappers.<Formula>lambdaQuery().in(Formula::getElementId, keyMappers.stream().map(KeyMapper::getFieldId).distinct().collect(Collectors.toList())));
+                TableElementConverter tec = new TableElementConverter(tableInfoList, keyMappers, formulas, coordinateMap, 1111111L);
+                if (tec.isPresent()) {
+                    tec.before();
+                    this.formulaService.execute(tec);
+                    tec.after();
+                }
+                stopWatch.stop();
+                StaticLog.info("{}", stopWatch);
+            }
+        }
+    }
+
+    /**
+     * 保存日志
+     */
+    private void saveOrUpdateTheLog(List<TableInfo> tableInfoList) {
+        //查询绑定的节点
+        WbsTreePrivate tableNode = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, tableInfoList.get(0).getPkeyId()));
+        WbsTreePrivate parentNode = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getProjectId, tableNode.getProjectId()).eq(WbsTreePrivate::getId, tableNode.getParentId()));
+
+        //填报日期
+        String recordTime = tableInfoList.get(0).getRecordTime();
+        if (StringUtils.isEmpty(recordTime)) {
+            //为空,默认今天
+            recordTime = DateUtil.format(new Date(), "yyyy-MM-dd");
+        }
+
+        String businessId = tableInfoList.get(0).getTheLogId();
+        if (StringUtils.isEmpty(businessId)) {
+
+            //检查是否存在原本的数据
+            JSONObject logJson = this.contractLogClient.queryContractLogByPrimaryKeyIdAndRecordTime(parentNode.getPKeyId().toString(), recordTime, tableInfoList.get(0).getContractId());
+
+            if (logJson == null) {
+                businessId = SnowFlakeUtil.getId().toString();
+            } else {
+                businessId = logJson.getString("dataId");
+                if (StringUtils.isEmpty(businessId)) {
+                    businessId = SnowFlakeUtil.getId().toString();
+                }
+            }
+        }
+
+        if (StringUtils.isNotEmpty(businessId)) {
+            //删除旧数据
+            String delSql = "delete from " + tableNode.getInitTableName() + " where group_id = " + businessId;
+            this.jdbcTemplate.execute(delSql);
+        }
+
+        List<JSONObject> logWbsList = new ArrayList<>();
+
+        for (TableInfo tableInfo : tableInfoList) {
+            WbsTreePrivate wbsTreePrivate = this.wbsTreePrivateService.getOne(Wrappers.<WbsTreePrivate>lambdaQuery().eq(WbsTreePrivate::getPKeyId, tableInfo.getPkeyId()));
+            if (wbsTreePrivate == null) {
+                continue;
+            }
+            String tabName = wbsTreePrivate.getInitTableName();
+
+            String id = tableInfo.getBusinessId();
+            if (StringUtils.isEmpty(id)) {
+                id = SnowFlakeUtil.getId() + "";
+            }
+
+            //拼接SQL
+            StringBuilder sql = new StringBuilder("INSERT INTO " + tabName),
+                    keySql = new StringBuilder("id, group_id"),
+                    valSql = new StringBuilder("" + id + ", " + businessId);
+            //参数
+            LinkedHashMap<String, String> dataMap2 = tableInfo.getDataMap();
+            for (String key : dataMap2.keySet()) {
+                keySql.append(", ").append(key);
+                valSql.append(", '").append(dataMap2.get(key)).append("'");
+            }
+
+            sql.append("(").append(keySql).append(")").append(" values(").append(valSql).append(")");
+
+            //新增数据
+            try {
+                this.jdbcTemplate.execute(sql.toString());
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+
+            List<Object> linkTabIds = tableInfo.getLinkTabIds();
+            if (linkTabIds == null || linkTabIds.size() <= 0) {
+                //这一步主要为了兼容同工序时只想在第一张勾选的情况
+                linkTabIds = tableInfoList.get(0).getLinkTabIds();
+            }
+            if (linkTabIds != null && linkTabIds.size() > 0) {
+                //处理每个表格的关联情况
+                List<JSONObject> jsonLinkTabIds = JSONArray.parseArray(JSONObject.toJSONString(linkTabIds), JSONObject.class);
+                for (JSONObject json : jsonLinkTabIds) {
+                    json.put("businessId", id);
+                }
+                logWbsList.addAll(jsonLinkTabIds);
+            }
+        }
+
+        //保存日志记录
+        this.contractLogClient.saveContractLog(new SaveContractLogVO(
+                Long.parseLong(businessId),
+                tableInfoList.get(0).getProjectId(),
+                tableInfoList.get(0).getContractId(),
+                parentNode.getPKeyId(),
+                tableNode.getPKeyId(),
+                parentNode.getMajorDataType(),
+                recordTime,
+                logWbsList
+        ));
+
+    }
+
+    private void saveOrUpdateFirst(List<TableInfo> tableInfoList) {
+        //获取首件绑定的节点
+        String firstNodeId = tableInfoList.get(0).getFirstNodeId();
+        //获取首件关联的施工记录
+        List<JSONObject> linkProcessList = JSONArray.parseArray(JSONObject.toJSONString(tableInfoList.get(0).getLinkProcessList()), JSONObject.class);
+        if (linkProcessList == null) {
+            linkProcessList = new ArrayList<>();
+        }
+
+        //获取数据所在数据表名
+        WbsTreeContract table = this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, tableInfoList.get(0).getPkeyId()));
+        if (table == null) {
+            return;
+        }
+        String tableName = table.getInitTableName();
+        if (StringUtils.isEmpty(tableName)) {
+            return;
+        }
+
+        //获取首件记录ID
+        String firstId = tableInfoList.get(0).getFirstId();
+        if (StringUtils.isNotEmpty(firstId)) {
+            //删除掉旧数据
+            this.jdbcTemplate.execute("DELETE FROM " + tableName + " WHERE group_id = " + firstId);
+        } else {
+            firstId = SnowFlakeUtil.getId() + "";
+        }
+
+        //获取上传的文件相关
+        String sourceUrl = tableInfoList.get(0).getSourceUrl(),
+                pdfUrl = tableInfoList.get(0).getPdfUrl(),
+                firstFileName = tableInfoList.get(0).getFirstFileName();
+
+        //新增数据
+        for (TableInfo tableInfo : tableInfoList) {
+            //获取字段信息
+            LinkedHashMap<String, String> dataMap2 = tableInfo.getDataMap();
+
+            //拼接SQL
+            StringBuilder sql = new StringBuilder("INSERT INTO " + tableName),
+                    keySql = new StringBuilder("id, group_id"),
+                    valSql = new StringBuilder("" + SnowFlakeUtil.getId() + ", " + firstId);
+
+            for (String key : dataMap2.keySet()) {
+                keySql.append(", ").append(key);
+                valSql.append(", '").append(dataMap2.get(key)).append("'");
+            }
+
+            sql.append("(").append(keySql).append(")").append(" values(").append(valSql).append(")");
+
+            //新增数据
+            try {
+                this.jdbcTemplate.execute(sql.toString());
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        try {
+            //新增或修改首件记录
+            this.informationQueryClient.saveOrUpdateInformationQueryData(firstNodeId, tableInfoList.get(0).getPkeyId() + "", firstId, "文件名称", Integer.parseInt(tableInfoList.get(0).getClassify()), 2, "true", sourceUrl, pdfUrl, firstFileName, linkProcessList);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    @Override
+    public void saveOrUpdateInfo(List<TableInfo> tableInfoList) {
+        if (ListUtils.isNotEmpty(tableInfoList)) {
+            if (StringUtils.isNotEmpty(tableInfoList.get(0).getIsFirst())) {
+                //首件填报
+                this.saveOrUpdateFirst(tableInfoList);
+
+            } else if (StringUtils.isNotEmpty(tableInfoList.get(0).getIsTheLog())) {
+                //日志填报
+                this.saveOrUpdateTheLog(tableInfoList);
+
+            } else {
+                //施工资料填报
+                for (TableInfo tableInfo : tableInfoList) {
+                    WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
+                            .eq(WbsTreeContract::getPKeyId, tableInfo.getPkeyId()));
+                    if (wbsTreeContract == null) {
+                        continue;
+                    }
+
+                    String tabName = wbsTreeContract.getInitTableName();
+
+                    // 判读修改还是 添加
+                    String delSql = "delete from " + tabName + " where p_key_id=" + tableInfo.getPkeyId();
+                    jdbcTemplate.execute(delSql);
+
+                    String sqlInfo = "";
+                    LinkedHashMap<String, String> dataMap2 = tableInfo.getDataMap();
+                    sqlInfo = "INSERT INTO " + tabName + " ( ";
+                    String keyStr = "id,";
+                    String valStr = SnowFlakeUtil.getId() + ",";
+                    for (String keys : dataMap2.keySet()) {
+                        keyStr += keys + ",";
+                        valStr += "'" + dataMap2.get(keys) + "',";
+                    }
+                    keyStr = keyStr.substring(0, keyStr.lastIndexOf(","));
+                    valStr = valStr.substring(0, valStr.lastIndexOf(","));
+                    sqlInfo = sqlInfo + keyStr + ") VALUES (" + valStr + ")";
+
+                    WbsTreeContract wbsTreeContractByP = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
+                            .eq(WbsTreeContract::getId, wbsTreeContract.getParentId()).eq(WbsTreeContract::getContractId, tableInfo.getContractId()));
+
+                    if (wbsTreeContractByP != null) {
+                        //处理文件提名
+                        String fileName = this.wbsParamService.createFileTitle(Func.isNotEmpty(wbsTreeContractByP.getOldId()) ? Long.valueOf(wbsTreeContractByP.getOldId()) : wbsTreeContractByP.getId(), Long.parseLong(wbsTreeContractByP.getContractId()), wbsTreeContractByP);
+                        fileName = StringUtils.isNotEmpty(fileName) ? fileName : "缺少文件提名配置";
+
+                        //huangjn 保存成功后调用生成资料查询列表数据
+                        this.informationQueryClient.saveOrUpdateInformationQueryData(wbsTreeContractByP.getPKeyId() + "", "首件使用字段", "业务ID(主要将来给首件使用)", fileName, Integer.parseInt(tableInfo.getClassify()), 2, "是否是首件(临时,暂时没用到)", "源文件(首件字段)", "pdf文件(首件字段)", "首件上传总结报告名称", new ArrayList<>());
+                    }
+
+                    UpdateWrapper<WbsTreeContract> updateWrapper = new UpdateWrapper<>();
+                    updateWrapper.in("p_key_id", tableInfo.getPkeyId());
+                    updateWrapper.set("is_tab_pdf", 2);
+                    wbsTreeContractService.update(updateWrapper);
+                    jdbcTemplate.execute(sqlInfo);
+                    // pdf 预览添加
+                    //this.getBussPdfInfo(Long.parseLong(tableInfo.getPkeyId()));
+                }
+
+                try {
+                    //获取节点
+                    WbsTreeContract wbsTreeContract = this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, tableInfoList.get(0).getPkeyId()));
+
+                    WbsTreeContract wbsTreeContractByP = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
+                            .eq(WbsTreeContract::getId, wbsTreeContract.getParentId()).eq(WbsTreeContract::getContractId, wbsTreeContract.getContractId()));
+                    //处理文件提名
+                    String fileName = this.wbsParamService.createFileTitle(Func.isNotEmpty(wbsTreeContractByP.getOldId()) ? Long.valueOf(wbsTreeContractByP.getOldId()) : wbsTreeContractByP.getId(), Long.parseLong(wbsTreeContractByP.getContractId()), wbsTreeContractByP);
+                    fileName = StringUtils.isNotEmpty(fileName) ? fileName : "缺少文件提名配置";
+
+                    //huangjn 保存成功后调用生成资料查询列表数据
+                    this.informationQueryClient.saveOrUpdateInformationQueryData(wbsTreeContractByP.getPKeyId() + "", "首件使用字段", "业务ID(主要将来给首件使用)", fileName, Integer.parseInt(tableInfoList.get(0).getClassify()), 2, "false", "源文件(首件字段)", "pdf文件(首件字段)", "首件上传总结报告名称", new ArrayList<>());
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+
+    // 获取用户
+    @Override
+    public Map<String, String> getTablbCols(String pkeyid, String colkey) throws FileNotFoundException {
+        Map<String, String> dataMap = new HashMap<>();
+        if (StringUtils.isEmpty(pkeyid)) {
+            return null;
+        }
+        //获取html
+        WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
+                .eq(WbsTreeContract::getPKeyId, pkeyid));
+        if (Func.isEmpty(wbsTreeContract.getHtmlUrl())) {
+            return dataMap;
+        }
+        File file1 = ResourceUtil.getFile(wbsTreeContract.getHtmlUrl());
+
+        FileInputStream fileInputStream = new FileInputStream(file1);
+        String htmlString = IoUtil.readToString(fileInputStream);
+        Document doc = Jsoup.parse(htmlString);
+        Element table = doc.select("table").first();
+        Elements trs = table.select("tr");
+
+        for (int i = 0; i <= trs.size() - 1; i++) {
+            Element tr = trs.get(i);
+            Elements tds = tr.select("td");
+            for (int j = 0; j < tds.size(); j++) {
+                Element data = tds.get(j);
+                if (!data.children().isEmpty()) {
+                    //	String x1 = data.children().get(0).attr("x1");
+                    //	String y1 = data.children().get(0).attr("y1");
+                    String keyVal = i + "_" + j;
+                    String keyname = data.children().get(0).attr("keyname");
+                    if (StringUtils.isNotEmpty(keyname)) {
+                        String[] keys = keyname.split("__");
+                        String datakey = keys[0];
+                        dataMap.merge(datakey, keyVal, (v1, v2) -> v1 + ";" + v2);
+                    }
+                }
+            }
+        }
+        return dataMap;
+    }
+
+    @Override
+    public R getBussPdfInfo(Long pkeyId) throws Exception {
+
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+
+        WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
+                .eq(WbsTreeContract::getPKeyId, pkeyId));
+
+        if (wbsTreeContract == null) {
+            return R.fail("该数据下无此节点!");
+        }
+        if (wbsTreeContract.getHtmlUrl() == null) {
+            return R.fail("请关联清表!");
+        }
+
+        String pdfPath = file_path + "/pdf//" + pkeyId + ".pdf";
+        File tabpdf = ResourceUtil.getFile(pdfPath);
+        if (tabpdf.exists()) {
+            tabpdf.delete();
+        }
+
+        // 获取清表信息
+        ExcelTab excelTab = this.getById(wbsTreeContract.getExcelId());
+
+        if (excelTab == null) {
+            return R.fail("失败");
+        }
+
+        Map<String, Object> DataInfo = (Map<String, Object>) getBussDataInfo(pkeyId).getData();
+
+        // 获取excel流 和 html流
+        Workbook wb = new Workbook();
+        wb.loadFromMHtml(CommonUtil.getOSSInputStream(excelTab.getFileUrl()));
+        //获取工作表
+        Worksheet sheet = wb.getWorksheets().get(0);
+
+
+        // 数据不为空 &&
+        if (StringUtils.isNotEmpty(wbsTreeContract.getHtmlUrl())) {
+            File htmlFile = ResourceUtil.getFile(wbsTreeContract.getHtmlUrl());
+            if (htmlFile.exists()) {
+                String htmlString = IoUtil.readToString(new FileInputStream(htmlFile));
+                Document doc = Jsoup.parse(htmlString);
+                Element table = doc.select("table").first();
+                Elements trs = table.select("tr");
+                Elements cols = table.select("col");
+
+                if (ObjectUtil.isNotEmpty(DataInfo)) {
+                    for (String val : DataInfo.keySet()) {
+                        if (val.indexOf("__") >= 0) {
+                            String DataVal[] = val.split("__");
+                            String[] xy = DataVal[1].split("_");
+                            Element data = trs.get(Integer.parseInt(xy[0])).select("td").get(Integer.parseInt(xy[1]));
+
+                            if (data.html().indexOf("x1") >= 0 && data.html().indexOf("y1") >= 0) {
+                                int x1 = 0;
+                                int y1 = 0;
+
+                                if (data.html().indexOf("el-tooltip") >= 0) {
+                                    x1 = Integer.parseInt(data.children().get(0).children().get(0).attr("x1"));
+                                    y1 = Integer.parseInt(data.children().get(0).children().get(0).attr("y1"));
+                                } else {
+                                    x1 = Integer.parseInt(data.children().get(0).attr("x1"));
+                                    y1 = Integer.parseInt(data.children().get(0).attr("y1"));
+                                }
+                                if (x1 == 0) {
+                                    x1 = 1;
+                                }
+                                String myData = DataInfo.get(val) + "";
+                                if (myData.indexOf("T") >= 0 && myData.indexOf("-") >= 0) {
+                                    if (myData.indexOf(",") >= 0 && myData.indexOf("]") >= 0) {
+                                        myData = myData.replace("[", "").replace("]", "");
+                                        String[] dataVal = myData.split(",");
+                                        String Start_dataStr[] = dataVal[0].split("T")[0].split("-");
+                                        String StartDate = StringUtil.format("{}年{}月{}日", new Object[]{Start_dataStr[0], Start_dataStr[1], Integer.parseInt(Start_dataStr[2]) + 1});
+
+                                        String end_dataStr[] = dataVal[1].split("T")[0].split("-");
+                                        String endDate = StringUtil.format("{}年{}月{}日", new Object[]{end_dataStr[0], end_dataStr[1], Integer.parseInt(end_dataStr[2]) + 1});
+
+                                        if (StartDate.equals(endDate)) {
+                                            myData = StartDate;
+                                        } else {
+                                            myData = StartDate + "-" + endDate;
+                                        }
+                                    } else {
+                                        String dataStr[] = myData.split("T")[0].split("-");
+                                        myData = StringUtil.format("{}年{}月{}日", new Object[]{dataStr[0], dataStr[1], Integer.parseInt(dataStr[2]) + 1});
+                                    }
+                                }
+                                //https:bladex-test-info.oss-cn-chengdu.aliyuncs.com//upload/20220819/b53cb6700db369381e3b03d7737bcdec.jpg__16_1
+                                if (myData.indexOf("https") >= 0 && myData.indexOf("aliyuncs") >= 0) {
+
+                                    BufferedImage image = ImageIO.read(CommonUtil.getOSSInputStream(myData));
+
+                                    int colspan = Integer.parseInt(data.attr("colspan"));
+                                    int rowspan = Integer.parseInt(data.attr("rowspan"));
+                                    int picHeight = 0;
+                                    int picWidth = 0;
+                                    for (int i = y1; i <= (y1 + rowspan); i++) { // 跨列处理
+                                        String dataInfo = trs.get(i).attr("height");
+                                        if (StringUtils.isNotEmpty(dataInfo)) {
+                                            picHeight += Integer.parseInt(dataInfo);
+                                        }
+                                    }
+
+                                    if (colspan >= 1) { //框行处理
+                                        for (int i = x1 - 1; i < x1 + colspan - 1; i++) {
+                                            String dataInfo = cols.get(i).attr("width").replaceAll("px", "");
+                                            if (StringUtils.isNotEmpty(dataInfo)) {
+                                                picWidth += Integer.parseInt(dataInfo);
+                                            }
+                                        }
+                                    }
+
+                                    ExcelPicture pic = sheet.getPictures().add(y1, x1, image);
+                                    pic.setWidth(picWidth - 10);
+                                    pic.setHeight(picHeight);
+                                    pic.setLeft(5);
+                                } else {
+                                    final CellRange cellRange = sheet.getCellRange(y1, x1);
+                                    cellRange.setText(myData);
+                                }
+                            }
+                        }
+                    }
+                }
+
+                // 组装电签设置
+                QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
+                queryWrapper.eq("type", 2);
+                queryWrapper.eq("tab_id", wbsTreeContract.getIsTypePrivatePid());
+
+                final List<TextdictInfo> textdictInfos = textdictInfoService.getBaseMapper().selectList(queryWrapper);
+                if (textdictInfos != null && !textdictInfos.isEmpty()) {
+                    textdictInfos.forEach(e -> {
+                        String key = e.getColKey();
+                        String keys[] = key.split("__");
+                        String[] trtd = keys[1].split("_");
+                        Element data = trs.get(Integer.parseInt(trtd[0])).select("td").get(Integer.parseInt(trtd[1]));
+                        int x1 = Integer.parseInt(data.children().get(0).attr("x1"));
+                        if (x1 == 0) {
+                            x1 = 1;
+                        }
+                        int y1 = Integer.parseInt(data.children().get(0).attr("y1"));
+
+                        final CellRange cellRange = sheet.getCellRange(y1, x1);
+                        cellRange.setText(e.getId() + "");
+                        cellRange.getCellStyle().getFont().setColor(Color.white);
+
+                    });
+                }
+            }
+        }
+
+
+        sheet.saveToPdf(pdfPath);
+
+        BladeFile bladeFile = newIOSSClient.uploadFile(pkeyId + ".pdf", pdfPath);
+        //
+        TableFile tableFile1 = tableFileService.getBaseMapper().selectOne(Wrappers.<TableFile>query().lambda()
+                .eq(TableFile::getTabId, pkeyId+"").eq(TableFile::getType, 1));
+        if (tableFile1 != null) {
+            tableFile1.setDomainPdfUrl(bladeFile.getLink());
+            tableFileService.saveOrUpdate(tableFile1);
+        } else {
+            TableFile tableFile = new TableFile();
+            String fileExtension = FileUtil.getFileExtension(wbsTreeContract.getFullName() + ".pdf");
+            tableFile.setTabId(pkeyId + "");
+            tableFile.setName(wbsTreeContract.getFullName() + ".pdf");
+            tableFile.setType(1);
+            tableFile.setDomainUrl(bladeFile.getLink());
+            tableFile.setIsDeleted(0);
+            tableFile.setExtension(fileExtension);
+            tableFile.setDomainPdfUrl(bladeFile.getLink());
+            tableFileService.saveOrUpdate(tableFile);
+        }
+
+        List<TableFile> tableFileList = tableFileService.getBaseMapper().selectList(Wrappers.<TableFile>query().lambda().eq(TableFile::getTabId, pkeyId+"").eq(TableFile::getIsDeleted, 0));
+        tableFileList.sort(Comparator.comparing(TableFile::getType));
+
+
+        List<String> dataListPdf = tableFileList.stream().filter(tableFile -> tableFile.getDomainPdfUrl() != null && (tableFile.getType() == 1 || tableFile.getType() == 2)).map(TableFile::getDomainPdfUrl).collect(Collectors.toList());
+
+        String pdfPath2 = file_path + "/pdf//" + pkeyId + "_2.pdf";
+
+        File tabpdf2 = ResourceUtil.getFile(pdfPath2);
+        if (tabpdf2.exists()) {
+            tabpdf2.delete();
+        }
+        FileUtils.mergePdfPublicMethods(dataListPdf, pdfPath2);
+
+        BladeFile bladeFile2 = newIOSSClient.uploadFile(pkeyId + "2.pdf", pdfPath2);
+
+        UpdateWrapper<WbsTreeContract> updateWrapper = new UpdateWrapper<>();
+        updateWrapper.in("p_key_id", pkeyId+"");
+        updateWrapper.set("pdf_url", bladeFile2.getLink());
+        wbsTreeContractService.update(updateWrapper);
+        wb.dispose();
+        return R.data(bladeFile2.getLink());
+    }
+
+    @Override
+    public void getBussPdfs(String nodeId, String classify, String contractId, String projectId) throws Exception {
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        // 获取有权限的节点信息
+        List<WbsTreeContract> wbsTreeContractList = wbsTreeContractService.searchNodeAllTable(nodeId, classify, contractId, projectId);
+        List<String> data = new ArrayList<>();
+        if (wbsTreeContractList != null && wbsTreeContractList.size() >= 1) {
+            for (WbsTreeContract wbsInfo : wbsTreeContractList) {
+                // 隐藏的不生成pdf
+                if (wbsInfo.getIsBussShow() != 2) { //
+                    if (StringUtils.isNotEmpty(wbsInfo.getPdfUrl())) {
+                        data.add(wbsInfo.getPdfUrl());
+                    } else {
+                        R bussPdfInfo = this.getBussPdfInfo(wbsInfo.getPKeyId());
+                        if (bussPdfInfo.getCode() == 200) {
+                            data.add(bussPdfInfo.getData() + "");
+                        }
+                    }
+                }
+            }
+        }
+
+        String listPdf = file_path + "pdf/" + nodeId + ".pdf";
+        File tabpdf2 = ResourceUtil.getFile(listPdf);
+        if (tabpdf2.exists()) {
+            tabpdf2.delete();
+        }
+        FileUtils.mergePdfPublicMethods(data, listPdf);
+        BladeFile bladeFile = this.newIOSSClient.uploadFile(nodeId + ".pdf", listPdf);
+
+        // 合并pdf集合
+        String sql = "update u_information_query set pdf_url ='" + bladeFile.getLink() + "' where classify='" + classify + "' and  wbs_id='" + nodeId + "' and contract_id ='" + contractId + "' ";
+        jdbcTemplate.execute(sql);
+    }
+
+    @Override
+    public R getBussDataInfo(Long pkeyId) {
+
+        Map<String, Object> reData = new HashMap<>();
+
+        WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
+                .eq(WbsTreeContract::getPKeyId, pkeyId));
+        if (wbsTreeContract == null) {
+            return R.data(reData);
+        }
+
+        if (wbsTreeContract == null) {
+            return R.data(reData);
+        }
+        if (wbsTreeContract.getHtmlUrl() == null) {
+            return R.data(reData);
+        }
+
+        //表单是否存储在
+        String tabName = wbsTreeContract.getInitTableName();
+        String isExitSql = " select * from information_schema.TABLES where TABLE_NAME='" + tabName + "'";
+        List<Map<String, Object>> tablist = jdbcTemplate.queryForList(isExitSql);
+        if (tablist == null || tablist.size() <= 0) {
+            return R.fail("无实体表对应");
+        }
+
+        String querySql = "select * from " + wbsTreeContract.getInitTableName() + " where p_key_id=" + pkeyId;
+        List<Map<String, Object>> dataIn = jdbcTemplate.queryForList(querySql);
+
+
+        // 匹配关联
+
+        try {
+            File  file1 = ResourceUtil.getFile(wbsTreeContract.getHtmlUrl());
+            String htmlString = IoUtil.readToString(new FileInputStream(file1));
+            Document doc = Jsoup.parse(htmlString);
+            //解析
+            Elements dwtitle = doc.select("el-input[placeholder~=^承包单位]");
+            Elements htdtitle = doc.select("el-input[placeholder~=^合同段]");
+            Elements jltitle = doc.select("el-input[placeholder~=^监理单位]");
+            Elements bhtitle = doc.select("el-input[placeholder~=^编号]");
+            ContractInfo contractInfo = contractInfoService.getById(wbsTreeContract.getContractId());
+            //
+            reData.put(dwtitle.attr("keyName"),contractInfo.getConstructionUnitName());
+            reData.put(htdtitle.attr("keyName"),contractInfo.getContractName());
+            reData.put(jltitle.attr("keyName"),contractInfo.getSupervisionUnitName());
+            reData.put(bhtitle.attr("keyName"),contractInfo.getContractNumber());
+
+
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+
+
+        if (dataIn != null && dataIn.size() >= 1) {
+            Map<String, Object> mysqlData = dataIn.get(0);
+            for (String key : mysqlData.keySet()) {
+                String tabVal = mysqlData.get(key) + "";
+                // 时间段处理
+                if (StringUtils.isNotEmpty(tabVal) && !tabVal.equals("null")) {
+                    if (tabVal.indexOf("T") >= 0 && tabVal.indexOf(".000Z]") >= 0) {
+                        String tabData[] = tabVal.split("_\\^_");
+
+                        if (reData.containsKey("pickerKey")) {
+                            String pickerKey = reData.get("pickerKey") + "," + key + "__" + tabData[1];
+                            reData.put("pickerKey", pickerKey);
+                        } else {
+                            reData.put("pickerKey", key + "__" + tabData[1]);
+                        }
+
+                        String sql = tabData[0];
+                        sql = sql.replaceAll("\\[", "['");
+                        sql = sql.replaceAll("]", "\']");
+                        sql = sql.replaceAll("000Z,", "000Z\',");
+                        sql = sql.replaceAll(", 20", ", \'20");
+                        sql = sql.replaceAll("'", "");
+                        reData.put(key + "__" + tabData[1], sql);
+                    } else if (tabVal.indexOf("T") >= 0 && tabVal.indexOf(".000Z") >= 0) { //时间
+
+                        String tabData[] = tabVal.split("_\\^_");
+                        reData.put(key + "__" + tabData[1], tabData[0]);
+
+                    } else if (tabVal.indexOf("☆") >= 0) {
+                        String mysql[] = tabVal.split("☆");
+                        for (String data : mysql) {
+                            String tabData[] = data.split("_\\^_");
+                            reData.put(key + "__" + tabData[1], tabData[0]);
+                        }
+                    } else if (tabVal.indexOf("_^_") >= 0) {
+                        String tabData[] = tabVal.split("_\\^_");
+                        reData.put(key + "__" + tabData[1], tabData[0]);
+                    } else {
+                        reData.put(key, tabVal);
+                    }
+                }
+            }
+        }
+        // 获取默认值
+        QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("type", 4);
+        queryWrapper.eq("tab_id", wbsTreeContract.getIsTypePrivatePid());
+        final List<TextdictInfo> textdictInfos = textdictInfoService.getBaseMapper().selectList(queryWrapper);
+        if (!textdictInfos.isEmpty()) {
+            for (TextdictInfo textdictInfo : textdictInfos) {
+                if (reData.containsKey(textdictInfo.getColKey())) {
+                    String keyVal = reData.get(textdictInfo.getColKey()) + "";
+                } else {
+                    reData.put(textdictInfo.getColKey() + "", textdictInfo.getSigRoleName());
+                }
+            }
+        }
+
+        // 添加4个长量值
+
+
+        // 移除Id 和 p_key_id
+        reData.remove("id");
+        reData.remove("p_key_id");
+        reData.remove("classify");
+        reData.remove("contractId");
+        reData.remove("pkeyId");
+        reData.remove("projectId");
+
+
+
+        return R.data(reData);
+    }
+
 
 }

+ 5 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TableFileServiceImpl.java

@@ -47,4 +47,9 @@ public class TableFileServiceImpl extends ServiceImpl<TableFileMapper, TableFile
 		return baseMapper.selectTableFileList(pkid+"");
 	}
 
+	@Override
+	public void delDataById(String pkid) {
+		 baseMapper.delDataById(pkid);
+	}
+
 }

+ 5 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/TextdictInfoServiceImpl.java

@@ -41,4 +41,9 @@ public class TextdictInfoServiceImpl extends ServiceImpl<TextdictInfoMapper, Tex
 		return page.setRecords(baseMapper.selectTextdictInfoPage(page, textdictInfo));
 	}
 
+	@Override
+	public void deleDataInfoById(String id) {
+		baseMapper.deleteById(id);
+	}
+
 }

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsParamServiceImpl.java

@@ -37,7 +37,7 @@ public class WbsParamServiceImpl extends BaseServiceImpl<WbsParamMapper, WbsPara
      * 文件题名*/
     public static final String FILE_TITLE="FILE_TITLE";
     @Override
-    @Cacheable(cacheNames = "file_title", key = "#nodeId+'@'+T(System).currentTimeMillis()/(1000*100)")
+    @Cacheable(cacheNames = "file_title", key = "#wbsTreeContract.pKeyId+'@'+T(System).currentTimeMillis()/(1000*100)")
     public String createFileTitle(Long nodeId,Long contractId,WbsTreeContract wbsTreeContract) {
         if(BaseUtils.isNotNull(nodeId,contractId)){
             StaticLog.info("获取节点{}文件题名",nodeId);

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно