Browse Source

数据修改

zhuwei 3 months ago
parent
commit
34ade93144
29 changed files with 1952 additions and 354 deletions
  1. 26 12
      blade-common/src/main/java/org/springblade/common/utils/CommonUtil.java
  2. 1 0
      blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/oss/OssBuilder.java
  3. 4 3
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TaskParallel.java
  4. 1 1
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TaskApprovalVO.java
  5. 84 0
      blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TaskSignInfoVO.java
  6. 0 26
      blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/vo/SigInfoVO.java
  7. 3 9
      blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java
  8. 1 0
      blade-service/blade-business/src/main/java/org/springblade/business/mapper/TaskParallelMapper.xml
  9. 8 2
      blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java
  10. 99 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVController.java
  11. 3 10
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVisaController.java
  12. 54 23
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVisaJLController.java
  13. 16 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/EVDataService.java
  14. 6 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/EVisaService.java
  15. 529 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVDataServiceImpl.java
  16. 105 52
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVisaServiceImpl.java
  17. 20 37
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/PDFUtils.java
  18. 386 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/PdfAddimgUtil.java
  19. 219 0
      blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/SignFtpUtil.java
  20. 26 59
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java
  21. 1 1
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/FormulaDaoImpl.java
  22. 1 0
      blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/SignPfxFilePreServiceImpl.java
  23. 0 67
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/FTPUtils.java
  24. 1 2
      blade-service/blade-manager/src/main/java/org/springblade/manager/utils/PdfAddimgUtil.java
  25. 80 48
      blade-service/blade-meter/src/main/java/org/springblade/meter/controller/TaskController.java
  26. 2 2
      blade-service/blade-meter/src/main/java/org/springblade/meter/utils/CollectionUtils.java
  27. 269 0
      blade-service/blade-meter/src/main/java/org/springblade/meter/utils/ExcelImageExample.java
  28. 6 0
      blade-service/blade-meter/src/main/java/org/springblade/meter/utils/FileUtils.java
  29. 1 0
      blade-service/blade-meter/src/main/java/org/springblade/meter/utils/StringUtils.java

+ 26 - 12
blade-common/src/main/java/org/springblade/common/utils/CommonUtil.java

@@ -1,6 +1,7 @@
 package org.springblade.common.utils;
 
 import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.lang.func.Func;
 import cn.hutool.http.HttpUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
@@ -608,9 +609,9 @@ public class CommonUtil {
         String formatName = "JPEG";
         ByteArrayInputStream bais = new ByteArrayInputStream(imageData);
         BufferedImage originalImage = ImageIO.read(bais);
-        long sizeLimit = 102400; //358KB
-        int width = 1500;
-        int height = 400;
+        long sizeLimit = 512000; //358KB
+        int width = originalImage.getWidth() ;
+        int height = originalImage.getHeight();
         Image scaledImage = originalImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
         BufferedImage resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
         resizedImage.getGraphics().drawImage(scaledImage, 0, 0, null);
@@ -624,11 +625,28 @@ public class CommonUtil {
             return baos.toByteArray();
         }
 
-        float quality = 0.5f; // 初始化压缩质量
+        float quality = 0.7f; // 初始化压缩质量
         int retries = 10; // 最多尝试 10 次
 
         while (baos.size() > sizeLimit && retries > 0) {
             // 压缩图像并重新计算压缩质量
+            bais = new ByteArrayInputStream(imageData);
+            originalImage = ImageIO.read(bais);
+            float width2 = originalImage.getWidth() * quality;
+            float height2 = originalImage.getHeight() * quality;
+             scaledImage = originalImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
+             resizedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+            resizedImage.getGraphics().drawImage(scaledImage, 0, 0, null);
+
+            // 压缩图像
+            baos = new ByteArrayOutputStream();
+            ImageIO.write(resizedImage, formatName, baos);
+
+            if (baos.size() <= sizeLimit) {
+                // 图片大小已经小于等于目标大小,直接返回原始数据
+                return baos.toByteArray();
+            }
+
             byte[] data = baos.toByteArray();
             bais = new ByteArrayInputStream(data);
             BufferedImage compressedImage = ImageIO.read(bais);
@@ -695,15 +713,10 @@ public class CommonUtil {
     }
 
     public static String replaceOssUrl(String url) {
-        String osName = System.getProperty("os.name");
-        if (osName != null && osName.toLowerCase().contains("Cloud Linux")) {
-            // 如果当前操作系统是Linux系统
-            Map<String, String> envMap = System.getenv();
-            if (!envMap.containsKey("linuxtesttest") && url.indexOf("-internal")<0) {
+      /*  if(url.indexOf("-internal")<0 && url.indexOf(".aliyuncs.com")>=0) {
                 // 如果当前环境变量不包含linuxtesttest,则替换URL中的oss路径
-                url = url.replace(".aliyuncs.com", "-internal.aliyuncs.com");
-            }
-        }
+            url = url.replace(".aliyuncs.com", "-internal.aliyuncs.com");
+        }*/
         //本地部署- 甬台温
         if (url.indexOf("183.247.216.148")>=0) {
             // 如果当前环境变量不包含linuxtesttest,则替换URL中的oss路径
@@ -713,6 +726,7 @@ public class CommonUtil {
                 url = url.replace("https://","http://").replace("183.247.216.148","152.168.2.15").replace(":9000//",":9000/");
             }
         }
+        System.out.println("11111"+url);
         return url;
     }
 

+ 1 - 0
blade-ops/blade-resource/src/main/java/org/springblade/resource/builder/oss/OssBuilder.java

@@ -86,6 +86,7 @@ public class OssBuilder {
         Oss oss = getOss(tenantId, code);
         oss.setEndpoint("http://183.247.216.148:9000/");
        //oss.setEndpoint("https://oss-cn-shenzhen.aliyuncs.com/");
+        System.out.println("3333333"+oss.getEndpoint());
         Oss ossCached = ossPool.get(tenantId);
         OssTemplateRe template = templatePool.get(tenantId);
         // 若为空或者不一致,则重新加载

+ 4 - 3
blade-service-api/blade-business-api/src/main/java/org/springblade/business/entity/TaskParallel.java

@@ -67,11 +67,12 @@ public class TaskParallel extends BaseEntity {
      */
     private String taskUserName;
 
-    /**
-     * 主动审批
-     */
+    @ApiModelProperty(value = "是否电签,2是,其他 否")
     private Integer initiative;
 
+    @ApiModelProperty(value = "是否是主动审批,1是,0否")
+    private Integer exeCount;
+
     /**
      * 排序
      */

+ 1 - 1
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TaskApprovalVO.java

@@ -26,7 +26,7 @@ public class TaskApprovalVO {
     @ApiModelProperty("数据源")
     private String formDataId;
 
-    // 1=填报数据(质量填报,试验上报) 2=工程文件 3=日志资料 4=档案数据   5=计量支付证书  6=计量 材料  7= 计量 中间支付  8委托单
+    // 1=填报数据(质量填报,试验上报) 2=工程文件 3=日志资料 4=档案数据   5=计量支付证书  6=计量 材料预付款  7= 计量 中间支付  8委托单
     @ApiModelProperty("上报类型")
     private Integer approvalType;
 

+ 84 - 0
blade-service-api/blade-business-api/src/main/java/org/springblade/business/vo/TaskSignInfoVO.java

@@ -0,0 +1,84 @@
+package org.springblade.business.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class TaskSignInfoVO {
+
+    @ApiModelProperty("id")
+    private String id;
+    /**
+     * 待审批列表中(TaskVO)对应的taskId字段值
+     */
+    @ApiModelProperty("待审批列表中对应的taskId字段值")
+    private String taskId;
+
+    /**
+     * parallelProcessInstanceId字段值
+     */
+    @ApiModelProperty("待审批列表中对应的parallelProcessInstanceId字段值")
+    private String parallelProcessInstanceId;
+
+    @ApiModelProperty("数据源")
+    private String formDataId;
+
+    // 1=填报数据(质量填报,试验上报) 2=工程文件 3=日志资料 4=档案数据   5=计量支付证书  6=计量 材料预付款  7= 计量 中间支付  8委托单
+    @ApiModelProperty("上报类型")
+    private Integer approvalType;
+
+    @ApiModelProperty("同意传OK(大写)")
+    private String flag;
+
+    @ApiModelProperty("同意传OK(大写)")
+    private String comment;
+
+    @ApiModelProperty("用户ID")
+    private Long userId;
+
+    @ApiModelProperty("签字人名")
+    private String nickName;
+
+    @ApiModelProperty("电签类型")
+    private String remarkType;
+
+    @ApiModelProperty("项目Id")
+    private String projectId;
+
+    @ApiModelProperty("合同段Id")
+    private String contractId;
+
+    @ApiModelProperty("签字文件")
+    private String signPdfUrl;
+
+    @ApiModelProperty("电签格式")
+    private String signFormat;
+
+    /**
+     * 获取是否通过
+     */
+    public boolean isPass() {
+        return "OK".equals(flag) || "同意".equals(comment);
+    }
+
+
+    /**
+     * 电签中的对象数据
+     */
+
+    @ApiModelProperty("电签后的PDf")
+    private String lastFilePdfUrl;
+
+    @ApiModelProperty("电签内型 1:个人签字 2:签章")
+    private Integer sigType;
+
+    @ApiModelProperty("电签状态 1:成功 2:失败")
+    private Integer sigState;
+
+    @ApiModelProperty("电签内容")
+    private String signSmg;
+
+}

+ 0 - 26
blade-service-api/blade-e-visa-api/src/main/java/org/springblade/evisa/vo/SigInfoVO.java

@@ -1,26 +0,0 @@
-package org.springblade.evisa.vo;
-
-import lombok.Data;
-
-import java.util.List;
-
-/**
- * @Param   批量电签传参- userSig是自定义的签字编号,code和password是账号密码
- * @Author wangwl
- * @Date 2024/1/18 17:21
- **/
-@Data
-public class SigInfoVO {
-
-    private String pdfUrl;
-    private List<SigInfo> list;
-
-    @Data
-    public static class SigInfo{
-        private String userName;
-        private String userSig;
-        private String sigPic;
-        private String sealCode;
-        private String sealPassword;
-    }
-}

+ 3 - 9
blade-service/blade-business/src/main/java/org/springblade/business/controller/InformationWriteQueryController.java

@@ -1246,16 +1246,10 @@ public class InformationWriteQueryController extends BladeController {
                 }
 
                 //修改试验任务状态为未上报
-                String sql;
-                if (StringUtils.isNotEmpty(primaryKeyId)) {
-                    //单个废除
-                    sql = "update u_trial_self_inspection_record set task_status = '已废除' where id = " + primaryKeyId;
-                } else {
-                    //批量废除直接调的该接口,primaryKeyId为null,ids=当前试验记录的ids
-                    sql = "update u_trial_self_inspection_record set task_status = '已废除' where id in(" + ids + ")";
-                }
-                jdbcTemplate.execute(sql);
 
+                //批量废除直接调的该接口,primaryKeyId为null,ids=当前试验记录的ids
+                 String sql = "update u_trial_self_inspection_record set task_status = '已废除' where id in(" + ids + ")";
+                jdbcTemplate.execute(sql);
                 return R.data(200, aopParamsSet, "废除成功");
 
             } catch (Exception e) {

+ 1 - 0
blade-service/blade-business/src/main/java/org/springblade/business/mapper/TaskParallelMapper.xml

@@ -19,6 +19,7 @@
         <result column="task_user" property="taskUser"/>
         <result column="task_user_name" property="taskUserName"/>
         <result column="initiative" property="initiative"/>
+        <result column="exe_count" property="exeCount"/>
     </resultMap>
 
     <select id="queryApprovalUser" resultMap="taskParallelResultMap">

+ 8 - 2
blade-service/blade-business/src/main/java/org/springblade/business/service/impl/TaskServiceImpl.java

@@ -265,8 +265,14 @@ public class TaskServiceImpl extends BaseServiceImpl<TaskMapper, Task> implement
                     //资料填报原始pdf
 //                    String approvalPdf = StringUtils.isNotEmpty(query.getEVisaPdfUrl()) ? query.getEVisaPdfUrl() : query.getPdfUrl();
                     /** 修改需求,任务查看时,附件不在列表中显示,需要拼接在电签后面。如果此处修改影响其他地方,则到时候再说*/
-                    String approvalPdf = StringUtils.isNotEmpty(query.getEVisaPdfUrl()) ? query.getEVisaPdfUrl() : query.getPdfUrl();
-                    vo.setApprovalFileList(query.getName(), this.getHppsToHttp(approvalPdf));
+                    if(isTask){
+                        String approvalPdf = StringUtils.isNotEmpty(query.getEVisaPdfUrl()) ? query.getEVisaPdfUrl() : query.getPdfUrl();
+                        vo.setApprovalFileList(query.getName(), this.getHppsToHttp(approvalPdf));
+                    }else{
+                        String approvalPdf = StringUtils.isNotEmpty(query.getNodePdfUrl()) ? query.getNodePdfUrl() : query.getEVisaPdfUrl();
+                        String approvalPdf2 = StringUtils.isNotEmpty(approvalPdf) ? approvalPdf : query.getPdfUrl();
+                        vo.setApprovalFileList(query.getName(), this.getHppsToHttp(approvalPdf2));
+                    }
 
                     //试验关联文件合并pdf
                     if (StringUtils.isNotEmpty(query.getPdfTrialUrl())) {

+ 99 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVController.java

@@ -0,0 +1,99 @@
+package org.springblade.evisa.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import io.swagger.annotations.Api;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springblade.business.entity.Task;
+import org.springblade.business.feign.TaskClient;
+import org.springblade.business.vo.TaskApprovalVO;
+import org.springblade.business.vo.TaskSignInfoVO;
+import org.springblade.common.utils.SystemUtils;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.evisa.service.EVDataService;
+import org.springblade.evisa.service.EVisaService;
+import org.springblade.evisa.vo.EVisaTaskApprovalVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.io.FileNotFoundException;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * 清表基础数据表 控制器
+ *
+ * @author BladeX
+ * @since 2022-05-18
+ */
+@RestController
+@AllArgsConstructor
+@Api(value = "电签类", tags = "电签类接口")
+@Slf4j
+public class EVController {
+
+    @Autowired
+    StringRedisTemplate RedisTemplate;
+    // jdbc
+    private final JdbcTemplate jdbcTemplate;
+
+    //电签服务类
+    private final EVDataService evDataService;
+
+    // 线程池
+    @Resource(name = "taskExecutor1")
+    private ThreadPoolExecutor executor;
+
+     @Scheduled(cron = "0/10 * * * * ?")
+    public void SignInfo() {
+        //执行代码
+        log.info("扫描开始");
+        String sql = "SELECT * from u_task_batch where is_deleted=5 and id in(SELECT max(id) as id from u_task_batch where is_deleted=5 GROUP BY JSON_EXTRACT(json_data, '$.formDataId')) LIMIT 10 ";
+        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
+        if (maps != null && maps.size() >= 1 ) {
+            for (Map<String, Object> dataInfo : maps) {
+                if (executor.getQueue().size()<=40 ) {
+                    String jsonData = dataInfo.get("json_data") + "";
+                    String signFormat = dataInfo.get("sign_format") + "";
+                    TaskSignInfoVO taskSignInfoVO = JSON.parseObject(jsonData, TaskSignInfoVO.class);
+                    String taskBatchId = dataInfo.get("id").toString();
+                    Long userId = Long.valueOf(dataInfo.get("create_user") + "");
+                    String nickName = dataInfo.get("nick_name") + "";
+                    Boolean aBoolean = RedisTemplate.hasKey("sign-" + taskSignInfoVO.getFormDataId());
+                    taskSignInfoVO.setId(taskBatchId);
+                    taskSignInfoVO.setUserId(userId);
+                    taskSignInfoVO.setNickName(nickName);
+                    taskSignInfoVO.setSignFormat(signFormat);
+                    if (!aBoolean) {
+                        RedisTemplate.opsForValue().set("sign-" + taskSignInfoVO.getFormDataId(), "1",1800, TimeUnit.SECONDS);
+                        CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
+                            try {
+                                /*===============执行批量任务===============*/
+                                evDataService.signTaskBatch(taskSignInfoVO);
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            }
+                        }, executor);
+                    }
+                }
+            }
+        }
+
+        System.out.println("队列数量" + executor.getQueue().size());
+        System.out.println("活跃数量" + executor.getActiveCount());
+        System.out.println("总共数量" + executor.getTaskCount());
+        System.out.println("完成数量" + executor.getCompletedTaskCount());
+    }
+}

+ 3 - 10
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVisaController.java

@@ -61,14 +61,11 @@ public class EVisaController {
 
     // 电签主类
 
-    @Scheduled(cron = "0/30 * * * * ?")
+   // @Scheduled(cron = "0/10 * * * * ?")
     public void SignInfo() {
         //执行代码
-
         log.info("扫描开始");
-       // String sql = "SELECT * from u_task_batch where json_data like '%1840658122872455168%' a
-        // nd is_deleted<>5  LIMIT 10";
-        String sql = "SELECT * from u_task_batch where is_deleted=0 and id in(SELECT max(id) as id from u_task_batch where is_deleted=0 GROUP BY JSON_EXTRACT(json_data, '$.formDataId')) LIMIT 10 ";
+        String sql = "SELECT * from u_task_batch where is_deleted=0 and JSON_EXTRACT(json_data, '$.taskId')=1858792664296587264 and id in(SELECT max(id) as id from u_task_batch where is_deleted=0 GROUP BY JSON_EXTRACT(json_data, '$.formDataId')) LIMIT 10 ";
         //String sql = "SELECT * from u_task_batch where is_deleted=5 and `status`=2";
         List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
         if (maps != null && maps.size() >= 1 && SystemUtils.isLinux()) {//&& SystemUtils.isLinux()
@@ -85,7 +82,7 @@ public class EVisaController {
                     taskApprovalVO.setNickName(nickName);
 
                     if (!aBoolean) {
-                        RedisTemplate.opsForValue().set("sign-" + taskApprovalVO.getFormDataId(), "1",1800, TimeUnit.SECONDS);
+                        RedisTemplate.opsForValue().set("sign-" + taskApprovalVO.getFormDataId(), "1",900, TimeUnit.SECONDS);
                         CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
                             try {
                                 /*===============执行批量任务===============*/
@@ -112,7 +109,6 @@ public class EVisaController {
 
             if (eVisaStatus == null || StringUtils.isEmpty(eVisaStatus)) {
                 //状态改为 == 4 --
-
             } else if ("notpdfsgin".equals(eVisaStatus) || eVisaStatus.contains("notpdfsgin")) { //没有找到关键字Id
                //状态改为 == 4 --
                 String up_task = "update u_task_batch set is_deleted=5 where id="+taskApprovalVO.getId();
@@ -178,9 +174,7 @@ public class EVisaController {
                     }
                 }
             }else if("eContractError".equals(eVisaStatus) || eVisaStatus.contains("eContractError")){ //合同段信息出错
-
                 this.jdbcTemplate.execute("delete from u_task_batch where id="+taskApprovalVO.getId());
-
             }else if ("eVisaError".equals(eVisaStatus) || eVisaStatus.contains("eVisaError")) {
                 // 修改 主 任务 u_task 表 状态改为3
                 String up_task_par = "update u_task_parallel set status=2 ,e_visa_status=99 ,e_visa_content='"+eVisaStatus.split("####")[1]+"' where parallel_process_instance_id='"+taskApprovalVO.getParallelProcessInstanceId()+"'";
@@ -206,7 +200,6 @@ public class EVisaController {
                 jdbcTemplate.execute("update u_information_query set e_visa_pdf_url='',status=0 where id='"+taskApprovalVO.getFormDataId()+"'");
             }
             RedisTemplate.delete("sign-" + taskApprovalVO.getFormDataId());
-
         }
     }
 

+ 54 - 23
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/controller/EVisaJLController.java

@@ -1,16 +1,15 @@
 package org.springblade.evisa.controller;
 
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
 import io.swagger.annotations.Api;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang.StringUtils;
-import org.springblade.business.entity.Task;
 import org.springblade.business.feign.TaskClient;
 import org.springblade.business.vo.TaskApprovalVO;
+import org.springblade.common.utils.CommonUtil;
 import org.springblade.evisa.service.EVisaService;
-import org.springblade.evisa.vo.EVisaTaskApprovalVO;
+import org.springblade.evisa.utils.FileUtils;
+import org.springblade.evisa.utils.PdfAddimgUtil;
+import org.springblade.manager.vo.PDFIndexInfo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -20,12 +19,13 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
-import java.io.FileNotFoundException;
+import java.io.InputStream;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
 
 
 /**
@@ -43,7 +43,6 @@ public class EVisaJLController {
 
     @Autowired
     StringRedisTemplate RedisTemplate;
-
     // jdbc
     private final JdbcTemplate jdbcTemplate;
 
@@ -54,30 +53,32 @@ public class EVisaJLController {
     @Resource(name = "taskExecutor1")
     private ThreadPoolExecutor executor;
 
-    private final TaskClient taskClient;
-
     // 电签主类
+    //@Scheduled(cron = "0/10 * * * * ?")
     public void SignInfo() {
         //执行代码
-
         log.info("扫描开始");
-        String sql = "SELECT * from u_task_batch where is_deleted=0 and id in(SELECT max(id) as id from u_task_batch where is_deleted=0 GROUP BY JSON_EXTRACT(json_data, '$.formDataId')) LIMIT 10 ";
+       // String sql = "SELECT a.* from u_information_query a where a.wbs_id in(SELECT p_key_id from m_wbs_tree_contract where project_id=1630011899725201410) and a.business_time is null and (a.pdf_url is not null or e_visa_pdf_url is not null) and `status` in(1,2) and is_deleted=0 limit 100";
+        String sql = "SELECT * FROM u_archive_file where project_id=1630011899725201410 and LENGTH(file_time)<=0 and is_deleted<>2  limit 100";
         List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
         if (maps != null && maps.size() >= 1 ) {//&& SystemUtils.isLinux()
             for (Map<String, Object> dataInfo : maps) {
-                if (executor.getQueue().size()<=40 ) {
-                    String jsonData = dataInfo.get("json_data") + "";
-                    TaskApprovalVO taskApprovalVO = JSON.parseObject(jsonData, TaskApprovalVO.class);
-                    String taskBatchId = dataInfo.get("id").toString();
-                    Long userId = Long.valueOf(dataInfo.get("create_user") + "");
-                    String nickName = dataInfo.get("nick_name") + "";
-                    Boolean aBoolean = RedisTemplate.hasKey("sign-" + taskApprovalVO.getFormDataId());
-                    taskApprovalVO.setId(taskBatchId);
-                    taskApprovalVO.setUserId(userId);
-                    taskApprovalVO.setNickName(nickName);
+                if (executor.getQueue().size()<=100 ) {
+
+
+                    TaskApprovalVO taskApprovalVO = new TaskApprovalVO();
+
+                    String id = dataInfo.get("id") + "";
+                    String pdfUrl = dataInfo.get("pdf_file_url") + "";
+                    String eVisaPdfUrl = dataInfo.get("e_visa_pdf_url") + "";
+
+                    Boolean aBoolean = RedisTemplate.hasKey("sign-" + id);
+                    taskApprovalVO.setId(id);
+                    taskApprovalVO.setComment(pdfUrl);
+                    taskApprovalVO.setNickName(eVisaPdfUrl);
 
                     if (!aBoolean) {
-                        RedisTemplate.opsForValue().set("sign-" + taskApprovalVO.getFormDataId(), "1",1800, TimeUnit.SECONDS);
+                        RedisTemplate.opsForValue().set("sign-" + taskApprovalVO.getId(), "1",100, TimeUnit.SECONDS);
                         CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
                             try {
                                 /*===============执行批量任务===============*/
@@ -97,8 +98,38 @@ public class EVisaJLController {
     }
 
     @Transactional
-    public void checkIsExsitTaskBatch(TaskApprovalVO taskApprovalVO){
+    public void checkIsExsitTaskBatch(TaskApprovalVO task) throws Exception {
+
+        String pdfUrl = task.getComment();
+        InputStream inputStream = FileUtils.getInputStreamByUrl(pdfUrl);
+        //转换
+        byte[] bytes = CommonUtil.InputStreamToBytes(inputStream);
+        List<PDFIndexInfo> allwordPostions = PdfAddimgUtil.findAllwordPostions(bytes);
+        PDFIndexInfo pdfIndex = allwordPostions.get(0);
+        String context = pdfIndex.getPkeyid();
+        String regex = "\\d{4}年\\d{2}月\\d{2}日";
+
+        char[] data = context.toCharArray();
+        for(int i=0;i<data.length;i++) {
+            String dataChar = data[i]+"";
+            if(dataChar.equals("日")){
+                String date = context.substring(i-15,i+1).trim();
+                if(date.indexOf("年")>=0 && date.indexOf("月")>=0 && date.indexOf("日")>=0 ){
+                    String data2 =date.substring(date.indexOf("年")-4,date.length());
+
+                    if(Pattern.matches(regex, data2)){
+                        // 判断字符串是否匹配日期格式
+                        System.out.println(data2);
+                        jdbcTemplate.execute("UPDATE u_archive_file set file_time='"+data2+"',is_deleted=2 where id='"+task.getId()+"'");
+                        return;
+                    }
+                }
+            }
+        }
+
+        jdbcTemplate.execute("UPDATE u_archive_file set is_deleted=2 where id='"+task.getId()+"'");
 
+        RedisTemplate.delete("sign-" + task.getId());
     }
 
 }

+ 16 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/EVDataService.java

@@ -0,0 +1,16 @@
+package org.springblade.evisa.service;
+
+import cfca.paperless.dto.bean.CertBean;
+import org.springblade.business.vo.TaskApprovalVO;
+import org.springblade.business.vo.TaskSignInfoVO;
+import org.springblade.core.tool.api.R;
+import org.springblade.evisa.vo.EVisaMakeSealVO;
+import org.springblade.evisa.vo.EVisaTaskApprovalVO;
+import org.springblade.evisa.vo.SealPdfVO;
+
+import java.util.List;
+
+public interface EVDataService {
+
+   void signTaskBatch(TaskSignInfoVO taskSignInfoVO);
+}

+ 6 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/EVisaService.java

@@ -6,6 +6,7 @@ import org.springblade.evisa.vo.EVisaMakeSealVO;
 import org.springblade.evisa.vo.EVisaTaskApprovalVO;
 import org.springblade.evisa.vo.SealPdfVO;
 
+import java.util.HashMap;
 import java.util.List;
 
 public interface EVisaService {
@@ -45,4 +46,9 @@ public interface EVisaService {
      */
     R<String> batchEVisa(SealPdfVO pdfVO);
 
+    Object[] signPdfByAXQZ(SealPdfVO pdfVO, byte[] fileByte);
+
+    Object[] signPdfByAXQZ(SealPdfVO pdfVO, String loPdfurl,String outPdfUrl);
+
+    String signPdfByDFZX(HashMap<String, Object> daMa);
 }

+ 529 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVDataServiceImpl.java

@@ -0,0 +1,529 @@
+package org.springblade.evisa.service.impl;
+
+
+import cfca.paperless.base.util.Base64;
+
+
+import cn.hutool.core.io.file.FileReader;
+import lombok.AllArgsConstructor;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.springblade.business.feign.TaskClient;
+import org.springblade.business.vo.TaskSignInfoVO;
+import org.springblade.common.constant.EVisaConstant;
+import org.springblade.common.utils.CommonUtil;
+import org.springblade.common.utils.SnowFlakeUtil;
+import org.springblade.core.oss.model.BladeFile;
+import org.springblade.core.tool.utils.DateUtil;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.evisa.service.EVDataService;
+import org.springblade.evisa.service.EVisaService;
+import org.springblade.evisa.utils.FileUtils;
+import org.springblade.evisa.utils.PDFUtils;
+import org.springblade.evisa.utils.SignFtpUtil;
+import org.springblade.evisa.vo.*;
+import org.springblade.manager.entity.ProjectInfo;
+import org.springblade.manager.feign.ProjectClient;
+import org.springblade.resource.feign.NewIOSSClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.*;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+@AllArgsConstructor
+public class EVDataServiceImpl implements EVDataService {
+
+    //jdbc对象
+    private final JdbcTemplate jdbcTemplate;
+    private final ProjectClient projectClient;
+    private final TaskClient taskClient;
+    private final NewIOSSClient newIOSSClient;
+    //电签服务类
+    private final EVisaService eVisaService;
+
+    @Autowired
+    StringRedisTemplate RedisTemplate;
+
+    /**
+     * 电签主要流程
+     *
+     * @param taskApp
+     */
+    @Override
+    public void signTaskBatch(TaskSignInfoVO taskApp) {
+        //获取pdf 文件
+        this.getSignPdfInfo(taskApp);
+        if (taskApp.getSigState() != 1) {
+            return;
+        }
+
+        String fileUrl = CommonUtil.replaceOssUrl(taskApp.getSignPdfUrl());
+        List<String> eVisaConfigList = PDFUtils.getPdfSignIds(fileUrl);
+        String ids = String.join(",", eVisaConfigList);
+        if (taskApp.getRemarkType().equals("1")) { //安心签
+            //添加电签策略
+            List<SealStrategyVO> strategyListByAXQ = getStrategyListByAXQ(taskApp, ids);
+            if (taskApp.getSigState() != 1) {
+                return;
+            }
+            //调用签字逻辑
+            signTaskBatchByAXQZ(strategyListByAXQ, taskApp);
+            if (taskApp.getSigState() != 1) {
+                return;
+            }
+            // 回归处理
+            SignBackPdfInfo(taskApp);
+            if (taskApp.getSigState() != 1) {
+                return;
+            }
+        } else if (taskApp.getRemarkType().equals("2")) { //东方中讯
+            //添加电签策略
+            List<Map<String, Object>> strategyListByDFZX = getStrategyListByDFZX(taskApp, ids);
+            //调用签字逻辑
+            signTaskBatchByDFZX(strategyListByDFZX, fileUrl);
+            // 回归处理
+            SignBackPdfInfo(taskApp);
+        }
+
+        // 判断签章信息
+        String sql = "SELECT a.* from u_task_parallel a where a.process_instance_id=(SELECT process_instance_id from u_task_parallel b where  b.parallel_process_instance_id='" + taskApp.getParallelProcessInstanceId() + "') and is_deleted=0 and initiative<>2 ";
+        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
+        if (maps == null || maps.size() == 0) {
+            taskApp.setSigType(2);
+            if (taskApp.getRemarkType().equals("1")) { //安心签
+                //添加电签策略
+                List<SealStrategyVO> strategyListByAXQ = getStrategyListByAXQ(taskApp, ids);
+                //调用签字逻辑
+                signTaskBatchByAXQZ(strategyListByAXQ, taskApp);
+                // 回归处理
+                SignBackPdfInfo(taskApp);
+
+            } else if (taskApp.getRemarkType().equals("2")) { //东方中讯
+                //添加电签策略
+                List<Map<String, Object>> strategyListByDFZX = getStrategyListByDFZX(taskApp, ids);
+                //调用签字逻辑
+                signTaskBatchByDFZX(strategyListByDFZX, fileUrl);
+                // 回归处理
+                SignBackPdfInfo(taskApp);
+            }
+        }
+    }
+
+    // 获取pdf 文件
+    @Transactional
+    public void SignBackPdfInfo(TaskSignInfoVO taskApp) {
+        Integer totalCount= this.jdbcTemplate.queryForObject("select exe_count from u_task_parallel where parallel_process_instance_id='" + taskApp.getParallelProcessInstanceId() + "'",Integer.class);
+        //上报类型: 1填报资料,2工程文件,3日志资料
+        //档案:4档案数据 ,
+        //计量: 5中间计量申请,6材料计量单 ,7开工预付款计量单, 8变更令
+        try {
+            if (taskApp.getApprovalType() == 1) {
+                if (taskApp.getSigType() == 2) {
+                    this.jdbcTemplate.execute("update u_information_query set e_visa_pdf_url='" + taskApp.getLastFilePdfUrl() + "',status=2,update_time=SYSDATE() where id='" + taskApp.getFormDataId() + "' ");
+                    this.jdbcTemplate.execute("update u_task set status=2,update_time=SYSDATE() where id=" + taskApp.getId());
+                } else {
+                    this.jdbcTemplate.execute("update u_information_query set e_visa_pdf_url='" + taskApp.getLastFilePdfUrl() + "', update_time=SYSDATE() where id='" + taskApp.getFormDataId() + "'");
+                    this.jdbcTemplate.execute("update u_task_parallel set status=2,initiative=2 ,update_time=SYSDATE() where parallel_process_instance_id='" + taskApp.getParallelProcessInstanceId() + "'");
+                    this.jdbcTemplate.execute("delete from u_task_batch where id=" + taskApp.getId());
+                    RedisTemplate.delete("sign-" + taskApp.getFormDataId());
+                }
+
+            } else if (taskApp.getApprovalType() == 2) {
+
+            } else if (taskApp.getApprovalType() == 3) {
+
+            } else if (taskApp.getApprovalType() == 4) {
+
+            } else if (taskApp.getApprovalType() == 5) {
+                if (taskApp.getSigState() == 1) { //成功
+                    this.jdbcTemplate.execute("update s_interim_pay_certificate set approve_status=" + taskApp.getSigType() + ",update_time=SYSDATE(), raw_url='" + taskApp.getLastFilePdfUrl() + "' where contract_period_id = " + taskApp.getFormDataId());
+                    this.jdbcTemplate.execute("update u_task_parallel set e_visa_status=1,e_visa_content='" + taskApp.getSignSmg() + "' , status=2 , initiative=2 ,update_time=SYSDATE() where parallel_process_instance_id='" + taskApp.getParallelProcessInstanceId() + "'");
+                    this.jdbcTemplate.execute("update u_task set status=" + taskApp.getSigType() + " ,update_time=SYSDATE() where id='" + taskApp.getTaskId() + "'");
+                    this.jdbcTemplate.execute("delete from u_task_batch where id=" + taskApp.getId());
+                } else {
+                    this.jdbcTemplate.execute("update s_interim_pay_certificate set approve_status=1,update_time=SYSDATE() where contract_period_id = " + taskApp.getFormDataId());
+                    this.jdbcTemplate.execute("update u_task_parallel set exe_count=(exe_count+1), e_visa_status=99,e_visa_content='" + taskApp.getSignSmg() + "' ,update_time=SYSDATE() where parallel_process_instance_id='" + taskApp.getParallelProcessInstanceId() + "'");
+                    this.jdbcTemplate.execute("update u_task set status=1 ,update_time=SYSDATE() where id='" + taskApp.getTaskId() + "'");
+                    if(totalCount>=3){
+                        this.jdbcTemplate.execute("delete from u_task_batch where id=" + taskApp.getId());
+                    }
+                }
+                RedisTemplate.delete("sign-" + taskApp.getFormDataId());
+            } else if (taskApp.getApprovalType() == 6 || taskApp.getApprovalType() == 7) {
+                this.jdbcTemplate.execute("update s_material_start_statement set raw_url='" + taskApp.getLastFilePdfUrl() + "' where meter_period_id = " + taskApp.getFormDataId());
+                this.jdbcTemplate.execute("delete from u_task_batch where id=" + taskApp.getId());
+                RedisTemplate.delete("sign-" + taskApp.getFormDataId());
+            } else if (taskApp.getApprovalType() == 8) {
+                if (taskApp.getSigType() == 2) {
+                    this.jdbcTemplate.execute("update u_entrust_info set sample_status=2,status=" + (taskApp.getSigType() + 1) + ",entrust_e_pdf='" + taskApp.getLastFilePdfUrl() + "' where id=(SELECT wbs_id from u_information_query where id='" + taskApp.getFormDataId() + "')");
+                }
+                jdbcTemplate.execute("update u_information_query set e_visa_pdf_url='" + taskApp.getLastFilePdfUrl() + "',status=" + taskApp.getSigType() + " where id='" + taskApp.getFormDataId() + "'");
+                this.jdbcTemplate.execute("delete from u_task_batch where id=" + taskApp.getId());
+                RedisTemplate.delete("sign-" + taskApp.getFormDataId());
+            }
+        } catch (Exception e) {
+            taskApp.setSigState(2);
+            taskApp.setSignSmg("修改业务数据异常-请联系开发人员");
+            SignBackPdfInfo(taskApp);
+            e.printStackTrace();
+        }
+    }
+
+
+    // 获取pdf 文件
+    public void getSignPdfInfo(TaskSignInfoVO taskApp) {
+        //上报类型: 1填报资料,2工程文件,3日志资料
+        //档案:4档案数据 ,
+        //计量: 5中间计量申请,6材料计量单 ,7开工预付款计量单, 8变更令
+        taskApp.setSigType(1);
+        taskApp.setSigState(1);
+        Map<String, Object> map = new HashMap<>();
+        try {
+            if (taskApp.getApprovalType() == 1) {
+                map = this.jdbcTemplate.queryForMap("select * from u_information_query where  is_deleted=0 and id = " + taskApp.getFormDataId());
+                String url = StringUtils.isNotEmpty(map.get("e_visa_pdf_url") + "") ? map.get("e_visa_pdf_url") + "" : map.get("pdf_url") + "";
+                taskApp.setSignPdfUrl(url);
+                taskApp.setContractId(map.get("contract_id") + "");
+                taskApp.setProjectId(map.get("project_id") + "");
+            } else if (taskApp.getApprovalType() == 2) {
+                map = this.jdbcTemplate.queryForMap("select * from u_information_query where  is_deleted=0 and id = " + taskApp.getFormDataId());
+                String url = StringUtils.isNotEmpty(map.get("e_visa_pdf_url") + "") ? map.get("e_visa_pdf_url") + "" : map.get("pdf_url") + "";
+                taskApp.setSignPdfUrl(url);
+                taskApp.setContractId(map.get("contract_id") + "");
+                taskApp.setProjectId(map.get("project_id") + "");
+            } else if (taskApp.getApprovalType() == 3) {
+                map = this.jdbcTemplate.queryForMap("select * from u_information_query where  is_deleted=0 and id = " + taskApp.getFormDataId());
+                String url = StringUtils.isNotEmpty(map.get("e_visa_pdf_url") + "") ? map.get("e_visa_pdf_url") + "" : map.get("pdf_url") + "";
+                taskApp.setSignPdfUrl(url);
+                taskApp.setContractId(map.get("contract_id") + "");
+                taskApp.setProjectId(map.get("project_id") + "");
+            } else if (taskApp.getApprovalType() == 4) {
+
+            } else if (taskApp.getApprovalType() == 5) {
+                map = this.jdbcTemplate.queryForMap("select * from s_interim_pay_certificate where  is_deleted=0 and contract_period_id = " + taskApp.getFormDataId());
+                taskApp.setSignPdfUrl(map.get("raw_url") + "");
+                taskApp.setContractId(map.get("contract_id") + "");
+                taskApp.setProjectId(map.get("project_id") + "");
+            } else if (taskApp.getApprovalType() == 6 || taskApp.getApprovalType() == 7) {
+                map = this.jdbcTemplate.queryForMap("select * from  s_material_start_statement where is_deleted=0 and meter_period_id = " + taskApp.getFormDataId());
+                taskApp.setSignPdfUrl(map.get("raw_url") + "");
+                taskApp.setContractId(map.get("contract_id") + "");
+                taskApp.setProjectId(map.get("project_id") + "");
+            } else if (taskApp.getApprovalType() == 8) {
+
+            }
+
+            if (taskApp.getSignPdfUrl() == null || taskApp.getSignPdfUrl() == "" || Func.isEmpty(taskApp.getSignPdfUrl()) || taskApp.getSignPdfUrl().length() <= 10) {
+                taskApp.setSigState(2);
+                taskApp.setSignSmg("未获取到PDF信息");
+                SignBackPdfInfo(taskApp);
+                return;
+            }
+            if (taskApp.getContractId() == null || taskApp.getContractId() == "" || Func.isEmpty(taskApp.getContractId()) || taskApp.getContractId().length() <= 10) {
+                taskApp.setSigState(2);
+                taskApp.setSignSmg("未获取到合同段Id");
+                SignBackPdfInfo(taskApp);
+                return;
+            }
+            if (taskApp.getProjectId() == null || taskApp.getProjectId() == "" || Func.isEmpty(taskApp.getProjectId()) || taskApp.getProjectId().length() <= 10) {
+                taskApp.setSigState(2);
+                taskApp.setSignSmg("未获取项目Id");
+                SignBackPdfInfo(taskApp);
+                return;
+            }
+            ProjectInfo projectInfo = projectClient.getById(taskApp.getProjectId());
+            if (projectInfo == null || Func.isEmpty(projectInfo)) {
+                taskApp.setSigState(2);
+                taskApp.setSignSmg("未获取项目信息");
+                SignBackPdfInfo(taskApp);
+                return;
+            } else {
+                Integer remarkType = projectInfo.getRemarkType();
+                if (remarkType != null && Func.isNotEmpty(remarkType) && remarkType == 2) {
+                    taskApp.setRemarkType("2");
+                } else {
+                    taskApp.setRemarkType("1");
+                }
+            }
+        } catch (Exception e) {
+            taskApp.setSigState(2);
+            taskApp.setSignSmg("获取pdf信息异常");
+            SignBackPdfInfo(taskApp);
+            return;
+        }
+    }
+
+    // 添加电签策略 -- 安心签
+    public List<Map<String, Object>> getStrategyListByDFZX(TaskSignInfoVO task, String ids) {
+
+        String sqlinfo = "SELECT * from ( SELECT DISTINCT a.id,a.pyzbx ,a.pyzby,a.project_id,(SELECT signature_file_url from m_sign_pfx_file where is_register=1 and certificate_user_id='" + task.getUserId() + "' and is_deleted=0  ) as signature_file_url from m_textdict_info a where  a.type =2 and a.id in (" + ids + ")  and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + task.getContractId() + " and user_id=" + task.getUserId() + " and c.is_deleted=0 ) ) x where x.signature_file_url is not null ";
+        if (task.getSigType() == 2) {
+            sqlinfo = "SELECT a.id,a.pyzbx,a.pyzby,b.signature_file_url,b.id as sfId,a.project_id,b.certificate_password,b.certificate_user_name,b.certificate_number from m_textdict_info a ,m_sign_pfx_file b where a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + task.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + ids + ")";
+        }
+
+        List<Map<String, Object>> maps2 = jdbcTemplate.queryForList(sqlinfo);
+        List<Map<String, Object>> maps = new ArrayList<>();
+        Map<String, List<Map<String, Object>>> peopleByAge = maps2.stream()
+                .collect(Collectors.groupingBy(hada -> (Func.toStr(hada.get("id")))));
+
+        for (String keyId : peopleByAge.keySet()) {
+            int exId = 0;
+            List<Map<String, Object>> keyList = peopleByAge.get(keyId);
+            if (keyList != null && keyList.size() == 1) {
+                maps.addAll(keyList);
+                exId = 1;
+            } else if (keyList != null && keyList.size() >= 2) {
+                for (Map<String, Object> datax : keyList) {
+                    if ((datax.get("project_id") + "").equals(task.getProjectId())) {
+                        maps.add(datax);
+                        exId = 1;
+                    }
+                }
+            }
+            if (exId == 0) {
+                maps.add(keyList.get(0));
+            }
+        }
+        return maps;
+    }
+
+    // 添加电签策略 -- 安心签
+    public List<SealStrategyVO> getStrategyListByAXQ(TaskSignInfoVO task, String ids) {
+        List<SealStrategyVO> sealStrategyVOS = new ArrayList<>();
+        String sqlinfo = "SELECT * from ( SELECT DISTINCT a.id,a.pyzbx ,a.pyzby,a.project_id,(SELECT signature_file_url from m_sign_pfx_file where is_register=1 and certificate_user_id='" + task.getUserId() + "' and is_deleted=0  ) as signature_file_url from m_textdict_info a where  a.type =2 and a.id in (" + ids + ") and sig_role_id in (SELECT DISTINCT c.role_id from m_project_assignment_user c  where c.contract_id=" + task.getContractId() + " and user_id=" + task.getUserId() + " and c.is_deleted=0 ) ) x where x.signature_file_url is not null ";
+        if (task.getSigType() == 2) {
+            sqlinfo = "SELECT a.id,a.pyzbx,a.pyzby,b.signature_file_url,b.id as sfId,a.project_id,b.certificate_password,b.certificate_user_name,b.certificate_number from m_textdict_info a ,m_sign_pfx_file b where a.sig_role_id = b.pfx_type and b.project_contract_role like '%" + task.getContractId() + "%' and a.is_deleted=0 and b.is_deleted=0 and a.type=6 and a.id in(" + ids + ")";
+        }
+
+        List<Map<String, Object>> maps2 = jdbcTemplate.queryForList(sqlinfo);
+        if (maps2 == null && maps2.size() <= 0) {
+            task.setSigState(2);
+            task.setSignSmg("未查询到电签策略");
+            SignBackPdfInfo(task);
+            return sealStrategyVOS;
+        }
+
+
+        List<Map<String, Object>> maps = new ArrayList<>();
+        Map<String, List<Map<String, Object>>> peopleByAge = maps2.stream()
+                .collect(Collectors.groupingBy(hada -> (Func.toStr(hada.get("id")))));
+
+        for (String keyId : peopleByAge.keySet()) {
+            int exId = 0;
+            List<Map<String, Object>> keyList = peopleByAge.get(keyId);
+            if (keyList != null && keyList.size() == 1) {
+                maps.addAll(keyList);
+                exId = 1;
+            } else if (keyList != null && keyList.size() >= 2) {
+                for (Map<String, Object> datax : keyList) {
+                    if ((datax.get("project_id") + "").equals(task.getProjectId())) {
+                        maps.add(datax);
+                        exId = 1;
+                    }
+                }
+            }
+            if (exId == 0) {
+                maps.add(keyList.get(0));
+            }
+        }
+
+        if (maps == null || maps.size() <= 0) {
+            task.setSigState(2);
+            task.setSignSmg("没有签字体的数据");
+            SignBackPdfInfo(task);
+            return sealStrategyVOS;
+        }
+        //准备签章策略
+
+        for (Map<String, Object> eVisaConfig : maps) {
+            //设置签章策略
+            SealStrategyVO vo = new SealStrategyVO();
+            if (task.getSigType() == 1) {
+                String userId = task.getUserId() + "";
+                vo.setSealCode(EVisaConstant.SIGN_SEAL_CODE + userId);
+                if (userId.length() <= EVisaConstant.USER_ID_SUB) {
+                    vo.setSealPassword(task.getUserId().toString());
+                } else {
+                    vo.setSealPassword(task.getUserId().toString().substring(0, EVisaConstant.USER_ID_SUB));
+                }
+                vo.setSealPerson(task.getNickName());
+                //设置签字文件
+                vo.setImageUrl(eVisaConfig.get("signature_file_url") + "");
+                vo.setSealType("3");
+                vo.setKeyword(eVisaConfig.get("id") + "");
+                vo.setOffSetX(eVisaConfig.get("pyzbx") + "");
+                vo.setOffSetY(eVisaConfig.get("pyzby") + "");
+            } else if (task.getSigType() == 2) {
+                vo.setSealCode(EVisaConstant.SIGN_SEAL_CODE + eVisaConfig.get("sfId"));
+                vo.setSealPassword(eVisaConfig.get("certificate_password") + "");
+                vo.setSealPerson(eVisaConfig.get("certificate_user_name") + "" + System.currentTimeMillis());
+                //设置签字文件
+                vo.setImageUrl(eVisaConfig.get("signature_file_url") + "");
+                vo.setSealType("3");
+                vo.setCompanySeal(true);
+                vo.setKeyword(eVisaConfig.get("id") + "");
+                vo.setOffSetX(eVisaConfig.get("pyzbx") + "");
+                vo.setOffSetY(eVisaConfig.get("pyzby") + "");
+            }
+            sealStrategyVOS.add(vo);
+        }
+        return sealStrategyVOS;
+    }
+
+    // 添加电签策略 -- 东方中讯
+    public String signTaskBatchByDFZX(List<Map<String, Object>> maps, String pdfUrl) {
+        if (maps != null && maps.size() > 0) {
+            String fileUrl = pdfUrl;
+            for (Map<String, Object> dataMap : maps) {
+                HashMap<String, Object> daMa = new HashMap<>();
+                daMa.put("keyWord", dataMap.get("keyWord"));
+                daMa.put("sealId", dataMap.get("sealId"));
+                // 设置图片显示大小
+                daMa.put("showHeight", 30);
+                daMa.put("showWidth", 60);
+                //设置显示签字体的位置
+                String yzx = dataMap.get("pyzby") + "";
+                String xzx = dataMap.get("pyzbx") + "";
+                Double sealOffsetY = Func.toDouble(yzx) - 15;
+                Double sealOffsetX = Func.toDouble(xzx) - 30;
+                daMa.put("sealOffsetX", sealOffsetX);
+                daMa.put("sealOffsetY", sealOffsetY);
+                byte[] fileByte = new byte[0];
+                if (fileUrl.indexOf("aliyuncs.com") >= 0 || fileUrl.indexOf("183.247.216.148") >= 0 || fileUrl.indexOf("152.168.2.15") >= 0) {
+                    try {
+                        InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(pdfUrl);
+                        fileByte = IOUtils.toByteArray(inputStreamByUrl);
+                    } catch (Exception e) {
+                        System.out.println("123");
+                    }
+                } else {
+                    FileReader fileReader = new FileReader(fileUrl);
+                    fileByte = fileReader.readBytes();
+                }
+
+                try {
+                    String originalFileB64 = Base64.toBase64String(fileByte);
+                    daMa.put("fileB64", originalFileB64);
+                    daMa.put("lastSignFlag", false);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+                String reData = eVisaService.signPdfByDFZX(daMa);
+                if (reData.indexOf("success@") >= 0) {
+                    fileUrl = reData.split("@@@@")[1];
+                } else {
+                    return reData;
+                }
+            }
+            if (fileUrl.indexOf("aliyuncs.com") >= 0) {
+                System.out.println("电签失败");
+            } else {
+                BladeFile bladeFile = this.newIOSSClient.uploadFile(fileUrl.substring(fileUrl.lastIndexOf("/") + 1, fileUrl.length()), fileUrl);
+                if (bladeFile != null) {
+                    System.out.println("pdf上传=" + bladeFile.getLink());
+                    return "sucess@@@@" + bladeFile.getLink();
+                } else {
+                    return "电签成功";
+                }
+            }
+        } else {
+            return "sucess@@@@" + pdfUrl;
+        }
+        return "sucess@@@@" + pdfUrl;
+    }
+
+    // 安心签 - 关键字策略
+    public void signTaskBatchByAXQZ(List<SealStrategyVO> list, TaskSignInfoVO taskApp) {
+        String pdfUrl = taskApp.getSignPdfUrl();
+        if (Func.isEmpty(pdfUrl) || list == null) {
+            taskApp.setLastFilePdfUrl(pdfUrl);
+        }
+        String sysLocalFileUrl = FileUtils.getSysLocalFileUrl();
+        String filecode = SnowFlakeUtil.getId() + "";
+        String dataFileUrl = sysLocalFileUrl + "/pdf/" + filecode + ".pdf";
+
+        SealPdfVO pdfVO = new SealPdfVO();
+        pdfVO.setStrategyVoList(list);
+        byte[] fileByte;
+        if (pdfUrl.indexOf("aliyuncs.com") >= 0 || pdfUrl.indexOf("183.247.216.148") >= 0 || pdfUrl.indexOf("152.168.2.15") >= 0) {
+            try {
+                InputStream inputStreamByUrl = CommonUtil.getOSSInputStreamTow(pdfUrl);
+                fileByte = IOUtils.toByteArray(inputStreamByUrl);
+            } catch (Exception e) {
+                taskApp.setSigState(2);
+                taskApp.setSignSmg("获取PDF字符流失败");
+                SignBackPdfInfo(taskApp);
+                return;
+            }
+        } else {
+            FileReader fileReader = new FileReader(pdfUrl);
+            fileByte = fileReader.readBytes();
+        }
+
+        Object[] result = null;
+        String fileUrl = pdfUrl;
+        if (list.size() >= 15 || fileByte.length > 10 * 1000 * 1000) {
+            String inUrl = "/inp/" + DateUtil.today();
+            String outUrl = "/out/" + DateUtil.today();
+            SignFtpUtil.FTPCreateDir(inUrl);
+            SignFtpUtil.FTPCreateDir(outUrl);
+            String locPdfUrl = inUrl + "/" + filecode + ".pdf";
+            String OutPdfUrl = outUrl + "/" + filecode + ".pdf";
+
+            InputStream inputStream = new ByteArrayInputStream(fileByte);
+            int i = SignFtpUtil.uploadFile(locPdfUrl, inputStream);
+            if (i == 1) {
+                result = eVisaService.signPdfByAXQZ(pdfVO, locPdfUrl, OutPdfUrl);
+                int i1 = SignFtpUtil.downloadFile(dataFileUrl, OutPdfUrl);
+                fileUrl = dataFileUrl;
+                SignFtpUtil.FTPDeleteDir(locPdfUrl);
+                SignFtpUtil.FTPDeleteDir(OutPdfUrl);
+            }
+        } else {
+            result = eVisaService.signPdfByAXQZ(pdfVO, fileByte);
+            //执行电签
+            if (result != null) {
+                try {
+                    ByteArrayInputStream inputStream = new ByteArrayInputStream((byte[]) result[0]);
+                    FileOutputStream fout = new FileOutputStream(dataFileUrl);
+                    int bytesRead = 0;
+                    byte[] buffer = new byte[8192];
+                    while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) {
+                        fout.write(buffer, 0, bytesRead);
+                    }
+                    fout.close();
+                    fileUrl = dataFileUrl;
+                } catch (Exception e) {
+                    taskApp.setSigState(2);
+                    taskApp.setSignSmg("二进制流读取本地失败");
+                    SignBackPdfInfo(taskApp);
+                    return;
+                }
+            }
+        }
+
+        if (fileUrl.indexOf("aliyuncs.com") >= 0 || fileUrl.indexOf("183.247.216.148") >= 0 || fileUrl.indexOf("152.168.2.15") >= 0) {
+            taskApp.setSigState(2);
+            taskApp.setSignSmg("电签后-无法读取本地文件");
+            SignBackPdfInfo(taskApp);
+            return;
+        } else {
+            BladeFile bladeFile = this.newIOSSClient.uploadFile(SnowFlakeUtil.getId() + ".pdf", fileUrl);
+            if (bladeFile != null) {
+                taskApp.setLastFilePdfUrl(bladeFile.getLink());
+                taskApp.setSignSmg("电签成功");
+            } else {
+                taskApp.setSigState(2);
+                taskApp.setSignSmg("上传OSS失败"+fileUrl);
+                SignBackPdfInfo(taskApp);
+                return;
+            }
+        }
+    }
+}

+ 105 - 52
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/service/impl/EVisaServiceImpl.java

@@ -95,7 +95,7 @@ import java.util.stream.Collectors;
 @AllArgsConstructor
 public class EVisaServiceImpl implements EVisaService {
 
- //   private static final String SIGN_HOST = "172.30.224.79";
+ //  private static final String SIGN_HOST = "172.30.224.79";
     private static final String SIGN_HOST = "47.115.117.246";
 
     private static final String SIGN_PORT = "8183";
@@ -410,15 +410,20 @@ public class EVisaServiceImpl implements EVisaService {
             taskFile = this.taskClient.queryBusinessDataTask(JSONObject.parseObject(JSONObject.toJSONString(task), TaskApprovalVO.class));
         } else if ( task.getApprovalType()>=5) {
            // 计量任务类型  5 = 中间计量申请,6 = 材料计量单,7 = 开工预付款计量单,8 = 变更令
-            Map<String, Object> map =new HashMap<>();
-            if(task.getApprovalType()==6 || task.getApprovalType()==7){
-                map = this.jdbcTemplate.queryForMap("select * from  s_material_start_statement where is_deleted=0 and meter_period_id = " + task.getFormDataId());
-                taskFile.setApprovalFileList(map.get("period_number")+"", map.get("raw_url")+"");
-            }else if (task.getApprovalType()==5) {
-                map = this.jdbcTemplate.queryForMap("select * from s_interim_pay_certificate where  is_deleted=0 and contract_period_id = " + task.getFormDataId());
-                taskFile.setApprovalFileList(map.get("period_number")+"", map.get("raw_url")+"");
+            try {
+                Map<String, Object> map = new HashMap<>();
+                if (task.getApprovalType() == 6 || task.getApprovalType() == 7) {
+                    map = this.jdbcTemplate.queryForMap("select * from  s_material_start_statement where is_deleted=0 and meter_period_id = " + task.getFormDataId());
+                    taskFile.setApprovalFileList(map.get("period_number") + "", map.get("raw_url") + "");
+                } else if (task.getApprovalType() == 5) {
+                    map = this.jdbcTemplate.queryForMap("select * from s_interim_pay_certificate where  is_deleted=0 and contract_period_id = " + task.getFormDataId());
+                    taskFile.setApprovalFileList(map.get("period_number") + "", map.get("raw_url") + "");
+                }
+                taskFile.setRemarkType("1");
+            }catch (Exception e) {
+                RedisTemplate.delete("sign-" + task.getFormDataId());
+                return NOT_PFX_SGIN;
             }
-            taskFile.setRemarkType("1");
         }
 
         if (taskFile == null || taskFile.getApprovalFileList().size() <= 0) {
@@ -439,6 +444,7 @@ public class EVisaServiceImpl implements EVisaService {
                 }
                 String pdfUrl = file.getFileUrl();
                 pdfUrl = CommonUtil.replaceOssUrl(pdfUrl);
+                System.out.println("11111111"+pdfUrl);
                 List<String> eVisaConfigList = PDFUtils.getPdfSignIds(pdfUrl);
                 if (eVisaConfigList == null || eVisaConfigList.size() == 0) {
                     //没有电签配置,默认当前任务为不签字审批,返回成功
@@ -500,6 +506,7 @@ public class EVisaServiceImpl implements EVisaService {
                            // daMa.put("sealOffsetX",-30);
                             byte[] fileByte;
                             if (fileUrl.indexOf("aliyuncs.com") >= 0 || fileUrl.indexOf("183.247.216.148") >= 0 || fileUrl.indexOf("152.168.2.15") >= 0) {
+                                System.out.println("2222222"+pdfUrl);
                                 URL url =new URL(pdfUrl);
                                 fileByte = IOUtils.toByteArray(url);
                             } else {
@@ -588,11 +595,13 @@ public class EVisaServiceImpl implements EVisaService {
                         vo.setOffSetX(eVisaConfig.get("pyzbx") + "");
                         vo.setOffSetY(eVisaConfig.get("pyzby") + "");
                         sealStrategyVOS.add(vo);
+
                     }
                     SealPdfVO pdfVO = new SealPdfVO();
                     pdfVO.setStrategyVoList(sealStrategyVOS);
 
                     //获取字节
+
                     URL url = new URL(pdfUrl);
                     byte[] fileByte;
                     try {
@@ -623,7 +632,6 @@ public class EVisaServiceImpl implements EVisaService {
                 }
             }
         } catch (Exception e) {
-            System.out.println("------5------");
             RedisTemplate.delete("sign-" + task.getFormDataId());
             e.printStackTrace();
         }
@@ -774,52 +782,13 @@ public class EVisaServiceImpl implements EVisaService {
         return "";
     }
 
-    public static void main22(String[] args) throws Exception {
-       // String pdfPath ="/Users/hongchuangyanfa/Desktop/pdf/1788120810012016640123.pdf";
-        String pdfPath ="/Users/hongchuangyanfa/Desktop/pdf/outPdf.pdf";
-        String sealId ="0ff724e095fc4a16b9c9c25ebe44e68f";
-        String formDataId ="vv";
-        List<Map<String,Object>> maps = new ArrayList<>();
-        Map<String,Object> daMap = new HashMap<>();
-        daMap.put("keyWord","12345");
-        daMap.put("sealId",sealId);
-        //设置显示签字体的宽高
-        daMap.put("showHeight",30);
-        daMap.put("showWidth",60);
-        //设置显示签字体的位置
-       // daMap.put("sealOffsetY",-15);
-       // daMap.put("sealOffsetX",-30);
-
-        maps.add(daMap);
-
-        String fileUrl =pdfPath;
-        for(int i=0;i<maps.size();i++){
-            HashMap daMa  = (HashMap) maps.get(i);
-            FileReader fileReader = new FileReader(fileUrl);
-            String originalFileB64 = Base64.toBase64String(fileReader.readBytes());
-            daMa.put("fileB64", originalFileB64);
-            daMa.put("lastSignFlag", false);
-
-            if(maps.size()==1){
-                 signPdfByDFZX(daMa);
-            }else{
-              String reData =  signPdfByDFZX(daMa);
-              if(reData.indexOf("success@")>=0){
-                  fileUrl = reData.split("@@@@")[1];
-              }
-
-            }
-            System.out.println(fileUrl);
-        }
-    }
-
 
     /**
      * 东方 中讯
      *
      * @throws Exception
      */
-    public static String signPdfByDFZX(HashMap<String, Object> request) {
+    public String signPdfByDFZX(HashMap<String, Object> request) {
         String url = "http://39.108.216.210:9125/FrontSys/SealServicezx/FileSignByKeyWord";
 
         String sysLocalFileUrl = FileUtils.getSysLocalFileUrl();
@@ -870,13 +839,14 @@ public class EVisaServiceImpl implements EVisaService {
     }
 
 
+
     /**
      * 安心 - 签章
      */
-    private Object[] signPdfByAXQZ(SealPdfVO pdfVO, byte[] fileByte) {
+    public Object[] signPdfByAXQZ(SealPdfVO pdfVO, byte[] fileByte) {
         Object[] result = new Object[3];
         try {
-            PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 18000000, 72000000);
+            PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 240000000, 810000000);
             paperlessClient.setSSL(false);
             //*****************************************************************************
             CompoundSealPdfListDetachedRequest compoundSealPdfListDetachedRequest = new CompoundSealPdfListDetachedRequest();
@@ -905,6 +875,8 @@ public class EVisaServiceImpl implements EVisaService {
             pdfBean.setInputType(BaseConstants.INPUT_TYPE_FILEDATA);
             logger.info("【电签模块】pdf{}", "长度"+fileByte.length);
             pdfBean.setPdfData(fileByte);
+           // pdfBean.set
+            //pdfBean.set
             pdfBeans.add(pdfBean);
 
             requestBody.setPdfBeans(pdfBeans);
@@ -1659,4 +1631,85 @@ public class EVisaServiceImpl implements EVisaService {
             return R.fail("电签解析失败");
         }
     }
+
+    /**
+     * 安心 - 签章
+     */
+    public Object[] signPdfByAXQZ(SealPdfVO pdfVO, String loPdfurl,String outPdfUrl) {
+        Object[] result = new Object[3];
+        try {
+            PaperlessClient paperlessClient = new PaperlessClient(SIGN_HOST, SIGN_PORT, 240000000, 810000000);
+            paperlessClient.setSSL(false);
+            //*****************************************************************************
+            CompoundSealPdfListDetachedRequest compoundSealPdfListDetachedRequest = new CompoundSealPdfListDetachedRequest();
+
+            RequestHead requestHead = new RequestHead();
+            //业务流水号 非空
+            String transactionNo = GUIDUtil.generateId();
+            //机构编码非空
+            String organizationCode = EVisaConstant.organizationCode;
+            //操作员编码 可为空(企业类型不能为空)
+            String operatorCode = EVisaConstant.operationCode;
+            //渠道编码 可为空
+            String channelCode = "";
+            //设置属性
+            requestHead.setBasicInfo(transactionNo, organizationCode, operatorCode, channelCode);
+
+            compoundSealPdfListDetachedRequest.setHead(requestHead);
+
+            //*****************************************************************************
+            CompoundSealPdfListRequestBody requestBody = new CompoundSealPdfListRequestBody();
+
+            List<PdfBean> pdfBeans = new ArrayList<>();
+            PdfBean pdfBean = new PdfBean();
+            pdfBean.setBizSerialNo(GUIDUtil.generateId());
+            pdfBean.setInputSource("/mnt/bladesign"+loPdfurl);
+            pdfBean.setInputType(BaseConstants.INPUT_TYPE_FILEPATH);
+            pdfBeans.add(pdfBean);
+            requestBody.setPdfBeans(pdfBeans);
+            //***********************构造机构章策略 ********************************
+            List<SealStrategy> sealStrategies = generateSealStrategies(pdfVO.getStrategyVoList());
+            if (null == sealStrategies || sealStrategies.size() <= 0) {
+                logger.info("【电签模块】{}", "签章策略为空");
+                return null;
+            }
+            requestBody.setSealStrategies(sealStrategies);
+
+            //签章后文件保存地址,不为空时,直接将签章文件保存在此地址,不再返回签章后文档数据;ftp:auto
+            requestBody.setOutputFilepath("/mnt/bladesign"+outPdfUrl);
+
+            //时间戳方式,默认为0;0:实时访问CFCA 时间戳服务;1:使用从CFCA购置并在本地部署的时间戳服务器产品;
+            requestBody.setTimestampChannel(BaseConstants.TIME_STAMP_CHANNEL_CFCA);
+            //获取场景证书的方式默认值为0;0:实时从CFCA CA服务申请下载场景证书;1:使用从CFCA CA服务预先申请下载并存储在本地的场景证书;
+            requestBody.setSceneCertChannel(BaseConstants.SCEND_CERT_CHANNEL_REAL);
+
+            compoundSealPdfListDetachedRequest.setBody(requestBody);
+            //****************************** 请求服务端进行签章 *********************************************
+            System.out.println("-----------------------" + new Date().toString() + "开始" + transactionNo + "----------------------------");
+
+            ResponseDto responseDto = paperlessClient.execute(compoundSealPdfListDetachedRequest);
+
+            System.out.println("-----------------------" + new Date().toString() + "结束" + transactionNo + "----------------------------");
+            //******************************解析响应结果 *********************************************
+            CompoundSealPdfListDetachedResponse compoundSealPdfListDetachedResponse = (CompoundSealPdfListDetachedResponse) responseDto;
+            ResponseHead responseHead = compoundSealPdfListDetachedResponse.getHead();
+            CompoundSealPdfListDetachedResponseBody responseBody = compoundSealPdfListDetachedResponse.getBody();
+            if (ClientConstants.CODE_SUCCESS.equals(responseHead.getCode())) {
+                List<PdfBean4Response> pdfBeanList = responseBody.getPdfBeans();
+                if (pdfBeanList != null && pdfBeanList.size() > 0) {
+                    PdfBean4Response pdfBean4Response = pdfBeanList.get(0);
+                    result[0] = pdfBean4Response.getPdf();
+                }
+            } else {
+                logger.info("【电签模块】{}", "签章响应Response:" + compoundSealPdfListDetachedResponse);
+                logger.info("【电签模块】{}", "签章响应code:" + responseHead.getCode());
+                result[0] = null;
+                result[1] = compoundSealPdfListDetachedResponse.toString();
+                result[2] = responseHead.getMessage();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
 }

+ 20 - 37
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/PDFUtils.java

@@ -1,61 +1,44 @@
 package org.springblade.evisa.utils;
 
-import com.spire.pdf.PdfDocument;
-import com.spire.pdf.PdfPageBase;
-import com.spire.pdf.general.find.PdfTextFind;
-import com.spire.pdf.general.find.PdfTextFindCollection;
-import com.spire.pdf.utilities.PdfTable;
-import com.spire.pdf.utilities.PdfTableExtractor;
-
-import org.apache.commons.io.IOUtils;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.text.PDFTextStripper;
 import org.springblade.common.utils.CommonUtil;
 import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.ResourceUtil;
 
-import java.io.File;
-import java.io.FileInputStream;
 import java.io.InputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.stream.Collectors;
 
 
 public class PDFUtils {
-    public static synchronized List<String>  getPdfSignIds(String pdfUrl) {
-        PdfDocument pdf = new PdfDocument();
+    public static List<String>  getPdfSignIds(String pdfUrl) {
         List<String> eVisaConfigList = new ArrayList<>();
-        try {
-            pdfUrl = CommonUtil.replaceOssUrl(pdfUrl);
-            URL url =new URL(pdfUrl);
-            byte[] byteArray = IOUtils.toByteArray(url);
-            pdf.loadFromBytes(byteArray);
-            for(int i= 0;i<pdf.getPages().getCount();i++){
-                PdfPageBase page = pdf.getPages().get(i);
-                PdfTextFindCollection allText = page.findAllText();
-                PdfTextFind[] finds = allText.getFinds();
-                for(int k=0;k<finds.length;k++){
-                    String textStr = finds[k].getMatchText();
-                    if(textStr.indexOf("*")>=0){
-                        textStr = textStr.substring(textStr.lastIndexOf("*")+1,textStr.length());
-                    }
-                    String[] textS = Func.toStrArray("\\|\\|",textStr);
-                    for(String txt : textS){
-                        if (txt.length() >= 15 && Func.isNumeric(txt)) {
-                            eVisaConfigList.add(txt);
-                        }
+        try  {
+            InputStream inputStream = CommonUtil.getOSSInputStream(pdfUrl);
+            PDDocument document = PDDocument.load(inputStream);
+            PDFTextStripper stripper = new PDFTextStripper();
+            String text = stripper.getText(document);
+            String[] lines = text.split("[ \\n]+");
+            for(int k=0;k<lines.length;k++){
+                String textStr = lines[k];
+                if(textStr.indexOf("*")>=0){
+                    textStr = textStr.substring(textStr.lastIndexOf("*")+1,textStr.length());
+                }
+                String[] textS = Func.toStrArray("\\|\\|",textStr);
+                for(String txt : textS){
+                    if (txt.length() >= 15 && Func.isNumeric(txt)) {
+                        eVisaConfigList.add(txt);
                     }
                 }
             }
+
             List<String> unique = eVisaConfigList.stream().distinct().collect(Collectors.toList());
+            document.close();
             return unique;
         }catch (Exception e){
             e.printStackTrace();
             return null;
-        }finally {
-            pdf.close();
         }
     }
 

+ 386 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/PdfAddimgUtil.java

@@ -0,0 +1,386 @@
+package org.springblade.evisa.utils;
+
+import com.itextpdf.text.BaseColor;
+import com.itextpdf.text.Element;
+import com.itextpdf.text.Image;
+import com.itextpdf.text.Rectangle;
+import com.itextpdf.text.pdf.*;
+import com.itextpdf.text.pdf.parser.*;
+import org.springblade.common.constant.CommonConstant;
+import org.springblade.core.tool.utils.Func;
+import org.springblade.manager.entity.TextdictInfo;
+import org.springblade.manager.vo.PDFIndexInfo;
+import org.springblade.system.cache.ParamCache;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class PdfAddimgUtil {
+
+    public static void pdfAddImgInfo(String pdfUrl, String keyword, Map<Long, TextdictInfo> textMap) throws Exception {
+        String file_path = FileUtils.getSysLocalFileUrl();
+        String signImg = file_path+"/print/241dc221f83929a87d55ce700d6a4cd7.png";
+
+        File pdfFile = new File(pdfUrl);
+        byte[] pdfData = new byte[(int) pdfFile.length()];
+        FileInputStream inputStream = null;
+        try {
+            inputStream = new FileInputStream(pdfFile);
+            inputStream.read(pdfData);
+        } catch (IOException e) {
+            throw e;
+        } finally {
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                } catch (IOException e) {
+                    inputStream.close();
+                }
+            }
+        }
+
+
+        List<PDFIndexInfo> positions = findKeywordPostions(pdfData, keyword);
+
+        System.out.println("total:" + positions.size());
+        if (positions != null && positions.size() > 0) {
+
+            for (int i = 0; i < positions.size(); i++) {
+
+                PDFIndexInfo pdfIndexInfo = positions.get(i);
+                float[] position = pdfIndexInfo.getDataInfo();
+                TextdictInfo textdictInfo = textMap.get(Func.toLong(pdfIndexInfo.getPkeyid()));
+                float pyzbx = 0;
+                float pyzby = 0;
+                String type ="2";
+                if(textdictInfo!=null){
+                    pyzbx = Func.toFloat(textdictInfo.getPyzbx());
+                    pyzby = Func.toFloat(textdictInfo.getPyzby());
+                    type = textdictInfo.getType()+"";
+                }
+                gaizhang(pdfFile, new File(pdfUrl), (int) position[0], position[1], position[2], signImg,pyzbx,pyzby,type);
+            }
+        }
+    }
+
+    public static void gaizhang(File src, File dest, int page, float x, float y, String imagePath,float pyzbx,float pyzby,String type) throws Exception {
+        // 读取模板文件
+        String sysLocalFileUrl = FileUtils.getSysLocalFileUrl();
+        InputStream input = new FileInputStream(src);
+        PdfReader reader = new PdfReader(input);
+        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
+        Rectangle pageSize = reader.getPageSize(1);
+        float height = pageSize.getHeight();
+        float width = pageSize.getWidth();
+        if(type.equals("6")){
+            x = width * x - 27+pyzbx;
+            y = height - height * y - 30+pyzby;
+            imagePath = sysLocalFileUrl + "/print/ht1234567890.png";
+        }else{
+            x = width * x - 20+pyzbx;
+            y = height - height * y - 8+pyzby;
+        }
+
+        // 读图片
+        Image image = Image.getInstance(imagePath);
+
+        // 获取操作的页面
+        PdfContentByte under = stamper.getOverContent(page);
+        // 添加图片
+
+        // 设置图片的新宽度和高度
+        float newWidth = 75f; // 新的宽度
+        float newHeight = image.getScaledHeight() * (newWidth / image.getScaledWidth()); // 根据宽度计算高度
+        image.scaleAbsolute(newWidth, newHeight); // 设置图片的新尺寸
+        //调整图片尺寸
+        image.setAbsolutePosition(x, y);
+        under.addImage(image);
+        // 假设的under.addImage方法,需要传入图片路径和大小参数
+        stamper.close();
+        reader.close();
+    }
+
+    /**
+     * 【功能描述:添加图片和文字水印】 【功能详细描述:功能详细描述】
+     *
+     * @param srcFile    待加水印文件
+     * @param destFile   加水印后存放地址
+     * @param text       加水印的文本内容
+     * @param textWidth  文字横坐标
+     * @param textHeight 文字纵坐标
+     * @throws Exception
+     */
+    public void addWaterMark(String srcFile, String destFile, String text,
+                             int textWidth, int textHeight) throws Exception {
+        // 待加水印的文件
+        PdfReader reader = new PdfReader(srcFile);
+        // 加完水印的文件
+        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(
+                destFile));
+        int total = reader.getNumberOfPages() + 1;
+        PdfContentByte content;
+        // 设置字体
+        BaseFont font = BaseFont.createFont();
+        // 循环对每页插入水印
+        for (int i = 1; i < total; i++) {
+            // 水印的起始
+            content = stamper.getUnderContent(i);
+            // 开始
+            content.beginText();
+            // 设置颜色 默认为蓝色
+            content.setColorFill(BaseColor.BLUE);
+            // content.setColorFill(Color.GRAY);
+            // 设置字体及字号
+            content.setFontAndSize(font, 38);
+            // 设置起始位置
+            // content.setTextMatrix(400, 880);
+            content.setTextMatrix(textWidth, textHeight);
+            // 开始写入水印
+            content.showTextAligned(Element.ALIGN_LEFT, text, textWidth,
+                    textHeight, 45);
+            content.endText();
+        }
+        stamper.close();
+    }
+
+    /**
+     * findKeywordPostions
+     *
+     * @param pdfData
+     * @param keyword
+     * @return List<float [ ]> : float[0]:pageNum float[1]:x float[2]:y
+     * @throws IOException
+     */
+    public static List<PDFIndexInfo> findKeywordPostions(byte[] pdfData,
+                                                    String keyword) throws IOException {
+        List<PDFIndexInfo> result = new ArrayList<PDFIndexInfo>();
+        List<PdfPageContentPositions> pdfPageContentPositions = getPdfContentPostionsList(pdfData);
+
+        for (PdfPageContentPositions pdfPageContentPosition : pdfPageContentPositions) {
+            List<PDFIndexInfo> charPositions = findPositions(keyword,
+                    pdfPageContentPosition);
+            if (charPositions == null || charPositions.size() < 1) {
+                continue;
+            }
+            result.addAll(charPositions);
+        }
+        return result;
+    }
+
+    /**
+     * findKeywordPostions
+     *
+     * @param pdfData
+     * @return List<float [ ]> : float[0]:pageNum float[1]:x float[2]:y
+     * @throws IOException
+     */
+    public static List<PDFIndexInfo> findAllwordPostions(byte[] pdfData) throws IOException {
+        List<PDFIndexInfo> result = new ArrayList<PDFIndexInfo>();
+        List<PdfPageContentPositions> pdfPageContentPositions = getPdfContentPostionsList(pdfData);
+
+        for (PdfPageContentPositions pdfPageContentPosition : pdfPageContentPositions) {
+            PDFIndexInfo pdfIndexInfo = new PDFIndexInfo();
+            pdfIndexInfo.setListData(pdfPageContentPosition.getPositions());
+            pdfIndexInfo.setPkeyid(pdfPageContentPosition.getContent());
+            result.add(pdfIndexInfo);
+        }
+        return result;
+    }
+
+
+    static List<PdfPageContentPositions> getPdfContentPostionsList(
+            byte[] pdfData) throws IOException {
+        PdfReader reader = new PdfReader(pdfData);
+
+        List<PdfPageContentPositions> result = new ArrayList<PdfPageContentPositions>();
+
+        int pages = reader.getNumberOfPages();
+        for (int pageNum = 1; pageNum <= pages; pageNum++) {
+            float width = reader.getPageSize(pageNum).getWidth();
+            float height = reader.getPageSize(pageNum).getHeight();
+
+            PdfRenderListener pdfRenderListener = new PdfRenderListener(
+                    pageNum, width, height);
+
+            // 解析pdf,定位位置
+            PdfContentStreamProcessor processor = new PdfContentStreamProcessor(
+                    pdfRenderListener);
+            PdfDictionary pageDic = reader.getPageN(pageNum);
+            PdfDictionary resourcesDic = pageDic.getAsDict(PdfName.RESOURCES);
+            try {
+                processor.processContent(ContentByteUtils
+                        .getContentBytesForPage(reader, pageNum), resourcesDic);
+            } catch (IOException e) {
+                reader.close();
+                throw e;
+            }
+
+            String content = pdfRenderListener.getContent();
+            List<CharPosition> charPositions = pdfRenderListener
+                    .getcharPositions();
+
+            List<float[]> positionsList = new ArrayList<float[]>();
+            for (CharPosition charPosition : charPositions) {
+                float[] positions = new float[]{charPosition.getPageNum(),
+                        charPosition.getX(), charPosition.getY()};
+                positionsList.add(positions);
+            }
+
+            PdfPageContentPositions pdfPageContentPositions = new PdfPageContentPositions();
+            pdfPageContentPositions.setContent(content);
+            pdfPageContentPositions.setPostions(positionsList);
+
+            result.add(pdfPageContentPositions);
+        }
+        reader.close();
+        return result;
+    }
+
+
+    private static List<PDFIndexInfo> findPositions(String keyword,
+                                                    PdfPageContentPositions pdfPageContentPositions) {
+
+        List<PDFIndexInfo> result =new ArrayList<>();
+        String content = pdfPageContentPositions.getContent();
+        List<float[]> charPositions = pdfPageContentPositions.getPositions();
+
+        List<String> strList = Func.toStrList(keyword);
+        for (String text : strList) {
+            for (int pos = 0; pos < content.length(); ) {
+                PDFIndexInfo data= new PDFIndexInfo();
+                int positionIndex = content.indexOf(text, pos);
+                if (positionIndex == -1) {
+                    break;
+                }
+                float[] postions = charPositions.get(positionIndex);
+                data.setDataInfo(postions);
+                data.setPkeyid(text);
+                result.add(data);
+                pos = positionIndex + 1;
+            }
+        }
+        return result;
+    }
+
+
+    private static class PdfPageContentPositions {
+        private String content;
+        private List<float[]> positions;
+
+        public String getContent() {
+            return content;
+        }
+
+        public void setContent(String content) {
+            this.content = content;
+        }
+
+        public List<float[]> getPositions() {
+            return positions;
+        }
+
+        public void setPostions(List<float[]> positions) {
+            this.positions = positions;
+        }
+    }
+
+    private static class PdfRenderListener implements RenderListener {
+        private int pageNum;
+        private float pageWidth;
+        private float pageHeight;
+        private StringBuilder contentBuilder = new StringBuilder();
+        private List<CharPosition> charPositions = new ArrayList<CharPosition>();
+
+        public PdfRenderListener(int pageNum, float pageWidth, float pageHeight) {
+            this.pageNum = pageNum;
+            this.pageWidth = pageWidth;
+            this.pageHeight = pageHeight;
+        }
+
+        @Override
+        public void beginTextBlock() {
+
+        }
+
+        @Override
+        public void renderText(TextRenderInfo renderInfo) {
+            List<TextRenderInfo> characterRenderInfos = renderInfo
+                    .getCharacterRenderInfos();
+            for (TextRenderInfo textRenderInfo : characterRenderInfos) {
+                String word = textRenderInfo.getText();
+                if (word.length() > 1) {
+                    word = word.substring(word.length() - 1, word.length());
+                }
+                com.itextpdf.awt.geom.Rectangle2D.Float rectangle = textRenderInfo.getAscentLine()
+                        .getBoundingRectange();
+                double x = rectangle.getMinX();
+                double y = rectangle.getMaxY();
+
+                float xPercent = Math.round(x / pageWidth * 10000) / 10000f;
+                float yPercent = Math.round((1 - y / pageHeight) * 10000) / 10000f;//
+
+                CharPosition charPosition = new CharPosition(pageNum, xPercent,
+                        yPercent);
+                charPositions.add(charPosition);
+                contentBuilder.append(word);
+            }
+        }
+
+        @Override
+        public void endTextBlock() {
+
+        }
+
+        @Override
+        public void renderImage(ImageRenderInfo renderInfo) {
+
+        }
+
+        public String getContent() {
+            return contentBuilder.toString();
+        }
+
+        public List<CharPosition> getcharPositions() {
+            return charPositions;
+        }
+    }
+
+    private static class CharPosition {
+        private int pageNum = 0;
+        private float x = 0;
+        private float y = 0;
+
+        public CharPosition(int pageNum, float x, float y) {
+            this.pageNum = pageNum;
+            this.x = x;
+            this.y = y;
+        }
+
+        public int getPageNum() {
+            return pageNum;
+        }
+
+        public float getX() {
+            return x;
+        }
+
+        public float getY() {
+            return y;
+        }
+
+        @Override
+        public String toString() {
+            return "[pageNum=" + this.pageNum + ",x=" + this.x + ",y=" + this.y
+                    + "]";
+        }
+    }
+
+    public static String getNetUrl(String fileUrl){
+        String file_path = ParamCache.getValue(CommonConstant.SYS_LOCAL_URL);
+        String sys_file_net_url = ParamCache.getValue(CommonConstant.SYS_FILE_NET_URL);
+        String path = sys_file_net_url + fileUrl.replaceAll("//", "/").replaceAll(file_path, "");
+        return path;
+    }
+}

+ 219 - 0
blade-service/blade-e-visa/src/main/java/org/springblade/evisa/utils/SignFtpUtil.java

@@ -0,0 +1,219 @@
+package org.springblade.evisa.utils;
+
+import org.apache.commons.net.ftp.FTP;
+import org.apache.commons.net.ftp.FTPClient;
+
+import java.io.*;
+
+public class SignFtpUtil {
+
+    private static final String SERVER = "47.115.117.246";
+    private static final int PORT = 6233;
+    private static final String USER = "signAdmin";
+    private static final String PASS = "123456";
+    private static final int CONNECT_TIMEOUT = 30000; // 30秒
+    private static final int DATA_TIMEOUT = 30000; // 30秒
+
+    /**
+     *  获取ftp 客户端
+     * @return
+     */
+    public static FTPClient getFTPClinet() {
+        FTPClient ftp = new FTPClient();
+        try {
+            ftp.setControlEncoding("UTF-8");
+            // 设置连接超时时间
+            ftp.setConnectTimeout(CONNECT_TIMEOUT);
+            // 设置数据传输超时时间
+            ftp.setDataTimeout(DATA_TIMEOUT);
+            // 连接到FTP服务器
+            ftp.connect(SERVER, PORT);
+            ftp.setControlEncoding("UTF-8");
+            ftp.enterLocalPassiveMode();
+            ftp.setFileType(FTP.BINARY_FILE_TYPE);
+            ftp.enterLocalPassiveMode();//被动模式
+            //登录
+            boolean loginS = ftp.login(USER, PASS);
+            if (!loginS) {
+                return null;
+            } else {
+                return ftp;
+            }
+        } catch (IOException e) {
+            System.out.println("ftp连接失败");
+            return null;
+        }
+    }
+
+    /**
+     *  上传
+     * @return
+     */
+    public static int uploadFile(String localFilePath, String remoteFilePath) {
+        // 设置连接超时时间
+        FTPClient ftpClinet = SignFtpUtil.getFTPClinet();
+        try {
+            // 检查本地文件是否存在
+            File localFile = new File(localFilePath);
+            if (!localFile.exists()) {
+                return 2;
+            }
+            // 上传文件
+            FileInputStream inputStream = new FileInputStream(localFile);
+            try {
+                boolean done = ftpClinet.storeFile(remoteFilePath, inputStream);
+                if (done) {
+                    return 1;
+                } else {
+                    return 3;
+                }
+            } finally {
+                inputStream.close();
+            }
+
+        } catch (IOException e) {
+            e.printStackTrace();
+            return 4;
+        } finally {
+            try {
+                if (ftpClinet.isConnected()) {
+                    ftpClinet.logout();
+                    ftpClinet.disconnect();
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+                return 5;
+            }
+        }
+    }
+
+    /**
+     *  上传
+     * @return
+     */
+    public static int uploadFile(String remoteFilePath, InputStream inputStream) {
+        // 设置连接超时时间
+        FTPClient ftpClinet = SignFtpUtil.getFTPClinet();
+        try {
+            try {
+                boolean done = ftpClinet.storeFile(remoteFilePath, inputStream);
+                if (done) {
+                    return 1;
+                } else {
+                    return 3;
+                }
+            } finally {
+                inputStream.close();
+            }
+
+        } catch (IOException e) {
+            e.printStackTrace();
+            return 4;
+        } finally {
+            try {
+                if (ftpClinet.isConnected()) {
+                    ftpClinet.logout();
+                    ftpClinet.disconnect();
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+                return 5;
+            }
+        }
+    }
+
+    /**
+     *  删除FTP文件
+     * @return
+     */
+    public static int FTPDeleteDir(String remoteFilePath) {
+        FTPClient ftpClinet = SignFtpUtil.getFTPClinet();
+        try {
+            if (ftpClinet.deleteFile(remoteFilePath)) {
+                return 1;
+            } else {
+                return 2;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 2;
+        } finally {
+            try {
+                if (ftpClinet.isConnected()) {
+                    ftpClinet.logout();
+                    ftpClinet.disconnect();
+                }
+                return 1;
+            } catch (IOException ex) {
+                ex.printStackTrace();
+                return 5;
+            }
+        }
+    }
+    /**
+     *  创建文件路径
+     * @return
+     */
+    public static int FTPCreateDir(String remoteFilePath) {
+        FTPClient ftpClinet = SignFtpUtil.getFTPClinet();
+        try {
+            if (ftpClinet.makeDirectory(remoteFilePath)) {
+                return 1;
+            } else {
+                return 2;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 2;
+        } finally {
+            try {
+                if (ftpClinet.isConnected()) {
+                    ftpClinet.logout();
+                    ftpClinet.disconnect();
+                }
+                return 1;
+            } catch (IOException ex) {
+                ex.printStackTrace();
+                return 5;
+            }
+        }
+    }
+
+
+    /**
+     *  下载
+     * @return
+     */
+    public static int downloadFile(String localFilePath, String remoteFilePath) {
+        // 设置连接超时时间
+        FTPClient ftpClinet = SignFtpUtil.getFTPClinet();
+        try {
+            // 上传文件
+            OutputStream outputStream = new FileOutputStream(new File(localFilePath));
+            try {
+                boolean done = ftpClinet.retrieveFile(remoteFilePath, outputStream);
+                if (done) {
+                    return 1;
+                } else {
+                    return 3;
+                }
+            } finally {
+                outputStream.close();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+            return 4;
+        } finally {
+            try {
+                if (ftpClinet.isConnected()) {
+                    ftpClinet.logout();
+                    ftpClinet.disconnect();
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+                return 5;
+            }
+        }
+    }
+
+}

+ 26 - 59
blade-service/blade-manager/src/main/java/org/springblade/manager/service/impl/ExcelTabServiceImpl.java

@@ -3013,9 +3013,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
         ProjectInfo projectInfo = projectInfoService.getById(wbsTreePrivate.getProjectId());
         int all = sheet.getRow(0).getLastCellNum();
         int mergedCellCnt = sheet.getNumMergedRegions();
-        for (
-                int i = 0;
-                i < mergedCellCnt - 1; i++) {
+        for (int i = 0; i < mergedCellCnt - 1; i++) {
             CellRangeAddress mergedCell = sheet.getMergedRegion(i);
             int xx = mergedCell.getNumberOfCells();
             if (xx <= all) {
@@ -3148,15 +3146,6 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                                         }
 
                                         // 特殊处理多选框
-                                      /*  if(data.toString().indexOf("el-select")>=0 && myData.indexOf("[")>=0 && myData.indexOf(",")<0){
-                                            System.out.println("123123");
-                                            myData = myData.replace("[","").replace("]","");
-                                        }*/
-
-
-
-                                        //https:bladex-test-info.oss-cn-chengdu.aliyuncs.com//upload/20220819/b53cb6700db369381e3b03d7737bcdec.jpg__16_1
-                                        //http:bladex-test-info.oss-cn-chengdu.aliyuncs.com//upload/20220819/b53cb6700db369381e3b03d7737bcdec.jpg__16_1 可能是http
                                         if (myData.contains("http") && myData.contains("aliyuncs")) {
                                             InputStream imageIn = CommonUtil.getOSSInputStream(myData);
                                             byte[] byteNew = new byte[0];
@@ -3226,55 +3215,33 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
                 }
 
                 // 组装电签设置
-                QueryWrapper<TextdictInfo> queryWrapper = new QueryWrapper<>();
-                queryWrapper.select("col_key", "id");
-                queryWrapper.in("type", 2, 6);
-                queryWrapper.eq("tab_id", wbsTreePrivate.getPKeyId());
-
-                List<TextdictInfo> textdictInfos = textdictInfoService.getBaseMapper().selectList(queryWrapper);
-                if (textdictInfos != null && !textdictInfos.isEmpty()) {
-                    for (TextdictInfo e : textdictInfos) {
-                        String key = e.getColKey();
-                        String[] keys = key.split("__");
-                        String[] trtd = keys[1].split("_");
-                        if (Integer.parseInt(trtd[0]) < trs.size()) {
-                            Element ytzData = trs.get(Integer.parseInt(trtd[0]));
-                            if (ytzData != null) {
-                                Elements tdsx = ytzData.select("td");
-                                if (Integer.parseInt(trtd[1]) < tdsx.size()) {
-                                    Element data = ytzData.select("td").get(Integer.parseInt(trtd[1]));
-                                    if (data.html().contains("el-tooltip")) {
-                                        data = data.children().get(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"));
-
-                                    Row row = sheet.getRow(y1 - 1);
-                                    if (row != null) {
-                                        Cell cell = sheet.getRow(y1 - 1).getCell(x1 - 1);
-                                        if (cell != null) {
-                                            short fontIndex = cell.getCellStyle().getFontIndex();
-                                            Font oldfontAt = workbook.getFontAt(fontIndex);
+                Elements dqids = table.getElementsByAttribute("dqid");
+                for (Element element : dqids) {
+                    String dqid = element.attr("dqid");
+                    Elements x11 = element.getElementsByAttribute("x1");
+                    if (x11 != null && x11.size() >= 1) {
+                        Element element1 = x11.get(x11.size() - 1);
+                        int x1 = Func.toInt(element1.attr("x1"));
+                        int y1 = Func.toInt(element1.attr("y1"));
 
-                                            Font redFont = workbook.createFont();
-                                            redFont.setColor(IndexedColors.WHITE.getIndex()); //设置字体颜色
-                                            redFont.setFontHeightInPoints(oldfontAt.getFontHeightInPoints());//设置字体大小
-                                            redFont.setFontName(oldfontAt.getFontName());//设置字体
+                        Row row = sheet.getRow(y1 - 1);
+                        if (row != null) {
+                            Cell cell = row.getCell(x1 - 1);
+                            if (cell != null || ObjectUtils.isNotEmpty(cell)) {
+                                short fontIndex = cell.getCellStyle().getFontIndex();
+                                Font oldfontAt = workbook.getFontAt(fontIndex);
+                                Font redFont = workbook.createFont();
+                                redFont.setColor(IndexedColors.WHITE.getIndex()); //设置字体颜色
+                                redFont.setFontHeightInPoints(Short.valueOf("1"));//设置字体大小
+                                redFont.setFontName(oldfontAt.getFontName());//设置字体
+                                String CellValue = cell.getStringCellValue().trim();
 
-                                            CellStyle newStyle = workbook.createCellStyle(); //创建单元格样式
-                                            newStyle.cloneStyleFrom(cell.getCellStyle());
-                                            newStyle.setFont(redFont);
-                                            cell.setCellStyle(newStyle);
-                                            cell.setCellValue(e.getId() + "");
-                                        } else {
-                                            ObjectUtils.isNotEmpty(cell);
-                                        }
-                                    }
-                                }
+                                CellStyle newStyle = workbook.createCellStyle(); //创建单元格样式
+                                newStyle.cloneStyleFrom(cell.getCellStyle());
+                                newStyle.setFont(redFont);
+                                newStyle.setShrinkToFit(true);
+                                cell.setCellStyle(newStyle);
+                                cell.setCellValue(dqid);
                             }
                         }
                     }

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

@@ -117,7 +117,7 @@ public class FormulaDaoImpl implements IFormulaDao {
     @Override
     public Function<Long, MeterApproveOpinion> getApproveOpinionFc() {
         return  periodId-> {
-            List<MeterApproveOpinion> beans = this.jdbcTemplate.query("select b.* from u_task  a join s_meter_approve_opinion b on a.id=b.task_id where a.form_data_id="+periodId, new BeanPropertyRowMapper<>(MeterApproveOpinion.class));
+            List<MeterApproveOpinion> beans = this.jdbcTemplate.query("select b.* from u_task  a join s_meter_approve_opinion b on a.id=b.task_id where  a.form_data_id="+periodId, new BeanPropertyRowMapper<>(MeterApproveOpinion.class));
             if(beans.size()>0){
                 return beans.get(0);
             }

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

@@ -80,6 +80,7 @@ public class SignPfxFilePreServiceImpl implements ISignPfxFilePreService {
         Double wide = vo.getWide();
         //高度
         Double high = vo.getHigh();
+
         if(ObjectUtil.isEmpty(wide) && ObjectUtil.isEmpty(high)){
             if(ObjectUtil.isEmpty(file1)){
                 InputStream inputStreamByUrl1 = FileUtils.getInputStreamByUrl(vo.getFileStr());

+ 0 - 67
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/FTPUtils.java

@@ -1,67 +0,0 @@
-package org.springblade.manager.utils;
-
-import org.apache.commons.net.ftp.FTPClient;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-public class FTPUtils {
-    String hostname = "192.168.0.109";
-    int port = 21;
-    String username = "fileadmin";
-    String password = "DpE5aYNybfeDEMcD";
-
-    // 获取ftp 客户端
-    public FTPClient getFTPClinet(){
-        FTPClient ftp = new FTPClient();
-        ftp.setControlEncoding("UTF-8");
-        System.out.println("准备连接到ftp");
-        try {
-            //连接
-            ftp.connect(hostname, port);
-            //登录
-            boolean loginS = ftp.login(username, password);
-            if (!loginS) {
-                System.out.println("ftp登录失败,用户名或密码错误");
-                return null;
-            }else{
-                System.out.println("ftp登录成功");
-            }
-            return ftp;
-        } catch (IOException e) {
-            System.out.println("ftp连接失败");
-            return null;
-        }
-    }
-
-    //文件覆盖上传
-    public static void main1(String[] args) throws Exception {
-
-       // InputStream input = FileUtils.getInputStreamByUrl("http://192.168.0.109:6371/1534807810770993152.html");
-        String dataUrl = "/Users/hongchuangyanfa/Desktop/预览图_千图网_编号357539942.jpg";
-        InputStream input = new FileInputStream(new File(dataUrl));
-
-        FTPUtils ftpUtils = new FTPUtils();
-        try {
-            FTPClient ftp = ftpUtils.getFTPClinet();
-            // 获取本地文件并上传
-
-            ftp.changeWorkingDirectory("/localArchive/");//跳转目录
-            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);//必须要设置以二进制的方式传输文件
-            ftp.enterLocalPassiveMode();//被动模式
-
-            if (!ftp.storeFile("1534807810770993152.jpg", input)) {
-                System.out.println("失败,服务器返回:" + ftp.getReplyString());//获取上传失败的原因
-            } else {
-                System.out.println("文件:1534807810770993152.html 上传成功");
-            }
-            input.close();
-            ftp.logout();
-        } catch (IOException e) {
-            System.out.println("ftp连接失败");
-        }
-    }
-
-}

+ 1 - 2
blade-service/blade-manager/src/main/java/org/springblade/manager/utils/PdfAddimgUtil.java

@@ -217,6 +217,7 @@ public class PdfAddimgUtil {
         int newHeight = cmToPx(hign);
         image.scaleAbsolute(newWidth, newHeight); // 设置图片的新尺寸
         //调整图片尺寸
+       // image.scaleAbsolute(newWidth, newHeight);
         image.setAbsolutePosition(x, y);
         under.addImage(image);
         // 假设的under.addImage方法,需要传入图片路径和大小参数
@@ -323,9 +324,7 @@ public class PdfAddimgUtil {
     static List<PdfPageContentPositions> getPdfContentPostionsList(
             byte[] pdfData) throws IOException {
         PdfReader reader = new PdfReader(pdfData);
-
         List<PdfPageContentPositions> result = new ArrayList<PdfPageContentPositions>();
-
         int pages = reader.getNumberOfPages();
         for (int pageNum = 1; pageNum <= pages; pageNum++) {
             float width = reader.getPageSize(pageNum).getWidth();

+ 80 - 48
blade-service/blade-meter/src/main/java/org/springblade/meter/controller/TaskController.java

@@ -76,6 +76,7 @@ import org.springblade.meter.service.ITaskRepealMessageService;
 import org.springblade.meter.service.impl.*;
 import org.springblade.meter.utils.CollectionUtils;
 import org.springblade.meter.utils.CreateDashedLine;
+import org.springblade.meter.utils.ExcelImageExample;
 import org.springblade.meter.utils.FileUtils;
 import org.springblade.meter.vo.*;
 import org.springblade.resource.feign.NewIOSSClient;
@@ -3623,7 +3624,8 @@ public class TaskController extends BladeController {
             }
             pdfUrl = jdbcTemplate.queryForObject(sql, String.class, reportId);
             if (StringUtils.isBlank(pdfUrl)){
-                return R.fail("电签报表生成中,请稍后再试");
+                 calculate(reportId, type, taskType);
+                return R.fail("电签报表生成中,请稍后刷新查看");
             }
             return R.data(pdfUrl);
         }/*else if (task.getStatus() == 1){
@@ -3767,6 +3769,7 @@ public class TaskController extends BladeController {
                 StringBuffer sb = new StringBuffer();
                 reportResults.parallelStream().forEach(rs -> {
                     try {
+
                         byte[] excelByte = CommonUtil.InputStreamToBytes(CommonUtil.getOSSInputStream(rs.getExcelUrl()));
                         PdfReader reader = null;
                         Document doc = new Document();
@@ -3790,7 +3793,6 @@ public class TaskController extends BladeController {
                         Map<Integer, Set<CellRangeAddress>> mergeConfig = rs.buildMergeConfig();
                         for (int n = 0; n < rs.getData().size(); n++) {
                             Map<String, Object> dataMap = rs.getData().get(n);
-
                             try {
                                 Workbook workbook = WorkbookFactory.create(new ByteArrayInputStream(excelByte));
                                 //获取工作表
@@ -3800,27 +3802,55 @@ public class TaskController extends BladeController {
                                /* dataMap = setDQTimeInfo(dataMap, rs.getPkeyId(), report.getContractId(), report.getPeriodId(), rs.getUrl());*/
                                 if (Func.isNotEmpty(dataMap)) {
                                     for (String keys : dataMap.keySet()) {
-                                        int y1 = Func.toInt(keys.split("_")[0]);
-                                        int x1 = Func.toInt(keys.split("_")[1]);
-                                        Row row = sheet.getRow(y1 - 1);
-                                        if (row != null) {
-                                            Cell cell = row.getCell(x1 - 1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
-                                            String value = dataMap.getOrDefault(keys, StringPool.EMPTY).toString();
-                                            if (value.startsWith("http") && RegexUtil.find("(?i)[.](jpeg|png|jpg)", value)) {
-                                                InputStream imageIn = CommonUtil.getOSSInputStream(value);
-                                                if (imageIn != null) {
-                                                    byte[] bytes = IOUtils.toByteArray(imageIn);
-                                                   /* byte[] bytes = CommonUtil.compressImage(IOUtils.toByteArray(imageIn));*/
-                                                    CreationHelper helper = workbook.getCreationHelper();
-                                                    ClientAnchor anchor = helper.createClientAnchor();
-                                                    Drawing<?> drawing = sheet.createDrawingPatriarch();
-                                                    anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);
-                                                    Picture pict = drawing.createPicture(anchor, workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG)); // 调整图片占单元格百分比的大小,1.0就是100%
-                                                    pict.resize(1, 1);
-                                                    CollectionUtils.imageOrientation(sheet, anchor, new DataVO(x1 - 1, y1 - 1));
+                                        if(keys.indexOf(";")>=0 && keys.indexOf("_")>=0){
+                                            String [] keysw2 = keys.split(";");
+                                            for(String key3 : keysw2){
+                                                int y1 = Func.toInt(key3.split("_")[0]);
+                                                int x1 = Func.toInt(key3.split("_")[1]);
+                                                Row row = sheet.getRow(y1 - 1);
+                                                if (row != null) {
+                                                    Cell cell = row.getCell(x1 - 1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
+                                                    String value = dataMap.getOrDefault(keys, StringPool.EMPTY).toString();
+                                                    if (value.startsWith("http") && RegexUtil.find("(?i)[.](jpeg|png|jpg)", value)) {
+                                                        InputStream imageIn = CommonUtil.getOSSInputStream(value);
+                                                        if (imageIn != null) {
+                                                            byte[] bytes = IOUtils.toByteArray(imageIn);
+                                                            /* byte[] bytes = CommonUtil.compressImage(IOUtils.toByteArray(imageIn));*/
+                                                            CreationHelper helper = workbook.getCreationHelper();
+                                                            ClientAnchor anchor = helper.createClientAnchor();
+                                                            Drawing<?> drawing = sheet.createDrawingPatriarch();
+                                                            anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
+                                                            Picture pict = drawing.createPicture(anchor, workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG)); // 调整图片占单元格百分比的大小,1.0就是100%
+                                                            ExcelImageExample.addImgInfo(sheet, anchor,value, y1 - 1,x1 - 1 );
+                                                        }
+                                                    } else {
+                                                        cell.setCellValue(value);
+                                                    }
+                                                }
+                                            }
+                                        }else{
+                                            int y1 = Func.toInt(keys.split("_")[0]);
+                                            int x1 = Func.toInt(keys.split("_")[1]);
+                                            Row row = sheet.getRow(y1 - 1);
+                                            if (row != null) {
+                                                Cell cell = row.getCell(x1 - 1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
+                                                String value = dataMap.getOrDefault(keys, StringPool.EMPTY).toString();
+                                                if (value.startsWith("http") && RegexUtil.find("(?i)[.](jpeg|png|jpg)", value)) {
+                                                    InputStream imageIn = CommonUtil.getOSSInputStream(value);
+                                                    if (imageIn != null) {
+                                                        byte[] bytes = IOUtils.toByteArray(imageIn);
+                                                        CreationHelper helper = workbook.getCreationHelper();
+                                                        ClientAnchor anchor = helper.createClientAnchor();
+
+                                                        Drawing<?> drawing = sheet.createDrawingPatriarch();
+                                                        anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
+                                                        Picture pict = drawing.createPicture(anchor, workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG)); // 调整图片占单元格百分比的大小,1.0就是100%
+                                                        pict.resize();
+                                                        ExcelImageExample.addImgInfo(sheet, anchor,value, y1 - 1,x1 - 1 );
+                                                    }
+                                                } else {
+                                                    cell.setCellValue(value);
                                                 }
-                                            } else {
-                                                cell.setCellValue(value);
                                             }
                                         }
                                     }
@@ -3858,11 +3888,15 @@ public class TaskController extends BladeController {
                                 //去掉表格虚线
                                 sheet.setPrintGridlines(false);
                                 //设置 整个工作表为一页
+                                if(rs.getName().indexOf("400")>=0){
+                                    System.out.println("123");
+                                }
                                 sheet.setFitToPage(true);
                                 ByteArrayOutputStream out = new ByteArrayOutputStream();
                                 workbook.write(out);
                                 workbook.write(new FileOutputStream(rs.getExcelPath()));
                                 com.aspose.cells.Workbook wb = new com.aspose.cells.Workbook(new ByteArrayInputStream(out.toByteArray()));
+                             //   com.aspose.cells.Workbook wb = new com.aspose.cells.Workbook(new FileInputStream(rs.getExcelPath()));
                                 PageSetup pageSetup = wb.getWorksheets().get(0).getPageSetup();
                                 pageSetup.setCenterHorizontally(true);
                                 pageSetup.setCenterVertically(true);
@@ -3888,33 +3922,35 @@ public class TaskController extends BladeController {
                             String local = rs.getPdfPath();
                             String url = "无效链接";
                             try {
-                                if(rs.getPkeyId() == 1760845593422331904l){
+                                if(rs.getName().indexOf("施工进度表")>=0){
                                     System.out.println("zw+1===="+local);
                                     Map<String, Object> dataMap = rs.getData().get(0);
                                     // key_39 实际
-                                    String key39= rs.getCoordinateMap().get("key_39");
-                                    String[] split39 = key39.split(";");
-                                    // key_34 累计
-                                    String key34= rs.getCoordinateMap().get("key_34");
-                                    String[] split34 = key34.split(";");
-                                    List<String> list39 = new ArrayList<>();
-                                    for(String val39:split39){
-                                        String data39 = dataMap.get(val39) + "";
-                                        if(data39!=null && Func.isNotEmpty(data39)){
-                                            list39.add(data39);
-                                        }
+                                    if(dataMap!=null && rs.getCoordinateMap().containsKey("key_39") && rs.getCoordinateMap().containsKey("key_34")) {
+                                        String key39 = rs.getCoordinateMap().get("key_39");
+                                        String[] split39 = key39.split(";");
+                                        // key_34 累计
+                                        String key34 = rs.getCoordinateMap().get("key_34");
+                                        String[] split34 = key34.split(";");
+                                        List<String> list39 = new ArrayList<>();
+                                        for (String val39 : split39) {
+                                            String data39 = dataMap.get(val39) + "";
+                                            if (data39 != null && Func.isNotEmpty(data39)) {
+                                                list39.add(data39);
+                                            }
 
-                                    }
-                                    CreateDashedLine.getPDFInfo(local,list39,"1");
+                                        }
+                                        CreateDashedLine.getPDFInfo(local, list39, "1");
 
-                                    List<String> list34 = new ArrayList<>();
-                                    for(String val34:split34){
-                                        String data34 = dataMap.get(val34) + "";
-                                        if(data34!=null && Func.isNotEmpty(data34)) {
-                                            list34.add(dataMap.get(val34) + "");
+                                        List<String> list34 = new ArrayList<>();
+                                        for (String val34 : split34) {
+                                            String data34 = dataMap.get(val34) + "";
+                                            if (data34 != null && Func.isNotEmpty(data34)) {
+                                                list34.add(dataMap.get(val34) + "");
+                                            }
                                         }
+                                        CreateDashedLine.getPDFInfo(local, list34, "2");
                                     }
-                                    CreateDashedLine.getPDFInfo(local,list34,"2");
                                 }
 
                                 BladeFile bladeFile = newIOSSClient.uploadFile(rs.getName() + SnowFlakeUtil.getId() + ".pdf", local);
@@ -4117,7 +4153,7 @@ public class TaskController extends BladeController {
     }
 
 
-    // 添加电签任务列表
+    // 添加电签任务列表lL
     @Transactional
     public void addSignTaskBatch(Report report) {
         try {
@@ -4649,7 +4685,7 @@ public class TaskController extends BladeController {
                                             x1 = 1;
                                         }
                                         String myData = DataInfo.get(val) + "";
-                                        if (myData.contains("T") && myData.contains("-") && myData.contains(":")) {
+                                        if (myData.contains("T") && myData.contains("-") && myData.contains(":") && data.html().contains("date") && myData.length()<=60) {
                                             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
                                             sdf.setTimeZone(TimeZone.getTimeZone("GTM+8"));
                                             SimpleDateFormat formatStr = new SimpleDateFormat("yyyy年MM月dd日");
@@ -4847,9 +4883,7 @@ public class TaskController extends BladeController {
     }
 
     public Map<String, Object> getBussDataInfo(WbsTreePrivate aPrivate, Long taskId) {
-
         Map<String, Object> reData = new HashMap<>();
-
         //表单是否存储在
         String tabName = aPrivate.getInitTableName();
         String isExitSql = " select * from information_schema.TABLES where TABLE_NAME='" + tabName + "'";
@@ -4860,8 +4894,6 @@ public class TaskController extends BladeController {
 
         String querySql = "select * from " + aPrivate.getInitTableName() + " where p_key_id=" + taskId;
 
-
-        //String querySql = "select * from table_data_info where p_key_id=" + pkeyId;
         List<Map<String, Object>> dataIn = jdbcTemplate.queryForList(querySql);
 
         if (dataIn != null && dataIn.size() >= 1) {

+ 2 - 2
blade-service/blade-meter/src/main/java/org/springblade/meter/utils/CollectionUtils.java

@@ -176,8 +176,8 @@ public class CollectionUtils {
             anchor.setCol2(ca.getLastColumn());
             anchor.setRow2(ca.getLastRow());
         }
-        int dx = (int) (sheet.getColumnWidthInPixels(anchor.getCol2()) + 3);
-        int dy = Units.pointsToPixel(sheet.getRow(anchor.getRow2()).getHeightInPoints()) - 5;
+        int dx = (int) (sheet.getColumnWidthInPixels(anchor.getCol2()));
+        int dy = Units.pointsToPixel(sheet.getRow(anchor.getRow2()).getHeightInPoints());
         anchor.setDx2(Units.pixelToEMU(dx));
         anchor.setDy2(Units.pixelToEMU(dy));
     }

+ 269 - 0
blade-service/blade-meter/src/main/java/org/springblade/meter/utils/ExcelImageExample.java

@@ -0,0 +1,269 @@
+
+package org.springblade.meter.utils;
+
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.xssf.usermodel.*;
+import org.checkerframework.checker.units.qual.A;
+import org.springblade.common.utils.CommonUtil;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+
+public class ExcelImageExample {
+/*    public static void main(String[] args) {
+        String filePath = "/Users/hongchuangyanfa/Desktop/pdf/1750071431349174274_【2-16】工程计量表 (400章).xlsx";
+        String imagePath = "/Users/hongchuangyanfa/Desktop/excel/bc64d878fed6eff18a896641874594ea.jpg";
+       // String imagePath = "/Users/hongchuangyanfa/Desktop/excel/李茂.png";
+
+        try (FileInputStream fis = new FileInputStream(filePath);
+             FileInputStream imageStream = new FileInputStream(imagePath);
+             FileInputStream imageStream2 = new FileInputStream(imagePath);
+             FileOutputStream fos = new FileOutputStream("/Users/hongchuangyanfa/Desktop/excel/output.xlsx")) {
+            // 创建或读取工作簿
+            XSSFWorkbook workbook = new XSSFWorkbook(fis);
+            // 获取第一个工作表
+            XSSFSheet sheet = workbook.getSheetAt(0);
+
+            // 获取A5单元格
+            int rowIndex = 11; // 行索引从0开始,第5行
+            int colIndex = 0; // 列索引从0开始,A列
+            Row row = sheet.getRow(rowIndex);
+            if (row == null) {
+                row = sheet.createRow(rowIndex);
+            }
+
+            // 检查单元格是否被合并
+            boolean isMerged = false;
+            CellRangeAddress mergedRegion = null;
+            for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
+                CellRangeAddress region = sheet.getMergedRegion(i);
+                if (region.isInRange(rowIndex, colIndex)) {
+                    isMerged = true;
+                    mergedRegion = region;
+                    break;
+                }
+            }
+
+
+            ArrayList<Double> doubleList = new ArrayList<>();
+            doubleList.add(0.0);
+            int firstRow=0;
+            int lastRow = 0;
+            int firstCol=0;
+            int lastCol=0;
+            double totalRowHeight = 0;
+            // 计算合并单元格的宽度
+            double totalColumnWidth = 0.0;
+            double x_y_scale =  1071872.0/85.0;
+            if (isMerged) {
+                // 获取合并区域的范围
+                 firstRow = mergedRegion.getFirstRow();
+                 lastRow = mergedRegion.getLastRow();
+                 firstCol = mergedRegion.getFirstColumn();
+                 lastCol = mergedRegion.getLastColumn();
+
+                for (int col = firstCol; col <= lastCol; col++) {
+                    double columnWidthInPixels = sheet.getColumnWidth(col) / ((double) 1 / 256);
+                    totalColumnWidth += columnWidthInPixels;
+                    doubleList.add(totalColumnWidth/x_y_scale);
+                }
+
+                // 计算合并单元格的高度
+
+                for (int r = firstRow; r <= lastRow; r++) {
+                    Row currentRow = sheet.getRow(r);
+                    if (currentRow != null) {
+                        totalRowHeight += currentRow.getHeightInPoints();
+                    }
+                }
+
+                System.out.println("合并单元格A5的宽度(像素): " + totalColumnWidth);
+                System.out.println("合并单元格A5的高度(磅): " + totalRowHeight);
+            } else {
+                // 如果不是合并单元格,直接获取单个单元格的宽度和高度
+                int columnWidth = sheet.getColumnWidth(colIndex);
+                totalColumnWidth = columnWidth / ((double) 1 / 256); // 转换为像素
+                totalRowHeight = row.getHeightInPoints();
+                System.out.println("单元格A5的宽度(像素): " + totalColumnWidth);
+                System.out.println("单元格A5的高度(磅): " + totalRowHeight);
+            }
+
+            // 读取图片数据
+            byte[] pictureData = IOUtils.toByteArray(imageStream);
+            // 添加图片到工作簿
+            int pictureIdx = workbook.addPicture(pictureData, Workbook.PICTURE_TYPE_PNG);
+
+            // 创建绘图层
+            XSSFDrawing drawing = sheet.createDrawingPatriarch();
+
+            // 读取图片数据
+            BufferedImage bufferedImage = ImageIO.read(imageStream2);
+            int pictureWidth = bufferedImage.getWidth();
+            int pictureHeight = bufferedImage.getHeight();
+
+            // 计算缩放比例
+            double cell_width = totalColumnWidth / x_y_scale ;
+
+            // 图片的新宽度
+            double v = totalRowHeight * pictureWidth / pictureHeight;
+
+
+            System.out.println(v);
+            int dx1 =0;//(int)((cell_width - v)/2*x_y_scale*12700);
+            int dx2 =0; //-((int)((cell_width + v)/2*x_y_scale*12700));
+
+            double qy_x1 = (cell_width - v)/2;
+            double qy_x2 = (cell_width + v)/2;
+
+            // 计算水平居中偏移量
+            for (int i = 0; i < doubleList.size()-1; i++) {
+                if(qy_x1 >=doubleList.get(i) && qy_x1<=doubleList.get(i+1)){
+                    firstCol=i;
+                    dx1 = (int)(qy_x1*12700);
+                }
+
+                if(qy_x2 >=doubleList.get(i) && qy_x2<=doubleList.get(i+1)){
+                    lastCol = i;
+                    dx2 =  -((int)( (cell_width-qy_x2)*12700));
+                }
+            }
+
+            // 创建锚点,指定图片的位置和大小
+            ClientAnchor anchor = new XSSFClientAnchor();
+            anchor.setCol1(firstCol); // 列索引从0开始,A列
+            anchor.setRow1(firstRow); // 行索引从0开始,第5行
+            anchor.setDx1(dx1);  // 水平居中偏移量
+            anchor.setDy1(0);  // 垂直居中偏移量
+            anchor.setCol2(lastCol + 1); // 图片右下角所在的列
+            anchor.setRow2(lastRow+1 ); // 图片右下角所在的行
+            anchor.setDx2(-1*12700);  // 水平居中偏移量
+            anchor.setDy2(-2*12700);  // 垂直居中偏移量
+
+            anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
+            // 创建图片并设置锚点
+            drawing.createPicture(anchor, pictureIdx);
+            // 写入文件
+            workbook.write(fos);
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }*/
+
+    public static void addImgInfo(Sheet sheet,ClientAnchor anchor,String imagePath,int rowIndex,int colIndex){
+
+
+        try {
+            InputStream imageIn = CommonUtil.getOSSInputStream(imagePath);
+            Row row = sheet.getRow(rowIndex);
+            if (row == null) {
+                row = sheet.createRow(rowIndex);
+            }
+            // 检查单元格是否被合并
+            boolean isMerged = false;
+            CellRangeAddress mergedRegion = null;
+            for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
+                CellRangeAddress region = sheet.getMergedRegion(i);
+                if (region.isInRange(rowIndex, colIndex)) {
+                    isMerged = true;
+                    mergedRegion = region;
+                    break;
+                }
+            }
+
+            ArrayList<Double> doubleList = new ArrayList<>();
+            doubleList.add(0.0);
+            int firstRow=0;
+            int lastRow = 0;
+            int firstCol=0;
+            int lastCol=0;
+            double totalRowHeight = 0;
+            // 计算合并单元格的宽度
+            double totalColumnWidth = 0.0;
+            double x_y_scale =  1071872.0/85.0;
+            if (isMerged) {
+                // 获取合并区域的范围
+                firstRow = mergedRegion.getFirstRow();
+                lastRow = mergedRegion.getLastRow();
+                firstCol = mergedRegion.getFirstColumn();
+                lastCol = mergedRegion.getLastColumn();
+
+                for (int col = firstCol; col <= lastCol; col++) {
+                    double columnWidthInPixels = sheet.getColumnWidth(col) / ((double) 1 / 256);
+                    totalColumnWidth += columnWidthInPixels;
+                    doubleList.add(totalColumnWidth/x_y_scale);
+                }
+
+                // 计算合并单元格的高度
+
+                for (int r = firstRow; r <= lastRow; r++) {
+                    Row currentRow = sheet.getRow(r);
+                    if (currentRow != null) {
+                        totalRowHeight += currentRow.getHeightInPoints();
+                    }
+                }
+
+                System.out.println("合并单元格A5的宽度(像素): " + totalColumnWidth);
+                System.out.println("合并单元格A5的高度(磅): " + totalRowHeight);
+            } else {
+                // 如果不是合并单元格,直接获取单个单元格的宽度和高度
+                int columnWidth = sheet.getColumnWidth(colIndex);
+                totalColumnWidth = columnWidth / ((double) 1 / 256); // 转换为像素
+                totalRowHeight = row.getHeightInPoints();
+                System.out.println("单元格A5的宽度(像素): " + totalColumnWidth);
+                System.out.println("单元格A5的高度(磅): " + totalRowHeight);
+            }
+
+            // 读取图片数据
+            BufferedImage bufferedImage = ImageIO.read(imageIn);
+            int pictureWidth = bufferedImage.getWidth();
+            int pictureHeight = bufferedImage.getHeight();
+
+            // 计算缩放比例
+            double cell_width = totalColumnWidth / x_y_scale ;
+
+            // 图片的新宽度
+            double v = totalRowHeight * pictureWidth / pictureHeight;
+
+            System.out.println(v);
+            int dx1 =0;//(int)((cell_width - v)/2*x_y_scale*12700);
+            int dx2 =0; //-((int)((cell_width + v)/2*x_y_scale*12700));
+
+            double qy_x1 = (cell_width - v)/2;
+            double qy_x2 = (cell_width + v)/2;
+
+            // 计算水平居中偏移量
+            for (int i = 0; i < doubleList.size()-1; i++) {
+                if(qy_x1 >=doubleList.get(i) && qy_x1<=doubleList.get(i+1)){
+                    firstCol=i;
+                    dx1 = (int)(qy_x1*12700);
+                }
+
+                if(qy_x2 >=doubleList.get(i) && qy_x2<=doubleList.get(i+1)){
+                    lastCol = i;
+                    dx2 =  -((int)( (cell_width-qy_x2)*12700));
+                }
+            }
+
+            // 创建锚点,指定图片的位置和大小
+            anchor.setCol1(firstCol); // 列索引从0开始,A列
+            anchor.setRow1(firstRow); // 行索引从0开始,第5行
+            anchor.setDx1(dx1);  // 水平居中偏移量
+            anchor.setDy1(0);  // 垂直居中偏移量
+            anchor.setCol2(lastCol + 1); // 图片右下角所在的列
+            anchor.setRow2(lastRow+1 ); // 图片右下角所在的行
+            anchor.setDx2(-1*12700);  // 水平居中偏移量
+            anchor.setDy2(-2*12700);  // 垂直居中偏移量
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 6 - 0
blade-service/blade-meter/src/main/java/org/springblade/meter/utils/FileUtils.java

@@ -3,6 +3,9 @@ package org.springblade.meter.utils;
 import com.aspose.cells.SaveFormat;
 import org.apache.commons.lang.StringUtils;
 import org.apache.poi.hssf.usermodel.HSSFPrintSetup;
+import org.apache.poi.ss.usermodel.PrintSetup;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
 import org.apache.poi.xssf.usermodel.XSSFPrintSetup;
 import org.apache.poi.xssf.usermodel.XSSFSheet;
 import org.apache.poi.xssf.usermodel.XSSFWorkbook;
@@ -15,6 +18,7 @@ import org.springblade.common.utils.CommonUtil;
 import org.springblade.common.utils.SystemUtils;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.tool.utils.IoUtil;
+import org.springblade.core.tool.utils.ResourceUtil;
 import org.springblade.system.cache.ParamCache;
 
 import java.io.*;
@@ -180,4 +184,6 @@ public class FileUtils {
         }
         return file_path;
     }
+
+
 }

+ 1 - 0
blade-service/blade-meter/src/main/java/org/springblade/meter/utils/StringUtils.java

@@ -22,4 +22,5 @@ public class StringUtils {
             return originalStr;
         }
     }
+
 }