Procházet zdrojové kódy

Merge remote-tracking branch 'origin/master' into master

yangyj před 2 roky
rodič
revize
ddc07d81b5
40 změnil soubory, kde provedl 1326 přidání a 780 odebrání
  1. 34 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/InformationQueryFileDTO.java
  2. 10 52
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/FirstInformation.java
  3. 6 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/InformationQuery.java
  4. 44 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/InformationQueryFile.java
  5. 20 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/InformationQueryClient.java
  6. 34 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/InformationQueryFileVO.java
  7. 0 23
      blade-service/blade-business/src/main/java/org/springblade/business/controller/FirstInformationController.java
  8. 0 1
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  9. 15 2
      blade-service/blade-business/src/main/java/org/springblade/business/feignClient/InformationQueryClientImpl.java
  10. 3 69
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/FirstInformationMapper.xml
  11. 33 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryFileMapper.java
  12. 21 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryFileMapper.xml
  13. 2 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryMapper.xml
  14. 0 26
      blade-service/blade-business/src/main/java/org/springblade/business/service/IFirstInformationService.java
  15. 30 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/IInformationQueryFileService.java
  16. 5 1
      blade-service/blade-business/src/main/java/org/springblade/business/service/IInformationQueryService.java
  17. 0 67
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/FirstInformationServiceImpl.java
  18. 34 0
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryFileServiceImpl.java
  19. 203 17
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryServiceImpl.java
  20. 65 34
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  21. 1 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/aop/AvoidRepeatableCommitAspect.java
  22. 32 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/bean/TableInfo.java
  23. 69 29
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java
  24. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExctabCellController.java
  25. 290 211
      blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FirstController.java
  26. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ArchiveTreeServiceImpl.java
  27. 146 37
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  28. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsFormElementServiceImpl.java
  29. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeContractServiceImpl.java
  30. 2 3
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java
  31. 0 187
      blade-service/blade-manager/src/main/java/org/springblade/manager/unit/WbsElementUtil.java
  32. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/CopyUtil.java
  33. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/DiffListUtil.java
  34. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/FileUtils.java
  35. 1 6
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/HtmlToPdf.java
  36. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/PdfConvertA4Utils.java
  37. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/ProtoStuffSerializerUtil.java
  38. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/RedisUtil.java
  39. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/RegularExpressionUtil.java
  40. 215 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/WbsElementUtil.java

+ 34 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/dto/InformationQueryFileDTO.java

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.dto;
+
+import org.springblade.business.entity.InformationQueryFile;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 数据传输对象实体类
+ *
+ * @author BladeX
+ * @since 2022-09-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class InformationQueryFileDTO extends InformationQueryFile {
+	private static final long serialVersionUID = 1L;
+
+}

+ 10 - 52
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/FirstInformation.java

@@ -32,70 +32,28 @@ import java.util.Date;
  * @since 2022-06-20
  */
 @Data
-@TableName("u_first_information")
+@TableName("u_first_link_data")
 @EqualsAndHashCode(callSuper = true)
 public class FirstInformation extends BaseEntity {
 
     private static final long serialVersionUID = 1L;
 
     /**
-     * 节点ID
+     * 首件记录ID
      */
-    @ApiModelProperty("节点ID")
-    private Long wbsNodeId;
+    @ApiModelProperty("首件记录ID")
+    private Long firstId;
 
     /**
-     * 文件名称
+     * 关联的文件名称
      */
-    @ApiModelProperty("文件名称")
-    private String fileName;
+    @ApiModelProperty("关联的文件名称")
+    private String title;
 
     /**
-     * 填报时间
+     * 关联的文件ID,指向u_information_query的ID
      */
-    @ApiModelProperty("填报时间")
-    private String reportTime;
-
-    /**
-     * 数据ID,通过这个字段去寻找相关联的数据
-     */
-    private Long dataId;
-
-    /**
-     * 流程批次
-     */
-    @ApiModelProperty("流程批次")
-    private Integer reportNumber;
-
-    /**
-     * 创建人姓名
-     */
-    @ApiModelProperty("创建人姓名")
-    private String createUserName;
-
-    /**
-     * 流程ID
-     */
-    @ApiModelProperty("流程ID")
-    private String taskId;
-
-    /**
-     * 1施工2质检
-     */
-    @ApiModelProperty("1施工2质检")
-    private Integer classify;
-
-    public FirstInformation(String fileName, Long wbsNodeId, Integer reportNumber, Integer status, Long userId, String userName, Long deptId){
-        this.fileName = fileName;
-        this.wbsNodeId = wbsNodeId;
-        this.reportNumber = reportNumber;
-        this.setStatus(status);
-        this.setCreateUser(userId);
-        this.createUserName = userName;
-        this.setDataId(deptId);
-        this.setCreateTime(new Date());
-    }
-
-    public FirstInformation(){}
+    @ApiModelProperty("关联的文件ID,指向u_information_query的ID")
+    private Long linkId;
 
 }

+ 6 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/InformationQuery.java

@@ -107,4 +107,10 @@ public class InformationQuery extends BaseEntity {
     @ApiModelProperty("电签的PDF")
     private String eVisaPdfUrl;
 
+    @ApiModelProperty("表格ID,当是首件记录时(type = 3)有值")
+    private String tableId;
+
+    @ApiModelProperty("合并的pdfUrl,当是首件记录时(type = 3)有值")
+    private String linkMergePdfUrl;
+
 }

+ 44 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/InformationQueryFile.java

@@ -0,0 +1,44 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import org.springblade.core.mp.base.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 实体类
+ *
+ * @author BladeX
+ * @since 2022-09-21
+ */
+@Data
+@TableName("u_information_query_file")
+@EqualsAndHashCode(callSuper = true)
+public class InformationQueryFile extends BaseEntity {
+
+	private static final long serialVersionUID = 1L;
+
+	private Long queryId;
+	private String name;
+	private String sourceUrl;
+	private String pdfUrl;
+
+
+}

+ 20 - 1
blade-service-api/blade-business-api/src/main/java/org/springblade/business/feign/InformationQueryClient.java

@@ -1,5 +1,6 @@
 package org.springblade.business.feign;
 
+import com.alibaba.fastjson.JSONObject;
 import org.springblade.common.constant.BusinessConstant;
 import org.springblade.core.secure.BladeUser;
 import org.springframework.cloud.openfeign.FeignClient;
@@ -7,6 +8,8 @@ import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestParam;
 
+import java.util.List;
+
 @FeignClient(value =
         BusinessConstant.APPLICATION_WEATHER_NAME
 )
@@ -17,6 +20,12 @@ public interface InformationQueryClient {
      */
     String API_PREFIX = "/api/business/informationQuery";
 
+    /**
+     * 获取记录
+     */
+    @PostMapping(API_PREFIX + "/queryFirstBusinessDataByFirstId")
+    JSONObject queryFirstBusinessDataByFirstId(@RequestParam String firstId);
+
     /**
      * 保存填报时新增或修改填报资料记录表数据
      * @param wbsId 当前填报节点
@@ -25,6 +34,16 @@ public interface InformationQueryClient {
      * @param sourceType 1原生2数据化
      */
     @PostMapping(API_PREFIX + "/saveOrUpdateInformationQueryData")
-    void saveOrUpdateInformationQueryData(@RequestParam String wbsId, @RequestParam String businessId, @RequestParam String fileName, @RequestParam Integer classify, @RequestParam Integer sourceType, @RequestParam String isFirst);
+    void saveOrUpdateInformationQueryData(@RequestParam String wbsId,
+                                          @RequestParam String tableId,
+                                          @RequestParam String businessId,
+                                          @RequestParam String fileName,
+                                          @RequestParam Integer classify,
+                                          @RequestParam Integer sourceType,
+                                          @RequestParam String isFirst,
+                                          @RequestParam String sourceUrl,
+                                          @RequestParam String pdfUrl,
+                                          @RequestParam String firstFileName,
+                                          @RequestBody List<JSONObject> linkDataList);
 
 }

+ 34 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/InformationQueryFileVO.java

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.vo;
+
+import org.springblade.business.entity.InformationQueryFile;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 视图实体类
+ *
+ * @author BladeX
+ * @since 2022-09-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class InformationQueryFileVO extends InformationQueryFile {
+	private static final long serialVersionUID = 1L;
+
+}

+ 0 - 23
blade-service/blade-business/src/main/java/org/springblade/business/controller/FirstInformationController.java

@@ -1,16 +1,8 @@
 package org.springblade.business.controller;
 
 import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import lombok.AllArgsConstructor;
-
-import org.springblade.core.mp.support.Condition;
-import org.springblade.core.mp.support.Query;
-import org.springblade.core.tool.api.R;
 import org.springframework.web.bind.annotation.*;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import org.springblade.business.vo.FirstInformationVO;
 import org.springblade.business.service.IFirstInformationService;
 import org.springblade.core.boot.ctrl.BladeController;
 
@@ -28,20 +20,5 @@ public class FirstInformationController extends BladeController {
 
 	private final IFirstInformationService firstInformationService;
 
-	/**
-	 * 自定义分页 首件信息记录表
-	 */
-	@GetMapping("/page")
-	@ApiOperationSupport(order = 1)
-	@ApiOperation(value = "分页")
-	public R<IPage<FirstInformationVO>> page(FirstInformationVO vo) {
-		//创建分页信息
-		Query query = new Query();
-		query.setCurrent(vo.getCurrent());
-		query.setSize(vo.getSize());
-
-		return R.data(firstInformationService.selectFirstInformationPage(Condition.getPage(query), vo));
-	}
-
 	
 }

+ 0 - 1
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -2,7 +2,6 @@ package org.springblade.business.controller;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;

+ 15 - 2
blade-service/blade-business/src/main/java/org/springblade/business/feignClient/InformationQueryClientImpl.java

@@ -1,10 +1,14 @@
 package org.springblade.business.feignClient;
 
+import com.alibaba.fastjson.JSONObject;
 import lombok.AllArgsConstructor;
+import org.springblade.business.entity.InformationQuery;
 import org.springblade.business.feign.InformationQueryClient;
 import org.springblade.business.service.IInformationQueryService;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.util.List;
+
 @RestController
 @AllArgsConstructor
 public class InformationQueryClientImpl implements InformationQueryClient {
@@ -12,7 +16,16 @@ public class InformationQueryClientImpl implements InformationQueryClient {
     private final IInformationQueryService iInformationQueryService;
 
     @Override
-    public void saveOrUpdateInformationQueryData(String wbsId, String businessId, String fileName, Integer classify, Integer sourceType, String isFirst) {
-        this.iInformationQueryService.saveOrUpdateInformationQueryData(wbsId, businessId, fileName, classify, sourceType, isFirst);
+    public JSONObject queryFirstBusinessDataByFirstId(String firstId) {
+        InformationQuery query = this.iInformationQueryService.getById(firstId);
+        return query != null ? JSONObject.parseObject(JSONObject.toJSONString(query), JSONObject.class) : null;
+    }
+
+    @Override
+    public void saveOrUpdateInformationQueryData(String wbsId, String tableId,
+                                                 String businessId, String fileName,
+                                                 Integer classify, Integer sourceType,
+                                                 String isFirst, String sourceUrl, String pdfUrl, String firstFileName, List<JSONObject> linkDataList) {
+        this.iInformationQueryService.saveOrUpdateInformationQueryData(wbsId, tableId, businessId, fileName, classify, sourceType, isFirst, sourceUrl, pdfUrl, firstFileName, linkDataList);
     }
 }

+ 3 - 69
blade-service/blade-business/src/main/java/org/springblade/business/mapper/FirstInformationMapper.xml

@@ -6,81 +6,15 @@
     <resultMap id="firstInformationResultMap" type="org.springblade.business.entity.FirstInformation">
         <result column="id" property="id"/>
         <result column="create_user" property="createUser"/>
-        <result column="create_user_name" property="createUserName"/>
         <result column="create_dept" property="createDept"/>
         <result column="create_time" property="createTime"/>
         <result column="update_user" property="updateUser"/>
         <result column="update_time" property="updateTime"/>
         <result column="status" property="status"/>
         <result column="is_deleted" property="isDeleted"/>
-        <result column="wbs_node_id" property="wbsNodeId"/>
-        <result column="file_name" property="fileName"/>
-        <result column="data_id" property="dataId"/>
-        <result column="report_number" property="reportNumber"/>
-        <result column="report_time" property="reportTime"/>
-        <result column="task_id" property="taskId"/>
-        <result column="classify" property="classify"/>
+        <result column="first_id" property="firstId"/>
+        <result column="title" property="title"/>
+        <result column="link_id" property="linkId"/>
     </resultMap>
 
-    <select id="countFirstInformation" resultType="java.lang.Integer">
-        select count(id) from u_first_information
-        where
-          is_deleted = 0
-        <if test="vo.betweenTime != null and vo.betweenTime != ''">
-            and report_time between #{vo.startTime} and #{vo.endTime}
-        </if>
-        <if test="vo.status != null">
-            and status = #{vo.status}
-        </if>
-        <if test="vo.reportNumber != null">
-            and report_number = #{vo.reportNumber}
-        </if>
-        <if test="vo.queryValue != null and vo.queryValue != ''">
-            and file_name like concat('%',#{vo.queryValue},'%')
-        </if>
-        <if test="vo.wbsNodeArray != null and vo.wbsNodeArray.size > 0">
-            and wbs_node_id in
-            <foreach collection="vo.wbsNodeArray" item="wbsNodeIds" open="(" separator="," close=")">
-                #{wbsNodeIds}
-            </foreach>
-        </if>
-    </select>
-
-    <select id="selectFirstInformationPage" resultMap="firstInformationResultMap">
-        select
-          id,
-          file_name,
-          create_user_name,
-          report_number,
-          report_time,
-          wbs_node_id,
-          status,
-          data_id,
-          task_id,
-          classify
-        from u_first_information
-        where
-          is_deleted = 0
-        <if test="vo.betweenTime != null and vo.betweenTime != ''">
-            and report_time between #{vo.startTime} and #{vo.endTime}
-        </if>
-        <if test="vo.status != null">
-            and status = #{vo.status}
-        </if>
-        <if test="vo.reportNumber != null">
-            and report_number = #{vo.reportNumber}
-        </if>
-        <if test="vo.queryValue != null and vo.queryValue != ''">
-            and file_name like concat('%',#{vo.queryValue},'%')
-        </if>
-        <if test="vo.wbsNodeArray != null and vo.wbsNodeArray.size > 0">
-            and wbs_node_id in
-            <foreach collection="vo.wbsNodeArray" item="wbsNodeIds" open="(" separator="," close=")">
-                #{wbsNodeIds}
-            </foreach>
-        </if>
-        order by wbs_node_id, report_time DESC
-        limit ${current}, ${size}
-    </select>
-
 </mapper>

+ 33 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryFileMapper.java

@@ -0,0 +1,33 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.mapper;
+
+import org.springblade.business.entity.InformationQueryFile;
+import org.springblade.business.vo.InformationQueryFileVO;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import java.util.List;
+
+/**
+ *  Mapper 接口
+ *
+ * @author BladeX
+ * @since 2022-09-21
+ */
+public interface InformationQueryFileMapper extends BaseMapper<InformationQueryFile> {
+
+}

+ 21 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/InformationQueryFileMapper.xml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.springblade.business.mapper.InformationQueryFileMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="informationQueryFileResultMap" type="org.springblade.business.entity.InformationQueryFile">
+        <result column="id" property="id"/>
+        <result column="create_user" property="createUser"/>
+        <result column="create_time" property="createTime"/>
+        <result column="create_dept" property="createDept"/>
+        <result column="update_user" property="updateUser"/>
+        <result column="update_time" property="updateTime"/>
+        <result column="status" property="status"/>
+        <result column="is_deleted" property="isDeleted"/>
+        <result column="query_id" property="queryId"/>
+        <result column="name" property="name"/>
+        <result column="source_url" property="sourceUrl"/>
+        <result column="pdf_url" property="pdfUrl"/>
+    </resultMap>
+
+</mapper>

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

@@ -30,6 +30,8 @@
         <result column="source_type" property="sourceType"/>
         <result column="pdf_url" property="pdfUrl"/>
         <result column="e_visa_pdf_url" property="eVisaPdfUrl"/>
+        <result column="table_id" property="tableId"/>
+        <result column="link_merge_pdf_url" property="linkMergePdfUrl"/>
     </resultMap>
 
     <resultMap id="queryProcessDataMap" type="org.springblade.business.vo.QueryProcessDataVO">

+ 0 - 26
blade-service/blade-business/src/main/java/org/springblade/business/service/IFirstInformationService.java

@@ -17,9 +17,7 @@
 package org.springblade.business.service;
 
 import org.springblade.business.entity.FirstInformation;
-import org.springblade.business.vo.FirstInformationVO;
 import org.springblade.core.mp.base.BaseService;
-import com.baomidou.mybatisplus.core.metadata.IPage;
 
 /**
  * 首件信息记录表 服务类
@@ -29,28 +27,4 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
  */
 public interface IFirstInformationService extends BaseService<FirstInformation> {
 
-	/**
-	 * 修改首件记录表信息
-	 * @param id 主键
-	 * @param fileName 文件名称
-	 * @param reportNumber 上报批次
-	 * @param status 流程状态
-	 * @return 修改结果
-	 */
-	Boolean updateFirstInformation(Long id, String fileName, Integer reportNumber, Integer status);
-
-	/**
-	 * 保存首件记录表信息
-	 * @param wbsNodeId 当前资料所在节点ID
-	 * @param fileName 文件名称
-	 * @param dataId 数据ID
-	 * @return 保存后数据的ID
-	 */
-	Long saveFirstInformation(Long wbsNodeId, String fileName, Long dataId);
-
-	/**
-	 * 自定义分页
-	 */
-	IPage<FirstInformationVO> selectFirstInformationPage(IPage<FirstInformationVO> page, FirstInformationVO vo);
-
 }

+ 30 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/IInformationQueryFileService.java

@@ -0,0 +1,30 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.service;
+
+import org.springblade.business.entity.InformationQueryFile;
+import org.springblade.core.mp.base.BaseService;
+
+/**
+ *  服务类
+ *
+ * @author BladeX
+ * @since 2022-09-21
+ */
+public interface IInformationQueryFileService extends BaseService<InformationQueryFile> {
+
+}

+ 5 - 1
blade-service/blade-business/src/main/java/org/springblade/business/service/IInformationQueryService.java

@@ -16,6 +16,7 @@
  */
 package org.springblade.business.service;
 
+import com.alibaba.fastjson.JSONObject;
 import org.springblade.business.entity.InformationQuery;
 import org.springblade.business.vo.FileUserVO;
 import org.springblade.business.vo.InformationQueryVO;
@@ -68,7 +69,10 @@ public interface IInformationQueryService extends BaseService<InformationQuery>
 	 * @param classify 1施工2质检
 	 * @param sourceType 1原生2数据化
 	 */
-	void saveOrUpdateInformationQueryData(String wbsId, String businessId, String fileName, Integer classify, Integer sourceType, String isFirst);
+	void saveOrUpdateInformationQueryData(String wbsId, String tableId,
+										  String businessId, String fileName,
+										  Integer classify, Integer sourceType,
+										  String isFirst, String sourceUrl, String pdfUrl, String firstFileName, List<JSONObject> linkDataList);
 
 	/**
 	 * 获取当前合同段下所有的上报批次

+ 0 - 67
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/FirstInformationServiceImpl.java

@@ -16,23 +16,11 @@
  */
 package org.springblade.business.service.impl;
 
-import cn.hutool.core.date.DateUtil;
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
-import org.apache.commons.lang.StringUtils;
 import org.springblade.business.entity.FirstInformation;
-import org.springblade.business.vo.FirstInformationVO;
 import org.springblade.business.mapper.FirstInformationMapper;
 import org.springblade.business.service.IFirstInformationService;
-import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.mp.base.BaseServiceImpl;
-import org.springblade.core.secure.BladeUser;
-import org.springblade.core.secure.utils.AuthUtil;
 import org.springframework.stereotype.Service;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-
-import java.util.Date;
-import java.util.List;
 
 /**
  * 首件信息记录表 服务实现类
@@ -43,59 +31,4 @@ import java.util.List;
 @Service
 public class FirstInformationServiceImpl extends BaseServiceImpl<FirstInformationMapper, FirstInformation> implements IFirstInformationService {
 
-	@Override
-	public Boolean updateFirstInformation(Long id, String fileName, Integer reportNumber, Integer status) {
-		if(StringUtils.isEmpty(fileName) && reportNumber == null && status == null){
-			return null;
-		} else {
-			FirstInformation update = new FirstInformation();
-			update.setId(id);
-			if(StringUtils.isNotEmpty(fileName)){
-				update.setFileName(fileName);
-			}
-			if(reportNumber != null){
-				update.setReportNumber(reportNumber);
-			}
-			if(status != null){
-				update.setStatus(status);
-			}
-			return this.updateById(update);
-		}
-	}
-
-	@Override
-	public Long saveFirstInformation(Long wbsNodeId, String fileName, Long dataId) {
-		BladeUser bladeUser = AuthUtil.getUser();
-		FirstInformation newData = new FirstInformation(fileName, wbsNodeId, null, 0, bladeUser.getUserId(), bladeUser.getUserName(), bladeUser.getDeptId().contains(",") ? Long.parseLong(bladeUser.getDeptId().split(",")[0]) : Long.parseLong(bladeUser.getDeptId()));
-		newData.setId(SnowFlakeUtil.getId());
-		//将主键返回,保存失败返回null
-		return this.save(newData) ? newData.getId() : null;
-	}
-
-	@Override
-	public IPage<FirstInformationVO> selectFirstInformationPage(IPage<FirstInformationVO> page, FirstInformationVO vo) {
-		//处理分页相关
-		Long current = (page.getCurrent() - 1L) * page.getSize();
-		if(StringUtils.isNotEmpty(vo.getWbsId()) && !",".equals(vo.getWbsId())){
-			List<String> wbsNodeArray = JSONArray.parseArray(JSONObject.toJSONString(vo.getWbsId().split(",")), String.class);
-			wbsNodeArray.removeIf(StringUtils::isEmpty);
-			vo.setWbsNodeArray(wbsNodeArray);
-		}
-		if(StringUtils.isNotEmpty(vo.getBetweenTime())){
-			if(vo.getBetweenTime().contains("~")){
-				String[] between = vo.getBetweenTime().split("~");
-				vo.setStartTime(between[0].trim());
-				vo.setEndTime(between[1].trim());
-			} else {
-				vo.setStartTime(vo.getBetweenTime().trim());
-				vo.setEndTime(DateUtil.format(new Date(), "yyyy-MM-dd"));
-			}
-		}
-		//获取列表总数
-		int countValue = this.baseMapper.countFirstInformation(vo);
-		//设置总数
-		page.setTotal(countValue);
-		return page.setRecords(this.baseMapper.selectFirstInformationPage(current, page.getSize(), vo));
-	}
-
 }

+ 34 - 0
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/InformationQueryFileServiceImpl.java

@@ -0,0 +1,34 @@
+/*
+ *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are met:
+ *
+ *  Redistributions of source code must retain the above copyright notice,
+ *  this list of conditions and the following disclaimer.
+ *  Redistributions in binary form must reproduce the above copyright
+ *  notice, this list of conditions and the following disclaimer in the
+ *  documentation and/or other materials provided with the distribution.
+ *  Neither the name of the dreamlu.net developer nor the names of its
+ *  contributors may be used to endorse or promote products derived from
+ *  this software without specific prior written permission.
+ *  Author: Chill 庄骞 (smallchill@163.com)
+ */
+package org.springblade.business.service.impl;
+
+import org.springblade.business.entity.InformationQueryFile;
+import org.springblade.business.mapper.InformationQueryFileMapper;
+import org.springblade.business.service.IInformationQueryFileService;
+import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ *  服务实现类
+ *
+ * @author BladeX
+ * @since 2022-09-21
+ */
+@Service
+public class InformationQueryFileServiceImpl extends BaseServiceImpl<InformationQueryFileMapper, InformationQueryFile> implements IInformationQueryFileService {
+
+}

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

@@ -2,26 +2,33 @@ package org.springblade.business.service.impl;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.AllArgsConstructor;
 import org.apache.commons.lang.StringUtils;
 import org.apache.http.client.utils.DateUtils;
-import org.springblade.business.entity.InformationQuery;
-import org.springblade.business.entity.Task;
-import org.springblade.business.entity.TaskParallel;
+import org.springblade.business.entity.*;
 import org.springblade.business.feign.TaskClient;
+import org.springblade.business.service.IFirstInformationService;
+import org.springblade.business.service.IInformationQueryFileService;
 import org.springblade.business.service.ITaskParallelService;
+import org.springblade.business.utils.FileUtils;
 import org.springblade.business.vo.FileUserVO;
 import org.springblade.business.vo.InformationQueryVO;
 import org.springblade.business.mapper.InformationQueryMapper;
 import org.springblade.business.service.IInformationQueryService;
 import org.springblade.business.vo.QueryProcessDataVO;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.mp.base.BaseServiceImpl;
+import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.utils.DateUtil;
 import org.springblade.manager.entity.WbsTreeContract;
 import org.springblade.manager.feign.WbsTreeContractClient;
 import org.springblade.manager.vo.WbsTreeContractTreeVOS;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springblade.system.cache.ParamCache;
 import org.springblade.system.user.entity.User;
 import org.springblade.system.user.feign.IUserClient;
 import org.springframework.stereotype.Service;
@@ -48,6 +55,12 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
 
 	private final ITaskParallelService taskParallelService;
 
+	private final IFirstInformationService firstInformationService;
+
+	private final NewIOSSClient newIOSSClient;
+
+	private final IInformationQueryFileService informationQueryFileService;
+
 	@Override
 	public List<String> queryBusinessTableData(String formDataId) {
 		//获取具体业务数据
@@ -92,22 +105,79 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
 		return result;
 	}
 
-	@Override
-	public void saveOrUpdateInformationQueryData(String primaryKeyId, String businessId, String fileName, Integer classify, Integer sourceType, String isFirst) {
-		BladeUser user = AuthUtil.getUser();
+	private List<FirstInformation> setFirstLinkData(List<JSONObject> linkDataList, String businessId){
+		List<FirstInformation> linkList = new ArrayList<>();
 
-		//首先根据wbsId获取合同段ID和项目ID
-		WbsTreeContract contractTree = this.wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(Long.parseLong(primaryKeyId));
+		Date nowDate = new Date();
+		linkDataList.forEach(json -> {
+			FirstInformation linkData = new FirstInformation();
+			linkData.setFirstId(Long.parseLong(businessId));
+			linkData.setTitle(json.getString("title"));
+			linkData.setLinkId(json.getLong("id"));
+
+			linkData.setCreateUser(AuthUtil.getUserId());
+			linkData.setCreateTime(nowDate);
+
+			linkList.add(linkData);
+		});
+
+		return linkList;
+	}
+
+	private void updateLinkMergePdfUrl(List<JSONObject> linkDataList, InformationQuery data, String businessId){
+		//保存关联数据
+		if(linkDataList != null && linkDataList.size() > 0){
+			try{
+				//获取配置的路径
+				String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+
+				//获取关联的数据
+				List<String> linkIds = linkDataList.stream().map(json -> json.getString("id")).distinct().collect(Collectors.toList());
+				//查询数据
+				List<InformationQuery> linkList = this.listByIds(linkIds);
+				//获取pdfUrl
+				List<String> pdfUrls = linkList.stream().map(query -> StringUtils.isNotEmpty(query.getEVisaPdfUrl()) ? query.getEVisaPdfUrl() : query.getPdfUrl()).distinct().collect(Collectors.toList());
+
+
+				String mergeFileName = SnowFlakeUtil.getId() + ".pdf", margePdfPath = file_path + "/pdf//" + mergeFileName;
+				//合并
+				FileUtils.mergePdfPublicMethods(pdfUrls, margePdfPath);
+				//上传
+				BladeFile file = this.newIOSSClient.uploadFile(mergeFileName, margePdfPath);
+				if(file != null){
+					data.setLinkMergePdfUrl(file.getLink());
+				}
+
+				//保存关联
+				this.firstInformationService.saveBatch(this.setFirstLinkData(linkDataList, businessId));
+			}catch (Exception e){
+				e.printStackTrace();
+			}
+		}
+
+
+	}
 
-		//判断当前填报节点下是否已经存在相应数据
-		InformationQuery oldData = this.baseMapper.getInformationQueryByWbsId(contractTree.getPKeyId(), classify);
+	private void saveOrUpdateFirstInformationQueryData(String primaryKeyId, String tableId,
+													   String businessId, String fileName,
+													   Integer classify, Integer sourceType,
+													   String sourceUrl,
+													   String pdfUrl, String firstFileName, List<JSONObject> linkDataList){
+
+		BladeUser user = AuthUtil.getUser();
+		//获取绑定的节点信息
+		WbsTreeContract contractTree = this.wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(Long.parseLong(primaryKeyId));
 
+		InformationQuery oldData = this.getById(businessId);
 		if(oldData != null){
 			//存在记录,修改
 			if(StringUtils.isNotEmpty(fileName)){
 				oldData.setName(fileName);
 			}
 
+			oldData.setUpdateTime(new Date());
+			oldData.setUpdateUser(user.getUserId());
+
 			//拼接填报人信息
 			String fileUser = user.getUserId() + "-" + user.getNickName();
 			if(StringUtils.isNotEmpty(oldData.getFileUserIdAndName())){
@@ -119,13 +189,45 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
 				oldData.setFileUserIdAndName(fileUser);
 			}
 
-			oldData.setUpdateTime(new Date());
-			oldData.setUpdateUser(user.getUserId());
+			//删除关联关系
+			this.firstInformationService.update(Wrappers.<FirstInformation>lambdaUpdate().set(FirstInformation::getIsDeleted, 1).eq(FirstInformation::getFirstId, businessId));
+			//重新添加并处理合并的pdf
+			this.updateLinkMergePdfUrl(linkDataList, oldData, businessId);
+
+			//找到关联附件
+			InformationQueryFile file = this.informationQueryFileService.getOne(Wrappers.<InformationQueryFile>lambdaQuery().eq(InformationQueryFile::getQueryId, businessId));
+			if(file != null){
+				file.setName(firstFileName);
+				file.setPdfUrl(pdfUrl);
+				file.setSourceUrl(sourceUrl);
+
+				file.setUpdateTime(new Date());
+				file.setUpdateUser(AuthUtil.getUserId());
+				//修改
+				this.informationQueryFileService.updateById(file);
+			} else {
+				file = new InformationQueryFile();
+				file.setQueryId(Long.parseLong(businessId));
+				file.setName(firstFileName);
+				file.setPdfUrl(pdfUrl);
+				file.setSourceUrl(sourceUrl);
+				file.setCreateUser(AuthUtil.getUserId());
+				file.setCreateTime(new Date());
+
+				this.informationQueryFileService.save(file);
+			}
+
 			//修改数据
 			this.baseMapper.updateById(oldData);
+
 		} else {
-			//新增基础数据
+			//新增
 			InformationQuery newData = new InformationQuery();
+			//处理关联数据及合并pdf
+			this.updateLinkMergePdfUrl(linkDataList, newData, businessId);
+
+			//数据ID
+			newData.setId(Long.parseLong(businessId));
 			//设置文件题名
 			newData.setName(fileName);
 			//设置文件类型
@@ -140,10 +242,7 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
 			newData.setWbsId(contractTree.getPKeyId());
 
 			//1资料填报,2试验,3首件
-			newData.setType(StringUtils.isNotEmpty(isFirst) ? 3 : (contractTree.getIsExpernode() == null || contractTree.getIsExpernode() <= 0) ? 1 : 2);
-
-			//数据ID
-//			newData.setDataId(dataId);
+			newData.setType(3);
 
 			//流程状态,默认未上报
 			newData.setStatus(0);
@@ -153,8 +252,95 @@ public class InformationQueryServiceImpl extends BaseServiceImpl<InformationQuer
 			newData.setSourceType(sourceType);
 			newData.setCreateUser(user.getUserId());
 			newData.setCreateTime(new Date());
+
+			newData.setTableId(tableId);
+
+			//新增附件
+			InformationQueryFile file = new InformationQueryFile();
+			file.setQueryId(Long.parseLong(businessId));
+			file.setName(firstFileName);
+			file.setPdfUrl(pdfUrl);
+			file.setSourceUrl(sourceUrl);
+			file.setCreateUser(AuthUtil.getUserId());
+			file.setCreateTime(new Date());
+
+			this.informationQueryFileService.save(file);
+
 			//保存数据
 			this.baseMapper.insert(newData);
+
+		}
+
+	}
+
+	@Override
+	public void saveOrUpdateInformationQueryData(String primaryKeyId, String tableId,
+												 String businessId, String fileName,
+												 Integer classify, Integer sourceType,
+												 String isFirst, String sourceUrl,
+												 String pdfUrl, String firstFileName, List<JSONObject> linkDataList) {
+		BladeUser user = AuthUtil.getUser();
+
+		if(StringUtils.isNotEmpty(isFirst) && "true".equals(isFirst)){
+			this.saveOrUpdateFirstInformationQueryData(primaryKeyId, tableId, businessId, fileName, classify, sourceType, sourceUrl, pdfUrl, firstFileName, linkDataList);
+		} else {
+			//首先根据wbsId获取合同段ID和项目ID
+			WbsTreeContract contractTree = this.wbsTreeContractClient.getContractWbsTreeByPrimaryKeyId(Long.parseLong(primaryKeyId));
+
+			//判断当前填报节点下是否已经存在相应数据
+			InformationQuery oldData = this.baseMapper.getInformationQueryByWbsId(contractTree.getPKeyId(), classify);
+
+			if(oldData != null){
+				//存在记录,修改
+				if(StringUtils.isNotEmpty(fileName)){
+					oldData.setName(fileName);
+				}
+
+				//拼接填报人信息
+				String fileUser = user.getUserId() + "-" + user.getNickName();
+				if(StringUtils.isNotEmpty(oldData.getFileUserIdAndName())){
+					if(!oldData.getFileUserIdAndName().contains(user.getUserId().toString())){
+						//不包含,拼接
+						oldData.setFileUserIdAndName(oldData.getFileUserIdAndName() + "," + fileUser);
+					}
+				} else {
+					oldData.setFileUserIdAndName(fileUser);
+				}
+
+				oldData.setUpdateTime(new Date());
+				oldData.setUpdateUser(user.getUserId());
+				//修改数据
+				this.baseMapper.updateById(oldData);
+			} else {
+				//新增基础数据
+				InformationQuery newData = new InformationQuery();
+				//设置文件题名
+				newData.setName(fileName);
+				//设置文件类型
+				newData.setCategory(contractTree.getNodeType());
+				//项目ID
+				newData.setProjectId(Long.parseLong(contractTree.getProjectId()));
+				//合同段ID
+				newData.setContractId(Long.parseLong(contractTree.getContractId()));
+				//施工资料还是质检资料
+				newData.setClassify(classify);
+				//节点ID
+				newData.setWbsId(contractTree.getPKeyId());
+
+				//1资料填报,2试验,3首件
+				newData.setType((contractTree.getIsExpernode() == null || contractTree.getIsExpernode() <= 0) ? 1 : 2);
+
+				//流程状态,默认未上报
+				newData.setStatus(0);
+				//填报人ID及姓名
+				newData.setFileUserIdAndName(user.getUserId() + "-" + user.getNickName());
+				//数据源类型
+				newData.setSourceType(sourceType);
+				newData.setCreateUser(user.getUserId());
+				newData.setCreateTime(new Date());
+				//保存数据
+				this.baseMapper.insert(newData);
+			}
 		}
 
 	}

+ 65 - 34
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -31,8 +31,6 @@ import org.springblade.flow.core.feign.NewFlowClient;
 import org.springblade.flow.core.utils.FlowUtil;
 import org.springblade.flow.core.utils.TaskUtil;
 import org.springblade.flow.core.vo.FlowProcessVO;
-import org.springblade.manager.entity.WbsTreeContract;
-import org.springblade.manager.feign.WbsTreeContractClient;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 
@@ -69,8 +67,6 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 
     private final IContractLogService contractLogService;
 
-    private final WbsTreeContractClient wbsTreeContractClient;
-
     @Override
     public List<TaskParallel> queryApprovalUser(String formDataIds) {
         //返回结果
@@ -105,10 +101,13 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                  switch (taskApprovalVO.getApprovalType()){
                      case 1:
                          //填报数据
-                         return this.queryProcessSubmitBusinessData(taskApprovalVO.getFormDataId());
+                         return this.queryProcessSubmitBusinessData(taskApprovalVO.getFormDataId(), true);
                      case 2:
                          //工程文件
                          return this.queryArchiveFileBusinessData(taskApprovalVO.getFormDataId());
+                     case 3:
+                         //日志资料
+                         return this.queryTheLogFileBusinessData(taskApprovalVO.getFormDataId());
                      default:
                          //未找到数据,解锁
                          DistributedRedisLock.release(taskApprovalVO.getFormDataId());
@@ -130,42 +129,62 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         switch (taskApprovalVO.getApprovalType()){
             case 1:
                 //填报数据
-                return this.queryProcessSubmitBusinessData(taskApprovalVO.getFormDataId());
+                return this.queryProcessSubmitBusinessData(taskApprovalVO.getFormDataId(), false);
             case 2:
                 //工程文件
                 return this.queryArchiveFileBusinessData(taskApprovalVO.getFormDataId());
+            case 3:
+                //日志资料
+                return this.queryTheLogFileBusinessData(taskApprovalVO.getFormDataId());
             default:
                 return null;
         }
     }
 
+    /**
+     * 日志资料
+     */
+    private TaskApprovalVO queryTheLogFileBusinessData(String formDataId){
+        //查询对应的数据
+        TaskApprovalVO vo = new TaskApprovalVO();
+        ContractLog log = this.contractLogService.getById(formDataId);
+        if(log != null && (StringUtils.isNotEmpty(log.getPdfUrl()) || StringUtils.isNotEmpty(log.getEVisaPdfUrl()))){
+            vo.setApprovalFileList(log.getFileName(), StringUtils.isNotEmpty(log.getEVisaPdfUrl()) ? log.getEVisaPdfUrl() : log.getPdfUrl());
+        }
+
+        return vo;
+    }
+
     /**
      * 查询填报数据
      */
-    private TaskApprovalVO queryProcessSubmitBusinessData(String formDataId){
+    private TaskApprovalVO queryProcessSubmitBusinessData(String formDataId, boolean isTask){
+        //查询对应的数据
+        TaskApprovalVO vo = new TaskApprovalVO();
+
         InformationQuery query = this.informationQueryService.getById(formDataId);
         if(query != null){
-            //查询对应的数据
-            TaskApprovalVO vo = new TaskApprovalVO();
-
-            if(StringUtils.isEmpty(query.getEVisaPdfUrl()) && StringUtils.isEmpty(query.getPdfUrl())){
-                //两个都为空,需要去其它地方获取数据
-                List<WbsTreeContract> tableData = this.wbsTreeContractClient.queryProcessSubmitBusinessDataByPrimaKeyIdAndClassify(query.getWbsId().toString(), query.getClassify().toString());
-                if(tableData != null && tableData.size() > 0){
-                    //设置数据
-//                    List<String> pdfUrls = tableData.stream().map(WbsTreeContract::getPdfUrl).distinct().collect(Collectors.toList());
-                    //需要重新合并PDF
-//                    FileUtils.mergePdfPublicMethods();
-
-                    return vo;
+            if(new Integer("3").equals(query.getType())){
+                //首件,首件的资料由三个部分组成:封面、关联资料、总结报告
+                if(StringUtils.isNotEmpty(query.getEVisaPdfUrl()) || StringUtils.isNotEmpty(query.getPdfUrl())){
+                    //封面
+                    vo.setApprovalFileList(query.getName(), StringUtils.isNotEmpty(query.getEVisaPdfUrl()) ? query.getEVisaPdfUrl() : query.getPdfUrl());
+                }
+                //不是审批时再查关联资料,因为关联资料都是审批好的pdf,存在关键字,不能再执行签 字/章
+                if(!isTask){
+                    //关联资料
+                    if(StringUtils.isNotEmpty(query.getLinkMergePdfUrl())){
+                        vo.setApprovalFileList("首件关联资料", query.getLinkMergePdfUrl());
+                    }
                 }
+
             } else {
-                //反之直接获取
-                vo.setApprovalFileList(query.getName(), StringUtils.isNotEmpty(query.getEVisaPdfUrl()) ? query.getEVisaPdfUrl() : query.getPdfUrl());
-                return vo;
+                if(StringUtils.isNotEmpty(query.getEVisaPdfUrl()) || StringUtils.isNotEmpty(query.getPdfUrl())){
+                    vo.setApprovalFileList(query.getName(), StringUtils.isNotEmpty(query.getEVisaPdfUrl()) ? query.getEVisaPdfUrl() : query.getPdfUrl());
+                }
             }
         }
-        return null;
+        return vo;
     }
 
     /**
@@ -250,6 +269,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         if(currentLink == null){
             return false;
         }
+        //获取主流程
+        Task masterTask = this.getOne(Wrappers.<Task>lambdaQuery().eq(Task::getIsDeleted, 0).eq(Task::getProcessInstanceId, currentLink.getProcessInstanceId()));
 
         if("OK".equals(taskApprovalVO.getFlag())){
             //同意,执行签章
@@ -276,8 +297,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 
                 //获取状态为1(待审批)的分支流程
                 List<TaskParallel> otherLink = this.taskParallelService.list(Wrappers.<TaskParallel>lambdaQuery().eq(TaskParallel::getProcessInstanceId, currentLink.getProcessInstanceId()).eq(TaskParallel::getIsDeleted, 0).eq(TaskParallel::getStatus, 1));
-                //获取主流程
-                Task task = this.getOne(Wrappers.<Task>lambdaQuery().eq(Task::getIsDeleted, 0).eq(Task::getProcessInstanceId, currentLink.getProcessInstanceId()));
+
                 if(otherLink == null || otherLink.size() == 0){
                     //说明都审批完成,将主表状态更改为已完成
                     String finalPdfUrl = null;
@@ -288,18 +308,18 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
 //                    finalPdfUrl = this.eVisaClient.eVisaContractSeal(JSONObject.parseObject(JSONObject.toJSONString(taskApprovalVO), EVisaTaskApprovalVO.class), finalPdfUrl);
 
                     //根据主表的业务ID(processInstanceId)获取主流程的taskId
-                    String masterTaskId = this.newFlowClient.queryTaskIdByProcessInstanceId(task.getProcessInstanceId());
+                    String masterTaskId = this.newFlowClient.queryTaskIdByProcessInstanceId(masterTask.getProcessInstanceId());
                     if(StringUtils.isNotEmpty(masterTaskId)){
                         //完成流程
-                        this.newFlowClient.completeApprovalTask(taskId, task.getProcessInstanceId(), "审批完成");
+                        this.newFlowClient.completeApprovalTask(taskId, masterTask.getProcessInstanceId(), "审批完成");
                         //修改主流程状态为已完成
-                        this.update(Wrappers.<Task>lambdaUpdate().set(Task::getStatus, 2).set(Task::getUpdateTime, new Date()).eq(Task::getId, task.getId()));
+                        this.update(Wrappers.<Task>lambdaUpdate().set(Task::getStatus, 2).set(Task::getUpdateTime, new Date()).eq(Task::getId, masterTask.getId()));
                         //修改对应的业务数据状态为已审批
-                        this.updateBusinessDataByFormDataId(task, 2, finalPdfUrl);
+                        this.updateBusinessDataByFormDataId(masterTask, 2, finalPdfUrl);
                     }
                 } else {
                     //只更新PDF路径
-                    this.updateBusinessDataByFormDataId(task, 1,  eVisaStatus.contains("@@@@") ? eVisaStatus.split("@@@@")[1] : null);
+                    this.updateBusinessDataByFormDataId(masterTask, 1,  eVisaStatus.contains("@@@@") ? eVisaStatus.split("@@@@")[1] : null);
                 }
             } else if("eVisaError".equals(eVisaStatus) || eVisaStatus.contains("eVisaError")){
                 //电签失败,将对应分支任务的电签状态修改为99并添加错误信息
@@ -315,6 +335,9 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                         .eq(TaskParallel::getParallelProcessInstanceId, parallelProcessInstanceId)
                 );
 
+                //解锁
+                DistributedRedisLock.release(masterTask.getFormDataId());
+
             } else {
                 //notPfxOrFile,没有证书或证书文件过期等
                 //修改
@@ -324,6 +347,10 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                         .set(TaskParallel::getUpdateTime, new Date())
                         .eq(TaskParallel::getParallelProcessInstanceId, parallelProcessInstanceId)
                 );
+
+                //解锁
+                DistributedRedisLock.release(masterTask.getFormDataId());
+
                 return false;
             }
         } else {
@@ -475,7 +502,7 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                 break;
             case 3:
                 //日志文件
-                this.updateContractLogBusinessDataStatus(task.getFormDataId(), status);
+                this.updateContractLogBusinessDataStatus(task.getFormDataId(), status, newFileUrl);
                 break;
             default:
                 break;
@@ -485,8 +512,10 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
     /**
      * 施工日志等
      */
-    private void updateContractLogBusinessDataStatus(String formDataId, Integer status){
-        this.contractLogService.update(Wrappers.<ContractLog>lambdaUpdate().set(ContractLog::getStatus, status).in(ContractLog::getId, Arrays.asList(formDataId.split(","))));
+    private void updateContractLogBusinessDataStatus(String formDataId, Integer status, String newFileUrl){
+        this.contractLogService.update(Wrappers.<ContractLog>lambdaUpdate().set(ContractLog::getStatus, status).set(ContractLog::getEVisaPdfUrl, newFileUrl).in(ContractLog::getId, Arrays.asList(formDataId.split(","))));
+        //解锁
+        DistributedRedisLock.release(formDataId);
     }
 
     /**
@@ -506,6 +535,8 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
         //更改状态,更改电签文件信息
         wrapper.set(ArchiveFile::getStatus, status).set(ArchiveFile::getEVisaFile, newFileUrl);
         this.archiveFileService.update(wrapper.in(ArchiveFile::getId, Arrays.asList(formDataId.split(","))));
+        //解锁
+        DistributedRedisLock.release(formDataId);
     }
 
 }

+ 1 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/aop/AvoidRepeatableCommitAspect.java

@@ -6,12 +6,10 @@ import org.apache.commons.lang.StringUtils;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Before;
 import org.aspectj.lang.reflect.MethodSignature;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.log.exception.ServiceException;
-import org.springblade.core.tool.utils.DateUtil;
-import org.springblade.manager.unit.RedisUtil;
+import org.springblade.manager.utils.RedisUtil;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;

+ 32 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/bean/TableInfo.java

@@ -19,11 +19,42 @@ public class TableInfo {
     private String projectId;
     private String groupId;
 
+    // =============================== 首件相关 start ===============================
     /**
      * huangjn 2022-09-08 11:18 是否是首件填报
      */
     private String isFirst;
 
+    /**
+     * 首件绑定的节点
+     */
+    private String firstNodeId;
+
+    /**
+     * 首件记录ID(修改时有值,新增时为空)
+     */
+    private String firstId;
+
+    /**
+     * 首件关联的资料信息
+     */
+    private List<Object> linkProcessList;
+
+    /**
+     * 源文件路径
+     */
+    private String sourceUrl;
+
+    /**
+     * pdfUrl
+     */
+    private String pdfUrl;
+
+    private String firstFileName;
+
+    // =============================== 首件相关 end ===============================
+
+    // =============================== 日志相关 start ===============================
     /**
      * huangjn 2022-09-14 15:27 是否是日志填报
      */
@@ -48,5 +79,6 @@ public class TableInfo {
      * id,用于给日志关联的工序信息做特殊化处理
      */
     private String businessId;
+    // =============================== 日志相关 end ===============================
 
 }

+ 69 - 29
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -14,11 +14,7 @@ import com.itextpdf.io.font.FontProgram;
 import com.itextpdf.io.font.FontProgramFactory;
 import com.itextpdf.layout.font.FontProvider;
 import com.spire.xls.*;
-import com.spire.xls.core.IStyle;
 import com.spire.xls.core.spreadsheet.HTMLOptions;
-import com.spire.xls.core.spreadsheet.pivottables.PivotStyle;
-import com.spire.xls.core.spreadsheet.shapes.XlsTextBoxShape;
-import io.reactivex.Single;
 import io.swagger.annotations.*;
 import lombok.AllArgsConstructor;
 import lombok.SneakyThrows;
@@ -29,6 +25,7 @@ import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 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;
@@ -46,9 +43,9 @@ import org.springblade.manager.bean.TableInfo;
 import org.springblade.manager.entity.*;
 import org.springblade.manager.mapper.WbsTreePrivateMapper;
 import org.springblade.manager.service.*;
-import org.springblade.manager.unit.FileUtils;
-import org.springblade.manager.unit.RegularExpressionUtil;
-import org.springblade.manager.unit.WbsElementUtil;
+import org.springblade.manager.utils.FileUtils;
+import org.springblade.manager.utils.RegularExpressionUtil;
+import org.springblade.manager.utils.WbsElementUtil;
 import org.springblade.manager.vo.*;
 import org.springblade.manager.wrapper.ExcelTabWrapper;
 import org.springblade.resource.feign.CommonFileClient;
@@ -128,6 +125,8 @@ public class ExcelTabController extends BladeController {
 
     private final ContractLogClient contractLogClient;
 
+    private final InformationQueryClient informationQueryClient;
+
     /**
      * 详情
      */
@@ -514,7 +513,7 @@ public class ExcelTabController extends BladeController {
                     String oncklickText = "'" + lastName + "'," + i + "," + j;
 
                     //字段正则表达式校验
-                    String regularExpression = "'" + RegularExpressionUtil.getRegularExpression(filedType) + "'," + "字段类型:" + (StringUtils.isNotEmpty(filedType) ? WbsElementUtil.getTypeName(filedType) : null) + "," + i + "," + j;
+                    String regularExpression = "'" + RegularExpressionUtil.getRegularExpression(filedType) + "'," + "'字段类型:" + (StringUtils.isNotEmpty(filedType) ? WbsElementUtil.getTypeName(filedType) : null) + "'," + i + "," + j;
 
                     if (is_true) {
                         element.children().get(0).attr("placeholder", lastName).attr("@focus", "getInformation(" + oncklickText + ")")
@@ -659,11 +658,12 @@ public class ExcelTabController extends BladeController {
 
 
 
- /*   public static void main(String[] args) throws FileNotFoundException {
+
+   /* public static void main(String[] args) throws FileNotFoundException {
 
         String thmlUrl = "/Users/hongchuangyanfa/Desktop/1234567890.html";
 
-        File file1 = ResourceUtil.getFile("/Users/hongchuangyanfa/Downloads/A16.xlsx");
+        File file1 = ResourceUtil.getFile("/Users/hongchuangyanfa/Downloads/D8.101.xlsx");
 
         Workbook wb = new Workbook();
         wb.loadFromMHtml(new FileInputStream(file1));
@@ -698,6 +698,7 @@ public class ExcelTabController extends BladeController {
         Element table = doc.select("table").first();
 
         Elements trs = table.select("tr");
+
         Element tableinfo = trs.get(0).parent().parent().attr("style", "border-collapse: collapse;");
 
         // 获取图片信息
@@ -958,11 +959,20 @@ public class ExcelTabController extends BladeController {
                         String parm = i + "," + j + "," + x1 + "," + x2 + "," + y1 + "," + y2 + ",$event";
                         // 设置文本信息
                         ExctabCell exctabCell = new ExctabCell();
-                        if (textInfo.indexOf("年") >= 0 && textInfo.indexOf("月") >= 0 && textInfo.indexOf("日") >= 0) {
+                        if ((textInfo.indexOf("年") >= 0 && textInfo.indexOf("月") >= 0 && textInfo.indexOf("日") >= 0)|| textInfo.indexOf("日期")>=0 ) {
 
                             data.empty().append("<el-input type='text'  @contextmenu.prevent.native='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + "  x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder='年月日'> </el-input>");
                             exctabCell.setExctabId(excelId);
                             exctabCell.setTextInfo(inputText);
+
+                            if (inputText.contains("日期") || inputText.contains("年") || inputText.contains("月") || inputText.contains("日")){
+                                //日期
+                                exctabCell.setTextElementType(4);
+                            }else {
+                                //字符串
+                                exctabCell.setTextElementType(1);
+                            }
+
                             exctabCell.setIsDeleted(0);
                             exctabCell.setXys(i + "_" + j);
                             colTitle.add(exctabCell);
@@ -1001,6 +1011,15 @@ public class ExcelTabController extends BladeController {
                             if (!inputText.equals("")) {
                                 exctabCell.setExctabId(excelId);
                                 exctabCell.setTextInfo(inputText);
+
+                                if (inputText.contains("日期") || inputText.contains("年") || inputText.contains("月") || inputText.contains("日")){
+                                    //日期
+                                    exctabCell.setTextElementType(4);
+                                }else {
+                                    //字符串
+                                    exctabCell.setTextElementType(1);
+                                }
+
                                 exctabCell.setIsDeleted(0);
                                 exctabCell.setXys(i + "_" + j);
                                 colTitle.add(exctabCell);
@@ -1011,12 +1030,12 @@ public class ExcelTabController extends BladeController {
                 }
             }
         }
-        System.out.println(zikey);
+        //System.out.println(zikey);
         // 去掉重复的数
        Map<String, String> groupMap2 = colTitle.stream()
                 .collect(Collectors.groupingBy(ExctabCell::getTextInfo, Collectors.mapping(ExctabCell::getXys, Collectors.joining(","))));
 
-      //  exctabCellService.DeletExcelByTableId(excelId + "");
+        exctabCellService.DeletExcelByTableId(excelId + "");
 
         List<ExctabCell> colTitle2 = new ArrayList<>();
         for (String title : groupMap2.keySet()) {
@@ -1024,10 +1043,19 @@ public class ExcelTabController extends BladeController {
             exctabCell.setExctabId(excelId);
             exctabCell.setIsDeleted(0);
             exctabCell.setTextInfo(title);
+
+            if (title.contains("日期") || title.contains("年") || title.contains("月") || title.contains("日")){
+                //日期
+                exctabCell.setTextElementType(4);
+            }else {
+                //字符串
+                exctabCell.setTextElementType(1);
+            }
+
             exctabCell.setXys(groupMap2.get(title));
             colTitle2.add(exctabCell);
         }
-     //   exctabCellService.saveBatch(colTitle2);
+        exctabCellService.saveBatch(colTitle2);
 
         // 保存
         File writefile = new File(thmlUrl);
@@ -1321,6 +1349,7 @@ public class ExcelTabController extends BladeController {
                 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()) {
@@ -1366,22 +1395,33 @@ public class ExcelTabController extends BladeController {
                                 }
                                 //https:bladex-test-info.oss-cn-chengdu.aliyuncs.com//upload/20220819/b53cb6700db369381e3b03d7737bcdec.jpg__16_1
                                 if (myData.indexOf("https") >= 0 && myData.indexOf("aliyuncs") >= 0) {
-                                  //  Element element = trs.get(y1).select("td").get(x1);
-                                    String styles[] = data.attr("style").split(";");
-                                    int Height = 0;
-                                    for (String sty : styles) {
-                                        if (sty.indexOf("height:") >= 0) {
-                                            Height = Integer.parseInt(sty.replace("height:", "").replace("px", ""));
+
+                                    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);
                                         }
                                     }
 
-                                    BufferedImage image = ImageIO.read(CommonUtil.getOSSInputStream(myData));
-                                    ExcelPicture pic = sheet.getPictures().add(y1, x1, image);
-                                    pic.setHeight(Height);
-                                    System.out.println(sheet.getCellRange(y1, x1).getRowHeight());
-                                    System.out.println(sheet.getCellRange(y1, x1).getColumnWidth());
-                                    sheet.getCellRange(y1, x1).getStyle().setShrinkToFit(true);
+                                    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);
@@ -1911,7 +1951,7 @@ public class ExcelTabController extends BladeController {
                         queryWrapper.eq("type", 2);
                         queryWrapper.eq("tab_id", tableNode.getPKeyId());
 
-                        final List<TextdictInfo> textdictInfos = textdictInfoService.getBaseMapper().selectList(queryWrapper);
+                        final List<TextdictInfo> textdictInfos = this.textdictInfoService.getBaseMapper().selectList(queryWrapper);
                         if (textdictInfos != null && !textdictInfos.isEmpty()) {
                             textdictInfos.forEach(e -> {
                                 String key = e.getColKey();
@@ -1939,7 +1979,7 @@ public class ExcelTabController extends BladeController {
 
                 sheet.saveToPdf(onePdfPath);
 
-                BladeFile bladeFile = newIOSSClient.uploadFile( fileName + ".pdf", onePdfPath);
+                BladeFile bladeFile = this.newIOSSClient.uploadFile( fileName + ".pdf", onePdfPath);
 
                 pdfUrls.add(bladeFile.getLink());
 
@@ -1956,7 +1996,7 @@ public class ExcelTabController extends BladeController {
 
                     FileUtils.mergePdfPublicMethods(pdfUrls, mergePdfPath);
 
-                    BladeFile mergeFile = newIOSSClient.uploadFile(theLogId + new Date().getTime() + ".pdf", mergePdfPath);
+                    BladeFile mergeFile = this.newIOSSClient.uploadFile(theLogId + new Date().getTime() + ".pdf", mergePdfPath);
 
                     //修改记录
                     this.contractLogClient.updateTheLogPdfUrl(theLogJson.getString("id"), mergeFile.getLink());

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

@@ -29,7 +29,7 @@ import org.springblade.core.mp.support.Query;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.entity.WbsFormElement;
-import org.springblade.manager.unit.CopyUtil;
+import org.springblade.manager.utils.CopyUtil;
 import org.springblade.manager.vo.ExctabCellVO2;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.RequestParam;

+ 290 - 211
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/FirstController.java

@@ -1,9 +1,11 @@
 package org.springblade.manager.controller;
 
 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.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
+import com.spire.xls.CellRange;
 import com.spire.xls.ExcelPicture;
 import com.spire.xls.Workbook;
 import com.spire.xls.Worksheet;
@@ -15,32 +17,35 @@ import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
+import org.springblade.business.feign.InformationQueryClient;
+import org.springblade.common.constant.CommonConstant;
 import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.boot.ctrl.BladeController;
 import org.springblade.core.oss.model.BladeFile;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.*;
 import org.springblade.manager.entity.*;
 import org.springblade.manager.service.*;
-import org.springblade.manager.unit.FileUtils;
+import org.springblade.manager.utils.FileUtils;
 import org.springblade.resource.feign.CommonFileClient;
 import org.springblade.resource.feign.IOSSClient;
 import org.springblade.resource.feign.NewIOSSClient;
 import org.springblade.resource.vo.NewBladeFile;
+import org.springblade.system.cache.ParamCache;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
 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.io.IOException;
-import java.util.Comparator;
-import java.util.HashMap;
+import java.util.*;
 import java.util.List;
-import java.util.Map;
 import java.util.stream.Collectors;
 
 
@@ -70,6 +75,11 @@ public class FirstController extends BladeController {
 
     private final JdbcTemplate jdbcTemplate;
 
+    private final InformationQueryClient informationQueryClient;
+
+    private final ITextdictInfoService textdictInfoService;
+
+
     /**
      * 首件表单获取 html页面
      */
@@ -79,7 +89,7 @@ public class FirstController extends BladeController {
     @ApiImplicitParams(value = {
             @ApiImplicitParam(name = "contractId", value = "contractId", required = true)
     })
-    public R getFirstExcelHtml(Long contractId) throws IOException, InterruptedException {
+    public R getFirstExcelHtml(Long contractId) throws IOException {
 
         WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
                 .eq(WbsTreeContract::getContractId,contractId).eq(WbsTreeContract::getTableType,"111"));
@@ -118,254 +128,323 @@ public class FirstController extends BladeController {
             @ApiImplicitParam(name = "file", value = "file", required = true),
             @ApiImplicitParam(name = "pkeyId", value = "pkeyId", required = true)
     })
-    public R addBussFile(@RequestParam("file") MultipartFile file, Long pkeyId) {
-
-        // 直接删除以前记录
-        tableFileService.getBaseMapper().delete(Wrappers.<TableFile>query().lambda().eq(TableFile::getTabId,pkeyId).eq(TableFile::getType,3));
-
-        R<BladeFile> bladeFile = iossClient.addFileInfo(file);
-        BladeFile bladeFile1 = bladeFile.getData();
-        TableFile tableFile = new TableFile();
-        String fileExtension = FileUtil.getFileExtension(bladeFile1.getName());
-        tableFile.setTabId(pkeyId+"");
-        tableFile.setName(file.getOriginalFilename());
-        tableFile.setType(3); // 表示首件的附件
-        tableFile.setDomainUrl(bladeFile1.getLink());
-        tableFile.setIsDeleted(0);
-        tableFile.setExtension(fileExtension);
-
-        NewBladeFile newBladeFile = new NewBladeFile();
-        if(fileExtension.contains("xlsx")){
-            newBladeFile = this.commonFileClient.excelToPdf(file);
-            tableFile.setDomainPdfUrl(newBladeFile.getPdfUrl());
-        } else if(fileExtension.contains("xls")){
+    public R<JSONObject> addBussFile(@RequestParam("file") MultipartFile file, Long pkeyId) {
+        //上传源文件
+        R<BladeFile> sourceFileList = iossClient.addFileInfo(file);
+        BladeFile sourceFile = sourceFileList.getData();
+        //源文件路径
+        String sourceUrl = sourceFile.getLink();
+        //pdfUrl路径
+        String pdfUrl = "";
+        //文件名称
+        String fileExtension = StringUtils.isNotEmpty(file.getOriginalFilename()) ? file.getOriginalFilename() : FileUtil.getFileExtension(sourceFile.getName());
+
+        NewBladeFile newBladeFile = null;
+        if(fileExtension.contains("pdf")){
+            pdfUrl = sourceUrl;
+        } else if(fileExtension.contains("xls") || fileExtension.contains("xlsx")){
             newBladeFile = this.commonFileClient.excelToPdf(file);
-            tableFile.setDomainPdfUrl(newBladeFile.getPdfUrl());
         } else if(fileExtension.contains("docx")){
             newBladeFile = this.commonFileClient.wordToPdf(file);
-            tableFile.setDomainPdfUrl(newBladeFile.getPdfUrl());
-        } else if(fileExtension.contains("png") || file.getOriginalFilename().contains("jpg")){
+        } else if(fileExtension.contains("png") || (StringUtils.isNotEmpty(file.getOriginalFilename()) && file.getOriginalFilename().contains("jpg"))){
             newBladeFile = this.commonFileClient.pngOrJpgToPdf(file);
-            tableFile.setDomainPdfUrl(newBladeFile.getPdfUrl());
-        } else if(fileExtension.contains("pdf")){
-            tableFile.setDomainPdfUrl(bladeFile1.getLink());
         }
-        tableFile.setStatus("finished");
-        tableFileService.saveOrUpdate(tableFile);
-        return R.data(tableFile.getId());
+
+        if(newBladeFile != null){
+            pdfUrl = newBladeFile.getPdfUrl();
+        }
+
+        //返回数据
+        JSONObject result = new JSONObject();
+        result.put("sourceUrl", sourceUrl);
+        result.put("pdfUrl", pdfUrl);
+        result.put("fileName", file.getOriginalFilename());
+
+        return R.data(result);
     }
 
 
 
     @GetMapping("/get-first-buss-pdfInfo")
     @ApiOperationSupport(order = 3)
-    @ApiOperation(value = "首件-pdf预览", notes = "首件-单pdf预览")
-    @ApiImplicitParams(value = {
-            @ApiImplicitParam(name = "pkeyId", value = "pkeyId", required = true),
-            @ApiImplicitParam(name = "liunkIds", value = "liunkIds", required = true)
-    })
-    public R getBussPdfInfo(Long pkeyId,String liunkIds) throws Exception {
-
-        WbsTreeContract wbsTreeContract = wbsTreeContractService.getBaseMapper().selectOne(Wrappers.<WbsTreeContract>query().lambda()
-                .eq(WbsTreeContract::getPKeyId, pkeyId));
+    @ApiOperation(value = "首件-pdf预览", notes = "首件列表ID")
+    @ApiImplicitParam(name = "firstId", value = "pkeyId", required = true)
+    public R<String> getBussPdfInfo(String firstId) {
+        if(StringUtils.isNotEmpty(firstId)){
+            //PDF路径集合
+            List<String> pdfUrls = new ArrayList<>();
+
+            //获取配置的路径
+            String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+            //获取数据
+            JSONObject firstJson = this.informationQueryClient.queryFirstBusinessDataByFirstId(firstId);
+            if(firstJson != null){
+                if(StringUtils.isNotEmpty(firstJson.getString("eVisaPdfUrl")) || StringUtils.isNotEmpty(firstJson.getString("pdfUrl"))){
+                    pdfUrls.add(StringUtils.isNotEmpty(firstJson.getString("eVisaPdfUrl")) ? firstJson.getString("eVisaPdfUrl") : firstJson.getString("pdfUrl"));
+                } else {
+                    //没有生成拼接的记录,生成
+                    //获取html
+                    WbsTreeContract tableNode = this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, firstJson.getString("tableId")));
+
+                    if(tableNode == null){
+                        return R.fail("该数据下无此节点!");
+                    }
 
-        if(wbsTreeContract ==null ){
-            return R.fail("该数据下无此节点!");
-        }
-        if(wbsTreeContract.getHtmlUrl()==null){
-            return R.fail("请关联清表!");
-        }
+                    if(StringUtils.isEmpty(tableNode.getHtmlUrl())){
+                        return R.fail("请关联清表!");
+                    }
 
-        String pdfPath="/Users/hongchuangyanfa/Desktop/pdf//"+pkeyId+".pdf";
-        File tabpdf = ResourceUtil.getFile(pdfPath);
-        if(tabpdf.exists()){
-            tabpdf.delete();
-        }
+                    // 获取清表信息
+                    ExcelTab excelTab = excelTabService.getById(tableNode.getExcelId());
+                    if (excelTab == null) {
+                        return R.fail("失败");
+                    }
 
-        // 获取清表信息
-        ExcelTab excelTab = excelTabService.getById(wbsTreeContract.getExcelId());
-
-        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 (DataInfo != null && DataInfo.size() >= 1) {
-            File htmlFile = ResourceUtil.getFile(wbsTreeContract.getHtmlUrl());
-            String htmlString =  IoUtil.readToString(new FileInputStream(htmlFile));
-            Document doc = Jsoup.parse(htmlString);
-            Element table = doc.select("table").first();
-            Elements trs = table.select("tr");
-            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 = Integer.parseInt(data.children().get(0).attr("x1"));
-                        if(x1==0){
-                            x1=1;
-                        }
-                        int y1 = Integer.parseInt(data.children().get(0).attr("y1"));
-                        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;
+                    List<Map<String, Object>> businessDataMapList = this.getFirstBusinessData(firstId).getData();
+
+                    try{
+                        //处理数据
+                        for(Map<String, Object> dataMap : businessDataMapList){
+                            // 获取excel流 和 html流
+                            Workbook wb = new Workbook();
+                            wb.loadFromMHtml(CommonUtil.getOSSInputStream(excelTab.getFileUrl()));
+                            //获取工作表
+                            Worksheet sheet = wb.getWorksheets().get(0);
+
+                            // 数据不为空 &&
+                            if (StringUtils.isNotEmpty(tableNode.getHtmlUrl())) {
+                                File htmlFile = ResourceUtil.getFile(tableNode.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");
+
+                                    if (ObjectUtil.isNotEmpty(dataMap)) {
+                                        for (String val : dataMap.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, y1;
+
+                                                    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 = dataMap.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});
+                                                        }
+                                                    }
+
+                                                    if (myData.indexOf("https") >= 0 && myData.indexOf("aliyuncs") >= 0) {
+                                                        Element element = trs.get(y1).select("td").get(x1);
+                                                        String styles[] = element.attr("style").split(";");
+                                                        int Height = 0;
+                                                        for (String sty : styles) {
+                                                            if (sty.indexOf("height:") >= 0) {
+                                                                Height = Integer.parseInt(sty.replace("height:", "").replace("px", ""));
+                                                            }
+                                                        }
+
+                                                        BufferedImage image = ImageIO.read(CommonUtil.getOSSInputStream(myData));
+                                                        ExcelPicture pic = sheet.getPictures().add(y1, x1, image);
+                                                        pic.setHeight(Height);
+                                                        sheet.getCellRange(y1, x1).getStyle().setShrinkToFit(true);
+
+                                                    } else {
+                                                        final CellRange cellRange = sheet.getCellRange(y1, x1);
+                                                        cellRange.setText(myData);
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+
+                                    // 组装电签设置
+                                    QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
+                                    queryWrapper.eq("type", 2);
+                                    queryWrapper.eq("tab_id", tableNode.getPKeyId());
+
+                                    final List<TextdictInfo> textdictInfos = this.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);
+
+                                        });
+                                    }
                                 }
-                            }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){
-                            System.out.println(myData);
 
-                            BufferedImage image = ImageIO.read(CommonUtil.getOSSInputStream(myData) );
-                            ExcelPicture pic = sheet.getPictures().add(y1, x1,image);
+                            Long fileName = SnowFlakeUtil.getId();
+                            String onePdfPath = file_path + "/pdf//" + fileName + ".pdf";
 
-                            sheet.getCellRange(y1,x1).getStyle().setShrinkToFit(true);
+                            sheet.saveToPdf(onePdfPath);
 
-                        }else{
-                            sheet.getCellRange(y1,x1).setText(myData);
-                        }
-                    }
-                }
-            }
-        }
+                            BladeFile bladeFile = this.newIOSSClient.uploadFile( fileName + ".pdf", onePdfPath);
 
-        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);
-        }
+                            pdfUrls.add(bladeFile.getLink());
 
-        List<TableFile> tableFileList = tableFileService.getBaseMapper().selectList(Wrappers.<TableFile>query().lambda().eq(TableFile::getTabId, pkeyId).eq(TableFile::getIsDeleted,0));
-        tableFileList.sort(Comparator.comparing(TableFile::getType));
+                            //将封面的pdf修改
+                            String updatePdfUrl = "UPDATE u_information_query SET pdf_url = " + bladeFile.getLink() + " WHERE id = " + firstId;
+                            this.jdbcTemplate.execute(updatePdfUrl);
 
+                            wb.dispose();
+                        }
+                    }catch (Exception e){
+                        e.printStackTrace();
+                    }
+                }
 
-        List<String> dataListPdf = tableFileList.stream().filter(tableFile -> tableFile.getDomainPdfUrl()!=null).map(TableFile::getDomainPdfUrl).collect(Collectors.toList());
+                if(pdfUrls.size() > 0){
+                    try{
+                        //关联的数据
+                        if(StringUtils.isNotEmpty(firstJson.getString("linkMergePdfUrl"))){
+                            pdfUrls.add(firstJson.getString("linkMergePdfUrl"));
+                        }
+                        //总结报告,暂时无
 
-        String pdfPath2 = "/Users/hongchuangyanfa/Desktop/pdf//"+pkeyId+"_2.pdf";
+                        //上传
+                        String mergePdfPath = file_path + "/pdf//" + firstId + ".pdf";
+                        File oldMergePdf = ResourceUtil.getFile(mergePdfPath);
+                        if (oldMergePdf.exists()) {
+                            oldMergePdf.delete();
+                        }
+                        //合并
+                        FileUtils.mergePdfPublicMethods(pdfUrls, mergePdfPath);
+                        //上传
+                        BladeFile mergeFile = this.newIOSSClient.uploadFile(firstId + '-' + new Date().getTime() + ".pdf", mergePdfPath);
 
-        FileUtils.mergePdfPublicMethods(dataListPdf,pdfPath2);
+                        //返回
+                        return R.data(mergeFile.getLink());
 
-        BladeFile bladeFile2 = newIOSSClient.uploadFile(pkeyId + "2.pdf", pdfPath2);
+                    }catch (Exception e){
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
 
-        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());
+        return R.data(300, null, "未找到数据");
     }
 
     @GetMapping("/get-first-buss-dataInfo")
     @ApiOperationSupport(order = 4)
     @ApiOperation(value = "获取首件用户保存数据", notes = "获取首件用户保存数据")
     @ApiImplicitParams(value = {
-            @ApiImplicitParam(name = "pkeyId", value = "pkeyId", required = true)
+            @ApiImplicitParam(name = "firstId", value = "pkeyId", required = true)
     })
-    public R getBussDataInfo(Long pkeyId) throws FileNotFoundException {
-
-        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.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("无实体表对应");
-        }
+    public R<List<Map<String, Object>>> getFirstBusinessData(String firstId) {
+        if(StringUtils.isNotEmpty(firstId)){
+            List<Map<String, Object>> result = new ArrayList<>();
+
+            JSONObject json = this.informationQueryClient.queryFirstBusinessDataByFirstId(firstId);
+            if(json != null){
+                //获取数据所在表格
+                WbsTreeContract tableNode = this.wbsTreeContractService.getOne(Wrappers.<WbsTreeContract>lambdaQuery().eq(WbsTreeContract::getPKeyId, json.getString("tableId")));
+                if(tableNode != null && StringUtils.isNotEmpty(tableNode.getInitTableName())){
+                    //获取填报数据
+                    List<Map<String, Object>> businessDataMapList = this.jdbcTemplate.queryForList("SELECT * FROM " + tableNode.getInitTableName() + " WHERE group_id = " + json.getString("id"));
+                    if(businessDataMapList.size() > 0){
+                        for(Map<String, Object> mysqlData : businessDataMapList){
+                            //数据结果
+                            Map<String, Object> reData = new HashMap<>();
+
+                            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);
+                                    }
+                                }
+                            }
 
-        String querySql = "select * from "+wbsTreeContract.getInitTableName()+" where p_key_id="+pkeyId ;
-        List<Map<String, Object>> dataIn = jdbcTemplate.queryForList(querySql);
+                            reData.remove("p_key_id");
+                            reData.remove("classify");
+                            reData.remove("contractId");
+                            reData.remove("pkeyId");
+                            reData.remove("projectId");
 
-        if(dataIn==null||dataIn.size()<=0){
-            return R.data(reData);
-        }
-        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") + "," + tabData[1];
-                        reData.put("pickerKey", pickerKey);
-                    } else {
-                        reData.put("pickerKey", key + "__" + tabData[1]);
-                    }
+                            result.add(reData);
+                        }
 
-                    String sql = tabData[0];
-                    sql = sql.replaceAll("\\[", "['");
-                    sql = sql.replaceAll("]", "\']");
-                    sql = sql.replaceAll("000Z,", "000Z\',");
-                    sql = sql.replaceAll(", 20", ", \'20");
-                    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]);
+                        return R.data(result);
                     }
-                } else if(tabVal.indexOf("__")>=0){
-                    String tabData[] = tabVal.split("__");
-                    reData.put(key + "__" + tabData[1], tabData[0]);
-                }else{
-                    reData.put(key, tabVal);
                 }
             }
         }
 
-        return R.data(reData);
+        return R.data(300, null, "未找到对应的业务数据");
     }
 
 }

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

@@ -13,7 +13,7 @@ import org.springblade.core.tool.utils.Func;
 import org.springblade.manager.dto.ArchiveTreeDTO;
 import org.springblade.manager.dto.ArchiveTreeSortDTO;
 import org.springblade.manager.entity.ArchiveTree;
-import org.springblade.manager.unit.DiffListUtil;
+import org.springblade.manager.utils.DiffListUtil;
 import org.springblade.manager.vo.ArchiveTreeVO;
 import org.springblade.manager.mapper.ArchiveTreeMapper;
 import org.springblade.manager.service.IArchiveTreeService;

+ 146 - 37
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -145,6 +145,69 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 		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()){
@@ -160,40 +223,10 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 				tableInfo.setClassify(dataInfo2.getString("classify"));
 				//huangjn 填报的类型,施工或监理
 
-				//huangjn 判断是否是首件
-				if(dataInfo2.containsKey("isFirst")){
-					tableInfo.setIsFirst(dataInfo2.getString("isFirst"));
-				}
-				//huangjn 判断是否是首件
-
-				//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,目前日志专用
+				//设置首件信息
+				this.setFirstData(dataInfo2, tableInfo);
+				//设置日志信息
+				this.setTheLogData(dataInfo2, tableInfo);
 
 				dataInfo2.fluentRemove("contractId")
 						 .fluentRemove("pkeyId")
@@ -203,10 +236,15 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 				         .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()));
@@ -379,10 +417,81 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 
 	}
 
+	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).getIsTheLog())){
+			if(StringUtils.isNotEmpty(tableInfoList.get(0).getIsFirst())){
+				//首件填报
+				this.saveOrUpdateFirst(tableInfoList);
+
+			} else if(StringUtils.isNotEmpty(tableInfoList.get(0).getIsTheLog())){
 				//日志填报
 				this.saveOrUpdateTheLog(tableInfoList);
 
@@ -423,7 +532,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 					fileName = StringUtils.isNotEmpty(fileName) ? fileName : "缺少文件提名配置";
 
 					//huangjn 保存成功后调用生成资料查询列表数据
-					this.informationQueryClient.saveOrUpdateInformationQueryData(wbsTreeContractByP.getPKeyId()+"", "业务ID(主要将来给首件使用)", fileName, Integer.parseInt(tableInfo.getClassify()), 2,"是否是首件(临时,暂时没用到)");
+					this.informationQueryClient.saveOrUpdateInformationQueryData(wbsTreeContractByP.getPKeyId()+"", "首件使用字段", "业务ID(主要将来给首件使用)", fileName, Integer.parseInt(tableInfo.getClassify()), 2,"是否是首件(临时,暂时没用到)", "源文件(首件字段)", "pdf文件(首件字段)", "首件上传总结报告名称", new ArrayList<>());
 				}
 
 				UpdateWrapper<WbsTreeContract> updateWrapper = new UpdateWrapper<>();
@@ -447,7 +556,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
 					fileName = StringUtils.isNotEmpty(fileName) ? fileName : "缺少文件提名配置";
 
 					//huangjn 保存成功后调用生成资料查询列表数据
-					this.informationQueryClient.saveOrUpdateInformationQueryData(wbsTreeContractByP.getPKeyId()+"", "业务ID(主要将来给首件使用)", fileName, Integer.parseInt(tableInfoList.get(0).getClassify()), 2,"是否是首件(临时,暂时没用到)");
+					this.informationQueryClient.saveOrUpdateInformationQueryData(wbsTreeContractByP.getPKeyId()+"", "首件使用字段", "业务ID(主要将来给首件使用)", fileName, Integer.parseInt(tableInfoList.get(0).getClassify()), 2,"false", "源文件(首件字段)", "pdf文件(首件字段)", "首件上传总结报告名称", new ArrayList<>());
 				}catch (Exception e){
 					e.printStackTrace();
 				}

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

@@ -25,7 +25,7 @@ import org.springblade.manager.mapper.WbsFormElementMapper;
 import org.springblade.manager.mapper.WbsTreeMapper;
 import org.springblade.manager.mapper.WbsTreePrivateMapper;
 import org.springblade.manager.service.IWbsFormElementService;
-import org.springblade.manager.unit.WbsElementUtil;
+import org.springblade.manager.utils.WbsElementUtil;
 import org.springblade.manager.vo.WbsFormElementVO;
 import org.springblade.manager.vo.WbsFormElementVO2;
 import org.springblade.manager.vo.WbsNodeTableVO;

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

@@ -17,7 +17,7 @@ import org.springblade.manager.entity.*;
 import org.springblade.manager.mapper.WbsTreeContractMapper;
 import org.springblade.manager.mapper.WbsTreePrivateMapper;
 import org.springblade.manager.service.IWbsTreeContractService;
-import org.springblade.manager.unit.DiffListUtil;
+import org.springblade.manager.utils.DiffListUtil;
 import org.springblade.manager.vo.WbsTreeContractTreeVO;
 import org.springblade.manager.vo.WbsTreeContractTreeVO3;
 import org.springframework.stereotype.Service;

+ 2 - 3
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/WbsTreeServiceImpl.java

@@ -10,7 +10,6 @@ import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.constant.BladeConstant;
 import org.springblade.core.tool.node.ForestNodeMerger;
 import org.springblade.core.tool.utils.*;
-import org.springblade.manager.aop.AvoidRepeatableCommit;
 import org.springblade.manager.dto.FormElementDTO;
 import org.springblade.manager.dto.WbsTreeBatchImportDTO;
 import org.springblade.manager.dto.WbsTreeContractDTO;
@@ -22,8 +21,8 @@ import org.springblade.manager.mapper.*;
 import org.springblade.manager.service.IWbsFormElementService;
 import org.springblade.manager.service.IWbsTreeService;
 import org.springblade.core.mp.base.BaseServiceImpl;
-import org.springblade.manager.unit.DiffListUtil;
-import org.springblade.manager.unit.WbsElementUtil;
+import org.springblade.manager.utils.DiffListUtil;
+import org.springblade.manager.utils.WbsElementUtil;
 import org.springblade.manager.vo.*;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;

+ 0 - 187
blade-service/blade-manager/src/main/java/org/springblade/manager/unit/WbsElementUtil.java

@@ -1,187 +0,0 @@
-package org.springblade.manager.unit;
-
-import net.sourceforge.pinyin4j.PinyinHelper;
-import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
-import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
-import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
-import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
-import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
-
-public class WbsElementUtil {
-
-    public static String getPinyin(String text, String separator) {
-        //text 文本, separator 转换后添加的分隔符
-        char[] chars = text.toCharArray();
-        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
-
-        // 设置大小写
-        format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
-
-        // 设置声调表示方法
-        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
-
-        // 设置字母u表示方法
-        format.setVCharType(HanyuPinyinVCharType.WITH_V);
-        String[] s;
-        String rs = "";
-        try {
-            StringBuilder sb = new StringBuilder();
-            for (int i = 0; i < chars.length; i++) {
-                // 判断是否为汉字字符
-                if (String.valueOf(chars[i]).matches("[\\u4E00-\\u9FA5]+")) {
-                    s = PinyinHelper.toHanyuPinyinStringArray(chars[i], format);
-                    if (s != null) {
-                        sb.append(s[0]).append(separator);
-                        continue;
-                    }
-                }
-
-                sb.append(chars[i]);
-
-                if ((i + 1 >= chars.length) || String.valueOf(chars[i + 1]).matches("[\\u4E00-\\u9FA5]+")) {
-                    sb.append(separator);
-                }
-            }
-
-            rs = sb.substring(0, sb.length());
-        } catch (BadHanyuPinyinOutputFormatCombination e) {
-            e.printStackTrace();
-
-        }
-        return rs;
-    }
-
-    public static String setDefaultElementLength(Integer type) {
-        switch (type) {
-            case 1:  //字符串
-            case 7:  //文件
-            case 6:  //签名
-                return "250";
-            case 2:  //整数
-            case 5:  //数值
-            case 3:  //小数
-            case 4:  //日期
-                return "50";
-            default:
-                return "0";
-        }
-    }
-
-    public static Integer getElementLength2(String type) {
-        switch (type) {
-            case "varchar":
-                return 250;
-            case "bigint":
-            case "decimal":
-            case "datetime":
-                return 50;
-            default:
-                return 0;
-        }
-    }
-
-    public static Integer getElementLength(String type) {
-        switch (type) {
-            case "字符串":
-            case "签名":
-            case "文件":
-                return 250;
-            case "整数":
-            case "数值":
-            case "小数":
-            case "日期":
-                return 50;
-            default:
-                return 0;
-        }
-    }
-
-    public static String getInitTableFiledType(Integer type) {
-        switch (type) {
-            case 2:
-                //整数
-                return "bigint";
-            case 3:
-                //小数
-                return "decimal";
-            case 4:
-                //日期
-                return "datetime";
-            case 5:
-                //数值
-                return "decimal";
-            case 6:
-                //签名
-                return "varchar";
-            case 7:
-                //文件
-                return "varchar";
-            case 1:
-            default:
-                //字符串
-                return "varchar";
-        }
-    }
-
-    public static Integer getElementType(String type) {
-        switch (type) {
-            case "字符串":
-                return 1;
-            case "整数":
-                return 2;
-            case "小数":
-                return 3;
-            case "日期":
-                return 4;
-            case "数值":
-                return 5;
-            case "签名":
-                return 6;
-            case "文件":
-                return 7;
-            default:
-                return 0;
-        }
-    }
-
-    public static Integer getTableType(String tableType) {
-        switch (tableType) {
-            case "检验表":
-                return 1;
-            case "记录表":
-                return 2;
-            case "通用表":
-                return 3;
-            case "监表":
-                return 4;
-            case "评定表":
-                return 5;
-            case "测量表":
-                return 6;
-            case "竣工表":
-                return 7;
-            case "汇总表":
-                return 8;
-            case "试验记录表":
-                return 9;
-            case "试验报告表":
-                return 10;
-            default:
-                return 0;
-        }
-    }
-
-    public static String getTypeName(String type) {
-        switch (type) {
-            case "bigint":
-                return "整数或数值";
-            case "decimal":
-                return "小数";
-            case "datetime":
-                return "日期";
-            default:
-                return "字符串";
-        }
-    }
-
-}

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/unit/CopyUtil.java → blade-service/blade-manager/src/main/java/org/springblade/manager/utils/CopyUtil.java

@@ -1,4 +1,4 @@
-package org.springblade.manager.unit;
+package org.springblade.manager.utils;
 
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/unit/DiffListUtil.java → blade-service/blade-manager/src/main/java/org/springblade/manager/utils/DiffListUtil.java

@@ -1,4 +1,4 @@
-package org.springblade.manager.unit;
+package org.springblade.manager.utils;
 
 import java.util.ArrayList;
 import java.util.HashMap;

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/unit/FileUtils.java → blade-service/blade-manager/src/main/java/org/springblade/manager/utils/FileUtils.java

@@ -1,4 +1,4 @@
-package org.springblade.manager.unit;
+package org.springblade.manager.utils;
 
 import com.itextpdf.text.Document;
 import com.itextpdf.text.pdf.PdfCopy;

+ 1 - 6
blade-service/blade-manager/src/main/java/org/springblade/manager/unit/HtmlToPdf.java → blade-service/blade-manager/src/main/java/org/springblade/manager/utils/HtmlToPdf.java

@@ -1,23 +1,18 @@
-package org.springblade.manager.unit;
+package org.springblade.manager.utils;
 
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 
-import com.alibaba.fastjson.JSONObject;
 import com.itextpdf.html2pdf.ConverterProperties;
 import com.itextpdf.html2pdf.HtmlConverter;
 import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;
 import com.itextpdf.kernel.colors.Color;
 import com.itextpdf.kernel.geom.Rectangle;
-import com.itextpdf.kernel.pdf.PdfDocument;
-import com.itextpdf.kernel.pdf.PdfPage;
 import com.itextpdf.kernel.pdf.PdfWriter;
 import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
 import com.itextpdf.kernel.pdf.canvas.draw.ILineDrawer;
-import com.itextpdf.layout.Document;
-import com.itextpdf.layout.element.LineSeparator;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/unit/PdfConvertA4Utils.java → blade-service/blade-manager/src/main/java/org/springblade/manager/utils/PdfConvertA4Utils.java

@@ -1,4 +1,4 @@
-package org.springblade.manager.unit;
+package org.springblade.manager.utils;
 
 import com.itextpdf.text.Document;
 import com.itextpdf.text.PageSize;

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/unit/ProtoStuffSerializerUtil.java → blade-service/blade-manager/src/main/java/org/springblade/manager/utils/ProtoStuffSerializerUtil.java

@@ -1,4 +1,4 @@
-package org.springblade.manager.unit;
+package org.springblade.manager.utils;
 
 import com.dyuproject.protostuff.LinkedBuffer;
 import com.dyuproject.protostuff.ProtostuffIOUtil;

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/unit/RedisUtil.java → blade-service/blade-manager/src/main/java/org/springblade/manager/utils/RedisUtil.java

@@ -1,4 +1,4 @@
-package org.springblade.manager.unit;
+package org.springblade.manager.utils;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.DataAccessException;

+ 1 - 1
blade-service/blade-manager/src/main/java/org/springblade/manager/unit/RegularExpressionUtil.java → blade-service/blade-manager/src/main/java/org/springblade/manager/utils/RegularExpressionUtil.java

@@ -1,4 +1,4 @@
-package org.springblade.manager.unit;
+package org.springblade.manager.utils;
 
 /**
  * 正则表达式工具类

+ 215 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/WbsElementUtil.java

@@ -0,0 +1,215 @@
+package org.springblade.manager.utils;
+
+import net.sourceforge.pinyin4j.PinyinHelper;
+import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
+import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
+import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
+import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
+import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
+
+public class WbsElementUtil {
+
+    public static String getPinyin(String text, String separator) {
+        //text 文本, separator 转换后添加的分隔符
+        char[] chars = text.toCharArray();
+        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
+
+        // 设置大小写
+        format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
+
+        // 设置声调表示方法
+        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
+
+        // 设置字母u表示方法
+        format.setVCharType(HanyuPinyinVCharType.WITH_V);
+        String[] s;
+        String rs = "";
+        try {
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < chars.length; i++) {
+                // 判断是否为汉字字符
+                if (String.valueOf(chars[i]).matches("[\\u4E00-\\u9FA5]+")) {
+                    s = PinyinHelper.toHanyuPinyinStringArray(chars[i], format);
+                    if (s != null) {
+                        sb.append(s[0]).append(separator);
+                        continue;
+                    }
+                }
+
+                sb.append(chars[i]);
+
+                if ((i + 1 >= chars.length) || String.valueOf(chars[i + 1]).matches("[\\u4E00-\\u9FA5]+")) {
+                    sb.append(separator);
+                }
+            }
+
+            rs = sb.substring(0, sb.length());
+        } catch (BadHanyuPinyinOutputFormatCombination e) {
+            e.printStackTrace();
+
+        }
+        return rs;
+    }
+
+    public static String setDefaultElementLength(Integer type) {
+        if (type != null) {
+            switch (type) {
+                case 1:  //字符串
+                case 7:  //文件
+                case 6:  //签名
+                    return "250";
+                case 2:  //整数
+                case 5:  //数值
+                case 3:  //小数
+                case 4:  //日期
+                    return "50";
+                default:
+                    return "0";
+            }
+        } else {
+            return "0";
+        }
+    }
+
+    public static Integer getElementLength2(String type) {
+        if (type != null) {
+            switch (type) {
+                case "varchar":
+                    return 250;
+                case "bigint":
+                case "decimal":
+                case "datetime":
+                    return 50;
+                default:
+                    return 0;
+            }
+        } else {
+            return 0;
+        }
+    }
+
+    public static Integer getElementLength(String type) {
+        if (type != null) {
+            switch (type) {
+                case "字符串":
+                case "签名":
+                case "文件":
+                    return 250;
+                case "整数":
+                case "数值":
+                case "小数":
+                case "日期":
+                    return 50;
+                default:
+                    return 0;
+            }
+        } else {
+            return 0;
+        }
+    }
+
+    public static String getInitTableFiledType(Integer type) {
+        if (type != null) {
+            switch (type) {
+                case 2:
+                    //整数
+                    return "bigint";
+                case 3:
+                    //小数
+                    return "decimal";
+                case 4:
+                    //日期
+                    return "datetime";
+                case 5:
+                    //数值
+                    return "decimal";
+                case 6:
+                    //签名
+                    return "varchar";
+                case 7:
+                    //文件
+                    return "varchar";
+                case 1:
+                default:
+                    //字符串
+                    return "varchar";
+            }
+        } else {
+            return "varchar";
+        }
+    }
+
+    public static Integer getElementType(String type) {
+        if (type != null) {
+            switch (type) {
+                case "字符串":
+                    return 1;
+                case "整数":
+                    return 2;
+                case "小数":
+                    return 3;
+                case "日期":
+                    return 4;
+                case "数值":
+                    return 5;
+                case "签名":
+                    return 6;
+                case "文件":
+                    return 7;
+                default:
+                    return 0;
+            }
+        } else {
+            return 0;
+        }
+    }
+
+    public static Integer getTableType(String tableType) {
+        if (tableType != null) {
+            switch (tableType) {
+                case "检验表":
+                    return 1;
+                case "记录表":
+                    return 2;
+                case "通用表":
+                    return 3;
+                case "监表":
+                    return 4;
+                case "评定表":
+                    return 5;
+                case "测量表":
+                    return 6;
+                case "竣工表":
+                    return 7;
+                case "汇总表":
+                    return 8;
+                case "试验记录表":
+                    return 9;
+                case "试验报告表":
+                    return 10;
+                default:
+                    return 0;
+            }
+        } else {
+            return 0;
+        }
+    }
+
+    public static String getTypeName(String type) {
+        if (type != null) {
+            switch (type) {
+                case "bigint":
+                    return "整数或数值";
+                case "decimal":
+                    return "小数";
+                case "datetime":
+                    return "日期";
+                default:
+                    return "字符串";
+            }
+        } else {
+            return "字符串";
+        }
+    }
+
+}